1 /* Utility routines for finding and reading Java(TM) .class files.
2 Copyright (C) 1996-2014 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"
32 #include "java-tree.h"
33 #include "hash-table.h"
39 jcf_unexpected_eof (JCF
*jcf
, int count ATTRIBUTE_UNUSED
)
42 fprintf (stderr
, "Premature end of .class file %s.\n", jcf
->filename
);
44 fprintf (stderr
, "Premature end of .class file <stdin>.\n");
49 jcf_trim_old_input (JCF
*jcf
)
51 int count
= jcf
->read_ptr
- jcf
->buffer
;
54 memmove (jcf
->buffer
, jcf
->read_ptr
, jcf
->read_end
- jcf
->read_ptr
);
55 jcf
->read_ptr
-= count
;
56 jcf
->read_end
-= count
;
61 jcf_filbuf_from_stdio (JCF
*jcf
, int count
)
63 FILE *file
= (FILE*) (jcf
->read_state
);
64 if (count
> jcf
->buffer_end
- jcf
->read_ptr
)
66 JCF_u4 old_read_ptr
= jcf
->read_ptr
- jcf
->buffer
;
67 JCF_u4 old_read_end
= jcf
->read_end
- jcf
->buffer
;
68 JCF_u4 old_size
= jcf
->buffer_end
- jcf
->buffer
;
69 JCF_u4 new_size
= (old_size
== 0 ? 2000 : 2 * old_size
) + count
;
70 unsigned char *new_buffer
71 = jcf
->buffer
== NULL
? XNEWVAR (unsigned char, new_size
)
72 : XRESIZEVAR (unsigned char, jcf
->buffer
, new_size
);
73 jcf
->buffer
= new_buffer
;
74 jcf
->buffer_end
= new_buffer
+ new_size
;
75 jcf
->read_ptr
= new_buffer
+ old_read_ptr
;
76 jcf
->read_end
= new_buffer
+ old_read_end
;
78 count
-= jcf
->read_end
- jcf
->read_ptr
;
81 if ((int) fread (jcf
->read_end
, 1, count
, file
) != count
)
82 jcf_unexpected_eof (jcf
, count
);
83 jcf
->read_end
+= count
;
89 struct ZipFile
*SeenZipFiles
= NULL
;
91 /* Open a zip file with the given name, and cache directory and file
92 descriptor. If the file is missing, treat it as an empty archive.
93 Return NULL if the .zip file is malformed.
97 opendir_in_zip (const char *zipfile
, int is_system
)
102 for (zipf
= SeenZipFiles
; zipf
!= NULL
; zipf
= zipf
->next
)
104 if (strcmp (zipf
->name
, zipfile
) == 0)
108 zipf
= XNEWVAR (struct ZipFile
, sizeof (struct ZipFile
) + strlen (zipfile
) + 1);
109 zipf
->next
= SeenZipFiles
;
110 zipf
->name
= (char*)(zipf
+1);
111 strcpy (zipf
->name
, zipfile
);
112 fd
= open (zipfile
, O_RDONLY
| O_BINARY
);
116 /* A missing zip file is not considered an error.
117 We may want to re-consider that. FIXME. */
120 zipf
->central_directory
= NULL
;
124 jcf_dependency_add_file (zipfile
, is_system
);
125 if (read (fd
, magic
, 4) != 4 || GET_u4 (magic
) != (JCF_u4
)ZIPMAGIC
)
131 lseek (fd
, 0L, SEEK_SET
);
132 if (read_zip_archive (zipf
) != 0)
145 0: OK - zipmember found.
147 -2: Malformed archive.
151 open_in_zip (JCF
*jcf
, const char *zipfile
, const char *zipmember
,
156 ZipFile
*zipf
= opendir_in_zip (zipfile
, is_system
);
164 len
= strlen (zipmember
);
166 zipd
= (struct ZipDirectory
*) zipf
->central_directory
;
167 for (i
= 0; i
< zipf
->count
; i
++, zipd
= ZIPDIR_NEXT (zipd
))
169 if (len
== zipd
->filename_length
&&
170 strncmp (ZIPDIR_FILENAME (zipd
), zipmember
, len
) == 0)
174 jcf
->filename
= xstrdup (zipfile
);
175 jcf
->classname
= xstrdup (zipmember
);
176 return read_zip_member(jcf
, zipd
, zipf
);
182 /* Read data from zip archive member. */
185 read_zip_member (JCF
*jcf
, ZipDirectory
*zipd
, ZipFile
*zipf
)
187 jcf
->filbuf
= jcf_unexpected_eof
;
190 if (zipd
->compression_method
== Z_NO_COMPRESSION
)
192 jcf
->buffer
= XNEWVEC (unsigned char, zipd
->size
);
193 jcf
->buffer_end
= jcf
->buffer
+ zipd
->size
;
194 jcf
->read_ptr
= jcf
->buffer
;
195 jcf
->read_end
= jcf
->buffer_end
;
196 if (lseek (zipf
->fd
, zipd
->filestart
, 0) < 0
197 || read (zipf
->fd
, jcf
->buffer
, zipd
->size
) != (long) zipd
->size
)
203 z_stream d_stream
; /* decompression stream */
204 memset (&d_stream
, 0, sizeof (d_stream
));
206 jcf
->buffer
= XNEWVEC (unsigned char, zipd
->uncompressed_size
);
207 d_stream
.next_out
= jcf
->buffer
;
208 d_stream
.avail_out
= zipd
->uncompressed_size
;
209 jcf
->buffer_end
= jcf
->buffer
+ zipd
->uncompressed_size
;
210 jcf
->read_ptr
= jcf
->buffer
;
211 jcf
->read_end
= jcf
->buffer_end
;
212 buffer
= XNEWVEC (char, zipd
->size
);
213 d_stream
.next_in
= (unsigned char *) buffer
;
214 d_stream
.avail_in
= zipd
->size
;
215 if (lseek (zipf
->fd
, zipd
->filestart
, 0) < 0
216 || read (zipf
->fd
, buffer
, zipd
->size
) != (long) zipd
->size
)
218 /* Handle NO_HEADER using undocumented zlib feature.
219 This is a very common hack. */
220 inflateInit2 (&d_stream
, -MAX_WBITS
);
221 inflate (&d_stream
, Z_NO_FLUSH
);
222 inflateEnd (&d_stream
);
230 open_class (const char *filename
, JCF
*jcf
, int fd
, const char *dep_name
)
234 struct stat stat_buf
;
235 if (fstat (fd
, &stat_buf
) != 0
236 || ! S_ISREG (stat_buf
.st_mode
))
238 perror ("Could not figure length of .class file");
241 if (dep_name
!= NULL
)
242 jcf_dependency_add_file (dep_name
, 0);
244 jcf
->buffer
= XNEWVEC (unsigned char, stat_buf
.st_size
);
245 jcf
->buffer_end
= jcf
->buffer
+ stat_buf
.st_size
;
246 jcf
->read_ptr
= jcf
->buffer
;
247 jcf
->read_end
= jcf
->buffer_end
;
248 jcf
->read_state
= NULL
;
249 jcf
->filename
= xstrdup (filename
);
250 if (read (fd
, jcf
->buffer
, stat_buf
.st_size
) != stat_buf
.st_size
)
252 perror ("Failed to read .class file");
256 jcf
->filbuf
= jcf_unexpected_eof
;
265 find_classfile (char *filename
, JCF
*jcf
, const char *dep_name
)
267 int fd
= open (filename
, O_RDONLY
| O_BINARY
);
270 return open_class (filename
, jcf
, fd
, dep_name
);
274 /* Hash table helper. */
276 struct charstar_hash
: typed_noop_remove
<char>
278 typedef const char value_type
;
279 typedef const char compare_type
;
280 static inline hashval_t
hash (const value_type
*candidate
);
281 static inline bool equal (const value_type
*existing
,
282 const compare_type
*candidate
);
286 charstar_hash::hash (const value_type
*candidate
)
288 return htab_hash_string (candidate
);
292 charstar_hash::equal (const value_type
*existing
, const compare_type
*candidate
)
294 return strcmp (existing
, candidate
) == 0;
298 /* A hash table keeping track of class names that were not found
299 during class lookup. (There is no need to cache the values
300 associated with names that were found; they are saved in
301 IDENTIFIER_CLASS_VALUE.) */
302 static hash_table
<charstar_hash
> *memoized_class_lookups
;
304 /* Returns a freshly malloc'd string with the fully qualified pathname
305 of the .class file for the class CLASSNAME. CLASSNAME must be
306 allocated in permanent storage; this function may retain a pointer
307 to it. Returns NULL on failure. If JCF != NULL, it is suitably
308 initialized. SOURCE_OK is true if we should also look for .java
312 find_class (const char *classname
, int classname_length
, JCF
*jcf
)
315 int i
, k
, klass
= -1;
316 struct stat class_buf
;
323 /* Create the hash table, if it does not already exist. */
324 if (!memoized_class_lookups
)
325 memoized_class_lookups
= new hash_table
<charstar_hash
> (37);
327 /* Loop for this class in the hashtable. If it is present, we've
328 already looked for this class and failed to find it. */
329 hash
= charstar_hash::hash (classname
);
330 if (memoized_class_lookups
->find_with_hash (classname
, hash
))
333 /* Allocate and zero out the buffer, since we don't explicitly put a
334 null pointer when we're copying it below. */
335 buflen
= jcf_path_max_len () + classname_length
+ 10;
336 buffer
= XNEWVAR (char, buflen
);
337 memset (buffer
, 0, buflen
);
339 for (entry
= jcf_path_start (); entry
!= NULL
; entry
= jcf_path_next (entry
))
341 const char *path_name
= jcf_path_name (entry
);
346 strcpy (buffer
, path_name
);
349 /* This is right because we know that `.zip' entries will have a
350 trailing slash. See jcf-path.c. */
353 for (k
= 0; k
< classname_length
; k
++, i
++)
355 char ch
= classname
[k
];
356 buffer
[i
] = ch
== '.' ? '/' : ch
;
358 strcpy (buffer
+i
, ".class");
360 if (jcf_path_is_zipfile (entry
))
364 buffer
[dir_len
] = '\0';
365 SOURCE_FRONTEND_DEBUG
366 (("Trying [...%s]:%s",
367 &buffer
[dir_len
-(dir_len
> 15 ? 15 : dir_len
)],
371 err_code
= open_in_zip (jcf
, buffer
, buffer
+dir_len
+1,
372 jcf_path_is_system (entry
));
375 /* Should we check if .zip is out-of-date wrt .java? */
376 buffer
[dir_len
] = '(';
377 strcpy (buffer
+i
, ".class)");
385 klass
= stat (buffer
, &class_buf
);
392 SOURCE_FRONTEND_DEBUG ((stderr
, "[Class selected: %s]\n",
393 classname
+classname_length
-
394 (classname_length
<= 30 ?
395 classname_length
: 30)));
396 fd
= JCF_OPEN_EXACT_CASE (buffer
, O_RDONLY
| O_BINARY
);
403 /* Remember that this class could not be found so that we do not
404 have to look again. */
405 *memoized_class_lookups
->find_slot_with_hash (classname
, hash
, INSERT
)
411 const char *const tmp
= open_class (buffer
, jcf
, fd
, dep_file
);
412 jcf
->classname
= xstrdup (classname
);
418 jcf_print_char (FILE *stream
, int ch
)
425 fprintf (stream
, "\\%c", ch
);
428 fprintf (stream
, "\\n");
431 fprintf (stream
, "\\t");
434 fprintf (stream
, "\\r");
437 if (ch
>= ' ' && ch
< 127)
440 fprintf (stream
, "\\%03x", ch
);
442 fprintf (stream
, "\\u%04x", ch
);
446 /* Print UTF8 string at STR of length LENGTH bytes to STREAM. */
449 jcf_print_utf8 (FILE *stream
, const unsigned char *str
, int length
)
451 const unsigned char * limit
= str
+ length
;
454 int ch
= UTF8_GET (str
, limit
);
457 fprintf (stream
, "\\<invalid>");
460 jcf_print_char (stream
, ch
);
464 /* Same as jcf_print_utf8, but print IN_CHAR as OUT_CHAR. */
467 jcf_print_utf8_replace (FILE *stream
, const unsigned char *str
, int length
,
468 int in_char
, int out_char
)
470 const unsigned char *limit
= str
+ length
;
473 int ch
= UTF8_GET (str
, limit
);
476 fprintf (stream
, "\\<invalid>");
479 jcf_print_char (stream
, ch
== in_char
? out_char
: ch
);
483 /* Check that all the cross-references in the constant pool are
484 valid. Returns 0 on success.
485 Otherwise, returns the index of the (first) invalid entry.
486 Only checks internal consistency, but does not check that
487 any classes, fields, or methods are valid.*/
490 verify_constant_pool (JCF
*jcf
)
493 for (i
= 1; i
< JPOOL_SIZE (jcf
); i
++)
495 switch (JPOOL_TAG (jcf
, i
))
497 case CONSTANT_NameAndType
:
498 n
= JPOOL_USHORT2 (jcf
, i
);
499 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
500 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
502 /* ... fall through ... */
504 case CONSTANT_String
:
505 n
= JPOOL_USHORT1 (jcf
, i
);
506 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
507 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
510 case CONSTANT_Fieldref
:
511 case CONSTANT_Methodref
:
512 case CONSTANT_InterfaceMethodref
:
513 n
= JPOOL_USHORT1 (jcf
, i
);
514 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
515 || JPOOL_TAG (jcf
, n
) != CONSTANT_Class
)
517 n
= JPOOL_USHORT2 (jcf
, i
);
518 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
519 || JPOOL_TAG (jcf
, n
) != CONSTANT_NameAndType
)
523 case CONSTANT_Double
:
527 case CONSTANT_Integer
:
529 case CONSTANT_Unicode
:
531 case CONSTANT_MethodHandle
:
532 n
= JPOOL_USHORT1 (jcf
, i
);
535 n
= JPOOL_USHORT2 (jcf
, i
);
536 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
))
539 case CONSTANT_MethodType
:
540 n
= JPOOL_USHORT1 (jcf
, i
);
541 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
542 || JPOOL_TAG (jcf
, n
) != CONSTANT_Utf8
)
545 case CONSTANT_InvokeDynamic
:
546 n
= JPOOL_USHORT2 (jcf
, i
);
547 if (n
<= 0 || n
>= JPOOL_SIZE(jcf
)
548 || JPOOL_TAG (jcf
, n
) != CONSTANT_NameAndType
)
559 format_uint (char *buffer
, uint64 value
, int base
)
561 #define WRITE_BUF_SIZE (4 + sizeof(uint64) * 8)
562 char buf
[WRITE_BUF_SIZE
];
563 char *buf_ptr
= buf
+WRITE_BUF_SIZE
; /* End of buf. */
567 /* Now do the actual conversion, placing the result at the *end* of buf. */
568 /* Note this code does not pretend to be optimized. */
570 int digit
= value
% base
;
571 static const char digit_chars
[] = "0123456789abcdefghijklmnopqrstuvwxyz";
572 *--buf_ptr
= digit_chars
[digit
];
574 } while (value
!= 0);
576 chars_written
= buf
+WRITE_BUF_SIZE
- buf_ptr
;
577 for (i
= 0; i
< chars_written
; i
++)
578 buffer
[i
] = *buf_ptr
++;
583 format_int (char *buffer
, jlong value
, int base
)
588 abs_value
= -(uint64
)value
;
592 abs_value
= (uint64
) value
;
593 format_uint (buffer
, abs_value
, base
);