1 /* Utility routines for finding and reading Java(TM) .class files.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GNU CC; see the file COPYING. If not, write to
16 the Free Software Foundation, 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
19 Java and all Java-based marks are trademarks or registered trademarks
20 of Sun Microsystems, Inc. in the United States and other countries.
21 The Free Software Foundation is independent of Sun Microsystems, Inc. */
23 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
27 #include "coretypes.h"
33 #include "java-tree.h"
42 /* DOS brain-damage */
44 #define O_BINARY 0 /* MS-DOS brain-damage */
48 DEFUN(jcf_unexpected_eof
, (jcf
, count
),
49 JCF
*jcf AND
int count ATTRIBUTE_UNUSED
)
52 fprintf (stderr
, "Premature end of .class file %s.\n", jcf
->filename
);
54 fprintf (stderr
, "Premature end of .class file <stdin>.\n");
59 DEFUN(jcf_trim_old_input
, (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 DEFUN(jcf_filbuf_from_stdio
, (jcf
, count
),
73 JCF
*jcf AND
int count
)
75 FILE *file
= (FILE*) (jcf
->read_state
);
76 if (count
> jcf
->buffer_end
- jcf
->read_ptr
)
78 JCF_u4 old_read_ptr
= jcf
->read_ptr
- jcf
->buffer
;
79 JCF_u4 old_read_end
= jcf
->read_end
- jcf
->buffer
;
80 JCF_u4 old_size
= jcf
->buffer_end
- jcf
->buffer
;
81 JCF_u4 new_size
= (old_size
== 0 ? 2000 : 2 * old_size
) + count
;
82 unsigned char *new_buffer
= jcf
->buffer
== NULL
? ALLOC (new_size
)
83 : REALLOC (jcf
->buffer
, new_size
);
84 jcf
->buffer
= new_buffer
;
85 jcf
->buffer_end
= new_buffer
+ new_size
;
86 jcf
->read_ptr
= new_buffer
+ old_read_ptr
;
87 jcf
->read_end
= new_buffer
+ old_read_end
;
89 count
-= jcf
->read_end
- jcf
->read_ptr
;
92 if ((int) fread (jcf
->read_end
, 1, count
, file
) != count
)
93 jcf_unexpected_eof (jcf
, count
);
94 jcf
->read_end
+= count
;
100 struct ZipFile
*SeenZipFiles
= NULL
;
102 /* Open a zip file with the given name, and cache directory and file
103 descriptor. If the file is missing, treat it as an empty archive.
104 Return NULL if the .zip file is malformed.
108 DEFUN(opendir_in_zip
, (zipfile
, is_system
),
109 const char *zipfile AND
int is_system
)
111 struct ZipFile
* zipf
;
114 for (zipf
= SeenZipFiles
; zipf
!= NULL
; zipf
= zipf
->next
)
116 if (strcmp (zipf
->name
, zipfile
) == 0)
120 zipf
= ALLOC (sizeof (struct ZipFile
) + strlen (zipfile
) + 1);
121 zipf
->next
= SeenZipFiles
;
122 zipf
->name
= (char*)(zipf
+1);
123 strcpy (zipf
->name
, zipfile
);
125 fd
= open (zipfile
, O_RDONLY
| O_BINARY
);
129 /* A missing zip file is not considered an error.
130 We may want to re-consider that. FIXME. */
133 zipf
->central_directory
= NULL
;
137 jcf_dependency_add_file (zipfile
, is_system
);
138 if (read (fd
, magic
, 4) != 4 || GET_u4 (magic
) != (JCF_u4
)ZIPMAGIC
)
140 lseek (fd
, 0L, SEEK_SET
);
141 if (read_zip_archive (zipf
) != 0)
148 0: OK - zipmember found.
150 -2: Malformed archive.
154 DEFUN(open_in_zip
, (jcf
, zipfile
, zipmember
, is_system
),
155 JCF
*jcf AND
const char *zipfile AND
const char *zipmember
160 ZipFile
*zipf
= opendir_in_zip (zipfile
, is_system
);
168 len
= strlen (zipmember
);
170 zipd
= (struct ZipDirectory
*) zipf
->central_directory
;
171 for (i
= 0; i
< zipf
->count
; i
++, zipd
= ZIPDIR_NEXT (zipd
))
173 if (len
== zipd
->filename_length
&&
174 strncmp (ZIPDIR_FILENAME (zipd
), zipmember
, len
) == 0)
178 jcf
->filename
= xstrdup (zipfile
);
179 jcf
->classname
= xstrdup (zipmember
);
180 return read_zip_member(jcf
, zipd
, zipf
);
186 /* Read data from zip archive member. */
189 DEFUN(read_zip_member
, (jcf
, zipd
, zipf
),
190 JCF
*jcf AND ZipDirectory
*zipd AND ZipFile
*zipf
)
192 jcf
->filbuf
= jcf_unexpected_eof
;
193 jcf
->zipd
= (void *)zipd
;
195 if (zipd
->compression_method
== Z_NO_COMPRESSION
)
197 jcf
->buffer
= ALLOC (zipd
->size
);
198 jcf
->buffer_end
= jcf
->buffer
+ zipd
->size
;
199 jcf
->read_ptr
= jcf
->buffer
;
200 jcf
->read_end
= jcf
->buffer_end
;
201 if (lseek (zipf
->fd
, zipd
->filestart
, 0) < 0
202 || read (zipf
->fd
, jcf
->buffer
, zipd
->size
) != (long) zipd
->size
)
208 z_stream d_stream
; /* decompression stream */
209 d_stream
.zalloc
= (alloc_func
) 0;
210 d_stream
.zfree
= (free_func
) 0;
211 d_stream
.opaque
= (voidpf
) 0;
213 jcf
->buffer
= ALLOC (zipd
->uncompressed_size
);
214 d_stream
.next_out
= jcf
->buffer
;
215 d_stream
.avail_out
= zipd
->uncompressed_size
;
216 jcf
->buffer_end
= jcf
->buffer
+ zipd
->uncompressed_size
;
217 jcf
->read_ptr
= jcf
->buffer
;
218 jcf
->read_end
= jcf
->buffer_end
;
219 buffer
= ALLOC (zipd
->size
);
220 d_stream
.next_in
= buffer
;
221 d_stream
.avail_in
= zipd
->size
;
222 if (lseek (zipf
->fd
, zipd
->filestart
, 0) < 0
223 || read (zipf
->fd
, buffer
, zipd
->size
) != (long) zipd
->size
)
225 /* Handle NO_HEADER using undocumented zlib feature.
226 This is a very common hack. */
227 inflateInit2 (&d_stream
, -MAX_WBITS
);
228 inflate (&d_stream
, Z_NO_FLUSH
);
229 inflateEnd (&d_stream
);
237 DEFUN(open_class
, (filename
, jcf
, fd
, dep_name
),
238 const char *filename AND JCF
*jcf AND
int fd AND
const char *dep_name
)
242 struct stat stat_buf
;
243 if (fstat (fd
, &stat_buf
) != 0
244 || ! S_ISREG (stat_buf
.st_mode
))
246 perror ("Could not figure length of .class file");
249 if (dep_name
!= NULL
)
250 jcf_dependency_add_file (dep_name
, 0);
252 jcf
->buffer
= ALLOC (stat_buf
.st_size
);
253 jcf
->buffer_end
= jcf
->buffer
+ stat_buf
.st_size
;
254 jcf
->read_ptr
= jcf
->buffer
;
255 jcf
->read_end
= jcf
->buffer_end
;
256 jcf
->read_state
= NULL
;
257 jcf
->filename
= filename
;
258 if (read (fd
, jcf
->buffer
, stat_buf
.st_size
) != stat_buf
.st_size
)
260 perror ("Failed to read .class file");
264 jcf
->filbuf
= jcf_unexpected_eof
;
273 DEFUN(find_classfile
, (filename
, jcf
, dep_name
),
274 char *filename AND JCF
*jcf AND
const char *dep_name
)
276 int fd
= open (filename
, O_RDONLY
| O_BINARY
);
279 return open_class (filename
, jcf
, fd
, dep_name
);
284 /* A comparison function (as for qsort) that compares KEY (a char *
285 giving the basename of a file) with the name stored in ENTRY (a
289 DEFUN(compare_path
, (key
, entry
),
290 const void *key AND
const void *entry
)
292 return strcmp ((const char *) key
,
293 (*((const struct dirent
**) entry
))->d_name
);
296 /* Returns nonzero if ENTRY names a .java or .class file. */
299 DEFUN(java_or_class_file
, (entry
),
300 const struct dirent
*entry
)
302 const char *base
= basename (entry
->d_name
);
303 return (fnmatch ("*.java", base
, 0) == 0 ||
304 fnmatch ("*.class", base
, 0) == 0);
307 /* Information about the files present in a particular directory. */
308 typedef struct memoized_dirlist_entry
310 /* The name of the directory. */
312 /* The number of .java and .class files present, or -1 if we could
313 not, for some reason, obtain the list. */
315 /* The .java and .class files in the directory, in alphabetical
317 struct dirent
**files
;
318 } memoized_dirlist_entry
;
320 /* Returns true if ENTRY (a memoized_dirlist_entry *) correponds to
321 the directory given by KEY (a char *) giving the directory
325 DEFUN(memoized_dirlist_lookup_eq
, (entry
, key
),
326 const void *entry AND
const void *key
)
328 return strcmp ((const char *) key
,
329 ((const memoized_dirlist_entry
*) entry
)->dir
) == 0;
332 /* A hash table mapping directory names to the lists of .java and
333 .class files in that directory. */
335 static htab_t memoized_dirlists
;
339 /* Like stat, but avoids actually making the stat system call if we
340 know that it cannot succeed. FILENAME and BUF are as for stat. */
343 DEFUN(caching_stat
, (filename
, buf
),
344 char *filename AND
struct stat
*buf
)
349 memoized_dirlist_entry
*dent
;
352 /* If the hashtable has not already been created, create it now. */
353 if (!memoized_dirlists
)
354 memoized_dirlists
= htab_create (37,
356 memoized_dirlist_lookup_eq
,
359 /* Get the name of the directory. */
360 sep
= strrchr (filename
, DIR_SEPARATOR
);
369 /* Obtain the entry for this directory form the hash table. */
370 slot
= htab_find_slot (memoized_dirlists
, filename
, INSERT
);
373 /* We have not already scanned this directory; scan it now. */
374 dent
= ((memoized_dirlist_entry
*)
375 ALLOC (sizeof (memoized_dirlist_entry
)));
376 dent
->dir
= xstrdup (filename
);
377 /* Unfortunately, scandir is not fully standardized. In
378 particular, the type of the function pointer passed as the
379 third argument sometimes takes a "const struct dirent *"
380 parameter, and sometimes just a "struct dirent *". We rely
381 on the ability to interchange these two types of function
383 dent
->num_files
= scandir (filename
, &dent
->files
,
389 dent
= *((memoized_dirlist_entry
**) slot
);
391 /* Put the spearator back. */
393 *sep
= DIR_SEPARATOR
;
395 /* If the file is not in the list, there is no need to stat it; it
397 if (dent
->num_files
!= -1
398 && !bsearch (base
, dent
->files
, dent
->num_files
,
399 sizeof (struct dirent
*), compare_path
))
403 return stat (filename
, buf
);
406 /* Returns 1 if the CLASSNAME (really a char *) matches the name
407 stored in TABLE_ENTRY (also a char *). */
410 DEFUN(memoized_class_lookup_eq
, (table_entry
, classname
),
411 const void *table_entry AND
const void *classname
)
413 return strcmp ((const char *)classname
, (const char *)table_entry
) == 0;
416 /* A hash table keeping track of class names that were not found
417 during class lookup. (There is no need to cache the values
418 associated with names that were found; they are saved in
419 IDENTIFIER_CLASS_VALUE.) */
420 static htab_t memoized_class_lookups
;
422 /* Returns a freshly malloc'd string with the fully qualified pathname
423 of the .class file for the class CLASSNAME. CLASSNAME must be
424 allocated in permanent storage; this function may retain a pointer
425 to it. Returns NULL on failure. If JCF != NULL, it is suitably
426 initialized. SOURCE_OK is true if we should also look for .java
430 DEFUN(find_class
, (classname
, classname_length
, jcf
, source_ok
),
431 const char *classname AND
int classname_length AND JCF
*jcf AND
int source_ok
)
435 int i
, k
, java
= -1, class = -1;
436 struct stat java_buf
, class_buf
;
444 /* Create the hash table, if it does not already exist. */
445 if (!memoized_class_lookups
)
446 memoized_class_lookups
= htab_create (37,
448 memoized_class_lookup_eq
,
451 /* Loop for this class in the hashtable. If it is present, we've
452 already looked for this class and failed to find it. */
453 hash
= htab_hash_string (classname
);
454 if (htab_find_with_hash (memoized_class_lookups
, classname
, hash
))
457 /* Allocate and zero out the buffer, since we don't explicitly put a
458 null pointer when we're copying it below. */
459 buflen
= jcf_path_max_len () + classname_length
+ 10;
460 buffer
= ALLOC (buflen
);
461 memset (buffer
, 0, buflen
);
463 java_buffer
= alloca (buflen
);
465 jcf
->java_source
= 0;
467 for (entry
= jcf_path_start (); entry
!= NULL
; entry
= jcf_path_next (entry
))
469 const char *path_name
= jcf_path_name (entry
);
474 strcpy (buffer
, path_name
);
477 /* This is right because we know that `.zip' entries will have a
478 trailing slash. See jcf-path.c. */
481 for (k
= 0; k
< classname_length
; k
++, i
++)
483 char ch
= classname
[k
];
484 buffer
[i
] = ch
== '.' ? '/' : ch
;
486 strcpy (buffer
+i
, ".class");
488 if (jcf_path_is_zipfile (entry
))
492 buffer
[dir_len
] = '\0';
493 SOURCE_FRONTEND_DEBUG
494 (("Trying [...%s]:%s",
495 &buffer
[dir_len
-(dir_len
> 15 ? 15 : dir_len
)],
499 err_code
= open_in_zip (jcf
, buffer
, buffer
+dir_len
+1,
500 jcf_path_is_system (entry
));
503 /* Should we check if .zip is out-of-date wrt .java? */
504 buffer
[dir_len
] = '(';
505 strcpy (buffer
+i
, ".class)");
513 class = caching_stat(buffer
, &class_buf
);
518 /* Compute name of .java file. */
520 strcpy (java_buffer
, path_name
);
521 l
= strlen (java_buffer
);
522 for (m
= 0; m
< classname_length
; ++m
)
523 java_buffer
[m
+ l
] = (classname
[m
] == '.' ? '/' : classname
[m
]);
524 strcpy (java_buffer
+ m
+ l
, ".java");
525 java
= caching_stat (java_buffer
, &java_buf
);
531 /* We preferably pick a class file if we have a chance. If the source
532 file is newer than the class file, we issue a warning and parse the
534 There should be a flag to allow people have the class file picked
535 up no matter what. FIXME. */
536 if (! java
&& ! class && java_buf
.st_mtime
> class_buf
.st_mtime
)
539 warning ("source file for class `%s' is newer than its matching class file. Source file `%s' used instead", classname
, java_buffer
);
544 dep_file
= java_buffer
;
549 SOURCE_FRONTEND_DEBUG ((stderr
, "[Class selected: %s]\n",
550 classname
+classname_length
-
551 (classname_length
<= 30 ?
552 classname_length
: 30)));
553 fd
= open (buffer
, O_RDONLY
| O_BINARY
);
557 /* Give .java a try, if necessary */
560 strcpy (buffer
, java_buffer
);
561 SOURCE_FRONTEND_DEBUG ((stderr
, "[Source selected: %s]\n",
562 classname
+classname_length
-
563 (classname_length
<= 30 ?
564 classname_length
: 30)));
565 fd
= open (buffer
, O_RDONLY
);
568 jcf
->java_source
= 1;
575 /* Remember that this class could not be found so that we do not
576 have to look again. */
577 *htab_find_slot_with_hash (memoized_class_lookups
, classname
, hash
, INSERT
)
578 = (void *) classname
;
582 if (jcf
->java_source
)
584 JCF_ZERO (jcf
); /* JCF_FINISH relies on this */
585 jcf
->java_source
= 1;
586 jcf
->filename
= xstrdup (buffer
);
587 close (fd
); /* We use STDIO for source file */
590 buffer
= (char *) open_class (buffer
, jcf
, fd
, dep_file
);
591 jcf
->classname
= xstrdup (classname
);
596 DEFUN(jcf_print_char
, (stream
, ch
),
597 FILE *stream AND
int ch
)
604 fprintf (stream
, "\\%c", ch
);
607 fprintf (stream
, "\\n");
610 fprintf (stream
, "\\t");
613 fprintf (stream
, "\\r");
616 if (ch
>= ' ' && ch
< 127)
619 fprintf (stream
, "\\%03x", ch
);
621 fprintf (stream
, "\\u%04x", ch
);
625 /* Print UTF8 string at STR of length LENGTH bytes to STREAM. */
628 DEFUN(jcf_print_utf8
, (stream
, str
, length
),
629 FILE *stream AND
register const unsigned char *str AND
int length
)
631 const unsigned char * limit
= str
+ length
;
634 int ch
= UTF8_GET (str
, limit
);
637 fprintf (stream
, "\\<invalid>");
640 jcf_print_char (stream
, ch
);
644 /* Same as jcf_print_utf8, but print IN_CHAR as OUT_CHAR. */
647 DEFUN(jcf_print_utf8_replace
, (stream
, str
, length
, in_char
, out_char
),
648 FILE *stream AND
const unsigned char *str AND
int length
649 AND
int in_char AND
int out_char
)
651 const unsigned char *limit
= str
+ length
;
654 int ch
= UTF8_GET (str
, limit
);
657 fprintf (stream
, "\\<invalid>");
660 jcf_print_char (stream
, ch
== in_char
? out_char
: ch
);
664 /* Check that all the cross-references in the constant pool are
665 valid. Returns 0 on success.
666 Otherwise, returns the index of the (first) invalid entry.
667 Only checks internal consistency, but does not check that
668 any classes, fields, or methods are valid.*/
671 DEFUN(verify_constant_pool
, (jcf
),
675 for (i
= 1; i
< JPOOL_SIZE (jcf
); i
++)
677 switch (JPOOL_TAG (jcf
, i
))
679 case CONSTANT_NameAndType
:
680 n
= JPOOL_USHORT2 (jcf
, i
);
681 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
682 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
684 /* ... fall through ... */
686 case CONSTANT_String
:
687 n
= JPOOL_USHORT1 (jcf
, i
);
688 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
689 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
692 case CONSTANT_Fieldref
:
693 case CONSTANT_Methodref
:
694 case CONSTANT_InterfaceMethodref
:
695 n
= JPOOL_USHORT1 (jcf
, i
);
696 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
697 || JPOOL_TAG (jcf
, n
) != CONSTANT_Class
)
699 n
= JPOOL_USHORT2 (jcf
, i
);
700 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
701 || JPOOL_TAG (jcf
, n
) != CONSTANT_NameAndType
)
705 case CONSTANT_Double
:
709 case CONSTANT_Integer
:
711 case CONSTANT_Unicode
:
721 DEFUN(format_uint
, (buffer
, value
, base
),
722 char *buffer AND uint64 value AND
int base
)
724 #define WRITE_BUF_SIZE (4 + sizeof(uint64) * 8)
725 char buf
[WRITE_BUF_SIZE
];
726 register char *buf_ptr
= buf
+WRITE_BUF_SIZE
; /* End of buf. */
730 /* Now do the actual conversion, placing the result at the *end* of buf. */
731 /* Note this code does not pretend to be optimized. */
733 int digit
= value
% base
;
734 static const char digit_chars
[] = "0123456789abcdefghijklmnopqrstuvwxyz";
735 *--buf_ptr
= digit_chars
[digit
];
737 } while (value
!= 0);
739 chars_written
= buf
+WRITE_BUF_SIZE
- buf_ptr
;
740 for (i
= 0; i
< chars_written
; i
++)
741 buffer
[i
] = *buf_ptr
++;
746 DEFUN(format_int
, (buffer
, value
, base
),
747 char *buffer AND jlong value AND
int base
)
752 abs_value
= -(uint64
)value
;
756 abs_value
= (uint64
) value
;
757 format_uint (buffer
, abs_value
, base
);