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