1 /* Utility routines for finding and reading Java(TM) .class files.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
3 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
29 #include "coretypes.h"
35 #include "java-tree.h"
44 /* DOS brain-damage */
46 #define O_BINARY 0 /* MS-DOS brain-damage */
50 jcf_unexpected_eof (JCF
*jcf
, int count ATTRIBUTE_UNUSED
)
53 fprintf (stderr
, "Premature end of .class file %s.\n", jcf
->filename
);
55 fprintf (stderr
, "Premature end of .class file <stdin>.\n");
60 jcf_trim_old_input (JCF
*jcf
)
62 int count
= jcf
->read_ptr
- jcf
->buffer
;
65 memmove (jcf
->buffer
, jcf
->read_ptr
, jcf
->read_end
- jcf
->read_ptr
);
66 jcf
->read_ptr
-= count
;
67 jcf
->read_end
-= count
;
72 jcf_filbuf_from_stdio (JCF
*jcf
, int count
)
74 FILE *file
= (FILE*) (jcf
->read_state
);
75 if (count
> jcf
->buffer_end
- jcf
->read_ptr
)
77 JCF_u4 old_read_ptr
= jcf
->read_ptr
- jcf
->buffer
;
78 JCF_u4 old_read_end
= jcf
->read_end
- jcf
->buffer
;
79 JCF_u4 old_size
= jcf
->buffer_end
- jcf
->buffer
;
80 JCF_u4 new_size
= (old_size
== 0 ? 2000 : 2 * old_size
) + count
;
81 unsigned char *new_buffer
= jcf
->buffer
== NULL
? ALLOC (new_size
)
82 : REALLOC (jcf
->buffer
, new_size
);
83 jcf
->buffer
= new_buffer
;
84 jcf
->buffer_end
= new_buffer
+ new_size
;
85 jcf
->read_ptr
= new_buffer
+ old_read_ptr
;
86 jcf
->read_end
= new_buffer
+ old_read_end
;
88 count
-= jcf
->read_end
- jcf
->read_ptr
;
91 if ((int) fread (jcf
->read_end
, 1, count
, file
) != count
)
92 jcf_unexpected_eof (jcf
, count
);
93 jcf
->read_end
+= count
;
99 struct ZipFile
*SeenZipFiles
= NULL
;
101 /* Open a zip file with the given name, and cache directory and file
102 descriptor. If the file is missing, treat it as an empty archive.
103 Return NULL if the .zip file is malformed.
107 opendir_in_zip (const char *zipfile
, int is_system
)
109 struct ZipFile
* zipf
;
112 for (zipf
= SeenZipFiles
; zipf
!= NULL
; zipf
= zipf
->next
)
114 if (strcmp (zipf
->name
, zipfile
) == 0)
118 zipf
= ALLOC (sizeof (struct ZipFile
) + strlen (zipfile
) + 1);
119 zipf
->next
= SeenZipFiles
;
120 zipf
->name
= (char*)(zipf
+1);
121 strcpy (zipf
->name
, zipfile
);
122 fd
= open (zipfile
, O_RDONLY
| O_BINARY
);
126 /* A missing zip file is not considered an error.
127 We may want to re-consider that. FIXME. */
130 zipf
->central_directory
= NULL
;
134 jcf_dependency_add_file (zipfile
, is_system
);
135 if (read (fd
, magic
, 4) != 4 || GET_u4 (magic
) != (JCF_u4
)ZIPMAGIC
)
141 lseek (fd
, 0L, SEEK_SET
);
142 if (read_zip_archive (zipf
) != 0)
155 0: OK - zipmember found.
157 -2: Malformed archive.
161 open_in_zip (JCF
*jcf
, const char *zipfile
, const char *zipmember
,
166 ZipFile
*zipf
= opendir_in_zip (zipfile
, is_system
);
174 len
= strlen (zipmember
);
176 zipd
= (struct ZipDirectory
*) zipf
->central_directory
;
177 for (i
= 0; i
< zipf
->count
; i
++, zipd
= ZIPDIR_NEXT (zipd
))
179 if (len
== zipd
->filename_length
&&
180 strncmp (ZIPDIR_FILENAME (zipd
), zipmember
, len
) == 0)
184 jcf
->filename
= xstrdup (zipfile
);
185 jcf
->classname
= xstrdup (zipmember
);
186 return read_zip_member(jcf
, zipd
, zipf
);
192 /* Read data from zip archive member. */
195 read_zip_member (JCF
*jcf
, ZipDirectory
*zipd
, ZipFile
*zipf
)
197 jcf
->filbuf
= jcf_unexpected_eof
;
200 if (zipd
->compression_method
== Z_NO_COMPRESSION
)
202 jcf
->buffer
= XNEWVEC (unsigned char, zipd
->size
);
203 jcf
->buffer_end
= jcf
->buffer
+ zipd
->size
;
204 jcf
->read_ptr
= jcf
->buffer
;
205 jcf
->read_end
= jcf
->buffer_end
;
206 if (lseek (zipf
->fd
, zipd
->filestart
, 0) < 0
207 || read (zipf
->fd
, jcf
->buffer
, zipd
->size
) != (long) zipd
->size
)
213 z_stream d_stream
; /* decompression stream */
214 d_stream
.zalloc
= (alloc_func
) 0;
215 d_stream
.zfree
= (free_func
) 0;
216 d_stream
.opaque
= (voidpf
) 0;
218 jcf
->buffer
= XNEWVEC (unsigned char, zipd
->uncompressed_size
);
219 d_stream
.next_out
= jcf
->buffer
;
220 d_stream
.avail_out
= zipd
->uncompressed_size
;
221 jcf
->buffer_end
= jcf
->buffer
+ zipd
->uncompressed_size
;
222 jcf
->read_ptr
= jcf
->buffer
;
223 jcf
->read_end
= jcf
->buffer_end
;
224 buffer
= XNEWVEC (char, zipd
->size
);
225 d_stream
.next_in
= (unsigned char *) buffer
;
226 d_stream
.avail_in
= zipd
->size
;
227 if (lseek (zipf
->fd
, zipd
->filestart
, 0) < 0
228 || read (zipf
->fd
, buffer
, zipd
->size
) != (long) zipd
->size
)
230 /* Handle NO_HEADER using undocumented zlib feature.
231 This is a very common hack. */
232 inflateInit2 (&d_stream
, -MAX_WBITS
);
233 inflate (&d_stream
, Z_NO_FLUSH
);
234 inflateEnd (&d_stream
);
242 open_class (const char *filename
, JCF
*jcf
, int fd
, const char *dep_name
)
246 struct stat stat_buf
;
247 if (fstat (fd
, &stat_buf
) != 0
248 || ! S_ISREG (stat_buf
.st_mode
))
250 perror ("Could not figure length of .class file");
253 if (dep_name
!= NULL
)
254 jcf_dependency_add_file (dep_name
, 0);
256 jcf
->buffer
= XNEWVEC (unsigned char, stat_buf
.st_size
);
257 jcf
->buffer_end
= jcf
->buffer
+ stat_buf
.st_size
;
258 jcf
->read_ptr
= jcf
->buffer
;
259 jcf
->read_end
= jcf
->buffer_end
;
260 jcf
->read_state
= NULL
;
261 jcf
->filename
= xstrdup (filename
);
262 if (read (fd
, jcf
->buffer
, stat_buf
.st_size
) != stat_buf
.st_size
)
264 perror ("Failed to read .class file");
268 jcf
->filbuf
= jcf_unexpected_eof
;
277 find_classfile (char *filename
, JCF
*jcf
, const char *dep_name
)
279 int fd
= open (filename
, O_RDONLY
| O_BINARY
);
282 return open_class (filename
, jcf
, fd
, dep_name
);
287 /* A comparison function (as for qsort) that compares KEY (a char *
288 giving the basename of a file) with the name stored in ENTRY (a
292 compare_path (const void *key
, const void *entry
)
294 return strcmp ((const char *) key
,
295 (*((const struct dirent
*const*) entry
))->d_name
);
298 /* Returns nonzero if ENTRY names a .java or .class file. */
301 java_or_class_file (const struct dirent
*entry
)
303 const char *base
= lbasename (entry
->d_name
);
304 return (fnmatch ("*.java", base
, 0) == 0 ||
305 fnmatch ("*.class", base
, 0) == 0);
308 /* Information about the files present in a particular directory. */
309 typedef struct memoized_dirlist_entry
311 /* The name of the directory. */
313 /* The number of .java and .class files present, or -1 if we could
314 not, for some reason, obtain the list. */
316 /* The .java and .class files in the directory, in alphabetical
318 struct dirent
**files
;
319 } memoized_dirlist_entry
;
321 /* A hash function for a memoized_dirlist_entry. */
323 memoized_dirlist_hash (const void *entry
)
325 const memoized_dirlist_entry
*mde
= (const memoized_dirlist_entry
*) entry
;
326 return htab_hash_string (mde
->dir
);
329 /* Returns true if ENTRY (a memoized_dirlist_entry *) corresponds to
330 the directory given by KEY (a char *) giving the directory
334 memoized_dirlist_lookup_eq (const void *entry
, const void *key
)
336 return strcmp ((const char *) key
,
337 ((const memoized_dirlist_entry
*) entry
)->dir
) == 0;
340 /* A hash table mapping directory names to the lists of .java and
341 .class files in that directory. */
343 static htab_t memoized_dirlists
;
347 /* Like stat, but avoids actually making the stat system call if we
348 know that it cannot succeed. FILENAME and BUF are as for stat. */
351 caching_stat (char *filename
, struct stat
*buf
)
357 memoized_dirlist_entry
*dent
;
359 struct memoized_dirlist_entry temp
;
361 /* If the hashtable has not already been created, create it now. */
362 if (!memoized_dirlists
)
363 memoized_dirlists
= htab_create (37,
364 memoized_dirlist_hash
,
365 memoized_dirlist_lookup_eq
,
368 /* Get the name of the directory. */
369 sep
= strrchr (filename
, DIR_SEPARATOR
);
370 #ifdef DIR_SEPARATOR_2
372 sep
= strrchr (filename
, DIR_SEPARATOR_2
);
383 /* Obtain the entry for this directory from the hash table. This
384 approach is ok since we know that the hash function only looks at
385 the directory name. */
389 slot
= htab_find_slot (memoized_dirlists
, &temp
, INSERT
);
392 /* We have not already scanned this directory; scan it now. */
393 dent
= XNEW (memoized_dirlist_entry
);
394 dent
->dir
= xstrdup (filename
);
395 /* Unfortunately, scandir is not fully standardized. In
396 particular, the type of the function pointer passed as the
397 third argument sometimes takes a "const struct dirent *"
398 parameter, and sometimes just a "struct dirent *". We cast
399 to (void *) and use __extension__ so that either way it is
400 quietly accepted. FIXME: scandir is not in POSIX. */
401 dent
->num_files
= __extension__
scandir (filename
, &dent
->files
,
402 (void *) java_or_class_file
,
407 dent
= *((memoized_dirlist_entry
**) slot
);
409 /* Put the separator back. */
413 /* If the file is not in the list, there is no need to stat it; it
415 if (dent
->num_files
!= -1
416 && !bsearch (base
, dent
->files
, dent
->num_files
,
417 sizeof (struct dirent
*), compare_path
))
421 return stat (filename
, buf
);
424 /* Returns 1 if the CLASSNAME (really a char *) matches the name
425 stored in TABLE_ENTRY (also a char *). */
428 memoized_class_lookup_eq (const void *table_entry
, const void *classname
)
430 return strcmp ((const char *)classname
, (const char *)table_entry
) == 0;
433 /* A hash table keeping track of class names that were not found
434 during class lookup. (There is no need to cache the values
435 associated with names that were found; they are saved in
436 IDENTIFIER_CLASS_VALUE.) */
437 static htab_t memoized_class_lookups
;
439 /* Returns a freshly malloc'd string with the fully qualified pathname
440 of the .class file for the class CLASSNAME. CLASSNAME must be
441 allocated in permanent storage; this function may retain a pointer
442 to it. Returns NULL on failure. If JCF != NULL, it is suitably
443 initialized. SOURCE_OK is true if we should also look for .java
447 find_class (const char *classname
, int classname_length
, JCF
*jcf
)
450 int i
, k
, class = -1;
451 struct stat class_buf
;
458 /* Create the hash table, if it does not already exist. */
459 if (!memoized_class_lookups
)
460 memoized_class_lookups
= htab_create (37,
462 memoized_class_lookup_eq
,
465 /* Loop for this class in the hashtable. If it is present, we've
466 already looked for this class and failed to find it. */
467 hash
= htab_hash_string (classname
);
468 if (htab_find_with_hash (memoized_class_lookups
, classname
, hash
))
471 /* Allocate and zero out the buffer, since we don't explicitly put a
472 null pointer when we're copying it below. */
473 buflen
= jcf_path_max_len () + classname_length
+ 10;
474 buffer
= ALLOC (buflen
);
475 memset (buffer
, 0, buflen
);
477 for (entry
= jcf_path_start (); entry
!= NULL
; entry
= jcf_path_next (entry
))
479 const char *path_name
= jcf_path_name (entry
);
484 strcpy (buffer
, path_name
);
487 /* This is right because we know that `.zip' entries will have a
488 trailing slash. See jcf-path.c. */
491 for (k
= 0; k
< classname_length
; k
++, i
++)
493 char ch
= classname
[k
];
494 buffer
[i
] = ch
== '.' ? '/' : ch
;
496 strcpy (buffer
+i
, ".class");
498 if (jcf_path_is_zipfile (entry
))
502 buffer
[dir_len
] = '\0';
503 SOURCE_FRONTEND_DEBUG
504 (("Trying [...%s]:%s",
505 &buffer
[dir_len
-(dir_len
> 15 ? 15 : dir_len
)],
509 err_code
= open_in_zip (jcf
, buffer
, buffer
+dir_len
+1,
510 jcf_path_is_system (entry
));
513 /* Should we check if .zip is out-of-date wrt .java? */
514 buffer
[dir_len
] = '(';
515 strcpy (buffer
+i
, ".class)");
523 class = caching_stat(buffer
, &class_buf
);
530 SOURCE_FRONTEND_DEBUG ((stderr
, "[Class selected: %s]\n",
531 classname
+classname_length
-
532 (classname_length
<= 30 ?
533 classname_length
: 30)));
534 fd
= JCF_OPEN_EXACT_CASE (buffer
, O_RDONLY
| O_BINARY
);
541 /* Remember that this class could not be found so that we do not
542 have to look again. */
543 *(const void **)htab_find_slot_with_hash (memoized_class_lookups
,
544 classname
, hash
, INSERT
)
550 const char *const tmp
= open_class (buffer
, jcf
, fd
, dep_file
);
551 jcf
->classname
= xstrdup (classname
);
557 jcf_print_char (FILE *stream
, int ch
)
564 fprintf (stream
, "\\%c", ch
);
567 fprintf (stream
, "\\n");
570 fprintf (stream
, "\\t");
573 fprintf (stream
, "\\r");
576 if (ch
>= ' ' && ch
< 127)
579 fprintf (stream
, "\\%03x", ch
);
581 fprintf (stream
, "\\u%04x", ch
);
585 /* Print UTF8 string at STR of length LENGTH bytes to STREAM. */
588 jcf_print_utf8 (FILE *stream
, const unsigned char *str
, int length
)
590 const unsigned char * limit
= str
+ length
;
593 int ch
= UTF8_GET (str
, limit
);
596 fprintf (stream
, "\\<invalid>");
599 jcf_print_char (stream
, ch
);
603 /* Same as jcf_print_utf8, but print IN_CHAR as OUT_CHAR. */
606 jcf_print_utf8_replace (FILE *stream
, const unsigned char *str
, int length
,
607 int in_char
, int out_char
)
609 const unsigned char *limit
= str
+ length
;
612 int ch
= UTF8_GET (str
, limit
);
615 fprintf (stream
, "\\<invalid>");
618 jcf_print_char (stream
, ch
== in_char
? out_char
: ch
);
622 /* Check that all the cross-references in the constant pool are
623 valid. Returns 0 on success.
624 Otherwise, returns the index of the (first) invalid entry.
625 Only checks internal consistency, but does not check that
626 any classes, fields, or methods are valid.*/
629 verify_constant_pool (JCF
*jcf
)
632 for (i
= 1; i
< JPOOL_SIZE (jcf
); i
++)
634 switch (JPOOL_TAG (jcf
, i
))
636 case CONSTANT_NameAndType
:
637 n
= JPOOL_USHORT2 (jcf
, i
);
638 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
639 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
641 /* ... fall through ... */
643 case CONSTANT_String
:
644 n
= JPOOL_USHORT1 (jcf
, i
);
645 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
646 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
649 case CONSTANT_Fieldref
:
650 case CONSTANT_Methodref
:
651 case CONSTANT_InterfaceMethodref
:
652 n
= JPOOL_USHORT1 (jcf
, i
);
653 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
654 || JPOOL_TAG (jcf
, n
) != CONSTANT_Class
)
656 n
= JPOOL_USHORT2 (jcf
, i
);
657 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
658 || JPOOL_TAG (jcf
, n
) != CONSTANT_NameAndType
)
662 case CONSTANT_Double
:
666 case CONSTANT_Integer
:
668 case CONSTANT_Unicode
:
678 format_uint (char *buffer
, uint64 value
, int base
)
680 #define WRITE_BUF_SIZE (4 + sizeof(uint64) * 8)
681 char buf
[WRITE_BUF_SIZE
];
682 char *buf_ptr
= buf
+WRITE_BUF_SIZE
; /* End of buf. */
686 /* Now do the actual conversion, placing the result at the *end* of buf. */
687 /* Note this code does not pretend to be optimized. */
689 int digit
= value
% base
;
690 static const char digit_chars
[] = "0123456789abcdefghijklmnopqrstuvwxyz";
691 *--buf_ptr
= digit_chars
[digit
];
693 } while (value
!= 0);
695 chars_written
= buf
+WRITE_BUF_SIZE
- buf_ptr
;
696 for (i
= 0; i
< chars_written
; i
++)
697 buffer
[i
] = *buf_ptr
++;
702 format_int (char *buffer
, jlong value
, int base
)
707 abs_value
= -(uint64
)value
;
711 abs_value
= (uint64
) value
;
712 format_uint (buffer
, abs_value
, base
);