* config/darwin.c (darwin_assemble_visibility): Treat
[official-gcc.git] / gcc / java / jcf-io.c
blob0fe30b30ca58b25a237e269fef6970b89b09ab62
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, 2008, 2009, 2010 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)
10 any later version.
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. */
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
31 #include "jcf.h"
32 #include "tree.h"
33 #include "java-tree.h"
34 #include "hashtab.h"
35 #include <dirent.h>
37 #include "zlib.h"
39 int
40 jcf_unexpected_eof (JCF *jcf, int count ATTRIBUTE_UNUSED)
42 if (jcf->filename)
43 fprintf (stderr, "Premature end of .class file %s.\n", jcf->filename);
44 else
45 fprintf (stderr, "Premature end of .class file <stdin>.\n");
46 exit (-1);
49 void
50 jcf_trim_old_input (JCF *jcf)
52 int count = jcf->read_ptr - jcf->buffer;
53 if (count > 0)
55 memmove (jcf->buffer, jcf->read_ptr, jcf->read_end - jcf->read_ptr);
56 jcf->read_ptr -= count;
57 jcf->read_end -= count;
61 int
62 jcf_filbuf_from_stdio (JCF *jcf, int count)
64 FILE *file = (FILE*) (jcf->read_state);
65 if (count > jcf->buffer_end - jcf->read_ptr)
67 JCF_u4 old_read_ptr = jcf->read_ptr - jcf->buffer;
68 JCF_u4 old_read_end = jcf->read_end - jcf->buffer;
69 JCF_u4 old_size = jcf->buffer_end - jcf->buffer;
70 JCF_u4 new_size = (old_size == 0 ? 2000 : 2 * old_size) + count;
71 unsigned char *new_buffer
72 = jcf->buffer == NULL ? XNEWVAR (unsigned char, new_size)
73 : XRESIZEVAR (unsigned char, jcf->buffer, new_size);
74 jcf->buffer = new_buffer;
75 jcf->buffer_end = new_buffer + new_size;
76 jcf->read_ptr = new_buffer + old_read_ptr;
77 jcf->read_end = new_buffer + old_read_end;
79 count -= jcf->read_end - jcf->read_ptr;
80 if (count <= 0)
81 return 0;
82 if ((int) fread (jcf->read_end, 1, count, file) != count)
83 jcf_unexpected_eof (jcf, count);
84 jcf->read_end += count;
85 return 0;
88 #include "zipfile.h"
90 struct ZipFile *SeenZipFiles = NULL;
92 /* Open a zip file with the given name, and cache directory and file
93 descriptor. If the file is missing, treat it as an empty archive.
94 Return NULL if the .zip file is malformed.
97 ZipFile *
98 opendir_in_zip (const char *zipfile, int is_system)
100 struct ZipFile* zipf;
101 char magic [4];
102 int fd;
103 for (zipf = SeenZipFiles; zipf != NULL; zipf = zipf->next)
105 if (strcmp (zipf->name, zipfile) == 0)
106 return zipf;
109 zipf = XNEWVAR (struct ZipFile, sizeof (struct ZipFile) + strlen (zipfile) + 1);
110 zipf->next = SeenZipFiles;
111 zipf->name = (char*)(zipf+1);
112 strcpy (zipf->name, zipfile);
113 fd = open (zipfile, O_RDONLY | O_BINARY);
114 zipf->fd = fd;
115 if (fd < 0)
117 /* A missing zip file is not considered an error.
118 We may want to re-consider that. FIXME. */
119 zipf->count = 0;
120 zipf->dir_size = 0;
121 zipf->central_directory = NULL;
123 else
125 jcf_dependency_add_file (zipfile, is_system);
126 if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC)
128 free (zipf);
129 close (fd);
130 return NULL;
132 lseek (fd, 0L, SEEK_SET);
133 if (read_zip_archive (zipf) != 0)
135 free (zipf);
136 close (fd);
137 return NULL;
141 SeenZipFiles = zipf;
142 return zipf;
145 /* Returns:
146 0: OK - zipmember found.
147 -1: Not found.
148 -2: Malformed archive.
152 open_in_zip (JCF *jcf, const char *zipfile, const char *zipmember,
153 int is_system)
155 ZipDirectory *zipd;
156 int i, len;
157 ZipFile *zipf = opendir_in_zip (zipfile, is_system);
159 if (zipf == NULL)
160 return -2;
162 if (!zipmember)
163 return 0;
165 len = strlen (zipmember);
167 zipd = (struct ZipDirectory*) zipf->central_directory;
168 for (i = 0; i < zipf->count; i++, zipd = ZIPDIR_NEXT (zipd))
170 if (len == zipd->filename_length &&
171 strncmp (ZIPDIR_FILENAME (zipd), zipmember, len) == 0)
173 JCF_ZERO (jcf);
175 jcf->filename = xstrdup (zipfile);
176 jcf->classname = xstrdup (zipmember);
177 return read_zip_member(jcf, zipd, zipf);
180 return -1;
183 /* Read data from zip archive member. */
186 read_zip_member (JCF *jcf, ZipDirectory *zipd, ZipFile *zipf)
188 jcf->filbuf = jcf_unexpected_eof;
189 jcf->zipd = zipd;
191 if (zipd->compression_method == Z_NO_COMPRESSION)
193 jcf->buffer = XNEWVEC (unsigned char, zipd->size);
194 jcf->buffer_end = jcf->buffer + zipd->size;
195 jcf->read_ptr = jcf->buffer;
196 jcf->read_end = jcf->buffer_end;
197 if (lseek (zipf->fd, zipd->filestart, 0) < 0
198 || read (zipf->fd, jcf->buffer, zipd->size) != (long) zipd->size)
199 return -2;
201 else
203 char *buffer;
204 z_stream d_stream; /* decompression stream */
205 memset (&d_stream, 0, sizeof (d_stream));
207 jcf->buffer = XNEWVEC (unsigned char, zipd->uncompressed_size);
208 d_stream.next_out = jcf->buffer;
209 d_stream.avail_out = zipd->uncompressed_size;
210 jcf->buffer_end = jcf->buffer + zipd->uncompressed_size;
211 jcf->read_ptr = jcf->buffer;
212 jcf->read_end = jcf->buffer_end;
213 buffer = XNEWVEC (char, zipd->size);
214 d_stream.next_in = (unsigned char *) buffer;
215 d_stream.avail_in = zipd->size;
216 if (lseek (zipf->fd, zipd->filestart, 0) < 0
217 || read (zipf->fd, buffer, zipd->size) != (long) zipd->size)
218 return -2;
219 /* Handle NO_HEADER using undocumented zlib feature.
220 This is a very common hack. */
221 inflateInit2 (&d_stream, -MAX_WBITS);
222 inflate (&d_stream, Z_NO_FLUSH);
223 inflateEnd (&d_stream);
224 free (buffer);
227 return 0;
230 const char *
231 open_class (const char *filename, JCF *jcf, int fd, const char *dep_name)
233 if (jcf)
235 struct stat stat_buf;
236 if (fstat (fd, &stat_buf) != 0
237 || ! S_ISREG (stat_buf.st_mode))
239 perror ("Could not figure length of .class file");
240 return NULL;
242 if (dep_name != NULL)
243 jcf_dependency_add_file (dep_name, 0);
244 JCF_ZERO (jcf);
245 jcf->buffer = XNEWVEC (unsigned char, stat_buf.st_size);
246 jcf->buffer_end = jcf->buffer + stat_buf.st_size;
247 jcf->read_ptr = jcf->buffer;
248 jcf->read_end = jcf->buffer_end;
249 jcf->read_state = NULL;
250 jcf->filename = xstrdup (filename);
251 if (read (fd, jcf->buffer, stat_buf.st_size) != stat_buf.st_size)
253 perror ("Failed to read .class file");
254 return NULL;
256 close (fd);
257 jcf->filbuf = jcf_unexpected_eof;
259 else
260 close (fd);
261 return filename;
265 const char *
266 find_classfile (char *filename, JCF *jcf, const char *dep_name)
268 int fd = open (filename, O_RDONLY | O_BINARY);
269 if (fd < 0)
270 return NULL;
271 return open_class (filename, jcf, fd, dep_name);
274 /* Returns 1 if the CLASSNAME (really a char *) matches the name
275 stored in TABLE_ENTRY (also a char *). */
277 static int
278 memoized_class_lookup_eq (const void *table_entry, const void *classname)
280 return strcmp ((const char *)classname, (const char *)table_entry) == 0;
283 /* A hash table keeping track of class names that were not found
284 during class lookup. (There is no need to cache the values
285 associated with names that were found; they are saved in
286 IDENTIFIER_CLASS_VALUE.) */
287 static htab_t memoized_class_lookups;
289 /* Returns a freshly malloc'd string with the fully qualified pathname
290 of the .class file for the class CLASSNAME. CLASSNAME must be
291 allocated in permanent storage; this function may retain a pointer
292 to it. Returns NULL on failure. If JCF != NULL, it is suitably
293 initialized. SOURCE_OK is true if we should also look for .java
294 file. */
296 const char *
297 find_class (const char *classname, int classname_length, JCF *jcf)
299 int fd;
300 int i, k, klass = -1;
301 struct stat class_buf;
302 char *dep_file;
303 void *entry;
304 int buflen;
305 char *buffer;
306 hashval_t hash;
308 /* Create the hash table, if it does not already exist. */
309 if (!memoized_class_lookups)
310 memoized_class_lookups = htab_create (37,
311 htab_hash_string,
312 memoized_class_lookup_eq,
313 NULL);
315 /* Loop for this class in the hashtable. If it is present, we've
316 already looked for this class and failed to find it. */
317 hash = htab_hash_string (classname);
318 if (htab_find_with_hash (memoized_class_lookups, classname, hash))
319 return NULL;
321 /* Allocate and zero out the buffer, since we don't explicitly put a
322 null pointer when we're copying it below. */
323 buflen = jcf_path_max_len () + classname_length + 10;
324 buffer = XNEWVAR (char, buflen);
325 memset (buffer, 0, buflen);
327 for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
329 const char *path_name = jcf_path_name (entry);
330 if (klass != 0)
332 int dir_len;
334 strcpy (buffer, path_name);
335 i = strlen (buffer);
337 /* This is right because we know that `.zip' entries will have a
338 trailing slash. See jcf-path.c. */
339 dir_len = i - 1;
341 for (k = 0; k < classname_length; k++, i++)
343 char ch = classname[k];
344 buffer[i] = ch == '.' ? '/' : ch;
346 strcpy (buffer+i, ".class");
348 if (jcf_path_is_zipfile (entry))
350 int err_code;
351 JCF _jcf;
352 buffer[dir_len] = '\0';
353 SOURCE_FRONTEND_DEBUG
354 (("Trying [...%s]:%s",
355 &buffer[dir_len-(dir_len > 15 ? 15 : dir_len)],
356 buffer+dir_len+1));
357 if (jcf == NULL)
358 jcf = &_jcf;
359 err_code = open_in_zip (jcf, buffer, buffer+dir_len+1,
360 jcf_path_is_system (entry));
361 if (err_code == 0)
363 /* Should we check if .zip is out-of-date wrt .java? */
364 buffer[dir_len] = '(';
365 strcpy (buffer+i, ".class)");
366 if (jcf == &_jcf)
367 JCF_FINISH (jcf);
368 return buffer;
370 else
371 continue;
373 klass = stat (buffer, &class_buf);
377 dep_file = buffer;
378 if (!klass)
380 SOURCE_FRONTEND_DEBUG ((stderr, "[Class selected: %s]\n",
381 classname+classname_length-
382 (classname_length <= 30 ?
383 classname_length : 30)));
384 fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY | O_BINARY);
385 if (fd >= 0)
386 goto found;
389 free (buffer);
391 /* Remember that this class could not be found so that we do not
392 have to look again. */
393 *htab_find_slot_with_hash (memoized_class_lookups, classname, hash, INSERT)
394 = (void *) CONST_CAST (char *, classname);
396 return NULL;
397 found:
399 const char *const tmp = open_class (buffer, jcf, fd, dep_file);
400 jcf->classname = xstrdup (classname);
401 return tmp;
405 void
406 jcf_print_char (FILE *stream, int ch)
408 switch (ch)
410 case '\'':
411 case '\\':
412 case '\"':
413 fprintf (stream, "\\%c", ch);
414 break;
415 case '\n':
416 fprintf (stream, "\\n");
417 break;
418 case '\t':
419 fprintf (stream, "\\t");
420 break;
421 case '\r':
422 fprintf (stream, "\\r");
423 break;
424 default:
425 if (ch >= ' ' && ch < 127)
426 putc (ch, stream);
427 else if (ch < 256)
428 fprintf (stream, "\\%03x", ch);
429 else
430 fprintf (stream, "\\u%04x", ch);
434 /* Print UTF8 string at STR of length LENGTH bytes to STREAM. */
436 void
437 jcf_print_utf8 (FILE *stream, const unsigned char *str, int length)
439 const unsigned char * limit = str + length;
440 while (str < limit)
442 int ch = UTF8_GET (str, limit);
443 if (ch < 0)
445 fprintf (stream, "\\<invalid>");
446 return;
448 jcf_print_char (stream, ch);
452 /* Same as jcf_print_utf8, but print IN_CHAR as OUT_CHAR. */
454 void
455 jcf_print_utf8_replace (FILE *stream, const unsigned char *str, int length,
456 int in_char, int out_char)
458 const unsigned char *limit = str + length;
459 while (str < limit)
461 int ch = UTF8_GET (str, limit);
462 if (ch < 0)
464 fprintf (stream, "\\<invalid>");
465 return;
467 jcf_print_char (stream, ch == in_char ? out_char : ch);
471 /* Check that all the cross-references in the constant pool are
472 valid. Returns 0 on success.
473 Otherwise, returns the index of the (first) invalid entry.
474 Only checks internal consistency, but does not check that
475 any classes, fields, or methods are valid.*/
478 verify_constant_pool (JCF *jcf)
480 int i, n;
481 for (i = 1; i < JPOOL_SIZE (jcf); i++)
483 switch (JPOOL_TAG (jcf, i))
485 case CONSTANT_NameAndType:
486 n = JPOOL_USHORT2 (jcf, i);
487 if (n <= 0 || n >= JPOOL_SIZE(jcf)
488 || JPOOL_TAG (jcf, n) != CONSTANT_Utf8)
489 return i;
490 /* ... fall through ... */
491 case CONSTANT_Class:
492 case CONSTANT_String:
493 n = JPOOL_USHORT1 (jcf, i);
494 if (n <= 0 || n >= JPOOL_SIZE(jcf)
495 || JPOOL_TAG (jcf, n) != CONSTANT_Utf8)
496 return i;
497 break;
498 case CONSTANT_Fieldref:
499 case CONSTANT_Methodref:
500 case CONSTANT_InterfaceMethodref:
501 n = JPOOL_USHORT1 (jcf, i);
502 if (n <= 0 || n >= JPOOL_SIZE(jcf)
503 || JPOOL_TAG (jcf, n) != CONSTANT_Class)
504 return i;
505 n = JPOOL_USHORT2 (jcf, i);
506 if (n <= 0 || n >= JPOOL_SIZE(jcf)
507 || JPOOL_TAG (jcf, n) != CONSTANT_NameAndType)
508 return i;
509 break;
510 case CONSTANT_Long:
511 case CONSTANT_Double:
512 i++;
513 break;
514 case CONSTANT_Float:
515 case CONSTANT_Integer:
516 case CONSTANT_Utf8:
517 case CONSTANT_Unicode:
518 break;
519 case CONSTANT_MethodHandle:
520 n = JPOOL_USHORT1 (jcf, i);
521 if (n < 1 || n > 9)
522 return i;
523 n = JPOOL_USHORT2 (jcf, i);
524 if (n <= 0 || n >= JPOOL_SIZE(jcf))
525 return i;
526 break;
527 case CONSTANT_MethodType:
528 n = JPOOL_USHORT1 (jcf, i);
529 if (n <= 0 || n >= JPOOL_SIZE(jcf)
530 || JPOOL_TAG (jcf, n) != CONSTANT_Utf8)
531 return i;
532 break;
533 case CONSTANT_InvokeDynamic:
534 n = JPOOL_USHORT2 (jcf, i);
535 if (n <= 0 || n >= JPOOL_SIZE(jcf)
536 || JPOOL_TAG (jcf, n) != CONSTANT_NameAndType)
537 return i;
538 break;
539 default:
540 return i;
543 return 0;
546 void
547 format_uint (char *buffer, uint64 value, int base)
549 #define WRITE_BUF_SIZE (4 + sizeof(uint64) * 8)
550 char buf[WRITE_BUF_SIZE];
551 char *buf_ptr = buf+WRITE_BUF_SIZE; /* End of buf. */
552 int chars_written;
553 int i;
555 /* Now do the actual conversion, placing the result at the *end* of buf. */
556 /* Note this code does not pretend to be optimized. */
557 do {
558 int digit = value % base;
559 static const char digit_chars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
560 *--buf_ptr = digit_chars[digit];
561 value /= base;
562 } while (value != 0);
564 chars_written = buf+WRITE_BUF_SIZE - buf_ptr;
565 for (i = 0; i < chars_written; i++)
566 buffer[i] = *buf_ptr++;
567 buffer[i] = 0;
570 void
571 format_int (char *buffer, jlong value, int base)
573 uint64 abs_value;
574 if (value < 0)
576 abs_value = -(uint64)value;
577 *buffer++ = '-';
579 else
580 abs_value = (uint64) value;
581 format_uint (buffer, abs_value, base);