1 /* ECOFF support on Alpha machines.
2    coff/ecoff.h must be included before this file.
3 
4    Copyright (C) 2001-2024 Free Software Foundation, Inc.
5 
6    This program 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 of the License, or
9    (at your option) any later version.
10 
11    This program 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.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20 
21 /********************** FILE HEADER **********************/
22 
23 struct external_filehdr
24 {
25   unsigned char f_magic[2];   /* magic number                         */
26   unsigned char f_nscns[2];   /* number of sections                   */
27   unsigned char f_timdat[4];  /* time & date stamp                    */
28   unsigned char f_symptr[8];  /* file pointer to symtab     */
29   unsigned char f_nsyms[4];   /* number of symtab entries   */
30   unsigned char f_opthdr[2];  /* sizeof(optional hdr)                 */
31   unsigned char f_flags[2];   /* flags                      */
32 };
33 
34 /* Magic numbers are defined in coff/ecoff.h.  */
35 #define ALPHA_ECOFF_BADMAG(x) \
36   ((x).f_magic != ALPHA_MAGIC && (x).f_magic != ALPHA_MAGIC_BSD)
37 
38 #define ALPHA_ECOFF_COMPRESSEDMAG(x) \
39   ((x).f_magic == ALPHA_MAGIC_COMPRESSED)
40 
41 /* The object type is encoded in the f_flags.  */
42 #define F_ALPHA_OBJECT_TYPE_MASK        0x3000
43 #define F_ALPHA_NO_SHARED               0x1000
44 #define F_ALPHA_SHARABLE                0x2000
45 #define F_ALPHA_CALL_SHARED             0x3000
46 
47 #define   FILHDR    struct external_filehdr
48 #define   FILHSZ    24
49 
50 /********************** AOUT "OPTIONAL HEADER" **********************/
51 
52 typedef struct external_aouthdr
53 {
54   unsigned char magic[2];     /* type of file                                   */
55   unsigned char     vstamp[2];          /* version stamp                        */
56   unsigned char bldrev[2];    /* ?? */
57   unsigned char padding[2];   /* pad to quadword boundary             */
58   unsigned char     tsize[8]; /* text size in bytes                             */
59   unsigned char     dsize[8]; /* initialized data "  "                */
60   unsigned char     bsize[8]; /* uninitialized data "   "             */
61   unsigned char     entry[8]; /* entry pt.                                      */
62   unsigned char text_start[8];          /* base of text used for this file */
63   unsigned char data_start[8];          /* base of data used for this file */
64   unsigned char bss_start[8]; /* base of bss used for this file */
65   unsigned char gprmask[4];   /* bitmask of general registers used */
66   unsigned char fprmask[4];   /* bitmask of floating point registers used */
67   unsigned char gp_value[8];  /* value for gp register */
68 } AOUTHDR;
69 
70 /* compute size of a header */
71 
72 #define AOUTSZ 80
73 #define AOUTHDRSZ 80
74 
75 /********************** SECTION HEADER **********************/
76 
77 struct external_scnhdr
78 {
79   unsigned char     s_name[8];          /* section name                         */
80   unsigned char     s_paddr[8];         /* physical address, aliased s_nlib */
81   unsigned char     s_vaddr[8];         /* virtual address            */
82   unsigned char     s_size[8];          /* section size                         */
83   unsigned char     s_scnptr[8];        /* file ptr to raw data for section */
84   unsigned char     s_relptr[8];        /* file ptr to relocation     */
85   unsigned char     s_lnnoptr[8];       /* file ptr to line numbers   */
86   unsigned char     s_nreloc[2];        /* number of relocation entries         */
87   unsigned char     s_nlnno[2];         /* number of line number entries*/
88   unsigned char     s_flags[4];         /* flags                      */
89 };
90 
91 #define   SCNHDR    struct external_scnhdr
92 #define   SCNHSZ    64
93 
94 /********************** RELOCATION DIRECTIVES **********************/
95 
96 struct external_reloc
97 {
98   unsigned char r_vaddr[8];
99   unsigned char r_symndx[4];
100   unsigned char r_bits[4];
101 };
102 
103 #define RELOC struct external_reloc
104 #define RELSZ 16
105 
106 /* Constants to unpack the r_bits field.  The Alpha seems to always be
107    little endian, so I haven't bothered to define big endian variants
108    of these.  */
109 
110 #define RELOC_BITS0_TYPE_LITTLE                             0xff
111 #define RELOC_BITS0_TYPE_SH_LITTLE                0
112 
113 #define RELOC_BITS1_EXTERN_LITTLE                 0x01
114 
115 #define RELOC_BITS1_OFFSET_LITTLE                 0x7e
116 #define RELOC_BITS1_OFFSET_SH_LITTLE              1
117 
118 #define RELOC_BITS1_RESERVED_LITTLE               0x80
119 #define RELOC_BITS1_RESERVED_SH_LITTLE            7
120 #define RELOC_BITS2_RESERVED_LITTLE               0xff
121 #define RELOC_BITS2_RESERVED_SH_LEFT_LITTLE       1
122 #define RELOC_BITS3_RESERVED_LITTLE               0x03
123 #define RELOC_BITS3_RESERVED_SH_LEFT_LITTLE       9
124 
125 #define RELOC_BITS3_SIZE_LITTLE                             0xfc
126 #define RELOC_BITS3_SIZE_SH_LITTLE                2
127 
128 /* The r_type field in a reloc is one of the following values.  */
129 #define ALPHA_R_IGNORE                  0
130 #define ALPHA_R_REFLONG                 1
131 #define ALPHA_R_REFQUAD                 2
132 #define ALPHA_R_GPREL32                 3
133 #define ALPHA_R_LITERAL                 4
134 #define ALPHA_R_LITUSE                  5
135 #define ALPHA_R_GPDISP                  6
136 #define ALPHA_R_BRADDR                  7
137 #define ALPHA_R_HINT                    8
138 #define ALPHA_R_SREL16                  9
139 #define ALPHA_R_SREL32               10
140 #define ALPHA_R_SREL64               11
141 #define ALPHA_R_OP_PUSH              12
142 #define ALPHA_R_OP_STORE       13
143 #define ALPHA_R_OP_PSUB              14
144 #define ALPHA_R_OP_PRSHIFT     15
145 #define ALPHA_R_GPVALUE              16
146 #define ALPHA_R_GPRELHIGH      17
147 #define ALPHA_R_GPRELLOW       18
148 #define ALPHA_R_IMMED          19
149 
150 /* Overloaded reloc value used by Net- and OpenBSD.  */
151 #define ALPHA_R_LITERALSLEAZY  17
152 
153 /* With ALPHA_R_LITUSE, the r_size field is one of the following values.  */
154 #define ALPHA_R_LU_BASE         1
155 #define ALPHA_R_LU_BYTOFF       2
156 #define ALPHA_R_LU_JSR          3
157 
158 /* With ALPHA_R_IMMED, the r_size field is one of the following values.  */
159 #define ALPHA_R_IMMED_GP_16     1
160 #define ALPHA_R_IMMED_GP_HI32   2
161 #define ALPHA_R_IMMED_SCN_HI32  3
162 #define ALPHA_R_IMMED_BR_HI32   4
163 #define ALPHA_R_IMMED_LO32      5
164 
165 /********************** SYMBOLIC INFORMATION **********************/
166 
167 /* Written by John Gilmore.  */
168 
169 /* ECOFF uses COFF-like section structures, but its own symbol format.
170    This file defines the symbol format in fields whose size and alignment
171    will not vary on different host systems.  */
172 
173 /* File header as a set of bytes */
174 
175 struct hdr_ext
176 {
177           unsigned char       h_magic[2];
178           unsigned char       h_vstamp[2];
179           unsigned char       h_ilineMax[4];
180           unsigned char       h_idnMax[4];
181           unsigned char       h_ipdMax[4];
182           unsigned char       h_isymMax[4];
183           unsigned char       h_ioptMax[4];
184           unsigned char       h_iauxMax[4];
185           unsigned char       h_issMax[4];
186           unsigned char       h_issExtMax[4];
187           unsigned char       h_ifdMax[4];
188           unsigned char       h_crfd[4];
189           unsigned char       h_iextMax[4];
190           unsigned char       h_cbLine[8];
191           unsigned char       h_cbLineOffset[8];
192           unsigned char       h_cbDnOffset[8];
193           unsigned char       h_cbPdOffset[8];
194           unsigned char       h_cbSymOffset[8];
195           unsigned char       h_cbOptOffset[8];
196           unsigned char       h_cbAuxOffset[8];
197           unsigned char       h_cbSsOffset[8];
198           unsigned char       h_cbSsExtOffset[8];
199           unsigned char       h_cbFdOffset[8];
200           unsigned char       h_cbRfdOffset[8];
201           unsigned char       h_cbExtOffset[8];
202 };
203 
204 /* File descriptor external record */
205 
206 struct fdr_ext
207 {
208           unsigned char       f_adr[8];
209           unsigned char       f_cbLineOffset[8];
210           unsigned char       f_cbLine[8];
211           unsigned char       f_cbSs[8];
212           unsigned char       f_rss[4];
213           unsigned char       f_issBase[4];
214           unsigned char       f_isymBase[4];
215           unsigned char       f_csym[4];
216           unsigned char       f_ilineBase[4];
217           unsigned char       f_cline[4];
218           unsigned char       f_ioptBase[4];
219           unsigned char       f_copt[4];
220           unsigned char       f_ipdFirst[4];
221           unsigned char       f_cpd[4];
222           unsigned char       f_iauxBase[4];
223           unsigned char       f_caux[4];
224           unsigned char       f_rfdBase[4];
225           unsigned char       f_crfd[4];
226           unsigned char       f_bits1[1];
227           unsigned char       f_bits2[3];
228           unsigned char       f_padding[4];
229 };
230 
231 #define   FDR_BITS1_LANG_BIG            0xF8
232 #define   FDR_BITS1_LANG_SH_BIG                   3
233 #define   FDR_BITS1_LANG_LITTLE                   0x1F
234 #define   FDR_BITS1_LANG_SH_LITTLE      0
235 
236 #define   FDR_BITS1_FMERGE_BIG                    0x04
237 #define   FDR_BITS1_FMERGE_LITTLE                 0x20
238 
239 #define   FDR_BITS1_FREADIN_BIG                   0x02
240 #define   FDR_BITS1_FREADIN_LITTLE      0x40
241 
242 #define   FDR_BITS1_FBIGENDIAN_BIG      0x01
243 #define   FDR_BITS1_FBIGENDIAN_LITTLE   0x80
244 
245 #define   FDR_BITS2_GLEVEL_BIG                    0xC0
246 #define   FDR_BITS2_GLEVEL_SH_BIG                 6
247 #define   FDR_BITS2_GLEVEL_LITTLE                 0x03
248 #define   FDR_BITS2_GLEVEL_SH_LITTLE    0
249 
250 /* We ignore the `reserved' field in bits2. */
251 
252 /* Procedure descriptor external record */
253 
254 struct pdr_ext {
255           unsigned char       p_adr[8];
256           unsigned char       p_cbLineOffset[8];
257           unsigned char       p_isym[4];
258           unsigned char       p_iline[4];
259           unsigned char       p_regmask[4];
260           unsigned char       p_regoffset[4];
261           unsigned char       p_iopt[4];
262           unsigned char       p_fregmask[4];
263           unsigned char       p_fregoffset[4];
264           unsigned char       p_frameoffset[4];
265           unsigned char       p_lnLow[4];
266           unsigned char       p_lnHigh[4];
267           unsigned char       p_gp_prologue[1];
268           unsigned char       p_bits1[1];
269           unsigned char       p_bits2[1];
270           unsigned char       p_localoff[1];
271           unsigned char       p_framereg[2];
272           unsigned char       p_pcreg[2];
273 };
274 
275 #define PDR_BITS1_GP_USED_BIG           0x80
276 #define PDR_BITS1_REG_FRAME_BIG                   0x40
277 #define PDR_BITS1_PROF_BIG              0x20
278 #define PDR_BITS1_RESERVED_BIG                    0x1f
279 #define PDR_BITS1_RESERVED_SH_LEFT_BIG  8
280 #define PDR_BITS2_RESERVED_BIG                    0xff
281 #define PDR_BITS2_RESERVED_SH_BIG       0
282 
283 #define PDR_BITS1_GP_USED_LITTLE        0x01
284 #define PDR_BITS1_REG_FRAME_LITTLE      0x02
285 #define PDR_BITS1_PROF_LITTLE           0x04
286 #define PDR_BITS1_RESERVED_LITTLE       0xf8
287 #define PDR_BITS1_RESERVED_SH_LITTLE    3
288 #define PDR_BITS2_RESERVED_LITTLE       0xff
289 #define PDR_BITS2_RESERVED_SH_LEFT_LITTLE 5
290 
291 /* Line numbers */
292 
293 struct line_ext {
294           unsigned char       l_line[4];
295 };
296 
297 /* Symbol external record */
298 
299 struct sym_ext {
300           unsigned char       s_value[8];
301           unsigned char       s_iss[4];
302           unsigned char       s_bits1[1];
303           unsigned char       s_bits2[1];
304           unsigned char       s_bits3[1];
305           unsigned char       s_bits4[1];
306 };
307 
308 #define   SYM_BITS1_ST_BIG              0xFC
309 #define   SYM_BITS1_ST_SH_BIG           2
310 #define   SYM_BITS1_ST_LITTLE           0x3F
311 #define   SYM_BITS1_ST_SH_LITTLE                  0
312 
313 #define   SYM_BITS1_SC_BIG              0x03
314 #define   SYM_BITS1_SC_SH_LEFT_BIG      3
315 #define   SYM_BITS1_SC_LITTLE           0xC0
316 #define   SYM_BITS1_SC_SH_LITTLE                  6
317 
318 #define   SYM_BITS2_SC_BIG              0xE0
319 #define   SYM_BITS2_SC_SH_BIG           5
320 #define   SYM_BITS2_SC_LITTLE           0x07
321 #define   SYM_BITS2_SC_SH_LEFT_LITTLE   2
322 
323 #define   SYM_BITS2_RESERVED_BIG                  0x10
324 #define   SYM_BITS2_RESERVED_LITTLE     0x08
325 
326 #define   SYM_BITS2_INDEX_BIG           0x0F
327 #define   SYM_BITS2_INDEX_SH_LEFT_BIG   16
328 #define   SYM_BITS2_INDEX_LITTLE                  0xF0
329 #define   SYM_BITS2_INDEX_SH_LITTLE     4
330 
331 #define   SYM_BITS3_INDEX_SH_LEFT_BIG   8
332 #define   SYM_BITS3_INDEX_SH_LEFT_LITTLE          4
333 
334 #define   SYM_BITS4_INDEX_SH_LEFT_BIG   0
335 #define   SYM_BITS4_INDEX_SH_LEFT_LITTLE          12
336 
337 /* External symbol external record */
338 
339 struct ext_ext {
340           struct    sym_ext es_asym;
341           unsigned char       es_bits1[1];
342           unsigned char       es_bits2[3];
343           unsigned char       es_ifd[4];
344 };
345 
346 #define   EXT_BITS1_JMPTBL_BIG                    0x80
347 #define   EXT_BITS1_JMPTBL_LITTLE                 0x01
348 
349 #define   EXT_BITS1_COBOL_MAIN_BIG      0x40
350 #define   EXT_BITS1_COBOL_MAIN_LITTLE   0x02
351 
352 #define   EXT_BITS1_WEAKEXT_BIG                   0x20
353 #define   EXT_BITS1_WEAKEXT_LITTLE      0x04
354 
355 /* Dense numbers external record */
356 
357 struct dnr_ext {
358           unsigned char       d_rfd[4];
359           unsigned char       d_index[4];
360 };
361 
362 /* Relative file descriptor */
363 
364 struct rfd_ext {
365   unsigned char     rfd[4];
366 };
367 
368 /* Optimizer symbol external record */
369 
370 struct opt_ext {
371   unsigned char o_bits1[1];
372   unsigned char o_bits2[1];
373   unsigned char o_bits3[1];
374   unsigned char o_bits4[1];
375   struct rndx_ext o_rndx;
376   unsigned char o_offset[4];
377 };
378 
379 #define OPT_BITS2_VALUE_SH_LEFT_BIG     16
380 #define OPT_BITS2_VALUE_SH_LEFT_LITTLE  0
381 
382 #define OPT_BITS3_VALUE_SH_LEFT_BIG     8
383 #define OPT_BITS3_VALUE_SH_LEFT_LITTLE  8
384 
385 #define OPT_BITS4_VALUE_SH_LEFT_BIG     0
386 #define OPT_BITS4_VALUE_SH_LEFT_LITTLE  16
387