ti.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  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. Copyright (C) 2000-2015 Free Software Foundation, Inc.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. MA 02110-1301, USA. */
  17. #ifndef COFF_TI_H
  18. #define COFF_TI_H
  19. /* Note "coff/external.h is not used because TI adds extra fields to the structures. */
  20. /********************** FILE HEADER **********************/
  21. struct external_filehdr
  22. {
  23. char f_magic[2]; /* magic number */
  24. char f_nscns[2]; /* number of sections */
  25. char f_timdat[4]; /* time & date stamp */
  26. char f_symptr[4]; /* file pointer to symtab */
  27. char f_nsyms[4]; /* number of symtab entries */
  28. char f_opthdr[2]; /* sizeof(optional hdr) */
  29. char f_flags[2]; /* flags */
  30. char f_target_id[2]; /* magic no. (TI COFF-specific) */
  31. };
  32. /* COFF0 has magic number in f_magic, and omits f_target_id from the file
  33. header; for later versions, f_magic is 0xC1 for COFF1 and 0xC2 for COFF2
  34. and the target-specific magic number is found in f_target_id */
  35. #define TICOFF0MAGIC TI_TARGET_ID
  36. #define TICOFF1MAGIC 0x00C1
  37. #define TICOFF2MAGIC 0x00C2
  38. #define TICOFF_AOUT_MAGIC 0x0108 /* magic number in optional header */
  39. #define TICOFF 1 /* customize coffcode.h */
  40. /* The target_id field changes depending on the particular CPU target */
  41. /* for COFF0, the target id appeared in f_magic, where COFFX magic is now */
  42. #ifndef TI_TARGET_ID
  43. #error "TI_TARGET_ID needs to be defined for your CPU"
  44. #endif
  45. /* Which bfd_arch to use... */
  46. #ifndef TICOFF_TARGET_ARCH
  47. #error "TICOFF_TARGET_ARCH needs to be defined for your CPU"
  48. #endif
  49. #ifndef TICOFF_TARGET_MACHINE_GET
  50. #define TICOFF_TARGET_MACHINE_GET(FLAGS) 0
  51. #endif
  52. #ifndef TICOFF_TARGET_MACHINE_SET
  53. #define TICOFF_TARGET_MACHINE_SET(FLAGSP, MACHINE)
  54. #endif
  55. /* Default to COFF2 for file output */
  56. #ifndef TICOFF_DEFAULT_MAGIC
  57. #define TICOFF_DEFAULT_MAGIC TICOFF2MAGIC
  58. #endif
  59. /* This value is made available in the rare case where a bfd is unavailable */
  60. #ifndef OCTETS_PER_BYTE_POWER
  61. #error "OCTETS_PER_BYTE_POWER not defined for this CPU"
  62. #else
  63. #define OCTETS_PER_BYTE (1<<OCTETS_PER_BYTE_POWER)
  64. #endif
  65. /* default alignment is on a byte (not octet!) boundary */
  66. #ifndef COFF_DEFAULT_SECTION_ALIGNMENT_POWER
  67. #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0
  68. #endif
  69. /* TI COFF encodes the section alignment in the section header flags */
  70. #define COFF_ALIGN_IN_SECTION_HEADER 1
  71. #define COFF_ALIGN_IN_S_FLAGS 1
  72. /* requires a power-of-two argument */
  73. #define COFF_ENCODE_ALIGNMENT(S,X) ((S).s_flags |= (((unsigned)(X)&0xF)<<8))
  74. /* result is a power of two */
  75. #define COFF_DECODE_ALIGNMENT(X) (((X)>>8)&0xF)
  76. #define COFF0_P(ABFD) (bfd_coff_filhsz(ABFD) == FILHSZ_V0)
  77. #define COFF2_P(ABFD) (bfd_coff_scnhsz(ABFD) != SCNHSZ_V01)
  78. #define COFF0_BADMAG(x) ((x).f_magic != TICOFF0MAGIC)
  79. #define COFF1_BADMAG(x) ((x).f_magic != TICOFF1MAGIC || (x).f_target_id != TI_TARGET_ID)
  80. #define COFF2_BADMAG(x) ((x).f_magic != TICOFF2MAGIC || (x).f_target_id != TI_TARGET_ID)
  81. /* we need to read/write an extra field in the coff file header */
  82. #ifndef COFF_ADJUST_FILEHDR_IN_POST
  83. #define COFF_ADJUST_FILEHDR_IN_POST(abfd, src, dst) \
  84. do \
  85. { \
  86. if (!COFF0_P (abfd)) \
  87. ((struct internal_filehdr *)(dst))->f_target_id = \
  88. H_GET_16 (abfd, ((FILHDR *)(src))->f_target_id); \
  89. } \
  90. while (0)
  91. #endif
  92. #ifndef COFF_ADJUST_FILEHDR_OUT_POST
  93. #define COFF_ADJUST_FILEHDR_OUT_POST(abfd, src, dst) \
  94. do \
  95. { \
  96. if (!COFF0_P (abfd)) \
  97. H_PUT_16 (abfd, ((struct internal_filehdr *)(src))->f_target_id, \
  98. ((FILHDR *)(dst))->f_target_id); \
  99. } \
  100. while (0)
  101. #endif
  102. #define FILHDR struct external_filehdr
  103. #define FILHSZ 22
  104. #define FILHSZ_V0 20 /* COFF0 omits target_id field */
  105. /* File header flags */
  106. #define F_RELFLG (0x0001)
  107. #define F_EXEC (0x0002)
  108. #define F_LNNO (0x0004)
  109. #define F_VERS (0x0010) /* TMS320C4x code */
  110. /* F_LSYMS needs to be redefined in your source file */
  111. #define F_LSYMS_TICOFF (0x0010) /* normal COFF is 0x8 */
  112. #define F_10 0x00 /* file built for TMS320C1x devices */
  113. #define F_20 0x10 /* file built for TMS320C2x devices */
  114. #define F_25 0x20 /* file built for TMS320C2x/C5x devices */
  115. #define F_LENDIAN 0x0100 /* 16 bits/word, LSB first */
  116. #define F_SYMMERGE 0x1000 /* duplicate symbols were removed */
  117. /********************** OPTIONAL HEADER **********************/
  118. typedef struct
  119. {
  120. char magic[2]; /* type of file (0x108) */
  121. char vstamp[2]; /* version stamp */
  122. char tsize[4]; /* text size in bytes, padded to FW bdry*/
  123. char dsize[4]; /* initialized data " " */
  124. char bsize[4]; /* uninitialized data " " */
  125. char entry[4]; /* entry pt. */
  126. char text_start[4]; /* base of text used for this file */
  127. char data_start[4]; /* base of data used for this file */
  128. }
  129. AOUTHDR;
  130. #define AOUTHDRSZ 28
  131. #define AOUTSZ 28
  132. /********************** SECTION HEADER **********************/
  133. /* COFF0, COFF1 */
  134. struct external_scnhdr_v01 {
  135. char s_name[8]; /* section name */
  136. char s_paddr[4]; /* physical address, aliased s_nlib */
  137. char s_vaddr[4]; /* virtual address */
  138. char s_size[4]; /* section size (in WORDS) */
  139. char s_scnptr[4]; /* file ptr to raw data for section */
  140. char s_relptr[4]; /* file ptr to relocation */
  141. char s_lnnoptr[4]; /* file ptr to line numbers */
  142. char s_nreloc[2]; /* number of relocation entries */
  143. char s_nlnno[2]; /* number of line number entries*/
  144. char s_flags[2]; /* flags */
  145. char s_reserved[1]; /* reserved */
  146. char s_page[1]; /* section page number (LOAD) */
  147. };
  148. /* COFF2 */
  149. struct external_scnhdr {
  150. char s_name[8]; /* section name */
  151. char s_paddr[4]; /* physical address, aliased s_nlib */
  152. char s_vaddr[4]; /* virtual address */
  153. char s_size[4]; /* section size (in WORDS) */
  154. char s_scnptr[4]; /* file ptr to raw data for section */
  155. char s_relptr[4]; /* file ptr to relocation */
  156. char s_lnnoptr[4]; /* file ptr to line numbers */
  157. char s_nreloc[4]; /* number of relocation entries */
  158. char s_nlnno[4]; /* number of line number entries*/
  159. char s_flags[4]; /* flags */
  160. char s_reserved[2]; /* reserved */
  161. char s_page[2]; /* section page number (LOAD) */
  162. };
  163. /*
  164. * Special section flags
  165. */
  166. /* TI COFF defines these flags;
  167. STYP_CLINK: the section should be excluded from the final
  168. linker output if there are no references found to any symbol in the section
  169. STYP_BLOCK: the section should be blocked, i.e. if the section would cross
  170. a page boundary, it is started at a page boundary instead.
  171. TI COFF puts the section alignment power of two in the section flags
  172. e.g. 2**N is alignment, flags |= (N & 0xF) << 8
  173. */
  174. #define STYP_CLINK (0x4000)
  175. #define STYP_BLOCK (0x1000)
  176. #define STYP_ALIGN (0x0F00) /* TI COFF stores section alignment here */
  177. #define SCNHDR_V01 struct external_scnhdr_v01
  178. #define SCNHDR struct external_scnhdr
  179. #define SCNHSZ_V01 40 /* for v0 and v1 */
  180. #define SCNHSZ 48
  181. /* COFF2 changes the offsets and sizes of these fields
  182. Assume we're dealing with the COFF2 scnhdr structure, and adjust
  183. accordingly. Note: The GNU C versions of some of these macros
  184. are necessary in order to avoid compile time warnings triggered
  185. gcc's array bounds checking. The PUT_SCNHDR_PAGE macro also has
  186. the advantage on not evaluating LOC twice. */
  187. #define GET_SCNHDR_NRELOC(ABFD, LOC) \
  188. (COFF2_P (ABFD) ? H_GET_32 (ABFD, LOC) : H_GET_16 (ABFD, LOC))
  189. #define PUT_SCNHDR_NRELOC(ABFD, VAL, LOC) \
  190. (COFF2_P (ABFD) ? H_PUT_32 (ABFD, VAL, LOC) : H_PUT_16 (ABFD, VAL, LOC))
  191. #ifdef __GNUC__
  192. #define GET_SCNHDR_NLNNO(ABFD, LOC) \
  193. ({ \
  194. int nlnno; \
  195. char * ptr = (LOC); \
  196. if (COFF2_P (ABFD)) \
  197. nlnno = H_GET_32 (ABFD, ptr); \
  198. else \
  199. nlnno = H_GET_16 (ABFD, ptr - 2); \
  200. nlnno; \
  201. })
  202. #define PUT_SCNHDR_NLNNO(ABFD, VAL, LOC) \
  203. do \
  204. { \
  205. char * ptr = (LOC); \
  206. if (COFF2_P (ABFD)) \
  207. H_PUT_32 (ABFD, VAL, ptr); \
  208. else \
  209. H_PUT_16 (ABFD, VAL, ptr - 2); \
  210. } \
  211. while (0)
  212. #define GET_SCNHDR_FLAGS(ABFD, LOC) \
  213. ({ \
  214. int flags; \
  215. char * ptr = (LOC); \
  216. if (COFF2_P (ABFD)) \
  217. flags = H_GET_32 (ABFD, ptr); \
  218. else \
  219. flags = H_GET_16 (ABFD, ptr - 4); \
  220. flags; \
  221. })
  222. #define PUT_SCNHDR_FLAGS(ABFD, VAL, LOC) \
  223. do \
  224. { \
  225. char * ptr = (LOC); \
  226. if (COFF2_P (ABFD)) \
  227. H_PUT_32 (ABFD, VAL, ptr); \
  228. else \
  229. H_PUT_16 (ABFD, VAL, ptr - 4); \
  230. } \
  231. while (0)
  232. #define GET_SCNHDR_PAGE(ABFD, LOC) \
  233. ({ \
  234. unsigned page; \
  235. char * ptr = (LOC); \
  236. if (COFF2_P (ABFD)) \
  237. page = H_GET_16 (ABFD, ptr); \
  238. else \
  239. page = (unsigned) H_GET_8 (ABFD, ptr - 7); \
  240. page; \
  241. })
  242. /* On output, make sure that the "reserved" field is zero. */
  243. #define PUT_SCNHDR_PAGE(ABFD, VAL, LOC) \
  244. do \
  245. { \
  246. char * ptr = (LOC); \
  247. if (COFF2_P (ABFD)) \
  248. H_PUT_16 (ABFD, VAL, ptr); \
  249. else \
  250. { \
  251. H_PUT_8 (ABFD, VAL, ptr - 7); \
  252. H_PUT_8 (ABFD, 0, ptr - 8); \
  253. } \
  254. } \
  255. while (0)
  256. #else
  257. #define GET_SCNHDR_NLNNO(ABFD, LOC) \
  258. (COFF2_P (ABFD) ? H_GET_32 (ABFD, LOC) : H_GET_16 (ABFD, (LOC) - 2))
  259. #define PUT_SCNHDR_NLNNO(ABFD, VAL, LOC) \
  260. (COFF2_P (ABFD) ? H_PUT_32 (ABFD, VAL, LOC) : H_PUT_16 (ABFD, VAL, (LOC) - 2))
  261. #define GET_SCNHDR_FLAGS(ABFD, LOC) \
  262. (COFF2_P (ABFD) ? H_GET_32 (ABFD, LOC) : H_GET_16 (ABFD, (LOC) - 4))
  263. #define PUT_SCNHDR_FLAGS(ABFD, VAL, LOC) \
  264. (COFF2_P (ABFD) ? H_PUT_32 (ABFD, VAL, LOC) : H_PUT_16 (ABFD, VAL, (LOC) - 4))
  265. #define GET_SCNHDR_PAGE(ABFD, LOC) \
  266. (COFF2_P (ABFD) ? H_GET_16 (ABFD, LOC) : (unsigned) H_GET_8 (ABFD, (LOC) - 7))
  267. /* On output, make sure that the "reserved" field is zero. */
  268. #define PUT_SCNHDR_PAGE(ABFD, VAL, LOC) \
  269. (COFF2_P (ABFD) \
  270. ? H_PUT_16 (ABFD, VAL, LOC) \
  271. : H_PUT_8 (ABFD, VAL, (LOC) - 7), H_PUT_8 (ABFD, 0, (LOC) - 8))
  272. #endif
  273. /* TI COFF stores section size as number of bytes (address units, not octets),
  274. so adjust to be number of octets, which is what BFD expects */
  275. #define GET_SCNHDR_SIZE(ABFD, SZP) \
  276. (H_GET_32 (ABFD, SZP) * bfd_octets_per_byte (ABFD))
  277. #define PUT_SCNHDR_SIZE(ABFD, SZ, SZP) \
  278. H_PUT_32 (ABFD, (SZ) / bfd_octets_per_byte (ABFD), SZP)
  279. #define COFF_ADJUST_SCNHDR_IN_POST(ABFD, EXT, INT) \
  280. do \
  281. { \
  282. ((struct internal_scnhdr *)(INT))->s_page = \
  283. GET_SCNHDR_PAGE (ABFD, ((SCNHDR *)(EXT))->s_page); \
  284. } \
  285. while (0)
  286. /* The entire scnhdr may not be assigned.
  287. Ensure that everything is initialized. */
  288. #define COFF_ADJUST_SCNHDR_OUT_PRE(ABFD, INT, EXT) \
  289. do \
  290. { \
  291. memset((EXT), 0, sizeof (SCNHDR)); \
  292. } \
  293. while (0)
  294. /* The line number and reloc overflow checking in coff_swap_scnhdr_out in
  295. coffswap.h doesn't use PUT_X for s_nlnno and s_nreloc.
  296. Due to different sized v0/v1/v2 section headers, we have to re-write these
  297. fields.
  298. */
  299. #define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \
  300. do \
  301. { \
  302. PUT_SCNHDR_NLNNO (ABFD, ((struct internal_scnhdr *)(INT))->s_nlnno, \
  303. ((SCNHDR *)(EXT))->s_nlnno); \
  304. PUT_SCNHDR_NRELOC (ABFD, ((struct internal_scnhdr *)(INT))->s_nreloc,\
  305. ((SCNHDR *)(EXT))->s_nreloc); \
  306. PUT_SCNHDR_FLAGS (ABFD, ((struct internal_scnhdr *)(INT))->s_flags, \
  307. ((SCNHDR *)(EXT))->s_flags); \
  308. PUT_SCNHDR_PAGE (ABFD, ((struct internal_scnhdr *)(INT))->s_page, \
  309. ((SCNHDR *)(EXT))->s_page); \
  310. } \
  311. while (0)
  312. /*
  313. * names of "special" sections
  314. */
  315. #define _TEXT ".text"
  316. #define _DATA ".data"
  317. #define _BSS ".bss"
  318. #define _CINIT ".cinit" /* initialized C data */
  319. #define _SCONST ".const" /* constants */
  320. #define _SWITCH ".switch" /* switch tables */
  321. #define _STACK ".stack" /* C stack */
  322. #define _SYSMEM ".sysmem" /* used for malloc et al. syscalls */
  323. /********************** LINE NUMBERS **********************/
  324. /* 1 line number entry for every "breakpointable" source line in a section.
  325. * Line numbers are grouped on a per function basis; first entry in a function
  326. * grouping will have l_lnno = 0 and in place of physical address will be the
  327. * symbol table index of the function name.
  328. */
  329. struct external_lineno {
  330. union {
  331. char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
  332. char l_paddr[4]; /* (physical) address of line number */
  333. } l_addr;
  334. char l_lnno[2]; /* line number */
  335. };
  336. #define LINENO struct external_lineno
  337. #define LINESZ 6
  338. /********************** SYMBOLS **********************/
  339. /* NOTE: this is what a local label looks like in assembly source; what it
  340. looks like in COFF output is undefined */
  341. #define TICOFF_LOCAL_LABEL_P(NAME) \
  342. ((NAME[0] == '$' && NAME[1] >= '0' && NAME[1] <= '9' && NAME[2] == '\0') \
  343. || NAME[strlen(NAME)-1] == '?')
  344. #define E_SYMNMLEN 8 /* # characters in a symbol name */
  345. #define E_FILNMLEN 14 /* # characters in a file name */
  346. #define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
  347. struct external_syment
  348. {
  349. union {
  350. char e_name[E_SYMNMLEN];
  351. struct {
  352. char e_zeroes[4];
  353. char e_offset[4];
  354. } e;
  355. } e;
  356. char e_value[4];
  357. char e_scnum[2];
  358. char e_type[2];
  359. char e_sclass[1];
  360. char e_numaux[1];
  361. };
  362. #define N_BTMASK (017)
  363. #define N_TMASK (060)
  364. #define N_BTSHFT (4)
  365. #define N_TSHIFT (2)
  366. union external_auxent {
  367. struct {
  368. char x_tagndx[4]; /* str, un, or enum tag indx */
  369. union {
  370. struct {
  371. char x_lnno[2]; /* declaration line number */
  372. char x_size[2]; /* str/union/array size */
  373. } x_lnsz;
  374. char x_fsize[4]; /* size of function */
  375. } x_misc;
  376. union {
  377. struct { /* if ISFCN, tag, or .bb */
  378. char x_lnnoptr[4]; /* ptr to fcn line # */
  379. char x_endndx[4]; /* entry ndx past block end */
  380. } x_fcn;
  381. struct { /* if ISARY, up to 4 dimen. */
  382. char x_dimen[E_DIMNUM][2];
  383. } x_ary;
  384. } x_fcnary;
  385. char x_tvndx[2]; /* tv index */
  386. } x_sym;
  387. union {
  388. char x_fname[E_FILNMLEN];
  389. struct {
  390. char x_zeroes[4];
  391. char x_offset[4];
  392. } x_n;
  393. } x_file;
  394. struct {
  395. char x_scnlen[4]; /* section length */
  396. char x_nreloc[2]; /* # relocation entries */
  397. char x_nlinno[2]; /* # line numbers */
  398. } x_scn;
  399. struct {
  400. char x_tvfill[4]; /* tv fill value */
  401. char x_tvlen[2]; /* length of .tv */
  402. char x_tvran[2][2]; /* tv range */
  403. } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
  404. };
  405. #define SYMENT struct external_syment
  406. #define SYMESZ 18
  407. #define AUXENT union external_auxent
  408. #define AUXESZ 18
  409. /* section lengths are in target bytes (not host bytes) */
  410. #define GET_SCN_SCNLEN(ABFD, EXT) \
  411. (H_GET_32 (ABFD, (EXT)->x_scn.x_scnlen) * bfd_octets_per_byte (ABFD))
  412. #define PUT_SCN_SCNLEN(ABFD, INT, EXT) \
  413. H_PUT_32 (ABFD, (INT) / bfd_octets_per_byte (ABFD), (EXT)->x_scn.x_scnlen)
  414. /* lnsz size is in bits in COFF file, in bytes in BFD */
  415. #define GET_LNSZ_SIZE(abfd, ext) \
  416. (H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size) / (in_class != C_FIELD ? 8 : 1))
  417. #define PUT_LNSZ_SIZE(abfd, in, ext) \
  418. H_PUT_16 (abfd, ((in_class != C_FIELD) ? (in) * 8 : (in)), \
  419. ext->x_sym.x_misc.x_lnsz.x_size)
  420. /* TI COFF stores offsets for MOS and MOU in bits; BFD expects bytes
  421. Also put the load page flag of the section into the symbol value if it's an
  422. address. */
  423. #ifndef NEEDS_PAGE
  424. #define NEEDS_PAGE(X) 0
  425. #define PAGE_MASK 0
  426. #endif
  427. #define COFF_ADJUST_SYM_IN_POST(ABFD, EXT, INT) \
  428. do \
  429. { \
  430. struct internal_syment *dst = (struct internal_syment *)(INT); \
  431. if (dst->n_sclass == C_MOS || dst->n_sclass == C_MOU) \
  432. dst->n_value /= 8; \
  433. else if (NEEDS_PAGE (dst->n_sclass)) { \
  434. asection *scn = coff_section_from_bfd_index (abfd, dst->n_scnum); \
  435. dst->n_value |= (scn->lma & PAGE_MASK); \
  436. } \
  437. } \
  438. while (0)
  439. #define COFF_ADJUST_SYM_OUT_POST(ABFD, INT, EXT) \
  440. do \
  441. { \
  442. struct internal_syment *src = (struct internal_syment *)(INT); \
  443. SYMENT *dst = (SYMENT *)(EXT); \
  444. if (src->n_sclass == C_MOU || src->n_sclass == C_MOS) \
  445. H_PUT_32 (abfd, src->n_value * 8, dst->e_value); \
  446. else if (NEEDS_PAGE (src->n_sclass)) { \
  447. H_PUT_32 (abfd, src->n_value &= ~PAGE_MASK, dst->e_value); \
  448. } \
  449. } \
  450. while (0)
  451. /* Detect section-relative absolute symbols so they get flagged with a sym
  452. index of -1.
  453. */
  454. #define SECTION_RELATIVE_ABSOLUTE_SYMBOL_P(RELOC, SECT) \
  455. ((*(RELOC)->sym_ptr_ptr)->section->output_section == (SECT) \
  456. && (RELOC)->howto->name[0] == 'A')
  457. /********************** RELOCATION DIRECTIVES **********************/
  458. struct external_reloc_v0
  459. {
  460. char r_vaddr[4];
  461. char r_symndx[2];
  462. char r_reserved[2];
  463. char r_type[2];
  464. };
  465. struct external_reloc
  466. {
  467. char r_vaddr[4];
  468. char r_symndx[4];
  469. char r_reserved[2]; /* extended pmad byte for COFF2 */
  470. char r_type[2];
  471. };
  472. #define RELOC struct external_reloc
  473. #define RELSZ_V0 10 /* FIXME -- coffcode.h needs fixing */
  474. #define RELSZ 12 /* for COFF1/2 */
  475. #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
  476. do memset (dst->r_reserved, 0, sizeof (dst->r_reserved)); while (0)
  477. /* various relocation types. */
  478. #define R_ABS 0x0000 /* no relocation */
  479. #define R_REL13 0x002A /* 13-bit direct reference (???) */
  480. #define R_PARTLS7 0x0028 /* 7 LSBs of an address */
  481. #define R_PARTMS9 0x0029 /* 9MSBs of an address */
  482. #define R_EXTWORD 0x002B /* 23-bit direct reference */
  483. #define R_EXTWORD16 0x002C /* 16-bit direct reference to 23-bit addr*/
  484. #define R_EXTWORDMS7 0x002D /* upper 7 bits of 23-bit address */
  485. #endif /* COFF_TI_H */