1 /* Utility routines for finding and reading Java(TM) .class files.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005
3 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 2, 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 COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
30 #include "coretypes.h"
36 #include "java-tree.h"
45 /* DOS brain-damage */
47 #define O_BINARY 0 /* MS-DOS brain-damage */
51 jcf_unexpected_eof (JCF
*jcf
, int count ATTRIBUTE_UNUSED
)
54 fprintf (stderr
, "Premature end of .class file %s.\n", jcf
->filename
);
56 fprintf (stderr
, "Premature end of .class file <stdin>.\n");
61 jcf_trim_old_input (JCF
*jcf
)
63 int count
= jcf
->read_ptr
- jcf
->buffer
;
66 memmove (jcf
->buffer
, jcf
->read_ptr
, jcf
->read_end
- jcf
->read_ptr
);
67 jcf
->read_ptr
-= count
;
68 jcf
->read_end
-= count
;
73 jcf_filbuf_from_stdio (JCF
*jcf
, 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 opendir_in_zip (const char *zipfile
, int is_system
)
110 struct ZipFile
* zipf
;
113 for (zipf
= SeenZipFiles
; zipf
!= NULL
; zipf
= zipf
->next
)
115 if (strcmp (zipf
->name
, zipfile
) == 0)
119 zipf
= ALLOC (sizeof (struct ZipFile
) + strlen (zipfile
) + 1);
120 zipf
->next
= SeenZipFiles
;
121 zipf
->name
= (char*)(zipf
+1);
122 strcpy (zipf
->name
, zipfile
);
123 fd
= open (zipfile
, O_RDONLY
| O_BINARY
);
127 /* A missing zip file is not considered an error.
128 We may want to re-consider that. FIXME. */
131 zipf
->central_directory
= NULL
;
135 jcf_dependency_add_file (zipfile
, is_system
);
136 if (read (fd
, magic
, 4) != 4 || GET_u4 (magic
) != (JCF_u4
)ZIPMAGIC
)
138 lseek (fd
, 0L, SEEK_SET
);
139 if (read_zip_archive (zipf
) != 0)
148 0: OK - zipmember found.
150 -2: Malformed archive.
154 open_in_zip (JCF
*jcf
, const char *zipfile
, const char *zipmember
,
159 ZipFile
*zipf
= opendir_in_zip (zipfile
, is_system
);
167 len
= strlen (zipmember
);
169 zipd
= (struct ZipDirectory
*) zipf
->central_directory
;
170 for (i
= 0; i
< zipf
->count
; i
++, zipd
= ZIPDIR_NEXT (zipd
))
172 if (len
== zipd
->filename_length
&&
173 strncmp (ZIPDIR_FILENAME (zipd
), zipmember
, len
) == 0)
177 jcf
->filename
= xstrdup (zipfile
);
178 jcf
->classname
= xstrdup (zipmember
);
179 return read_zip_member(jcf
, zipd
, zipf
);
185 /* Read data from zip archive member. */
188 read_zip_member (JCF
*jcf
, ZipDirectory
*zipd
, ZipFile
*zipf
)
190 jcf
->filbuf
= jcf_unexpected_eof
;
191 jcf
->zipd
= (void *)zipd
;
193 if (zipd
->compression_method
== Z_NO_COMPRESSION
)
195 jcf
->buffer
= ALLOC (zipd
->size
);
196 jcf
->buffer_end
= jcf
->buffer
+ zipd
->size
;
197 jcf
->read_ptr
= jcf
->buffer
;
198 jcf
->read_end
= jcf
->buffer_end
;
199 if (lseek (zipf
->fd
, zipd
->filestart
, 0) < 0
200 || read (zipf
->fd
, jcf
->buffer
, zipd
->size
) != (long) zipd
->size
)
206 z_stream d_stream
; /* decompression stream */
207 d_stream
.zalloc
= (alloc_func
) 0;
208 d_stream
.zfree
= (free_func
) 0;
209 d_stream
.opaque
= (voidpf
) 0;
211 jcf
->buffer
= ALLOC (zipd
->uncompressed_size
);
212 d_stream
.next_out
= jcf
->buffer
;
213 d_stream
.avail_out
= zipd
->uncompressed_size
;
214 jcf
->buffer_end
= jcf
->buffer
+ zipd
->uncompressed_size
;
215 jcf
->read_ptr
= jcf
->buffer
;
216 jcf
->read_end
= jcf
->buffer_end
;
217 buffer
= ALLOC (zipd
->size
);
218 d_stream
.next_in
= (unsigned char *) buffer
;
219 d_stream
.avail_in
= zipd
->size
;
220 if (lseek (zipf
->fd
, zipd
->filestart
, 0) < 0
221 || read (zipf
->fd
, buffer
, zipd
->size
) != (long) zipd
->size
)
223 /* Handle NO_HEADER using undocumented zlib feature.
224 This is a very common hack. */
225 inflateInit2 (&d_stream
, -MAX_WBITS
);
226 inflate (&d_stream
, Z_NO_FLUSH
);
227 inflateEnd (&d_stream
);
235 open_class (const char *filename
, JCF
*jcf
, int fd
, const char *dep_name
)
239 struct stat stat_buf
;
240 if (fstat (fd
, &stat_buf
) != 0
241 || ! S_ISREG (stat_buf
.st_mode
))
243 perror ("Could not figure length of .class file");
246 if (dep_name
!= NULL
)
247 jcf_dependency_add_file (dep_name
, 0);
249 jcf
->buffer
= ALLOC (stat_buf
.st_size
);
250 jcf
->buffer_end
= jcf
->buffer
+ stat_buf
.st_size
;
251 jcf
->read_ptr
= jcf
->buffer
;
252 jcf
->read_end
= jcf
->buffer_end
;
253 jcf
->read_state
= NULL
;
254 jcf
->filename
= filename
;
255 if (read (fd
, jcf
->buffer
, stat_buf
.st_size
) != stat_buf
.st_size
)
257 perror ("Failed to read .class file");
261 jcf
->filbuf
= jcf_unexpected_eof
;
270 find_classfile (char *filename
, JCF
*jcf
, const char *dep_name
)
272 int fd
= open (filename
, O_RDONLY
| O_BINARY
);
275 return open_class (filename
, jcf
, fd
, dep_name
);
280 /* A comparison function (as for qsort) that compares KEY (a char *
281 giving the basename of a file) with the name stored in ENTRY (a
285 compare_path (const void *key
, const void *entry
)
287 return strcmp ((const char *) key
,
288 (*((const struct dirent
**) entry
))->d_name
);
291 /* Returns nonzero if ENTRY names a .java or .class file. */
294 java_or_class_file (const struct dirent
*entry
)
296 const char *base
= lbasename (entry
->d_name
);
297 return (fnmatch ("*.java", base
, 0) == 0 ||
298 fnmatch ("*.class", base
, 0) == 0);
301 /* Information about the files present in a particular directory. */
302 typedef struct memoized_dirlist_entry
304 /* The name of the directory. */
306 /* The number of .java and .class files present, or -1 if we could
307 not, for some reason, obtain the list. */
309 /* The .java and .class files in the directory, in alphabetical
311 struct dirent
**files
;
312 } memoized_dirlist_entry
;
314 /* A hash function for a memoized_dirlist_entry. */
316 memoized_dirlist_hash (const void *entry
)
318 const memoized_dirlist_entry
*mde
= (const memoized_dirlist_entry
*) entry
;
319 return htab_hash_string (mde
->dir
);
322 /* Returns true if ENTRY (a memoized_dirlist_entry *) corresponds to
323 the directory given by KEY (a char *) giving the directory
327 memoized_dirlist_lookup_eq (const void *entry
, const void *key
)
329 return strcmp ((const char *) key
,
330 ((const memoized_dirlist_entry
*) entry
)->dir
) == 0;
333 /* A hash table mapping directory names to the lists of .java and
334 .class files in that directory. */
336 static htab_t memoized_dirlists
;
340 /* Like stat, but avoids actually making the stat system call if we
341 know that it cannot succeed. FILENAME and BUF are as for stat. */
344 caching_stat (char *filename
, struct stat
*buf
)
350 memoized_dirlist_entry
*dent
;
352 struct memoized_dirlist_entry temp
;
354 /* If the hashtable has not already been created, create it now. */
355 if (!memoized_dirlists
)
356 memoized_dirlists
= htab_create (37,
357 memoized_dirlist_hash
,
358 memoized_dirlist_lookup_eq
,
361 /* Get the name of the directory. */
362 sep
= strrchr (filename
, DIR_SEPARATOR
);
363 #ifdef DIR_SEPARATOR_2
365 sep
= strrchr (filename
, DIR_SEPARATOR_2
);
376 /* Obtain the entry for this directory from the hash table. This
377 approach is ok since we know that the hash function only looks at
378 the directory name. */
382 slot
= htab_find_slot (memoized_dirlists
, &temp
, INSERT
);
385 /* We have not already scanned this directory; scan it now. */
386 dent
= ((memoized_dirlist_entry
*)
387 ALLOC (sizeof (memoized_dirlist_entry
)));
388 dent
->dir
= xstrdup (filename
);
389 /* Unfortunately, scandir is not fully standardized. In
390 particular, the type of the function pointer passed as the
391 third argument sometimes takes a "const struct dirent *"
392 parameter, and sometimes just a "struct dirent *". We cast
393 to (void *) and use __extension__ so that either way it is
394 quietly accepted. FIXME: scandir is not in POSIX. */
395 dent
->num_files
= __extension__
scandir (filename
, &dent
->files
,
396 (void *) java_or_class_file
,
401 dent
= *((memoized_dirlist_entry
**) slot
);
403 /* Put the separator back. */
407 /* If the file is not in the list, there is no need to stat it; it
409 if (dent
->num_files
!= -1
410 && !bsearch (base
, dent
->files
, dent
->num_files
,
411 sizeof (struct dirent
*), compare_path
))
415 return stat (filename
, buf
);
418 /* Returns 1 if the CLASSNAME (really a char *) matches the name
419 stored in TABLE_ENTRY (also a char *). */
422 memoized_class_lookup_eq (const void *table_entry
, const void *classname
)
424 return strcmp ((const char *)classname
, (const char *)table_entry
) == 0;
427 /* A hash table keeping track of class names that were not found
428 during class lookup. (There is no need to cache the values
429 associated with names that were found; they are saved in
430 IDENTIFIER_CLASS_VALUE.) */
431 static htab_t memoized_class_lookups
;
433 /* Returns a freshly malloc'd string with the fully qualified pathname
434 of the .class file for the class CLASSNAME. CLASSNAME must be
435 allocated in permanent storage; this function may retain a pointer
436 to it. Returns NULL on failure. If JCF != NULL, it is suitably
437 initialized. SOURCE_OK is true if we should also look for .java
441 find_class (const char *classname
, int classname_length
, JCF
*jcf
,
445 int i
, k
, java
= -1, class = -1;
446 struct stat java_buf
, class_buf
;
454 /* Create the hash table, if it does not already exist. */
455 if (!memoized_class_lookups
)
456 memoized_class_lookups
= htab_create (37,
458 memoized_class_lookup_eq
,
461 /* Loop for this class in the hashtable. If it is present, we've
462 already looked for this class and failed to find it. */
463 hash
= htab_hash_string (classname
);
464 if (htab_find_with_hash (memoized_class_lookups
, classname
, hash
))
467 /* Allocate and zero out the buffer, since we don't explicitly put a
468 null pointer when we're copying it below. */
469 buflen
= jcf_path_max_len () + classname_length
+ 10;
470 buffer
= ALLOC (buflen
);
471 memset (buffer
, 0, buflen
);
473 java_buffer
= alloca (buflen
);
475 jcf
->java_source
= 0;
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
);
528 /* Compute name of .java file. */
530 strcpy (java_buffer
, path_name
);
531 l
= strlen (java_buffer
);
532 for (m
= 0; m
< classname_length
; ++m
)
533 java_buffer
[m
+ l
] = (classname
[m
] == '.'
534 ? DIR_SEPARATOR
: classname
[m
]);
535 strcpy (java_buffer
+ m
+ l
, ".java");
536 java
= caching_stat (java_buffer
, &java_buf
);
542 /* We preferably pick a class file if we have a chance. If the source
543 file is newer than the class file, we issue a warning and parse the
545 There should be a flag to allow people have the class file picked
546 up no matter what. FIXME. */
547 if (! java
&& ! class && java_buf
.st_mtime
> class_buf
.st_mtime
)
550 warning (0, "source file for class %qs is newer than its matching class file. Source file %qs used instead", classname
, java_buffer
);
555 dep_file
= java_buffer
;
560 SOURCE_FRONTEND_DEBUG ((stderr
, "[Class selected: %s]\n",
561 classname
+classname_length
-
562 (classname_length
<= 30 ?
563 classname_length
: 30)));
564 fd
= JCF_OPEN_EXACT_CASE (buffer
, O_RDONLY
| O_BINARY
);
568 /* Give .java a try, if necessary */
571 strcpy (buffer
, java_buffer
);
572 SOURCE_FRONTEND_DEBUG ((stderr
, "[Source selected: %s]\n",
573 classname
+classname_length
-
574 (classname_length
<= 30 ?
575 classname_length
: 30)));
576 fd
= JCF_OPEN_EXACT_CASE (buffer
, O_RDONLY
);
579 jcf
->java_source
= 1;
586 /* Remember that this class could not be found so that we do not
587 have to look again. */
588 *htab_find_slot_with_hash (memoized_class_lookups
, classname
, hash
, INSERT
)
589 = (void *) classname
;
593 if (jcf
->java_source
)
595 JCF_ZERO (jcf
); /* JCF_FINISH relies on this */
596 jcf
->java_source
= 1;
597 jcf
->filename
= xstrdup (buffer
);
598 close (fd
); /* We use STDIO for source file */
601 buffer
= (char *) open_class (buffer
, jcf
, fd
, dep_file
);
602 jcf
->classname
= xstrdup (classname
);
607 jcf_print_char (FILE *stream
, int ch
)
614 fprintf (stream
, "\\%c", ch
);
617 fprintf (stream
, "\\n");
620 fprintf (stream
, "\\t");
623 fprintf (stream
, "\\r");
626 if (ch
>= ' ' && ch
< 127)
629 fprintf (stream
, "\\%03x", ch
);
631 fprintf (stream
, "\\u%04x", ch
);
635 /* Print UTF8 string at STR of length LENGTH bytes to STREAM. */
638 jcf_print_utf8 (FILE *stream
, const unsigned char *str
, int length
)
640 const unsigned char * limit
= str
+ length
;
643 int ch
= UTF8_GET (str
, limit
);
646 fprintf (stream
, "\\<invalid>");
649 jcf_print_char (stream
, ch
);
653 /* Same as jcf_print_utf8, but print IN_CHAR as OUT_CHAR. */
656 jcf_print_utf8_replace (FILE *stream
, const unsigned char *str
, int length
,
657 int in_char
, int out_char
)
659 const unsigned char *limit
= str
+ length
;
662 int ch
= UTF8_GET (str
, limit
);
665 fprintf (stream
, "\\<invalid>");
668 jcf_print_char (stream
, ch
== in_char
? out_char
: ch
);
672 /* Check that all the cross-references in the constant pool are
673 valid. Returns 0 on success.
674 Otherwise, returns the index of the (first) invalid entry.
675 Only checks internal consistency, but does not check that
676 any classes, fields, or methods are valid.*/
679 verify_constant_pool (JCF
*jcf
)
682 for (i
= 1; i
< JPOOL_SIZE (jcf
); i
++)
684 switch (JPOOL_TAG (jcf
, i
))
686 case CONSTANT_NameAndType
:
687 n
= JPOOL_USHORT2 (jcf
, i
);
688 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
689 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
691 /* ... fall through ... */
693 case CONSTANT_String
:
694 n
= JPOOL_USHORT1 (jcf
, i
);
695 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
696 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
699 case CONSTANT_Fieldref
:
700 case CONSTANT_Methodref
:
701 case CONSTANT_InterfaceMethodref
:
702 n
= JPOOL_USHORT1 (jcf
, i
);
703 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
704 || JPOOL_TAG (jcf
, n
) != CONSTANT_Class
)
706 n
= JPOOL_USHORT2 (jcf
, i
);
707 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
708 || JPOOL_TAG (jcf
, n
) != CONSTANT_NameAndType
)
712 case CONSTANT_Double
:
716 case CONSTANT_Integer
:
718 case CONSTANT_Unicode
:
728 format_uint (char *buffer
, uint64 value
, int base
)
730 #define WRITE_BUF_SIZE (4 + sizeof(uint64) * 8)
731 char buf
[WRITE_BUF_SIZE
];
732 char *buf_ptr
= buf
+WRITE_BUF_SIZE
; /* End of buf. */
736 /* Now do the actual conversion, placing the result at the *end* of buf. */
737 /* Note this code does not pretend to be optimized. */
739 int digit
= value
% base
;
740 static const char digit_chars
[] = "0123456789abcdefghijklmnopqrstuvwxyz";
741 *--buf_ptr
= digit_chars
[digit
];
743 } while (value
!= 0);
745 chars_written
= buf
+WRITE_BUF_SIZE
- buf_ptr
;
746 for (i
= 0; i
< chars_written
; i
++)
747 buffer
[i
] = *buf_ptr
++;
752 format_int (char *buffer
, jlong value
, int base
)
757 abs_value
= -(uint64
)value
;
761 abs_value
= (uint64
) value
;
762 format_uint (buffer
, abs_value
, base
);