| 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 |  | 
|---|
| 27 | struct 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 |  | 
|---|
| 142 | typedef 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 | } | 
|---|
| 153 | AOUTHDR; | 
|---|
| 154 |  | 
|---|
| 155 |  | 
|---|
| 156 | #define AOUTHDRSZ 28 | 
|---|
| 157 | #define AOUTSZ 28 | 
|---|
| 158 |  | 
|---|
| 159 |  | 
|---|
| 160 | /********************** SECTION HEADER **********************/ | 
|---|
| 161 | /* COFF0, COFF1 */ | 
|---|
| 162 | struct 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 */ | 
|---|
| 178 | struct 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 | */ | 
|---|
| 291 | struct 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 |  | 
|---|
| 315 | struct 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 |  | 
|---|
| 338 | union 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 |  | 
|---|
| 444 | struct 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 |  | 
|---|
| 452 | struct 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 */ | 
|---|