| 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 */
|
|---|