From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- gcc/java/zextract.c | 396 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 gcc/java/zextract.c (limited to 'gcc/java/zextract.c') diff --git a/gcc/java/zextract.c b/gcc/java/zextract.c new file mode 100644 index 000000000..b11319720 --- /dev/null +++ b/gcc/java/zextract.c @@ -0,0 +1,396 @@ +/* Handle a .class file embedded in a .zip archive. + This extracts a member from a .zip file, but does not handle + uncompression (since that is not needed for classes.zip). + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, + 2007 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. + +Java and all Java-based marks are trademarks or registered trademarks +of Sun Microsystems, Inc. in the United States and other countries. +The Free Software Foundation is independent of Sun Microsystems, Inc. */ + +/* Written by Per Bothner , February 1996. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "zipfile.h" + +/* This stuff is partly based on the 28 August 1994 public release of the +Info-ZIP group's portable UnZip zipfile-extraction program (and related +utilities). */ + +/*************/ +/* Defines */ +/*************/ + +#define UNZIP +#define UNZIP_VERSION 20 /* compatible with PKUNZIP 2.0 */ +#define VMS_UNZIP_VERSION 42 /* if OS-needed-to-extract is VMS: can do */ + + +#define ZSUFX ".zip" +#define CENTRAL_HDR_SIG "\113\001\002" /* the infamous "PK" signature */ +#define LOCAL_HDR_SIG "\113\003\004" /* bytes, sans "P" (so unzip */ +#define END_CENTRAL_SIG "\113\005\006" /* executable not mistaken for */ +#define EXTD_LOCAL_SIG "\113\007\010" /* zipfile itself) */ + +#define STORED 0 /* compression methods */ +#define SHRUNK 1 +#define REDUCED1 2 +#define REDUCED2 3 +#define REDUCED3 4 +#define REDUCED4 5 +#define IMPLODED 6 +#define TOKENIZED 7 +#define DEFLATED 8 +#define NUM_METHODS 9 /* index of last method + 1 */ +/* don't forget to update list_files() appropriately if NUM_METHODS changes */ + +#define PK_OK 0 /* no error */ +#define PK_COOL 0 /* no error */ +#define PK_GNARLY 0 /* no error */ +#define PK_WARN 1 /* warning error */ +#define PK_ERR 2 /* error in zipfile */ +#define PK_BADERR 3 /* severe error in zipfile */ +#define PK_MEM 4 /* insufficient memory */ +#define PK_MEM2 5 /* insufficient memory */ +#define PK_MEM3 6 /* insufficient memory */ +#define PK_MEM4 7 /* insufficient memory */ +#define PK_MEM5 8 /* insufficient memory */ +#define PK_NOZIP 9 /* zipfile not found */ +#define PK_PARAM 10 /* bad or illegal parameters specified */ +#define PK_FIND 11 /* no files found */ +#define PK_DISK 50 /* disk full */ +#define PK_EOF 51 /* unexpected EOF */ + +/*--------------------------------------------------------------------------- + True sizes of the various headers, as defined by PKWARE--so it is not + likely that these will ever change. But if they do, make sure both these + defines AND the typedefs below get updated accordingly. + ---------------------------------------------------------------------------*/ +#define LREC_SIZE 26 /* lengths of local file headers, central */ +#define CREC_SIZE 42 /* directory headers, and the end-of- */ +#define ECREC_SIZE 18 /* central-dir record, respectively */ + + +#ifndef SEEK_SET +# define SEEK_SET 0 +# define SEEK_CUR 1 +# define SEEK_END 2 +#endif + +/**************/ +/* Typedefs */ +/**************/ + +typedef char boolean; +typedef unsigned char uch; /* code assumes unsigned bytes; these type- */ +typedef unsigned short ush; /* defs replace byte/UWORD/ULONG (which are */ +typedef unsigned long ulg; /* predefined on some systems) & match zip */ + +/*--------------------------------------------------------------------------- + Zipfile layout declarations. If these headers ever change, make sure the + xxREC_SIZE defines (above) change with them! + ---------------------------------------------------------------------------*/ + + typedef uch local_byte_hdr[ LREC_SIZE ]; +# define L_VERSION_NEEDED_TO_EXTRACT_0 0 +# define L_VERSION_NEEDED_TO_EXTRACT_1 1 +# define L_GENERAL_PURPOSE_BIT_FLAG 2 +# define L_COMPRESSION_METHOD 4 +# define L_LAST_MOD_FILE_TIME 6 +# define L_LAST_MOD_FILE_DATE 8 +# define L_CRC32 10 +# define L_COMPRESSED_SIZE 14 +# define L_UNCOMPRESSED_SIZE 18 +# define L_FILENAME_LENGTH 22 +# define L_EXTRA_FIELD_LENGTH 24 + + typedef uch cdir_byte_hdr[ CREC_SIZE ]; +# define C_VERSION_MADE_BY_0 0 +# define C_VERSION_MADE_BY_1 1 +# define C_VERSION_NEEDED_TO_EXTRACT_0 2 +# define C_VERSION_NEEDED_TO_EXTRACT_1 3 +# define C_GENERAL_PURPOSE_BIT_FLAG 4 +# define C_COMPRESSION_METHOD 6 +# define C_LAST_MOD_FILE_TIME 8 +# define C_LAST_MOD_FILE_DATE 10 +# define C_CRC32 12 +# define C_COMPRESSED_SIZE 16 +# define C_UNCOMPRESSED_SIZE 20 +# define C_FILENAME_LENGTH 24 +# define C_EXTRA_FIELD_LENGTH 26 +# define C_FILE_COMMENT_LENGTH 28 +# define C_DISK_NUMBER_START 30 +# define C_INTERNAL_FILE_ATTRIBUTES 32 +# define C_EXTERNAL_FILE_ATTRIBUTES 34 +# define C_RELATIVE_OFFSET_LOCAL_HEADER 38 + + typedef uch ec_byte_rec[ ECREC_SIZE+4 ]; +/* define SIGNATURE 0 space-holder only */ +# define NUMBER_THIS_DISK 4 +# define NUM_DISK_WITH_START_CENTRAL_DIR 6 +# define NUM_ENTRIES_CENTRL_DIR_THS_DISK 8 +# define TOTAL_ENTRIES_CENTRAL_DIR 10 +# define SIZE_CENTRAL_DIRECTORY 12 +# define OFFSET_START_CENTRAL_DIRECTORY 16 +# define ZIPFILE_COMMENT_LENGTH 20 + + + typedef struct local_file_header { /* LOCAL */ + uch version_needed_to_extract[2]; + ush general_purpose_bit_flag; + ush compression_method; + ush last_mod_file_time; + ush last_mod_file_date; + ulg crc32; + ulg csize; + ulg ucsize; + ush filename_length; + ush extra_field_length; + } local_file_hdr; + + typedef struct central_directory_file_header { /* CENTRAL */ + uch version_made_by[2]; + uch version_needed_to_extract[2]; + ush general_purpose_bit_flag; + ush compression_method; + ush last_mod_file_time; + ush last_mod_file_date; + ulg crc32; + ulg csize; + ulg ucsize; + ush filename_length; + ush extra_field_length; + ush file_comment_length; + ush disk_number_start; + ush internal_file_attributes; + ulg external_file_attributes; + ulg relative_offset_local_header; + } cdir_file_hdr; + + typedef struct end_central_dir_record { /* END CENTRAL */ + ush number_this_disk; + ush num_disk_with_start_central_dir; + ush num_entries_centrl_dir_ths_disk; + ush total_entries_central_dir; + ulg size_central_directory; + ulg offset_start_central_directory; + ush zipfile_comment_length; + } ecdir_rec; + + +/************/ +/* Macros */ +/************/ + +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + + +/***********************/ +/* Prototypes */ +/***********************/ + +static ush makeword (const uch *); +static ulg makelong (const uch *); +static long find_zip_file_start (int fd, long offset); + +/***********************/ +/* Function makeword() */ +/***********************/ + +static ush makeword(const uch *b) +{ + /* + * Convert Intel style 'short' integer to non-Intel non-16-bit + * host format. This routine also takes care of byte-ordering. + */ + return (ush)((b[1] << 8) | b[0]); +} + + +/***********************/ +/* Function makelong() */ +/***********************/ + +static ulg +makelong (const uch *sig) +{ + /* + * Convert intel style 'long' variable to non-Intel non-16-bit + * host format. This routine also takes care of byte-ordering. + */ + return (((ulg)sig[3]) << 24) + + (((ulg)sig[2]) << 16) + + (((ulg)sig[1]) << 8) + + ((ulg)sig[0]); +} + +/* Examine file's header in zip file and return the offset of the + start of the actual data. Return -1 on error. OFFSET is the + offset from the beginning of the zip file of the file's header. */ +static long +find_zip_file_start (int fd, long offset) +{ + int filename_length, extra_field_length; + unsigned char buffer[LREC_SIZE + 4]; + + if (lseek (fd, offset, SEEK_SET) < 0) + return -1; + + if (read (fd, buffer, LREC_SIZE + 4) != LREC_SIZE + 4) + return -1; + + if (buffer[0] != 'P' || strncmp ((const char *) &buffer[1], LOCAL_HDR_SIG, 3)) + return -1; + + filename_length = makeword (&buffer[4 + L_FILENAME_LENGTH]); + extra_field_length = makeword (&buffer[4 + L_EXTRA_FIELD_LENGTH]); + + return offset + (4 + LREC_SIZE) + filename_length + extra_field_length; +} + +int +read_zip_archive (ZipFile *zipf) +{ + int i; + int dir_last_pad; + char *dir_ptr; + char buffer[100]; + + zipf->size = lseek (zipf->fd, 0L, SEEK_END); + + if (zipf->size < (ECREC_SIZE+4) || lseek (zipf->fd, (long)(-(ECREC_SIZE+4)), SEEK_CUR) <= 0) + return -1; + if (read (zipf->fd, buffer, ECREC_SIZE+4) != ECREC_SIZE+4) + return -2; + if (buffer[0] != 'P' + || strncmp ((const char *) &buffer[1], END_CENTRAL_SIG, 3)) + { + /* We could not find the end-central-header signature, probably + because a zipfile comment is present. Scan backwards until we + find the signature. */ + if (lseek (zipf->fd, (long)(-ECREC_SIZE), SEEK_END) <= 0) + return -2; + while (buffer[0] != 'P' + || strncmp ((const char *) &buffer[1], END_CENTRAL_SIG, 3)) + { + if (lseek (zipf->fd, -5, SEEK_CUR) < 0) + return -2; + if (read (zipf->fd, buffer, 4) != 4) + return -2; + } + if (read (zipf->fd, buffer + 4, ECREC_SIZE) != ECREC_SIZE) + return -2; + } + zipf->count = makeword((const uch *) &buffer[TOTAL_ENTRIES_CENTRAL_DIR]); + zipf->dir_size = makelong((const uch *) &buffer[SIZE_CENTRAL_DIRECTORY]); + /* Allocate 1 more to allow appending '\0' to last filename. */ + zipf->central_directory = XNEWVEC (char, zipf->dir_size + 1); + if (lseek (zipf->fd, -(zipf->dir_size+ECREC_SIZE+4), SEEK_CUR) < 0) + return -2; + if (read (zipf->fd, zipf->central_directory, zipf->dir_size) < 0) + return -2; + +#ifdef TEST + printf ("number_this_disk = %d\n", makeword(&buffer[NUMBER_THIS_DISK])); + printf ("num_disk_with_start_central_dir = %d\n", makeword(&buffer[NUM_DISK_WITH_START_CENTRAL_DIR])); + + printf ("num_entries_centrl_dir_ths_disk = %d\n", + makeword(&buffer[NUM_ENTRIES_CENTRL_DIR_THS_DISK])); + printf ("total_entries_central_dir = %d\n", + makeword(&buffer[TOTAL_ENTRIES_CENTRAL_DIR])); + printf ("size_central_directory = %d\n", + makelong((const uch *) &buffer[SIZE_CENTRAL_DIRECTORY])); + printf ("offset_start_central_directory = %d\n", + makelong((const uch *) &buffer[OFFSET_START_CENTRAL_DIRECTORY])); + printf ("zipfile_comment_length = %d\n", + makeword(&buffer[ZIPFILE_COMMENT_LENGTH])); +#endif + + dir_last_pad = 0; + dir_ptr = zipf->central_directory; + for (i = 0; i < zipf->count; i++) + { + ZipDirectory *zipd = (ZipDirectory*)(dir_ptr + dir_last_pad); + int compression_method = (int) dir_ptr[4+C_COMPRESSION_METHOD]; + long size = makelong ((const uch *) &dir_ptr[4+C_COMPRESSED_SIZE]); + long uncompressed_size = makelong ((const uch *) &dir_ptr[4+C_UNCOMPRESSED_SIZE]); + long filename_length = makeword ((const uch *) &dir_ptr[4+C_FILENAME_LENGTH]); + long extra_field_length = makeword ((const uch *) &dir_ptr[4+C_EXTRA_FIELD_LENGTH]); + long file_offset = makelong ((const uch *) &dir_ptr[4+C_RELATIVE_OFFSET_LOCAL_HEADER]); + int unpadded_direntry_length; + if ((dir_ptr-zipf->central_directory)+filename_length+CREC_SIZE+4>zipf->dir_size) + return -1; + + zipd->filename_length = filename_length; + zipd->compression_method = compression_method; + zipd->size = size; + zipd->uncompressed_size = uncompressed_size; + zipd->zipf = zipf; +#ifdef __GNUC__ +#define DIR_ALIGN __alignof__(ZipDirectory) +#else +#define DIR_ALIGN sizeof(long) +#endif + zipd->filestart = find_zip_file_start (zipf->fd, file_offset); + zipd->filename_offset = CREC_SIZE+4 - dir_last_pad; + unpadded_direntry_length + = zipd->filename_offset + zipd->filename_length + extra_field_length; + zipd->direntry_size = + ((unpadded_direntry_length + DIR_ALIGN) / DIR_ALIGN) * DIR_ALIGN; + dir_last_pad = zipd->direntry_size - unpadded_direntry_length; + dir_ptr = (char*)zipd + unpadded_direntry_length; + *dir_ptr = '\0'; + } + return 0; +} + +#ifdef TEST +main (void) +{ + ZipFile zipf[1]; + ZipDirectory *zipd; + int i; + + zipf->fd = 0; + + i = read_zip_archive (zipf); + if (i) + { + fprintf (stderr, "Bad zip file.\n"); + exit (i); + } + + zipd = (ZipDirectory*) zipf->central_directory; + for (i = 0; i < zipf->count; i++, zipd = ZIPDIR_NEXT (zipd)) + { + printf ("%d: size:%d, name(#%d)%s, offset:%d\n", + i, zipd->size, zipd->filename_length, + ZIPDIR_FILENAME (zipd), + zipd->filestart); + } +} +#endif -- cgit v1.2.3