177298Sobrien/* COFF information for TI COFF support. Definitions in this file should be 277298Sobrien customized in a target-specific file, and then this file included (see 378828Sobrien tic54x.h for an example). 478828Sobrien 5218822Sdim Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 678828Sobrien 778828Sobrien This program is free software; you can redistribute it and/or modify 878828Sobrien it under the terms of the GNU General Public License as published by 978828Sobrien the Free Software Foundation; either version 2 of the License, or 1078828Sobrien (at your option) any later version. 1178828Sobrien 1278828Sobrien This program is distributed in the hope that it will be useful, 1378828Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1478828Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1578828Sobrien GNU General Public License for more details. 1678828Sobrien 1778828Sobrien You should have received a copy of the GNU General Public License 1878828Sobrien along with this program; if not, write to the Free Software 19218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2077298Sobrien#ifndef COFF_TI_H 2177298Sobrien#define COFF_TI_H 2277298Sobrien 2389857Sobrien/* Note "coff/external.h is not used because TI adds extra fields to the structures. */ 2489857Sobrien 2577298Sobrien/********************** FILE HEADER **********************/ 2677298Sobrien 2789857Sobrienstruct external_filehdr 2889857Sobrien { 2989857Sobrien char f_magic[2]; /* magic number */ 3089857Sobrien char f_nscns[2]; /* number of sections */ 3189857Sobrien char f_timdat[4]; /* time & date stamp */ 3289857Sobrien char f_symptr[4]; /* file pointer to symtab */ 3389857Sobrien char f_nsyms[4]; /* number of symtab entries */ 3489857Sobrien char f_opthdr[2]; /* sizeof(optional hdr) */ 3589857Sobrien char f_flags[2]; /* flags */ 3689857Sobrien char f_target_id[2]; /* magic no. (TI COFF-specific) */ 3789857Sobrien }; 3877298Sobrien 3977298Sobrien/* COFF0 has magic number in f_magic, and omits f_target_id from the file 4077298Sobrien header; for later versions, f_magic is 0xC1 for COFF1 and 0xC2 for COFF2 4177298Sobrien and the target-specific magic number is found in f_target_id */ 4277298Sobrien 4377298Sobrien#define TICOFF0MAGIC TI_TARGET_ID 4477298Sobrien#define TICOFF1MAGIC 0x00C1 4577298Sobrien#define TICOFF2MAGIC 0x00C2 4677298Sobrien#define TICOFF_AOUT_MAGIC 0x0108 /* magic number in optional header */ 4777298Sobrien#define TICOFF 1 /* customize coffcode.h */ 4877298Sobrien 4977298Sobrien/* The target_id field changes depending on the particular CPU target */ 5077298Sobrien/* for COFF0, the target id appeared in f_magic, where COFFX magic is now */ 5177298Sobrien#ifndef TI_TARGET_ID 5277298Sobrien#error "TI_TARGET_ID needs to be defined for your CPU" 5377298Sobrien#endif 5477298Sobrien 5577298Sobrien/* Which bfd_arch to use... */ 5677298Sobrien#ifndef TICOFF_TARGET_ARCH 5777298Sobrien#error "TICOFF_TARGET_ARCH needs to be defined for your CPU" 5877298Sobrien#endif 5977298Sobrien 60130561Sobrien#ifndef TICOFF_TARGET_MACHINE_GET 61130561Sobrien#define TICOFF_TARGET_MACHINE_GET(FLAGS) 0 62130561Sobrien#endif 63130561Sobrien 64130561Sobrien#ifndef TICOFF_TARGET_MACHINE_SET 65130561Sobrien#define TICOFF_TARGET_MACHINE_SET(FLAGSP, MACHINE) 66130561Sobrien#endif 67130561Sobrien 6877298Sobrien/* Default to COFF2 for file output */ 6977298Sobrien#ifndef TICOFF_DEFAULT_MAGIC 7077298Sobrien#define TICOFF_DEFAULT_MAGIC TICOFF2MAGIC 7177298Sobrien#endif 7277298Sobrien 7377298Sobrien/* This value is made available in the rare case where a bfd is unavailable */ 7477298Sobrien#ifndef OCTETS_PER_BYTE_POWER 7577298Sobrien#error "OCTETS_PER_BYTE_POWER not defined for this CPU" 7677298Sobrien#else 7777298Sobrien#define OCTETS_PER_BYTE (1<<OCTETS_PER_BYTE_POWER) 7877298Sobrien#endif 7977298Sobrien 8077298Sobrien/* default alignment is on a byte (not octet!) boundary */ 8177298Sobrien#ifndef COFF_DEFAULT_SECTION_ALIGNMENT_POWER 8277298Sobrien#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0 8377298Sobrien#endif 8477298Sobrien 8577298Sobrien/* TI COFF encodes the section alignment in the section header flags */ 8677298Sobrien#define COFF_ALIGN_IN_SECTION_HEADER 1 8777298Sobrien#define COFF_ALIGN_IN_S_FLAGS 1 8877298Sobrien/* requires a power-of-two argument */ 8977298Sobrien#define COFF_ENCODE_ALIGNMENT(S,X) ((S).s_flags |= (((unsigned)(X)&0xF)<<8)) 9077298Sobrien/* result is a power of two */ 9177298Sobrien#define COFF_DECODE_ALIGNMENT(X) (((X)>>8)&0xF) 9277298Sobrien 9377298Sobrien#define COFF0_P(ABFD) (bfd_coff_filhsz(ABFD) == FILHSZ_V0) 9477298Sobrien#define COFF2_P(ABFD) (bfd_coff_scnhsz(ABFD) != SCNHSZ_V01) 9577298Sobrien 9677298Sobrien#define COFF0_BADMAG(x) ((x).f_magic != TICOFF0MAGIC) 9777298Sobrien#define COFF1_BADMAG(x) ((x).f_magic != TICOFF1MAGIC || (x).f_target_id != TI_TARGET_ID) 9877298Sobrien#define COFF2_BADMAG(x) ((x).f_magic != TICOFF2MAGIC || (x).f_target_id != TI_TARGET_ID) 9977298Sobrien 10077298Sobrien/* we need to read/write an extra field in the coff file header */ 10177298Sobrien#ifndef COFF_ADJUST_FILEHDR_IN_POST 10289857Sobrien#define COFF_ADJUST_FILEHDR_IN_POST(abfd, src, dst) \ 10389857Sobrien do \ 10489857Sobrien { \ 10589857Sobrien ((struct internal_filehdr *)(dst))->f_target_id = \ 10689857Sobrien H_GET_16 (abfd, ((FILHDR *)(src))->f_target_id); \ 10789857Sobrien } \ 10889857Sobrien while (0) 10977298Sobrien#endif 11077298Sobrien 11177298Sobrien#ifndef COFF_ADJUST_FILEHDR_OUT_POST 11289857Sobrien#define COFF_ADJUST_FILEHDR_OUT_POST(abfd, src, dst) \ 11389857Sobrien do \ 11489857Sobrien { \ 11589857Sobrien H_PUT_16 (abfd, ((struct internal_filehdr *)(src))->f_target_id, \ 11689857Sobrien ((FILHDR *)(dst))->f_target_id); \ 11789857Sobrien } \ 11889857Sobrien while (0) 11977298Sobrien#endif 12077298Sobrien 12177298Sobrien#define FILHDR struct external_filehdr 12277298Sobrien#define FILHSZ 22 12377298Sobrien#define FILHSZ_V0 20 /* COFF0 omits target_id field */ 12477298Sobrien 12577298Sobrien/* File header flags */ 12677298Sobrien#define F_RELFLG (0x0001) 12777298Sobrien#define F_EXEC (0x0002) 12877298Sobrien#define F_LNNO (0x0004) 129130561Sobrien#define F_VERS (0x0010) /* TMS320C4x code */ 13077298Sobrien/* F_LSYMS needs to be redefined in your source file */ 13177298Sobrien#define F_LSYMS_TICOFF (0x0010) /* normal COFF is 0x8 */ 13277298Sobrien 13377298Sobrien#define F_10 0x00 /* file built for TMS320C1x devices */ 13477298Sobrien#define F_20 0x10 /* file built for TMS320C2x devices */ 13577298Sobrien#define F_25 0x20 /* file built for TMS320C2x/C5x devices */ 13677298Sobrien#define F_LENDIAN 0x0100 /* 16 bits/word, LSB first */ 13777298Sobrien#define F_SYMMERGE 0x1000 /* duplicate symbols were removed */ 13877298Sobrien 13977298Sobrien/********************** OPTIONAL HEADER **********************/ 14077298Sobrien 14177298Sobrien 14277298Sobrientypedef struct 14377298Sobrien{ 14477298Sobrien char magic[2]; /* type of file (0x108) */ 14577298Sobrien char vstamp[2]; /* version stamp */ 14677298Sobrien char tsize[4]; /* text size in bytes, padded to FW bdry*/ 14777298Sobrien char dsize[4]; /* initialized data " " */ 14877298Sobrien char bsize[4]; /* uninitialized data " " */ 14977298Sobrien char entry[4]; /* entry pt. */ 15077298Sobrien char text_start[4]; /* base of text used for this file */ 15177298Sobrien char data_start[4]; /* base of data used for this file */ 15277298Sobrien} 15377298SobrienAOUTHDR; 15477298Sobrien 15577298Sobrien 15677298Sobrien#define AOUTHDRSZ 28 15777298Sobrien#define AOUTSZ 28 15877298Sobrien 15977298Sobrien 16077298Sobrien/********************** SECTION HEADER **********************/ 16177298Sobrien/* COFF0, COFF1 */ 16277298Sobrienstruct external_scnhdr_v01 { 16377298Sobrien char s_name[8]; /* section name */ 16477298Sobrien char s_paddr[4]; /* physical address, aliased s_nlib */ 16577298Sobrien char s_vaddr[4]; /* virtual address */ 16677298Sobrien char s_size[4]; /* section size (in WORDS) */ 16777298Sobrien char s_scnptr[4]; /* file ptr to raw data for section */ 16877298Sobrien char s_relptr[4]; /* file ptr to relocation */ 16977298Sobrien char s_lnnoptr[4]; /* file ptr to line numbers */ 17077298Sobrien char s_nreloc[2]; /* number of relocation entries */ 17177298Sobrien char s_nlnno[2]; /* number of line number entries*/ 17277298Sobrien char s_flags[2]; /* flags */ 17377298Sobrien char s_reserved[1]; /* reserved */ 17477298Sobrien char s_page[1]; /* section page number (LOAD) */ 17577298Sobrien}; 17677298Sobrien 17777298Sobrien/* COFF2 */ 17877298Sobrienstruct external_scnhdr { 17977298Sobrien char s_name[8]; /* section name */ 18077298Sobrien char s_paddr[4]; /* physical address, aliased s_nlib */ 18177298Sobrien char s_vaddr[4]; /* virtual address */ 18277298Sobrien char s_size[4]; /* section size (in WORDS) */ 18377298Sobrien char s_scnptr[4]; /* file ptr to raw data for section */ 18477298Sobrien char s_relptr[4]; /* file ptr to relocation */ 18577298Sobrien char s_lnnoptr[4]; /* file ptr to line numbers */ 18677298Sobrien char s_nreloc[4]; /* number of relocation entries */ 18777298Sobrien char s_nlnno[4]; /* number of line number entries*/ 18877298Sobrien char s_flags[4]; /* flags */ 18977298Sobrien char s_reserved[2]; /* reserved */ 19077298Sobrien char s_page[2]; /* section page number (LOAD) */ 19177298Sobrien}; 19277298Sobrien 19377298Sobrien/* 19477298Sobrien * Special section flags 19577298Sobrien */ 19677298Sobrien 19777298Sobrien/* TI COFF defines these flags; 19877298Sobrien STYP_CLINK: the section should be excluded from the final 19977298Sobrien linker output if there are no references found to any symbol in the section 20077298Sobrien STYP_BLOCK: the section should be blocked, i.e. if the section would cross 20177298Sobrien a page boundary, it is started at a page boundary instead. 20277298Sobrien TI COFF puts the section alignment power of two in the section flags 20377298Sobrien e.g. 2**N is alignment, flags |= (N & 0xF) << 8 20477298Sobrien*/ 20577298Sobrien#define STYP_CLINK (0x4000) 20677298Sobrien#define STYP_BLOCK (0x1000) 20777298Sobrien#define STYP_ALIGN (0x0F00) /* TI COFF stores section alignment here */ 20877298Sobrien 20977298Sobrien#define SCNHDR_V01 struct external_scnhdr_v01 21077298Sobrien#define SCNHDR struct external_scnhdr 21177298Sobrien#define SCNHSZ_V01 40 /* for v0 and v1 */ 21277298Sobrien#define SCNHSZ 48 21377298Sobrien 21477298Sobrien/* COFF2 changes the offsets and sizes of these fields 21577298Sobrien Assume we're dealing with the COFF2 scnhdr structure, and adjust 21677298Sobrien accordingly 21777298Sobrien */ 218130561Sobrien#define GET_SCNHDR_NRELOC(ABFD, LOC) \ 219130561Sobrien (COFF2_P (ABFD) ? H_GET_32 (ABFD, LOC) : H_GET_16 (ABFD, LOC)) 220130561Sobrien#define PUT_SCNHDR_NRELOC(ABFD, VAL, LOC) \ 221130561Sobrien (COFF2_P (ABFD) ? H_PUT_32 (ABFD, VAL, LOC) : H_PUT_16 (ABFD, VAL, LOC)) 222130561Sobrien#define GET_SCNHDR_NLNNO(ABFD, LOC) \ 223130561Sobrien (COFF2_P (ABFD) ? H_GET_32 (ABFD, LOC) : H_GET_16 (ABFD, (LOC) - 2)) 224130561Sobrien#define PUT_SCNHDR_NLNNO(ABFD, VAL, LOC) \ 225130561Sobrien (COFF2_P (ABFD) ? H_PUT_32 (ABFD, VAL, LOC) : H_PUT_16 (ABFD, VAL, (LOC) - 2)) 226130561Sobrien#define GET_SCNHDR_FLAGS(ABFD, LOC) \ 227130561Sobrien (COFF2_P (ABFD) ? H_GET_32 (ABFD, LOC) : H_GET_16 (ABFD, (LOC) - 4)) 228130561Sobrien#define PUT_SCNHDR_FLAGS(ABFD, VAL, LOC) \ 229130561Sobrien (COFF2_P (ABFD) ? H_PUT_32 (ABFD, VAL, LOC) : H_PUT_16 (ABFD, VAL, (LOC) - 4)) 230130561Sobrien#define GET_SCNHDR_PAGE(ABFD, LOC) \ 231130561Sobrien (COFF2_P (ABFD) ? H_GET_16 (ABFD, LOC) : (unsigned) H_GET_8 (ABFD, (LOC) - 7)) 23277298Sobrien/* on output, make sure that the "reserved" field is zero */ 233130561Sobrien#define PUT_SCNHDR_PAGE(ABFD, VAL, LOC) \ 23489857Sobrien (COFF2_P (ABFD) \ 235130561Sobrien ? H_PUT_16 (ABFD, VAL, LOC) \ 236130561Sobrien : H_PUT_8 (ABFD, VAL, (LOC) - 7), H_PUT_8 (ABFD, 0, (LOC) - 8)) 23777298Sobrien 23877298Sobrien/* TI COFF stores section size as number of bytes (address units, not octets), 23977298Sobrien so adjust to be number of octets, which is what BFD expects */ 24089857Sobrien#define GET_SCNHDR_SIZE(ABFD, SZP) \ 24189857Sobrien (H_GET_32 (ABFD, SZP) * bfd_octets_per_byte (ABFD)) 24289857Sobrien#define PUT_SCNHDR_SIZE(ABFD, SZ, SZP) \ 24389857Sobrien H_PUT_32 (ABFD, (SZ) / bfd_octets_per_byte (ABFD), SZP) 24477298Sobrien 24589857Sobrien#define COFF_ADJUST_SCNHDR_IN_POST(ABFD, EXT, INT) \ 24689857Sobrien do \ 24789857Sobrien { \ 24889857Sobrien ((struct internal_scnhdr *)(INT))->s_page = \ 24989857Sobrien GET_SCNHDR_PAGE (ABFD, ((SCNHDR *)(EXT))->s_page); \ 25089857Sobrien } \ 25189857Sobrien while (0) 25277298Sobrien 25377298Sobrien/* The line number and reloc overflow checking in coff_swap_scnhdr_out in 25477298Sobrien coffswap.h doesn't use PUT_X for s_nlnno and s_nreloc. 25577298Sobrien Due to different sized v0/v1/v2 section headers, we have to re-write these 25677298Sobrien fields. 25777298Sobrien */ 25889857Sobrien#define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \ 25989857Sobrien do \ 26089857Sobrien { \ 26189857Sobrien PUT_SCNHDR_NLNNO (ABFD, ((struct internal_scnhdr *)(INT))->s_nlnno, \ 26289857Sobrien ((SCNHDR *)(EXT))->s_nlnno); \ 26389857Sobrien PUT_SCNHDR_NRELOC (ABFD, ((struct internal_scnhdr *)(INT))->s_nreloc,\ 26489857Sobrien ((SCNHDR *)(EXT))->s_nreloc); \ 26589857Sobrien PUT_SCNHDR_FLAGS (ABFD, ((struct internal_scnhdr *)(INT))->s_flags, \ 26689857Sobrien ((SCNHDR *)(EXT))->s_flags); \ 26789857Sobrien PUT_SCNHDR_PAGE (ABFD, ((struct internal_scnhdr *)(INT))->s_page, \ 26889857Sobrien ((SCNHDR *)(EXT))->s_page); \ 26989857Sobrien } \ 27089857Sobrien while (0) 27177298Sobrien 27277298Sobrien/* 27377298Sobrien * names of "special" sections 27477298Sobrien */ 27577298Sobrien#define _TEXT ".text" 27677298Sobrien#define _DATA ".data" 27777298Sobrien#define _BSS ".bss" 27877298Sobrien#define _CINIT ".cinit" /* initialized C data */ 27977298Sobrien#define _SCONST ".const" /* constants */ 28077298Sobrien#define _SWITCH ".switch" /* switch tables */ 28177298Sobrien#define _STACK ".stack" /* C stack */ 28277298Sobrien#define _SYSMEM ".sysmem" /* used for malloc et al. syscalls */ 28377298Sobrien 28477298Sobrien/********************** LINE NUMBERS **********************/ 28577298Sobrien 28677298Sobrien/* 1 line number entry for every "breakpointable" source line in a section. 28777298Sobrien * Line numbers are grouped on a per function basis; first entry in a function 28877298Sobrien * grouping will have l_lnno = 0 and in place of physical address will be the 28977298Sobrien * symbol table index of the function name. 29077298Sobrien */ 29177298Sobrienstruct external_lineno { 29277298Sobrien union { 29377298Sobrien char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ 29477298Sobrien char l_paddr[4]; /* (physical) address of line number */ 29577298Sobrien } l_addr; 29677298Sobrien char l_lnno[2]; /* line number */ 29777298Sobrien}; 29877298Sobrien 29977298Sobrien#define LINENO struct external_lineno 30077298Sobrien#define LINESZ 6 30177298Sobrien 30277298Sobrien 30377298Sobrien/********************** SYMBOLS **********************/ 30477298Sobrien 30577298Sobrien/* NOTE: this is what a local label looks like in assembly source; what it 30677298Sobrien looks like in COFF output is undefined */ 30777298Sobrien#define TICOFF_LOCAL_LABEL_P(NAME) \ 30877298Sobrien((NAME[0] == '$' && NAME[1] >= '0' && NAME[1] <= '9' && NAME[2] == '\0') \ 30977298Sobrien || NAME[strlen(NAME)-1] == '?') 31077298Sobrien 31177298Sobrien#define E_SYMNMLEN 8 /* # characters in a symbol name */ 31277298Sobrien#define E_FILNMLEN 14 /* # characters in a file name */ 31377298Sobrien#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ 31477298Sobrien 31577298Sobrienstruct external_syment 31677298Sobrien{ 31777298Sobrien union { 31877298Sobrien char e_name[E_SYMNMLEN]; 31977298Sobrien struct { 32077298Sobrien char e_zeroes[4]; 32177298Sobrien char e_offset[4]; 32277298Sobrien } e; 32377298Sobrien } e; 32477298Sobrien char e_value[4]; 32577298Sobrien char e_scnum[2]; 32677298Sobrien char e_type[2]; 32777298Sobrien char e_sclass[1]; 32877298Sobrien char e_numaux[1]; 32977298Sobrien}; 33077298Sobrien 33177298Sobrien 33277298Sobrien#define N_BTMASK (017) 33377298Sobrien#define N_TMASK (060) 33477298Sobrien#define N_BTSHFT (4) 33577298Sobrien#define N_TSHIFT (2) 33677298Sobrien 33777298Sobrien 33877298Sobrienunion external_auxent { 33977298Sobrien struct { 34077298Sobrien char x_tagndx[4]; /* str, un, or enum tag indx */ 34177298Sobrien union { 34277298Sobrien struct { 34377298Sobrien char x_lnno[2]; /* declaration line number */ 34477298Sobrien char x_size[2]; /* str/union/array size */ 34577298Sobrien } x_lnsz; 34677298Sobrien char x_fsize[4]; /* size of function */ 34777298Sobrien } x_misc; 34877298Sobrien union { 34977298Sobrien struct { /* if ISFCN, tag, or .bb */ 35077298Sobrien char x_lnnoptr[4]; /* ptr to fcn line # */ 35177298Sobrien char x_endndx[4]; /* entry ndx past block end */ 35277298Sobrien } x_fcn; 35377298Sobrien struct { /* if ISARY, up to 4 dimen. */ 35477298Sobrien char x_dimen[E_DIMNUM][2]; 35577298Sobrien } x_ary; 35677298Sobrien } x_fcnary; 35777298Sobrien char x_tvndx[2]; /* tv index */ 35877298Sobrien } x_sym; 35977298Sobrien 36077298Sobrien union { 36177298Sobrien char x_fname[E_FILNMLEN]; 36277298Sobrien struct { 36377298Sobrien char x_zeroes[4]; 36477298Sobrien char x_offset[4]; 36577298Sobrien } x_n; 36677298Sobrien } x_file; 36777298Sobrien 36877298Sobrien struct { 36977298Sobrien char x_scnlen[4]; /* section length */ 37077298Sobrien char x_nreloc[2]; /* # relocation entries */ 37177298Sobrien char x_nlinno[2]; /* # line numbers */ 37277298Sobrien } x_scn; 37377298Sobrien 37477298Sobrien struct { 37577298Sobrien char x_tvfill[4]; /* tv fill value */ 37677298Sobrien char x_tvlen[2]; /* length of .tv */ 37777298Sobrien char x_tvran[2][2]; /* tv range */ 37877298Sobrien } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ 37977298Sobrien 38077298Sobrien 38177298Sobrien}; 38277298Sobrien 38377298Sobrien#define SYMENT struct external_syment 38477298Sobrien#define SYMESZ 18 38577298Sobrien#define AUXENT union external_auxent 38677298Sobrien#define AUXESZ 18 38777298Sobrien 38877298Sobrien/* section lengths are in target bytes (not host bytes) */ 38989857Sobrien#define GET_SCN_SCNLEN(ABFD, EXT) \ 39089857Sobrien (H_GET_32 (ABFD, (EXT)->x_scn.x_scnlen) * bfd_octets_per_byte (ABFD)) 39189857Sobrien#define PUT_SCN_SCNLEN(ABFD, INT, EXT) \ 39289857Sobrien H_PUT_32 (ABFD, (INT) / bfd_octets_per_byte (ABFD), (EXT)->x_scn.x_scnlen) 39377298Sobrien 39477298Sobrien/* lnsz size is in bits in COFF file, in bytes in BFD */ 39577298Sobrien#define GET_LNSZ_SIZE(abfd, ext) \ 39689857Sobrien (H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size) / (class != C_FIELD ? 8 : 1)) 39777298Sobrien 39877298Sobrien#define PUT_LNSZ_SIZE(abfd, in, ext) \ 39989857Sobrien H_PUT_16 (abfd, ((class != C_FIELD) ? (in) * 8 : (in)), \ 40089857Sobrien ext->x_sym.x_misc.x_lnsz.x_size) 40177298Sobrien 40289857Sobrien/* TI COFF stores offsets for MOS and MOU in bits; BFD expects bytes 40389857Sobrien Also put the load page flag of the section into the symbol value if it's an 40489857Sobrien address. */ 40589857Sobrien#ifndef NEEDS_PAGE 40689857Sobrien#define NEEDS_PAGE(X) 0 40789857Sobrien#define PAGE_MASK 0 40889857Sobrien#endif 40989857Sobrien#define COFF_ADJUST_SYM_IN_POST(ABFD, EXT, INT) \ 41089857Sobrien do \ 41189857Sobrien { \ 41289857Sobrien struct internal_syment *dst = (struct internal_syment *)(INT); \ 41389857Sobrien if (dst->n_sclass == C_MOS || dst->n_sclass == C_MOU) \ 41489857Sobrien dst->n_value /= 8; \ 41589857Sobrien else if (NEEDS_PAGE (dst->n_sclass)) { \ 41689857Sobrien asection *scn = coff_section_from_bfd_index (abfd, dst->n_scnum); \ 41789857Sobrien dst->n_value |= (scn->lma & PAGE_MASK); \ 41889857Sobrien } \ 41989857Sobrien } \ 42089857Sobrien while (0) 42177298Sobrien 42289857Sobrien#define COFF_ADJUST_SYM_OUT_POST(ABFD, INT, EXT) \ 42389857Sobrien do \ 42489857Sobrien { \ 42589857Sobrien struct internal_syment *src = (struct internal_syment *)(INT); \ 42689857Sobrien SYMENT *dst = (SYMENT *)(EXT); \ 42789857Sobrien if (src->n_sclass == C_MOU || src->n_sclass == C_MOS) \ 42889857Sobrien H_PUT_32 (abfd, src->n_value * 8, dst->e_value); \ 42989857Sobrien else if (NEEDS_PAGE (src->n_sclass)) { \ 43089857Sobrien H_PUT_32 (abfd, src->n_value &= ~PAGE_MASK, dst->e_value); \ 43189857Sobrien } \ 43289857Sobrien } \ 43389857Sobrien while (0) 43477298Sobrien 43577298Sobrien/* Detect section-relative absolute symbols so they get flagged with a sym 43677298Sobrien index of -1. 43777298Sobrien*/ 43889857Sobrien#define SECTION_RELATIVE_ABSOLUTE_SYMBOL_P(RELOC, SECT) \ 43989857Sobrien ((*(RELOC)->sym_ptr_ptr)->section->output_section == (SECT) \ 44089857Sobrien && (RELOC)->howto->name[0] == 'A') 44177298Sobrien 44277298Sobrien/********************** RELOCATION DIRECTIVES **********************/ 44377298Sobrien 44489857Sobrienstruct external_reloc_v0 44589857Sobrien{ 44677298Sobrien char r_vaddr[4]; 44777298Sobrien char r_symndx[2]; 44877298Sobrien char r_reserved[2]; 44977298Sobrien char r_type[2]; 45077298Sobrien}; 45177298Sobrien 45289857Sobrienstruct external_reloc 45389857Sobrien{ 45477298Sobrien char r_vaddr[4]; 45577298Sobrien char r_symndx[4]; 45677298Sobrien char r_reserved[2]; /* extended pmad byte for COFF2 */ 45777298Sobrien char r_type[2]; 45877298Sobrien}; 45977298Sobrien 46077298Sobrien#define RELOC struct external_reloc 46177298Sobrien#define RELSZ_V0 10 /* FIXME -- coffcode.h needs fixing */ 46277298Sobrien#define RELSZ 12 /* for COFF1/2 */ 46377298Sobrien 46477298Sobrien/* various relocation types. */ 46577298Sobrien#define R_ABS 0x0000 /* no relocation */ 46677298Sobrien#define R_REL13 0x002A /* 13-bit direct reference (???) */ 46777298Sobrien#define R_PARTLS7 0x0028 /* 7 LSBs of an address */ 46877298Sobrien#define R_PARTMS9 0x0029 /* 9MSBs of an address */ 46977298Sobrien#define R_EXTWORD 0x002B /* 23-bit direct reference */ 47077298Sobrien#define R_EXTWORD16 0x002C /* 16-bit direct reference to 23-bit addr*/ 47177298Sobrien#define R_EXTWORDMS7 0x002D /* upper 7 bits of 23-bit address */ 47277298Sobrien 47377298Sobrien#endif /* COFF_TI_H */ 474