source: branches/libc-0.6/src/binutils/include/coff/ti.h

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 16.2 KB
Line 
1/* COFF information for TI COFF support. Definitions in this file should be
2 customized in a target-specific file, and then this file included (see
3 tic54x.h for an example).
4
5 Copyright 2001 Free Software Foundation, Inc.
6
7 This program 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 2 of the License, or
10 (at your option) any later version.
11
12 This program 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.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20#ifndef COFF_TI_H
21#define COFF_TI_H
22
23/* Note "coff/external.h is not used because TI adds extra fields to the structures. */
24
25/********************** FILE HEADER **********************/
26
27struct external_filehdr
28 {
29 char f_magic[2]; /* magic number */
30 char f_nscns[2]; /* number of sections */
31 char f_timdat[4]; /* time & date stamp */
32 char f_symptr[4]; /* file pointer to symtab */
33 char f_nsyms[4]; /* number of symtab entries */
34 char f_opthdr[2]; /* sizeof(optional hdr) */
35 char f_flags[2]; /* flags */
36 char f_target_id[2]; /* magic no. (TI COFF-specific) */
37 };
38
39/* COFF0 has magic number in f_magic, and omits f_target_id from the file
40 header; for later versions, f_magic is 0xC1 for COFF1 and 0xC2 for COFF2
41 and the target-specific magic number is found in f_target_id */
42
43#define TICOFF0MAGIC TI_TARGET_ID
44#define TICOFF1MAGIC 0x00C1
45#define TICOFF2MAGIC 0x00C2
46#define TICOFF_AOUT_MAGIC 0x0108 /* magic number in optional header */
47#define TICOFF 1 /* customize coffcode.h */
48
49/* The target_id field changes depending on the particular CPU target */
50/* for COFF0, the target id appeared in f_magic, where COFFX magic is now */
51#ifndef TI_TARGET_ID
52#error "TI_TARGET_ID needs to be defined for your CPU"
53#endif
54
55/* Which bfd_arch to use... */
56#ifndef TICOFF_TARGET_ARCH
57#error "TICOFF_TARGET_ARCH needs to be defined for your CPU"
58#endif
59
60#ifndef TICOFF_TARGET_MACHINE_GET
61#define TICOFF_TARGET_MACHINE_GET(FLAGS) 0
62#endif
63
64#ifndef TICOFF_TARGET_MACHINE_SET
65#define TICOFF_TARGET_MACHINE_SET(FLAGSP, MACHINE)
66#endif
67
68/* Default to COFF2 for file output */
69#ifndef TICOFF_DEFAULT_MAGIC
70#define TICOFF_DEFAULT_MAGIC TICOFF2MAGIC
71#endif
72
73/* This value is made available in the rare case where a bfd is unavailable */
74#ifndef OCTETS_PER_BYTE_POWER
75#error "OCTETS_PER_BYTE_POWER not defined for this CPU"
76#else
77#define OCTETS_PER_BYTE (1<<OCTETS_PER_BYTE_POWER)
78#endif
79
80/* default alignment is on a byte (not octet!) boundary */
81#ifndef COFF_DEFAULT_SECTION_ALIGNMENT_POWER
82#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0
83#endif
84
85/* TI COFF encodes the section alignment in the section header flags */
86#define COFF_ALIGN_IN_SECTION_HEADER 1
87#define COFF_ALIGN_IN_S_FLAGS 1
88/* requires a power-of-two argument */
89#define COFF_ENCODE_ALIGNMENT(S,X) ((S).s_flags |= (((unsigned)(X)&0xF)<<8))
90/* result is a power of two */
91#define COFF_DECODE_ALIGNMENT(X) (((X)>>8)&0xF)
92
93#define COFF0_P(ABFD) (bfd_coff_filhsz(ABFD) == FILHSZ_V0)
94#define COFF2_P(ABFD) (bfd_coff_scnhsz(ABFD) != SCNHSZ_V01)
95
96#define COFF0_BADMAG(x) ((x).f_magic != TICOFF0MAGIC)
97#define COFF1_BADMAG(x) ((x).f_magic != TICOFF1MAGIC || (x).f_target_id != TI_TARGET_ID)
98#define COFF2_BADMAG(x) ((x).f_magic != TICOFF2MAGIC || (x).f_target_id != TI_TARGET_ID)
99
100/* we need to read/write an extra field in the coff file header */
101#ifndef COFF_ADJUST_FILEHDR_IN_POST
102#define COFF_ADJUST_FILEHDR_IN_POST(abfd, src, dst) \
103 do \
104 { \
105 ((struct internal_filehdr *)(dst))->f_target_id = \
106 H_GET_16 (abfd, ((FILHDR *)(src))->f_target_id); \
107 } \
108 while (0)
109#endif
110
111#ifndef COFF_ADJUST_FILEHDR_OUT_POST
112#define COFF_ADJUST_FILEHDR_OUT_POST(abfd, src, dst) \
113 do \
114 { \
115 H_PUT_16 (abfd, ((struct internal_filehdr *)(src))->f_target_id, \
116 ((FILHDR *)(dst))->f_target_id); \
117 } \
118 while (0)
119#endif
120
121#define FILHDR struct external_filehdr
122#define FILHSZ 22
123#define FILHSZ_V0 20 /* COFF0 omits target_id field */
124
125/* File header flags */
126#define F_RELFLG (0x0001)
127#define F_EXEC (0x0002)
128#define F_LNNO (0x0004)
129#define F_VERS (0x0010) /* TMS320C4x code */
130/* F_LSYMS needs to be redefined in your source file */
131#define F_LSYMS_TICOFF (0x0010) /* normal COFF is 0x8 */
132
133#define F_10 0x00 /* file built for TMS320C1x devices */
134#define F_20 0x10 /* file built for TMS320C2x devices */
135#define F_25 0x20 /* file built for TMS320C2x/C5x devices */
136#define F_LENDIAN 0x0100 /* 16 bits/word, LSB first */
137#define F_SYMMERGE 0x1000 /* duplicate symbols were removed */
138
139/********************** OPTIONAL HEADER **********************/
140
141
142typedef struct
143{
144 char magic[2]; /* type of file (0x108) */
145 char vstamp[2]; /* version stamp */
146 char tsize[4]; /* text size in bytes, padded to FW bdry*/
147 char dsize[4]; /* initialized data " " */
148 char bsize[4]; /* uninitialized data " " */
149 char entry[4]; /* entry pt. */
150 char text_start[4]; /* base of text used for this file */
151 char data_start[4]; /* base of data used for this file */
152}
153AOUTHDR;
154
155
156#define AOUTHDRSZ 28
157#define AOUTSZ 28
158
159
160/********************** SECTION HEADER **********************/
161/* COFF0, COFF1 */
162struct external_scnhdr_v01 {
163 char s_name[8]; /* section name */
164 char s_paddr[4]; /* physical address, aliased s_nlib */
165 char s_vaddr[4]; /* virtual address */
166 char s_size[4]; /* section size (in WORDS) */
167 char s_scnptr[4]; /* file ptr to raw data for section */
168 char s_relptr[4]; /* file ptr to relocation */
169 char s_lnnoptr[4]; /* file ptr to line numbers */
170 char s_nreloc[2]; /* number of relocation entries */
171 char s_nlnno[2]; /* number of line number entries*/
172 char s_flags[2]; /* flags */
173 char s_reserved[1]; /* reserved */
174 char s_page[1]; /* section page number (LOAD) */
175};
176
177/* COFF2 */
178struct external_scnhdr {
179 char s_name[8]; /* section name */
180 char s_paddr[4]; /* physical address, aliased s_nlib */
181 char s_vaddr[4]; /* virtual address */
182 char s_size[4]; /* section size (in WORDS) */
183 char s_scnptr[4]; /* file ptr to raw data for section */
184 char s_relptr[4]; /* file ptr to relocation */
185 char s_lnnoptr[4]; /* file ptr to line numbers */
186 char s_nreloc[4]; /* number of relocation entries */
187 char s_nlnno[4]; /* number of line number entries*/
188 char s_flags[4]; /* flags */
189 char s_reserved[2]; /* reserved */
190 char s_page[2]; /* section page number (LOAD) */
191};
192
193/*
194 * Special section flags
195 */
196
197/* TI COFF defines these flags;
198 STYP_CLINK: the section should be excluded from the final
199 linker output if there are no references found to any symbol in the section
200 STYP_BLOCK: the section should be blocked, i.e. if the section would cross
201 a page boundary, it is started at a page boundary instead.
202 TI COFF puts the section alignment power of two in the section flags
203 e.g. 2**N is alignment, flags |= (N & 0xF) << 8
204*/
205#define STYP_CLINK (0x4000)
206#define STYP_BLOCK (0x1000)
207#define STYP_ALIGN (0x0F00) /* TI COFF stores section alignment here */
208
209#define SCNHDR_V01 struct external_scnhdr_v01
210#define SCNHDR struct external_scnhdr
211#define SCNHSZ_V01 40 /* for v0 and v1 */
212#define SCNHSZ 48
213
214/* COFF2 changes the offsets and sizes of these fields
215 Assume we're dealing with the COFF2 scnhdr structure, and adjust
216 accordingly
217 */
218#define GET_SCNHDR_NRELOC(ABFD, PTR) \
219 (COFF2_P (ABFD) ? H_GET_32 (ABFD, PTR) : H_GET_16 (ABFD, PTR))
220#define PUT_SCNHDR_NRELOC(ABFD, VAL, PTR) \
221 (COFF2_P (ABFD) ? H_PUT_32 (ABFD, VAL, PTR) : H_PUT_16 (ABFD, VAL, PTR))
222#define GET_SCNHDR_NLNNO(ABFD, PTR) \
223 (COFF2_P (ABFD) ? H_GET_32 (ABFD, PTR) : H_GET_16 (ABFD, (PTR) -2))
224#define PUT_SCNHDR_NLNNO(ABFD, VAL, PTR) \
225 (COFF2_P (ABFD) ? H_PUT_32 (ABFD, VAL, PTR) : H_PUT_16 (ABFD, VAL, (PTR) -2))
226#define GET_SCNHDR_FLAGS(ABFD, PTR) \
227 (COFF2_P (ABFD) ? H_GET_32 (ABFD, PTR) : H_GET_16 (ABFD, (PTR) -4))
228#define PUT_SCNHDR_FLAGS(ABFD, VAL, PTR) \
229 (COFF2_P (ABFD) ? H_PUT_32 (ABFD, VAL, PTR) : H_PUT_16 (ABFD, VAL, (PTR) -4))
230#define GET_SCNHDR_PAGE(ABFD, PTR) \
231 (COFF2_P (ABFD) ? H_GET_16 (ABFD, PTR) : (unsigned) H_GET_8 (ABFD, (PTR) -7))
232/* on output, make sure that the "reserved" field is zero */
233#define PUT_SCNHDR_PAGE(ABFD, VAL, PTR) \
234 (COFF2_P (ABFD) \
235 ? H_PUT_16 (ABFD, VAL, PTR) \
236 : H_PUT_8 (ABFD, VAL, (PTR) -7), H_PUT_8 (ABFD, 0, (PTR) -8))
237
238/* TI COFF stores section size as number of bytes (address units, not octets),
239 so adjust to be number of octets, which is what BFD expects */
240#define GET_SCNHDR_SIZE(ABFD, SZP) \
241 (H_GET_32 (ABFD, SZP) * bfd_octets_per_byte (ABFD))
242#define PUT_SCNHDR_SIZE(ABFD, SZ, SZP) \
243 H_PUT_32 (ABFD, (SZ) / bfd_octets_per_byte (ABFD), SZP)
244
245#define COFF_ADJUST_SCNHDR_IN_POST(ABFD, EXT, INT) \
246 do \
247 { \
248 ((struct internal_scnhdr *)(INT))->s_page = \
249 GET_SCNHDR_PAGE (ABFD, ((SCNHDR *)(EXT))->s_page); \
250 } \
251 while (0)
252
253/* The line number and reloc overflow checking in coff_swap_scnhdr_out in
254 coffswap.h doesn't use PUT_X for s_nlnno and s_nreloc.
255 Due to different sized v0/v1/v2 section headers, we have to re-write these
256 fields.
257 */
258#define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \
259 do \
260 { \
261 PUT_SCNHDR_NLNNO (ABFD, ((struct internal_scnhdr *)(INT))->s_nlnno, \
262 ((SCNHDR *)(EXT))->s_nlnno); \
263 PUT_SCNHDR_NRELOC (ABFD, ((struct internal_scnhdr *)(INT))->s_nreloc,\
264 ((SCNHDR *)(EXT))->s_nreloc); \
265 PUT_SCNHDR_FLAGS (ABFD, ((struct internal_scnhdr *)(INT))->s_flags, \
266 ((SCNHDR *)(EXT))->s_flags); \
267 PUT_SCNHDR_PAGE (ABFD, ((struct internal_scnhdr *)(INT))->s_page, \
268 ((SCNHDR *)(EXT))->s_page); \
269 } \
270 while (0)
271
272/*
273 * names of "special" sections
274 */
275#define _TEXT ".text"
276#define _DATA ".data"
277#define _BSS ".bss"
278#define _CINIT ".cinit" /* initialized C data */
279#define _SCONST ".const" /* constants */
280#define _SWITCH ".switch" /* switch tables */
281#define _STACK ".stack" /* C stack */
282#define _SYSMEM ".sysmem" /* used for malloc et al. syscalls */
283
284/********************** LINE NUMBERS **********************/
285
286/* 1 line number entry for every "breakpointable" source line in a section.
287 * Line numbers are grouped on a per function basis; first entry in a function
288 * grouping will have l_lnno = 0 and in place of physical address will be the
289 * symbol table index of the function name.
290 */
291struct external_lineno {
292 union {
293 char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
294 char l_paddr[4]; /* (physical) address of line number */
295 } l_addr;
296 char l_lnno[2]; /* line number */
297};
298
299#define LINENO struct external_lineno
300#define LINESZ 6
301
302
303/********************** SYMBOLS **********************/
304
305/* NOTE: this is what a local label looks like in assembly source; what it
306 looks like in COFF output is undefined */
307#define TICOFF_LOCAL_LABEL_P(NAME) \
308((NAME[0] == '$' && NAME[1] >= '0' && NAME[1] <= '9' && NAME[2] == '\0') \
309 || NAME[strlen(NAME)-1] == '?')
310
311#define E_SYMNMLEN 8 /* # characters in a symbol name */
312#define E_FILNMLEN 14 /* # characters in a file name */
313#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
314
315struct external_syment
316{
317 union {
318 char e_name[E_SYMNMLEN];
319 struct {
320 char e_zeroes[4];
321 char e_offset[4];
322 } e;
323 } e;
324 char e_value[4];
325 char e_scnum[2];
326 char e_type[2];
327 char e_sclass[1];
328 char e_numaux[1];
329};
330
331
332#define N_BTMASK (017)
333#define N_TMASK (060)
334#define N_BTSHFT (4)
335#define N_TSHIFT (2)
336
337
338union external_auxent {
339 struct {
340 char x_tagndx[4]; /* str, un, or enum tag indx */
341 union {
342 struct {
343 char x_lnno[2]; /* declaration line number */
344 char x_size[2]; /* str/union/array size */
345 } x_lnsz;
346 char x_fsize[4]; /* size of function */
347 } x_misc;
348 union {
349 struct { /* if ISFCN, tag, or .bb */
350 char x_lnnoptr[4]; /* ptr to fcn line # */
351 char x_endndx[4]; /* entry ndx past block end */
352 } x_fcn;
353 struct { /* if ISARY, up to 4 dimen. */
354 char x_dimen[E_DIMNUM][2];
355 } x_ary;
356 } x_fcnary;
357 char x_tvndx[2]; /* tv index */
358 } x_sym;
359
360 union {
361 char x_fname[E_FILNMLEN];
362 struct {
363 char x_zeroes[4];
364 char x_offset[4];
365 } x_n;
366 } x_file;
367
368 struct {
369 char x_scnlen[4]; /* section length */
370 char x_nreloc[2]; /* # relocation entries */
371 char x_nlinno[2]; /* # line numbers */
372 } x_scn;
373
374 struct {
375 char x_tvfill[4]; /* tv fill value */
376 char x_tvlen[2]; /* length of .tv */
377 char x_tvran[2][2]; /* tv range */
378 } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
379
380
381};
382
383#define SYMENT struct external_syment
384#define SYMESZ 18
385#define AUXENT union external_auxent
386#define AUXESZ 18
387
388/* section lengths are in target bytes (not host bytes) */
389#define GET_SCN_SCNLEN(ABFD, EXT) \
390 (H_GET_32 (ABFD, (EXT)->x_scn.x_scnlen) * bfd_octets_per_byte (ABFD))
391#define PUT_SCN_SCNLEN(ABFD, INT, EXT) \
392 H_PUT_32 (ABFD, (INT) / bfd_octets_per_byte (ABFD), (EXT)->x_scn.x_scnlen)
393
394/* lnsz size is in bits in COFF file, in bytes in BFD */
395#define GET_LNSZ_SIZE(abfd, ext) \
396 (H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size) / (class != C_FIELD ? 8 : 1))
397
398#define PUT_LNSZ_SIZE(abfd, in, ext) \
399 H_PUT_16 (abfd, ((class != C_FIELD) ? (in) * 8 : (in)), \
400 ext->x_sym.x_misc.x_lnsz.x_size)
401
402/* TI COFF stores offsets for MOS and MOU in bits; BFD expects bytes
403 Also put the load page flag of the section into the symbol value if it's an
404 address. */
405#ifndef NEEDS_PAGE
406#define NEEDS_PAGE(X) 0
407#define PAGE_MASK 0
408#endif
409#define COFF_ADJUST_SYM_IN_POST(ABFD, EXT, INT) \
410 do \
411 { \
412 struct internal_syment *dst = (struct internal_syment *)(INT); \
413 if (dst->n_sclass == C_MOS || dst->n_sclass == C_MOU) \
414 dst->n_value /= 8; \
415 else if (NEEDS_PAGE (dst->n_sclass)) { \
416 asection *scn = coff_section_from_bfd_index (abfd, dst->n_scnum); \
417 dst->n_value |= (scn->lma & PAGE_MASK); \
418 } \
419 } \
420 while (0)
421
422#define COFF_ADJUST_SYM_OUT_POST(ABFD, INT, EXT) \
423 do \
424 { \
425 struct internal_syment *src = (struct internal_syment *)(INT); \
426 SYMENT *dst = (SYMENT *)(EXT); \
427 if (src->n_sclass == C_MOU || src->n_sclass == C_MOS) \
428 H_PUT_32 (abfd, src->n_value * 8, dst->e_value); \
429 else if (NEEDS_PAGE (src->n_sclass)) { \
430 H_PUT_32 (abfd, src->n_value &= ~PAGE_MASK, dst->e_value); \
431 } \
432 } \
433 while (0)
434
435/* Detect section-relative absolute symbols so they get flagged with a sym
436 index of -1.
437*/
438#define SECTION_RELATIVE_ABSOLUTE_SYMBOL_P(RELOC, SECT) \
439 ((*(RELOC)->sym_ptr_ptr)->section->output_section == (SECT) \
440 && (RELOC)->howto->name[0] == 'A')
441
442/********************** RELOCATION DIRECTIVES **********************/
443
444struct external_reloc_v0
445{
446 char r_vaddr[4];
447 char r_symndx[2];
448 char r_reserved[2];
449 char r_type[2];
450};
451
452struct external_reloc
453{
454 char r_vaddr[4];
455 char r_symndx[4];
456 char r_reserved[2]; /* extended pmad byte for COFF2 */
457 char r_type[2];
458};
459
460#define RELOC struct external_reloc
461#define RELSZ_V0 10 /* FIXME -- coffcode.h needs fixing */
462#define RELSZ 12 /* for COFF1/2 */
463
464/* various relocation types. */
465#define R_ABS 0x0000 /* no relocation */
466#define R_REL13 0x002A /* 13-bit direct reference (???) */
467#define R_PARTLS7 0x0028 /* 7 LSBs of an address */
468#define R_PARTMS9 0x0029 /* 9MSBs of an address */
469#define R_EXTWORD 0x002B /* 23-bit direct reference */
470#define R_EXTWORD16 0x002C /* 16-bit direct reference to 23-bit addr*/
471#define R_EXTWORDMS7 0x002D /* upper 7 bits of 23-bit address */
472
473#endif /* COFF_TI_H */
Note: See TracBrowser for help on using the repository browser.