ti.h revision 78828
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 578828Sobrien Copyright 2001 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 1978828Sobrien Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2078828Sobrien 2177298Sobrien#ifndef COFF_TI_H 2277298Sobrien#define COFF_TI_H 2377298Sobrien 2477298Sobrien/********************** FILE HEADER **********************/ 2577298Sobrien 2677298Sobrienstruct external_filehdr { 2777298Sobrien char f_magic[2]; /* magic number */ 2877298Sobrien char f_nscns[2]; /* number of sections */ 2977298Sobrien char f_timdat[4]; /* time & date stamp */ 3077298Sobrien char f_symptr[4]; /* file pointer to symtab */ 3177298Sobrien char f_nsyms[4]; /* number of symtab entries */ 3277298Sobrien char f_opthdr[2]; /* sizeof(optional hdr) */ 3377298Sobrien char f_flags[2]; /* flags */ 3477298Sobrien char f_target_id[2]; /* magic no. (TI COFF-specific) */ 3577298Sobrien}; 3677298Sobrien 3777298Sobrien/* COFF0 has magic number in f_magic, and omits f_target_id from the file 3877298Sobrien header; for later versions, f_magic is 0xC1 for COFF1 and 0xC2 for COFF2 3977298Sobrien and the target-specific magic number is found in f_target_id */ 4077298Sobrien 4177298Sobrien#define TICOFF0MAGIC TI_TARGET_ID 4277298Sobrien#define TICOFF1MAGIC 0x00C1 4377298Sobrien#define TICOFF2MAGIC 0x00C2 4477298Sobrien#define TICOFF_AOUT_MAGIC 0x0108 /* magic number in optional header */ 4577298Sobrien#define TICOFF 1 /* customize coffcode.h */ 4677298Sobrien 4777298Sobrien/* The target_id field changes depending on the particular CPU target */ 4877298Sobrien/* for COFF0, the target id appeared in f_magic, where COFFX magic is now */ 4977298Sobrien#ifndef TI_TARGET_ID 5077298Sobrien#error "TI_TARGET_ID needs to be defined for your CPU" 5177298Sobrien#endif 5277298Sobrien 5377298Sobrien/* Which bfd_arch to use... */ 5477298Sobrien#ifndef TICOFF_TARGET_ARCH 5577298Sobrien#error "TICOFF_TARGET_ARCH needs to be defined for your CPU" 5677298Sobrien#endif 5777298Sobrien 5877298Sobrien/* Default to COFF2 for file output */ 5977298Sobrien#ifndef TICOFF_DEFAULT_MAGIC 6077298Sobrien#define TICOFF_DEFAULT_MAGIC TICOFF2MAGIC 6177298Sobrien#endif 6277298Sobrien 6377298Sobrien/* This value is made available in the rare case where a bfd is unavailable */ 6477298Sobrien#ifndef OCTETS_PER_BYTE_POWER 6577298Sobrien#error "OCTETS_PER_BYTE_POWER not defined for this CPU" 6677298Sobrien#else 6777298Sobrien#define OCTETS_PER_BYTE (1<<OCTETS_PER_BYTE_POWER) 6877298Sobrien#endif 6977298Sobrien 7077298Sobrien/* default alignment is on a byte (not octet!) boundary */ 7177298Sobrien#ifndef COFF_DEFAULT_SECTION_ALIGNMENT_POWER 7277298Sobrien#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0 7377298Sobrien#endif 7477298Sobrien 7577298Sobrien/* TI COFF encodes the section alignment in the section header flags */ 7677298Sobrien#define COFF_ALIGN_IN_SECTION_HEADER 1 7777298Sobrien#define COFF_ALIGN_IN_S_FLAGS 1 7877298Sobrien/* requires a power-of-two argument */ 7977298Sobrien#define COFF_ENCODE_ALIGNMENT(S,X) ((S).s_flags |= (((unsigned)(X)&0xF)<<8)) 8077298Sobrien/* result is a power of two */ 8177298Sobrien#define COFF_DECODE_ALIGNMENT(X) (((X)>>8)&0xF) 8277298Sobrien 8377298Sobrien#define COFF0_P(ABFD) (bfd_coff_filhsz(ABFD) == FILHSZ_V0) 8477298Sobrien#define COFF2_P(ABFD) (bfd_coff_scnhsz(ABFD) != SCNHSZ_V01) 8577298Sobrien 8677298Sobrien#define COFF0_BADMAG(x) ((x).f_magic != TICOFF0MAGIC) 8777298Sobrien#define COFF1_BADMAG(x) ((x).f_magic != TICOFF1MAGIC || (x).f_target_id != TI_TARGET_ID) 8877298Sobrien#define COFF2_BADMAG(x) ((x).f_magic != TICOFF2MAGIC || (x).f_target_id != TI_TARGET_ID) 8977298Sobrien 9077298Sobrien/* we need to read/write an extra field in the coff file header */ 9177298Sobrien#ifndef COFF_ADJUST_FILEHDR_IN_POST 9277298Sobrien#define COFF_ADJUST_FILEHDR_IN_POST(abfd,src,dst) \ 9377298Sobriendo { ((struct internal_filehdr *)(dst))->f_target_id = \ 9477298Sobrienbfd_h_get_16(abfd, (bfd_byte *)(((FILHDR *)(src))->f_target_id)); \ 9577298Sobrien} while(0) 9677298Sobrien#endif 9777298Sobrien 9877298Sobrien#ifndef COFF_ADJUST_FILEHDR_OUT_POST 9977298Sobrien#define COFF_ADJUST_FILEHDR_OUT_POST(abfd,src,dst) \ 10077298Sobriendo { bfd_h_put_16(abfd, ((struct internal_filehdr *)(src))->f_target_id, \ 10177298Sobrien (bfd_byte *)(((FILHDR *)(dst))->f_target_id)); \ 10277298Sobrien} while(0) 10377298Sobrien#endif 10477298Sobrien 10577298Sobrien#define FILHDR struct external_filehdr 10677298Sobrien#define FILHSZ 22 10777298Sobrien#define FILHSZ_V0 20 /* COFF0 omits target_id field */ 10877298Sobrien 10977298Sobrien/* File header flags */ 11077298Sobrien#define F_RELFLG (0x0001) 11177298Sobrien#define F_EXEC (0x0002) 11277298Sobrien#define F_LNNO (0x0004) 11377298Sobrien/* F_LSYMS needs to be redefined in your source file */ 11477298Sobrien#define F_LSYMS_TICOFF (0x0010) /* normal COFF is 0x8 */ 11577298Sobrien 11677298Sobrien#define F_10 0x00 /* file built for TMS320C1x devices */ 11777298Sobrien#define F_20 0x10 /* file built for TMS320C2x devices */ 11877298Sobrien#define F_25 0x20 /* file built for TMS320C2x/C5x devices */ 11977298Sobrien#define F_LENDIAN 0x0100 /* 16 bits/word, LSB first */ 12077298Sobrien#define F_SYMMERGE 0x1000 /* duplicate symbols were removed */ 12177298Sobrien 12277298Sobrien/********************** OPTIONAL HEADER **********************/ 12377298Sobrien 12477298Sobrien 12577298Sobrientypedef struct 12677298Sobrien{ 12777298Sobrien char magic[2]; /* type of file (0x108) */ 12877298Sobrien char vstamp[2]; /* version stamp */ 12977298Sobrien char tsize[4]; /* text size in bytes, padded to FW bdry*/ 13077298Sobrien char dsize[4]; /* initialized data " " */ 13177298Sobrien char bsize[4]; /* uninitialized data " " */ 13277298Sobrien char entry[4]; /* entry pt. */ 13377298Sobrien char text_start[4]; /* base of text used for this file */ 13477298Sobrien char data_start[4]; /* base of data used for this file */ 13577298Sobrien} 13677298SobrienAOUTHDR; 13777298Sobrien 13877298Sobrien 13977298Sobrien#define AOUTHDRSZ 28 14077298Sobrien#define AOUTSZ 28 14177298Sobrien 14277298Sobrien 14377298Sobrien/********************** SECTION HEADER **********************/ 14477298Sobrien/* COFF0, COFF1 */ 14577298Sobrienstruct external_scnhdr_v01 { 14677298Sobrien char s_name[8]; /* section name */ 14777298Sobrien char s_paddr[4]; /* physical address, aliased s_nlib */ 14877298Sobrien char s_vaddr[4]; /* virtual address */ 14977298Sobrien char s_size[4]; /* section size (in WORDS) */ 15077298Sobrien char s_scnptr[4]; /* file ptr to raw data for section */ 15177298Sobrien char s_relptr[4]; /* file ptr to relocation */ 15277298Sobrien char s_lnnoptr[4]; /* file ptr to line numbers */ 15377298Sobrien char s_nreloc[2]; /* number of relocation entries */ 15477298Sobrien char s_nlnno[2]; /* number of line number entries*/ 15577298Sobrien char s_flags[2]; /* flags */ 15677298Sobrien char s_reserved[1]; /* reserved */ 15777298Sobrien char s_page[1]; /* section page number (LOAD) */ 15877298Sobrien}; 15977298Sobrien 16077298Sobrien/* COFF2 */ 16177298Sobrienstruct external_scnhdr { 16277298Sobrien char s_name[8]; /* section name */ 16377298Sobrien char s_paddr[4]; /* physical address, aliased s_nlib */ 16477298Sobrien char s_vaddr[4]; /* virtual address */ 16577298Sobrien char s_size[4]; /* section size (in WORDS) */ 16677298Sobrien char s_scnptr[4]; /* file ptr to raw data for section */ 16777298Sobrien char s_relptr[4]; /* file ptr to relocation */ 16877298Sobrien char s_lnnoptr[4]; /* file ptr to line numbers */ 16977298Sobrien char s_nreloc[4]; /* number of relocation entries */ 17077298Sobrien char s_nlnno[4]; /* number of line number entries*/ 17177298Sobrien char s_flags[4]; /* flags */ 17277298Sobrien char s_reserved[2]; /* reserved */ 17377298Sobrien char s_page[2]; /* section page number (LOAD) */ 17477298Sobrien}; 17577298Sobrien 17677298Sobrien/* 17777298Sobrien * Special section flags 17877298Sobrien */ 17977298Sobrien 18077298Sobrien/* TI COFF defines these flags; 18177298Sobrien STYP_CLINK: the section should be excluded from the final 18277298Sobrien linker output if there are no references found to any symbol in the section 18377298Sobrien STYP_BLOCK: the section should be blocked, i.e. if the section would cross 18477298Sobrien a page boundary, it is started at a page boundary instead. 18577298Sobrien TI COFF puts the section alignment power of two in the section flags 18677298Sobrien e.g. 2**N is alignment, flags |= (N & 0xF) << 8 18777298Sobrien*/ 18877298Sobrien#define STYP_CLINK (0x4000) 18977298Sobrien#define STYP_BLOCK (0x1000) 19077298Sobrien#define STYP_ALIGN (0x0F00) /* TI COFF stores section alignment here */ 19177298Sobrien 19277298Sobrien#define SCNHDR_V01 struct external_scnhdr_v01 19377298Sobrien#define SCNHDR struct external_scnhdr 19477298Sobrien#define SCNHSZ_V01 40 /* for v0 and v1 */ 19577298Sobrien#define SCNHSZ 48 19677298Sobrien 19777298Sobrien/* COFF2 changes the offsets and sizes of these fields 19877298Sobrien Assume we're dealing with the COFF2 scnhdr structure, and adjust 19977298Sobrien accordingly 20077298Sobrien */ 20177298Sobrien#define GET_SCNHDR_NRELOC(ABFD,PTR) \ 20277298Sobrien(COFF2_P(ABFD) ? bfd_h_get_32 (ABFD,PTR) : bfd_h_get_16 (ABFD, PTR)) 20377298Sobrien#define PUT_SCNHDR_NRELOC(ABFD,VAL,PTR) \ 20477298Sobrien(COFF2_P(ABFD) ? bfd_h_put_32 (ABFD,VAL,PTR) : bfd_h_put_16 (ABFD,VAL,PTR)) 20577298Sobrien#define GET_SCNHDR_NLNNO(ABFD,PTR) \ 20677298Sobrien(COFF2_P(ABFD) ? bfd_h_get_32 (ABFD,PTR) : bfd_h_get_16 (ABFD, (PTR)-2)) 20777298Sobrien#define PUT_SCNHDR_NLNNO(ABFD,VAL,PTR) \ 20877298Sobrien(COFF2_P(ABFD) ? bfd_h_put_32 (ABFD,VAL,PTR) : bfd_h_put_16 (ABFD,VAL,(PTR)-2)) 20977298Sobrien#define GET_SCNHDR_FLAGS(ABFD,PTR) \ 21077298Sobrien(COFF2_P(ABFD) ? bfd_h_get_32 (ABFD,PTR) : bfd_h_get_16 (ABFD, (PTR)-4)) 21177298Sobrien#define PUT_SCNHDR_FLAGS(ABFD,VAL,PTR) \ 21277298Sobrien(COFF2_P(ABFD) ? bfd_h_put_32 (ABFD,VAL,PTR) : bfd_h_put_16 (ABFD,VAL,(PTR)-4)) 21377298Sobrien#define GET_SCNHDR_PAGE(ABFD,PTR) \ 21477298Sobrien(COFF2_P(ABFD) ? bfd_h_get_16 (ABFD,PTR) : bfd_h_get_8 (ABFD, (PTR)-7)) 21577298Sobrien/* on output, make sure that the "reserved" field is zero */ 21677298Sobrien#define PUT_SCNHDR_PAGE(ABFD,VAL,PTR) \ 21777298Sobrien(COFF2_P(ABFD) ? bfd_h_put_16 (ABFD,VAL,PTR) : \ 21877298Sobrienbfd_h_put_8 (ABFD,VAL,(PTR)-7), bfd_h_put_8 (ABFD, 0, (PTR)-8)) 21977298Sobrien 22077298Sobrien/* TI COFF stores section size as number of bytes (address units, not octets), 22177298Sobrien so adjust to be number of octets, which is what BFD expects */ 22277298Sobrien#define GET_SCNHDR_SIZE(ABFD,SZP) \ 22377298Sobrien(bfd_h_get_32(ABFD,SZP)*bfd_octets_per_byte(ABFD)) 22477298Sobrien#define PUT_SCNHDR_SIZE(ABFD,SZ,SZP) \ 22577298Sobrienbfd_h_put_32(ABFD,(SZ)/bfd_octets_per_byte(ABFD),SZP) 22677298Sobrien 22777298Sobrien#define COFF_ADJUST_SCNHDR_IN_POST(ABFD,EXT,INT) \ 22877298Sobriendo { ((struct internal_scnhdr *)(INT))->s_page = \ 22977298SobrienGET_SCNHDR_PAGE(ABFD,(bfd_byte *)((SCNHDR *)(EXT))->s_page); \ 23077298Sobrien} while(0) 23177298Sobrien 23277298Sobrien/* The line number and reloc overflow checking in coff_swap_scnhdr_out in 23377298Sobrien coffswap.h doesn't use PUT_X for s_nlnno and s_nreloc. 23477298Sobrien Due to different sized v0/v1/v2 section headers, we have to re-write these 23577298Sobrien fields. 23677298Sobrien */ 23777298Sobrien#define COFF_ADJUST_SCNHDR_OUT_POST(ABFD,INT,EXT) \ 23877298Sobriendo { \ 23977298SobrienPUT_SCNHDR_NLNNO(ABFD,((struct internal_scnhdr *)(INT))->s_nlnno,\ 24077298Sobrien (bfd_byte *)((SCNHDR *)(EXT))->s_nlnno); \ 24177298SobrienPUT_SCNHDR_NRELOC(ABFD,((struct internal_scnhdr *)(INT))->s_nreloc,\ 24277298Sobrien (bfd_byte *)((SCNHDR *)(EXT))->s_nreloc); \ 24377298SobrienPUT_SCNHDR_FLAGS(ABFD,((struct internal_scnhdr *)(INT))->s_flags, \ 24477298Sobrien (bfd_byte *)((SCNHDR *)(EXT))->s_flags); \ 24577298SobrienPUT_SCNHDR_PAGE(ABFD,((struct internal_scnhdr *)(INT))->s_page, \ 24677298Sobrien (bfd_byte *)((SCNHDR *)(EXT))->s_page); \ 24777298Sobrien} while(0) 24877298Sobrien 24977298Sobrien/* Page macros 25077298Sobrien 25177298Sobrien The first GDB port requires flags in its remote memory access commands to 25277298Sobrien distinguish between data/prog space. Hopefully we can make this go away 25377298Sobrien eventually. Stuff the page in the upper bits of a 32-bit address, since 25477298Sobrien the c5x family only uses 16 or 23 bits. 25577298Sobrien 25677298Sobrien c2x, c5x and most c54x devices have 16-bit addresses, but the c548 has 25777298Sobrien 23-bit program addresses. Make sure the page flags don't interfere. 25877298Sobrien These flags are used by GDB to identify the destination page for 25977298Sobrien addresses. 26077298Sobrien*/ 26177298Sobrien 26277298Sobrien/* recognized load pages */ 26377298Sobrien#define PG_PROG 0x0 /* PROG page */ 26477298Sobrien#define PG_DATA 0x1 /* DATA page */ 26577298Sobrien 26677298Sobrien#define ADDR_MASK 0x00FFFFFF 26777298Sobrien#define PG_TO_FLAG(p) (((unsigned long)(p) & 0xFF) << 24) 26877298Sobrien#define FLAG_TO_PG(f) (((f) >> 24) & 0xFF) 26977298Sobrien 27077298Sobrien/* 27177298Sobrien * names of "special" sections 27277298Sobrien */ 27377298Sobrien#define _TEXT ".text" 27477298Sobrien#define _DATA ".data" 27577298Sobrien#define _BSS ".bss" 27677298Sobrien#define _CINIT ".cinit" /* initialized C data */ 27777298Sobrien#define _SCONST ".const" /* constants */ 27877298Sobrien#define _SWITCH ".switch" /* switch tables */ 27977298Sobrien#define _STACK ".stack" /* C stack */ 28077298Sobrien#define _SYSMEM ".sysmem" /* used for malloc et al. syscalls */ 28177298Sobrien 28277298Sobrien/********************** LINE NUMBERS **********************/ 28377298Sobrien 28477298Sobrien/* 1 line number entry for every "breakpointable" source line in a section. 28577298Sobrien * Line numbers are grouped on a per function basis; first entry in a function 28677298Sobrien * grouping will have l_lnno = 0 and in place of physical address will be the 28777298Sobrien * symbol table index of the function name. 28877298Sobrien */ 28977298Sobrienstruct external_lineno { 29077298Sobrien union { 29177298Sobrien char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ 29277298Sobrien char l_paddr[4]; /* (physical) address of line number */ 29377298Sobrien } l_addr; 29477298Sobrien char l_lnno[2]; /* line number */ 29577298Sobrien}; 29677298Sobrien 29777298Sobrien#define LINENO struct external_lineno 29877298Sobrien#define LINESZ 6 29977298Sobrien 30077298Sobrien 30177298Sobrien/********************** SYMBOLS **********************/ 30277298Sobrien 30377298Sobrien/* NOTE: this is what a local label looks like in assembly source; what it 30477298Sobrien looks like in COFF output is undefined */ 30577298Sobrien#define TICOFF_LOCAL_LABEL_P(NAME) \ 30677298Sobrien((NAME[0] == '$' && NAME[1] >= '0' && NAME[1] <= '9' && NAME[2] == '\0') \ 30777298Sobrien || NAME[strlen(NAME)-1] == '?') 30877298Sobrien 30977298Sobrien#define E_SYMNMLEN 8 /* # characters in a symbol name */ 31077298Sobrien#define E_FILNMLEN 14 /* # characters in a file name */ 31177298Sobrien#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ 31277298Sobrien 31377298Sobrienstruct external_syment 31477298Sobrien{ 31577298Sobrien union { 31677298Sobrien char e_name[E_SYMNMLEN]; 31777298Sobrien struct { 31877298Sobrien char e_zeroes[4]; 31977298Sobrien char e_offset[4]; 32077298Sobrien } e; 32177298Sobrien } e; 32277298Sobrien char e_value[4]; 32377298Sobrien char e_scnum[2]; 32477298Sobrien char e_type[2]; 32577298Sobrien char e_sclass[1]; 32677298Sobrien char e_numaux[1]; 32777298Sobrien}; 32877298Sobrien 32977298Sobrien 33077298Sobrien#define N_BTMASK (017) 33177298Sobrien#define N_TMASK (060) 33277298Sobrien#define N_BTSHFT (4) 33377298Sobrien#define N_TSHIFT (2) 33477298Sobrien 33577298Sobrien 33677298Sobrienunion external_auxent { 33777298Sobrien struct { 33877298Sobrien char x_tagndx[4]; /* str, un, or enum tag indx */ 33977298Sobrien union { 34077298Sobrien struct { 34177298Sobrien char x_lnno[2]; /* declaration line number */ 34277298Sobrien char x_size[2]; /* str/union/array size */ 34377298Sobrien } x_lnsz; 34477298Sobrien char x_fsize[4]; /* size of function */ 34577298Sobrien } x_misc; 34677298Sobrien union { 34777298Sobrien struct { /* if ISFCN, tag, or .bb */ 34877298Sobrien char x_lnnoptr[4]; /* ptr to fcn line # */ 34977298Sobrien char x_endndx[4]; /* entry ndx past block end */ 35077298Sobrien } x_fcn; 35177298Sobrien struct { /* if ISARY, up to 4 dimen. */ 35277298Sobrien char x_dimen[E_DIMNUM][2]; 35377298Sobrien } x_ary; 35477298Sobrien } x_fcnary; 35577298Sobrien char x_tvndx[2]; /* tv index */ 35677298Sobrien } x_sym; 35777298Sobrien 35877298Sobrien union { 35977298Sobrien char x_fname[E_FILNMLEN]; 36077298Sobrien struct { 36177298Sobrien char x_zeroes[4]; 36277298Sobrien char x_offset[4]; 36377298Sobrien } x_n; 36477298Sobrien } x_file; 36577298Sobrien 36677298Sobrien struct { 36777298Sobrien char x_scnlen[4]; /* section length */ 36877298Sobrien char x_nreloc[2]; /* # relocation entries */ 36977298Sobrien char x_nlinno[2]; /* # line numbers */ 37077298Sobrien } x_scn; 37177298Sobrien 37277298Sobrien struct { 37377298Sobrien char x_tvfill[4]; /* tv fill value */ 37477298Sobrien char x_tvlen[2]; /* length of .tv */ 37577298Sobrien char x_tvran[2][2]; /* tv range */ 37677298Sobrien } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ 37777298Sobrien 37877298Sobrien 37977298Sobrien}; 38077298Sobrien 38177298Sobrien#define SYMENT struct external_syment 38277298Sobrien#define SYMESZ 18 38377298Sobrien#define AUXENT union external_auxent 38477298Sobrien#define AUXESZ 18 38577298Sobrien 38677298Sobrien/* section lengths are in target bytes (not host bytes) */ 38777298Sobrien#define GET_SCN_SCNLEN(ABFD,EXT) \ 38877298Sobrien(bfd_h_get_32(ABFD,(bfd_byte *)(EXT)->x_scn.x_scnlen)*bfd_octets_per_byte(ABFD)) 38977298Sobrien#define PUT_SCN_SCNLEN(ABFD,INT,EXT) \ 39077298Sobrienbfd_h_put_32(ABFD,(INT)/bfd_octets_per_byte(ABFD),\ 39177298Sobrien (bfd_byte *)(EXT)->x_scn.x_scnlen) 39277298Sobrien 39377298Sobrien/* lnsz size is in bits in COFF file, in bytes in BFD */ 39477298Sobrien#define GET_LNSZ_SIZE(abfd, ext) \ 39577298Sobrien(bfd_h_get_16(abfd, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_size) / \ 39677298Sobrien (class != C_FIELD ? 8 : 1)) 39777298Sobrien 39877298Sobrien#define PUT_LNSZ_SIZE(abfd, in, ext) \ 39977298Sobrien bfd_h_put_16(abfd, ((class != C_FIELD) ? (in)*8 : (in)), \ 40077298Sobrien (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size) 40177298Sobrien 40277298Sobrien/* TI COFF stores offsets for MOS and MOU in bits; BFD expects bytes */ 40377298Sobrien#define COFF_ADJUST_SYM_IN_POST(ABFD,EXT,INT) \ 40477298Sobriendo { struct internal_syment *dst = (struct internal_syment *)(INT); \ 40577298Sobrienif (dst->n_sclass == C_MOS || dst->n_sclass == C_MOU) dst->n_value /= 8; \ 40677298Sobrien} while (0) 40777298Sobrien 40877298Sobrien#define COFF_ADJUST_SYM_OUT_POST(ABFD,INT,EXT) \ 40977298Sobriendo { struct internal_syment *src = (struct internal_syment *)(INT); \ 41077298SobrienSYMENT *dst = (SYMENT *)(EXT); \ 41177298Sobrienif(src->n_sclass == C_MOU || src->n_sclass == C_MOS) \ 41277298Sobrienbfd_h_put_32(abfd,src->n_value * 8,(bfd_byte *)dst->e_value); \ 41377298Sobrien} while (0) 41477298Sobrien 41577298Sobrien/* Detect section-relative absolute symbols so they get flagged with a sym 41677298Sobrien index of -1. 41777298Sobrien*/ 41877298Sobrien#define SECTION_RELATIVE_ABSOLUTE_SYMBOL_P(RELOC,SECT) \ 41977298Sobrien((*(RELOC)->sym_ptr_ptr)->section->output_section == (SECT) \ 42077298Sobrien && (RELOC)->howto->name[0] == 'A') 42177298Sobrien 42277298Sobrien/********************** RELOCATION DIRECTIVES **********************/ 42377298Sobrien 42477298Sobrienstruct external_reloc_v0 { 42577298Sobrien char r_vaddr[4]; 42677298Sobrien char r_symndx[2]; 42777298Sobrien char r_reserved[2]; 42877298Sobrien char r_type[2]; 42977298Sobrien}; 43077298Sobrien 43177298Sobrienstruct external_reloc { 43277298Sobrien char r_vaddr[4]; 43377298Sobrien char r_symndx[4]; 43477298Sobrien char r_reserved[2]; /* extended pmad byte for COFF2 */ 43577298Sobrien char r_type[2]; 43677298Sobrien}; 43777298Sobrien 43877298Sobrien#define RELOC struct external_reloc 43977298Sobrien#define RELSZ_V0 10 /* FIXME -- coffcode.h needs fixing */ 44077298Sobrien#define RELSZ 12 /* for COFF1/2 */ 44177298Sobrien 44277298Sobrien/* various relocation types. */ 44377298Sobrien#define R_ABS 0x0000 /* no relocation */ 44477298Sobrien#define R_REL13 0x002A /* 13-bit direct reference (???) */ 44577298Sobrien#define R_PARTLS7 0x0028 /* 7 LSBs of an address */ 44677298Sobrien#define R_PARTMS9 0x0029 /* 9MSBs of an address */ 44777298Sobrien#define R_EXTWORD 0x002B /* 23-bit direct reference */ 44877298Sobrien#define R_EXTWORD16 0x002C /* 16-bit direct reference to 23-bit addr*/ 44977298Sobrien#define R_EXTWORDMS7 0x002D /* upper 7 bits of 23-bit address */ 45077298Sobrien 45177298Sobrien#endif /* COFF_TI_H */ 452