1 /* Utility routines for finding and reading Java(TM) .class files.
2 Copyright (C) 1996-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>.
20 Java and all Java-based marks are trademarks or registered trademarks
21 of Sun Microsystems, Inc. in the United States and other countries.
22 The Free Software Foundation is independent of Sun Microsystems, Inc. */
24 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
28 #include "coretypes.h"
34 #include "double-int.h"
42 #include "java-tree.h"
43 #include "hash-table.h"
49 jcf_unexpected_eof (JCF
*jcf
, 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 jcf_trim_old_input (JCF
*jcf
)
61 int count
= jcf
->read_ptr
- jcf
->buffer
;
64 memmove (jcf
->buffer
, jcf
->read_ptr
, jcf
->read_end
- jcf
->read_ptr
);
65 jcf
->read_ptr
-= count
;
66 jcf
->read_end
-= count
;
71 jcf_filbuf_from_stdio (JCF
*jcf
, int count
)
73 FILE *file
= (FILE*) (jcf
->read_state
);
74 if (count
> jcf
->buffer_end
- jcf
->read_ptr
)
76 JCF_u4 old_read_ptr
= jcf
->read_ptr
- jcf
->buffer
;
77 JCF_u4 old_read_end
= jcf
->read_end
- jcf
->buffer
;
78 JCF_u4 old_size
= jcf
->buffer_end
- jcf
->buffer
;
79 JCF_u4 new_size
= (old_size
== 0 ? 2000 : 2 * old_size
) + count
;
80 unsigned char *new_buffer
81 = jcf
->buffer
== NULL
? XNEWVAR (unsigned char, new_size
)
82 : XRESIZEVAR (unsigned char, 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
= XNEWVAR (struct ZipFile
, 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 memset (&d_stream
, 0, sizeof (d_stream
));
216 jcf
->buffer
= XNEWVEC (unsigned char, zipd
->uncompressed_size
);
217 d_stream
.next_out
= jcf
->buffer
;
218 d_stream
.avail_out
= zipd
->uncompressed_size
;
219 jcf
->buffer_end
= jcf
->buffer
+ zipd
->uncompressed_size
;
220 jcf
->read_ptr
= jcf
->buffer
;
221 jcf
->read_end
= jcf
->buffer_end
;
222 buffer
= XNEWVEC (char, zipd
->size
);
223 d_stream
.next_in
= (unsigned char *) buffer
;
224 d_stream
.avail_in
= zipd
->size
;
225 if (lseek (zipf
->fd
, zipd
->filestart
, 0) < 0
226 || read (zipf
->fd
, buffer
, zipd
->size
) != (long) zipd
->size
)
228 /* Handle NO_HEADER using undocumented zlib feature.
229 This is a very common hack. */
230 inflateInit2 (&d_stream
, -MAX_WBITS
);
231 inflate (&d_stream
, Z_NO_FLUSH
);
232 inflateEnd (&d_stream
);
240 open_class (const char *filename
, JCF
*jcf
, int fd
, const char *dep_name
)
244 struct stat stat_buf
;
245 if (fstat (fd
, &stat_buf
) != 0
246 || ! S_ISREG (stat_buf
.st_mode
))
248 perror ("Could not figure length of .class file");
251 if (dep_name
!= NULL
)
252 jcf_dependency_add_file (dep_name
, 0);
254 jcf
->buffer
= XNEWVEC (unsigned char, stat_buf
.st_size
);
255 jcf
->buffer_end
= jcf
->buffer
+ stat_buf
.st_size
;
256 jcf
->read_ptr
= jcf
->buffer
;
257 jcf
->read_end
= jcf
->buffer_end
;
258 jcf
->read_state
= NULL
;
259 jcf
->filename
= xstrdup (filename
);
260 if (read (fd
, jcf
->buffer
, stat_buf
.st_size
) != stat_buf
.st_size
)
262 perror ("Failed to read .class file");
266 jcf
->filbuf
= jcf_unexpected_eof
;
275 find_classfile (char *filename
, JCF
*jcf
, const char *dep_name
)
277 int fd
= open (filename
, O_RDONLY
| O_BINARY
);
280 return open_class (filename
, jcf
, fd
, dep_name
);
284 /* Hash table helper. */
286 struct charstar_hash
: typed_noop_remove
<char>
288 typedef const char *value_type
;
289 typedef const char *compare_type
;
290 static inline hashval_t
hash (const char *candidate
);
291 static inline bool equal (const char *existing
, const char *candidate
);
295 charstar_hash::hash (const char *candidate
)
297 return htab_hash_string (candidate
);
301 charstar_hash::equal (const char *existing
, const char *candidate
)
303 return strcmp (existing
, candidate
) == 0;
307 /* A hash table keeping track of class names that were not found
308 during class lookup. (There is no need to cache the values
309 associated with names that were found; they are saved in
310 IDENTIFIER_CLASS_VALUE.) */
311 static hash_table
<charstar_hash
> *memoized_class_lookups
;
313 /* Returns a freshly malloc'd string with the fully qualified pathname
314 of the .class file for the class CLASSNAME. CLASSNAME must be
315 allocated in permanent storage; this function may retain a pointer
316 to it. Returns NULL on failure. If JCF != NULL, it is suitably
317 initialized. SOURCE_OK is true if we should also look for .java
321 find_class (const char *classname
, int classname_length
, JCF
*jcf
)
324 int i
, k
, klass
= -1;
325 struct stat class_buf
;
332 /* Create the hash table, if it does not already exist. */
333 if (!memoized_class_lookups
)
334 memoized_class_lookups
= new hash_table
<charstar_hash
> (37);
336 /* Loop for this class in the hashtable. If it is present, we've
337 already looked for this class and failed to find it. */
338 hash
= charstar_hash::hash (classname
);
339 if (memoized_class_lookups
->find_with_hash (classname
, hash
))
342 /* Allocate and zero out the buffer, since we don't explicitly put a
343 null pointer when we're copying it below. */
344 buflen
= jcf_path_max_len () + classname_length
+ 10;
345 buffer
= XNEWVAR (char, buflen
);
346 memset (buffer
, 0, buflen
);
348 for (entry
= jcf_path_start (); entry
!= NULL
; entry
= jcf_path_next (entry
))
350 const char *path_name
= jcf_path_name (entry
);
355 strcpy (buffer
, path_name
);
358 /* This is right because we know that `.zip' entries will have a
359 trailing slash. See jcf-path.c. */
362 for (k
= 0; k
< classname_length
; k
++, i
++)
364 char ch
= classname
[k
];
365 buffer
[i
] = ch
== '.' ? '/' : ch
;
367 strcpy (buffer
+i
, ".class");
369 if (jcf_path_is_zipfile (entry
))
373 buffer
[dir_len
] = '\0';
374 SOURCE_FRONTEND_DEBUG
375 (("Trying [...%s]:%s",
376 &buffer
[dir_len
-(dir_len
> 15 ? 15 : dir_len
)],
380 err_code
= open_in_zip (jcf
, buffer
, buffer
+dir_len
+1,
381 jcf_path_is_system (entry
));
384 /* Should we check if .zip is out-of-date wrt .java? */
385 buffer
[dir_len
] = '(';
386 strcpy (buffer
+i
, ".class)");
394 klass
= stat (buffer
, &class_buf
);
401 SOURCE_FRONTEND_DEBUG ((stderr
, "[Class selected: %s]\n",
402 classname
+classname_length
-
403 (classname_length
<= 30 ?
404 classname_length
: 30)));
405 fd
= JCF_OPEN_EXACT_CASE (buffer
, O_RDONLY
| O_BINARY
);
412 /* Remember that this class could not be found so that we do not
413 have to look again. */
414 *memoized_class_lookups
->find_slot_with_hash (classname
, hash
, INSERT
)
420 const char *const tmp
= open_class (buffer
, jcf
, fd
, dep_file
);
421 jcf
->classname
= xstrdup (classname
);
427 jcf_print_char (FILE *stream
, int ch
)
434 fprintf (stream
, "\\%c", ch
);
437 fprintf (stream
, "\\n");
440 fprintf (stream
, "\\t");
443 fprintf (stream
, "\\r");
446 if (ch
>= ' ' && ch
< 127)
449 fprintf (stream
, "\\%03x", ch
);
451 fprintf (stream
, "\\u%04x", ch
);
455 /* Print UTF8 string at STR of length LENGTH bytes to STREAM. */
458 jcf_print_utf8 (FILE *stream
, const unsigned char *str
, int length
)
460 const unsigned char * limit
= str
+ length
;
463 int ch
= UTF8_GET (str
, limit
);
466 fprintf (stream
, "\\<invalid>");
469 jcf_print_char (stream
, ch
);
473 /* Same as jcf_print_utf8, but print IN_CHAR as OUT_CHAR. */
476 jcf_print_utf8_replace (FILE *stream
, const unsigned char *str
, int length
,
477 int in_char
, int out_char
)
479 const unsigned char *limit
= str
+ length
;
482 int ch
= UTF8_GET (str
, limit
);
485 fprintf (stream
, "\\<invalid>");
488 jcf_print_char (stream
, ch
== in_char
? out_char
: ch
);
492 /* Check that all the cross-references in the constant pool are
493 valid. Returns 0 on success.
494 Otherwise, returns the index of the (first) invalid entry.
495 Only checks internal consistency, but does not check that
496 any classes, fields, or methods are valid.*/
499 verify_constant_pool (JCF
*jcf
)
502 for (i
= 1; i
< JPOOL_SIZE (jcf
); i
++)
504 switch (JPOOL_TAG (jcf
, i
))
506 case CONSTANT_NameAndType
:
507 n
= JPOOL_USHORT2 (jcf
, i
);
508 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
509 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
511 /* ... fall through ... */
513 case CONSTANT_String
:
514 n
= JPOOL_USHORT1 (jcf
, i
);
515 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
516 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
519 case CONSTANT_Fieldref
:
520 case CONSTANT_Methodref
:
521 case CONSTANT_InterfaceMethodref
:
522 n
= JPOOL_USHORT1 (jcf
, i
);
523 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
524 || JPOOL_TAG (jcf
, n
) != CONSTANT_Class
)
526 n
= JPOOL_USHORT2 (jcf
, i
);
527 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
528 || JPOOL_TAG (jcf
, n
) != CONSTANT_NameAndType
)
532 case CONSTANT_Double
:
536 case CONSTANT_Integer
:
538 case CONSTANT_Unicode
:
540 case CONSTANT_MethodHandle
:
541 n
= JPOOL_USHORT1 (jcf
, i
);
544 n
= JPOOL_USHORT2 (jcf
, i
);
545 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
))
548 case CONSTANT_MethodType
:
549 n
= JPOOL_USHORT1 (jcf
, i
);
550 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
551 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
554 case CONSTANT_InvokeDynamic
:
555 n
= JPOOL_USHORT2 (jcf
, i
);
556 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
557 || JPOOL_TAG (jcf
, n
) != CONSTANT_NameAndType
)
568 format_uint (char *buffer
, uint64 value
, int base
)
570 #define WRITE_BUF_SIZE (4 + sizeof(uint64) * 8)
571 char buf
[WRITE_BUF_SIZE
];
572 char *buf_ptr
= buf
+WRITE_BUF_SIZE
; /* End of buf. */
576 /* Now do the actual conversion, placing the result at the *end* of buf. */
577 /* Note this code does not pretend to be optimized. */
579 int digit
= value
% base
;
580 static const char digit_chars
[] = "0123456789abcdefghijklmnopqrstuvwxyz";
581 *--buf_ptr
= digit_chars
[digit
];
583 } while (value
!= 0);
585 chars_written
= buf
+WRITE_BUF_SIZE
- buf_ptr
;
586 for (i
= 0; i
< chars_written
; i
++)
587 buffer
[i
] = *buf_ptr
++;
592 format_int (char *buffer
, jlong value
, int base
)
597 abs_value
= -(uint64
)value
;
601 abs_value
= (uint64
) value
;
602 format_uint (buffer
, abs_value
, base
);