1/* Utility macros to read Java(TM) .class files and byte codes.
2   Copyright (C) 1996-2015 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3.  If not see
18<http://www.gnu.org/licenses/>.
19
20Java and all Java-based marks are trademarks or registered trademarks
21of Sun Microsystems, Inc. in the United States and other countries.
22The Free Software Foundation is independent of Sun Microsystems, Inc.  */
23
24/* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
25
26#ifndef GCC_JCF_H
27#define GCC_JCF_H
28#include "javaop.h"
29
30#ifndef JCF_u4
31#define JCF_u4 unsigned long
32#endif
33#ifndef JCF_u2
34#define JCF_u2 unsigned short
35#endif
36
37#define ALLOC xmalloc
38#define REALLOC xrealloc
39#ifndef FREE
40#define FREE(PTR) free(PTR)
41#endif
42
43#ifdef JCF_word
44#define JCF_word JCF_u4
45#endif
46
47/* On case-insensitive file systems, we need to ensure that a request
48   to open a .java or .class file is honored only if the file to be
49   opened is of the exact case we are asking for. In other words, we
50   want to override the inherent case insensitivity of the underlying
51   file system. On other platforms, this macro becomes the vanilla
52   open() call.
53
54   If you want to add another host, add your define to the list below
55   (i.e. defined(WIN32) || defined(YOUR_HOST)) and add a host-specific
56   .c file to Make-lang.in similar to win32-host.c.  */
57#if defined(WIN32)
58extern int
59jcf_open_exact_case (const char* filename, int oflag);
60#define JCF_OPEN_EXACT_CASE(X, Y) jcf_open_exact_case (X, Y)
61#else
62#define JCF_OPEN_EXACT_CASE open
63#endif /* WIN32 */
64
65struct JCF;
66typedef int (*jcf_filbuf_t) (struct JCF*, int needed);
67
68union GTY(()) cpool_entry {
69  jword GTY ((tag ("0"))) w;
70  tree GTY ((tag ("1"))) t;
71};
72
73#define cpool_entry_is_tree(tag) \
74  (tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8
75
76typedef struct GTY(()) CPool {
77  /* Available number of elements in the constants array, before it
78     must be re-allocated. */
79  int capacity;
80
81  /* The constant_pool_count. */
82  int		count;
83
84  uint8 * GTY((atomic)) tags;
85
86  union cpool_entry * GTY((length ("%h.count"),
87			   desc ("cpool_entry_is_tree (%1.tags%a)")))	data;
88} CPool;
89
90typedef struct GTY(()) bootstrap_method {
91  unsigned method_ref;
92  unsigned num_arguments;
93  unsigned * GTY((atomic)) bootstrap_arguments;
94} bootstrap_method;
95
96typedef struct GTY(()) BootstrapMethods {
97  unsigned count;
98  bootstrap_method* GTY((length ("%h.count"))) methods;
99} BootstrapMethods;
100
101struct ZipDirectory;
102
103/* JCF encapsulates the state of reading a Java Class File. */
104
105typedef struct GTY(()) JCF {
106  unsigned char * GTY ((skip)) buffer;
107  unsigned char * GTY ((skip)) buffer_end;
108  unsigned char * GTY ((skip)) read_ptr;
109  unsigned char * GTY ((skip)) read_end;
110  unsigned int right_zip : 1;
111  unsigned int finished : 1;
112  jcf_filbuf_t filbuf;
113  PTR GTY ((skip)) read_state;
114  const char *filename;
115  const char *classname;
116  /* Directory entry where it was found.  */
117  struct ZipDirectory * GTY ((skip)) zipd;
118  JCF_u2 access_flags;
119  JCF_u2 this_class;
120  JCF_u2 super_class;
121  CPool cpool;
122  BootstrapMethods bootstrap_methods;
123} JCF;
124/*typedef JCF*  JCF_FILE;*/
125
126#define JCF_SEEN_IN_ZIP(JCF) ((JCF)->zipd != NULL)
127
128/* The CPOOL macros take a (pointer to a) CPool.
129   The JPOOL macros take a (pointer to a) JCF.
130   Some of the latter should perhaps be deprecated or removed. */
131
132#define CPOOL_COUNT(CPOOL) ((CPOOL)->count)
133#define JPOOL_SIZE(JCF) CPOOL_COUNT(&(JCF)->cpool)
134#define JPOOL_TAG(JCF, INDEX) ((JCF)->cpool.tags[INDEX])
135/* The INDEX'th constant pool entry as a JCF_u4. */
136#define CPOOL_UINT(CPOOL, INDEX) ((CPOOL)->data[INDEX].w)
137#define JPOOL_UINT(JCF, INDEX) CPOOL_UINT(&(JCF)->cpool, INDEX) /*deprecated*/
138/* The first uint16 of the INDEX'th constant pool entry. */
139#define CPOOL_USHORT1(CPOOL, INDEX) ((CPOOL)->data[INDEX].w & 0xFFFF)
140#define JPOOL_USHORT1(JCF, INDEX) CPOOL_USHORT1(&(JCF)->cpool, INDEX)
141/* The second uint16 of the INDEX'th constant pool entry. */
142#define CPOOL_USHORT2(CPOOL, INDEX) ((CPOOL)->data[INDEX].w >> 16)
143#define JPOOL_USHORT2(JCF, INDEX) CPOOL_USHORT2(&(JCF)->cpool, INDEX)
144#define JPOOL_LONG(JCF, INDEX) \
145  WORDS_TO_LONG (JPOOL_UINT(JCF, INDEX), JPOOL_UINT(JCF, (INDEX)+1))
146#define JPOOL_DOUBLE(JCF, INDEX) \
147  WORDS_TO_DOUBLE  (JPOOL_UINT(JCF, INDEX), JPOOL_UINT(JCF, (INDEX)+1))
148#ifndef JPOOL_UTF_LENGTH
149#define JPOOL_UTF_LENGTH(JCF, INDEX) \
150  GET_u2 ((JCF)->buffer+JPOOL_UINT(JCF, INDEX))
151#endif
152#ifndef JPOOL_UTF_DATA
153#define JPOOL_UTF_DATA(JCF, INDEX) \
154  ((JCF)->buffer+JPOOL_UINT(JCF, INDEX)+2)
155#endif
156#define JPOOL_INT(JCF, INDEX) (WORD_TO_INT(JPOOL_UINT (JCF, INDEX)))
157#define JPOOL_FLOAT(JCF, INDEX) WORD_TO_FLOAT (JPOOL_UINT (JCF, INDEX))
158
159#define CPOOL_INDEX_IN_RANGE(CPOOL, INDEX) \
160 ((INDEX) > 0 && (INDEX) < CPOOL_COUNT(CPOOL))
161
162#define CPOOL_FINISH(CPOOL) {			\
163    (CPOOL)->tags = 0;				\
164    (CPOOL)->data = 0;				\
165  }
166
167#define JCF_FINISH(JCF) { \
168  CPOOL_FINISH(&(JCF)->cpool); \
169  if ((JCF)->buffer) free ((JCF)->buffer); \
170  if ((JCF)->filename) free (CONST_CAST (char *, (JCF)->filename)); \
171  if ((JCF)->classname) free (CONST_CAST (char *, (JCF)->classname)); \
172  (JCF)->finished = 1; }
173
174#define CPOOL_INIT(CPOOL) \
175  ((CPOOL)->capacity = 0, (CPOOL)->count = 0, (CPOOL)->tags = 0, (CPOOL)->data = 0)
176
177#define CPOOL_REINIT(CPOOL) ((CPOOL)->count = 0)
178
179#define JCF_ZERO(JCF)  \
180  ((JCF)->buffer = (JCF)->buffer_end = (JCF)->read_ptr = (JCF)->read_end = 0,\
181   (JCF)->read_state = 0, (JCF)->filename = (JCF)->classname = 0, \
182   CPOOL_INIT(&(JCF)->cpool), (JCF)->zipd = 0, \
183   (JCF)->finished = 0)
184
185/* Given that PTR points to a 2-byte unsigned integer in network
186   (big-endian) byte-order, return that integer. */
187#define GET_u2(PTR) (((PTR)[0] << 8) | ((PTR)[1]))
188/* Like GET_u2, but for little-endian format. */
189#define GET_u2_le(PTR) (((PTR)[1] << 8) | ((PTR)[0]))
190
191/* Given that PTR points to a 4-byte unsigned integer in network
192   (big-endian) byte-order, return that integer. */
193#define GET_u4(PTR) (((JCF_u4)(PTR)[0] << 24) | ((JCF_u4)(PTR)[1] << 16) \
194  | ((JCF_u4)(PTR)[2] << 8) | ((JCF_u4)(PTR)[3]))
195/* Like GET_u4, but for little-endian order. */
196#define GET_u4_le(PTR) (((JCF_u4)(PTR)[3] << 24) | ((JCF_u4)(PTR)[2] << 16) \
197  | ((JCF_u4)(PTR)[1] << 8) | ((JCF_u4)(PTR)[0]))
198
199/* Make sure there are COUNT bytes readable. */
200#define JCF_FILL(JCF, COUNT) \
201  ((JCF)->read_end-(JCF)->read_ptr >= (COUNT) ? 0 : (*(JCF)->filbuf)(JCF, COUNT))
202#define JCF_GETC(JCF) (JCF_FILL(JCF, 1) ? -1 : *(JCF)->read_ptr++)
203#define JCF_READ(JCF, BUFFER, N) \
204    (memcpy (BUFFER, (JCF)->read_ptr, N), (JCF)->read_ptr += (N))
205#define JCF_SKIP(JCF,N) ((JCF)->read_ptr += (N))
206#define JCF_readu(JCF) (*(JCF)->read_ptr++)
207
208/* Reads an unsigned 2-byte integer in network (big-endian) byte-order
209   from JCF.  Returns that integer.
210   Does not check for EOF (make sure to call JCF_FILL before-hand). */
211#define JCF_readu2(JCF) ((JCF)->read_ptr += 2, GET_u2 ((JCF)->read_ptr-2))
212#define JCF_readu2_le(JCF) ((JCF)->read_ptr += 2, GET_u2_le((JCF)->read_ptr-2))
213
214/* Like JCF_readu2, but read a 4-byte unsigned integer. */
215#define JCF_readu4(JCF) ((JCF)->read_ptr += 4, GET_u4 ((JCF)->read_ptr-4))
216#define JCF_readu4_le(JCF) ((JCF)->read_ptr += 4, GET_u4_le((JCF)->read_ptr-4))
217
218#define JCF_TELL(JCF) ((JCF)->read_ptr - (JCF)->buffer)
219#define JCF_SEEK(JCF, POS) ((JCF)->read_ptr = (JCF)->buffer + (POS))
220
221#define ACC_PUBLIC 0x0001
222#define ACC_PRIVATE 0x0002
223#define ACC_PROTECTED 0x0004
224#define ACC_STATIC 0x0008
225#define ACC_FINAL 0x0010
226#define ACC_SYNCHRONIZED 0x0020
227#define ACC_SUPER 0x0020
228#define ACC_BRIDGE 0x0040
229#define ACC_VOLATILE 0x0040
230#define ACC_TRANSIENT 0x0080
231#define ACC_VARARGS 0x0080
232#define ACC_NATIVE 0x0100
233#define ACC_INTERFACE 0x0200
234#define ACC_ABSTRACT 0x0400
235#define ACC_STRICT 0x0800
236#define ACC_SYNTHETIC 0x01000
237#define ACC_ANNOTATION 0x02000
238#define ACC_ENUM 0x04000
239/* "Invisible" refers to Miranda methods inserted into an abstract
240   class.  It is also used in the runtime.  */
241#define ACC_INVISIBLE 0x8000
242
243#define ACC_VISIBILITY (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED)
244
245enum cpool_tag
246{
247  CONSTANT_Class = 7,
248  CONSTANT_Fieldref = 9,
249  CONSTANT_Methodref = 10,
250  CONSTANT_InterfaceMethodref = 11,
251  CONSTANT_String = 8,
252  CONSTANT_Integer = 3,
253  CONSTANT_Float = 4,
254  CONSTANT_Long = 5,
255  CONSTANT_Double = 6,
256  CONSTANT_NameAndType = 12,
257  CONSTANT_Utf8 = 1,
258  CONSTANT_Unicode = 2,
259  CONSTANT_MethodHandle = 15,
260  CONSTANT_MethodType = 16,
261  CONSTANT_InvokeDynamic = 18,
262
263  CONSTANT_None = 0
264};
265
266#define DEFAULT_CLASS_PATH "."
267
268extern const char *find_class (const char *, int, JCF *);
269extern const char *find_classfile (char *, JCF*, const char *);
270extern int jcf_filbuf_from_stdio (JCF *jcf, int count);
271extern int jcf_unexpected_eof (JCF*, int) ATTRIBUTE_NORETURN;
272
273/* Extract a character from a Java-style Utf8 string.
274 * PTR points to the current character.
275 * LIMIT points to the end of the Utf8 string.
276 * PTR is incremented to point after the character that gets returned.
277 * On an error, -1 is returned. */
278#define UTF8_GET(PTR, LIMIT) \
279  ((PTR) >= (LIMIT) ? -1 \
280   : *(PTR) < 128 ? *(PTR)++ \
281   : (*(PTR)&0xE0) == 0xC0 && ((PTR)+=2)<=(LIMIT) && ((PTR)[-1]&0xC0) == 0x80 \
282   ? (((PTR)[-2] & 0x1F) << 6) + ((PTR)[-1] & 0x3F) \
283   : (*(PTR) & 0xF0) == 0xE0 && ((PTR) += 3) <= (LIMIT) \
284   && ((PTR)[-2] & 0xC0) == 0x80 && ((PTR)[-1] & 0xC0) == 0x80 \
285   ? (((PTR)[-3]&0x0F) << 12) + (((PTR)[-2]&0x3F) << 6) + ((PTR)[-1]&0x3F) \
286   : ((PTR)++, -1))
287
288extern const char *jcf_write_base_directory;
289
290/* Debug macros, for the front end */
291
292#ifdef VERBOSE_SKELETON
293#undef SOURCE_FRONTEND_DEBUG
294#define SOURCE_FRONTEND_DEBUG(X)				\
295  {if (!quiet_flag) {printf ("* "); printf X; putchar ('\n');} }
296#else
297#define SOURCE_FRONTEND_DEBUG(X)
298#endif
299
300/* Declarations for dependency code.  */
301extern void jcf_dependency_reset (void);
302extern void jcf_dependency_set_target (const char *);
303extern void jcf_dependency_add_target (const char *);
304extern void jcf_dependency_set_dep_file (const char *);
305extern void jcf_dependency_add_file (const char *, int);
306extern void jcf_dependency_write (void);
307extern void jcf_dependency_init (int);
308extern void jcf_dependency_print_dummies (void);
309
310/* Declarations for path handling code.  */
311extern void jcf_path_init (void);
312extern void jcf_path_classpath_arg (const char *);
313extern void jcf_path_bootclasspath_arg (const char *);
314extern void jcf_path_extdirs_arg (const char *);
315extern void jcf_path_include_arg (const char *);
316extern void jcf_path_seal (int);
317extern void *jcf_path_start (void);
318extern void *jcf_path_next (void *);
319extern char *jcf_path_name (void *);
320extern char *jcf_path_compute (const char *);
321extern int jcf_path_is_zipfile (void *);
322extern int jcf_path_is_system (void *);
323extern int jcf_path_max_len (void);
324
325#endif /* ! GCC_JCF_H */
326