coff-tic80.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. /* BFD back-end for Texas Instruments TMS320C80 Multimedia Video Processor (MVP).
  2. Copyright (C) 1996-2015 Free Software Foundation, Inc.
  3. Written by Fred Fish (fnf@cygnus.com)
  4. There is nothing new under the sun. This file draws a lot on other
  5. coff files.
  6. This file is part of BFD, the Binary File Descriptor library.
  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 3 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, 51 Franklin Street - Fifth Floor,
  18. Boston, MA 02110-1301, USA. */
  19. #include "sysdep.h"
  20. #include "bfd.h"
  21. #include "bfdlink.h"
  22. #include "libbfd.h"
  23. #ifdef _CONST
  24. /* Newlib-based hosts define _CONST as a STDC-safe alias for const,
  25. but to the tic80 toolchain it means something altogether different.
  26. Since sysdep.h will have pulled in stdio.h and hence _ansi.h which
  27. contains this definition, we must undef it before including the
  28. tic80-specific definition. */
  29. #undef _CONST
  30. #endif /* _CONST */
  31. #include "coff/tic80.h"
  32. #include "coff/internal.h"
  33. #include "libcoff.h"
  34. #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
  35. #define COFF_ALIGN_IN_SECTION_HEADER 1
  36. #define COFF_ALIGN_IN_SFLAGS 1
  37. #define GET_SCNHDR_FLAGS H_GET_16
  38. #define PUT_SCNHDR_FLAGS H_PUT_16
  39. static bfd_reloc_status_type ppbase_reloc
  40. (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
  41. static bfd_reloc_status_type glob15_reloc
  42. (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
  43. static bfd_reloc_status_type glob16_reloc
  44. (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
  45. static bfd_reloc_status_type local16_reloc
  46. (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
  47. static reloc_howto_type tic80_howto_table[] =
  48. {
  49. HOWTO (R_RELLONG, /* type */
  50. 0, /* rightshift */
  51. 2, /* size (0 = byte, 1 = short, 2 = long) */
  52. 32, /* bitsize */
  53. FALSE, /* pc_relative */
  54. 0, /* bitpos */
  55. complain_overflow_bitfield, /* complain_on_overflow */
  56. NULL, /* special_function */
  57. "RELLONG", /* name */
  58. TRUE, /* partial_inplace */
  59. 0xffffffff, /* src_mask */
  60. 0xffffffff, /* dst_mask */
  61. FALSE), /* pcrel_offset */
  62. HOWTO (R_MPPCR, /* type */
  63. 2, /* rightshift */
  64. 2, /* size (0 = byte, 1 = short, 2 = long) */
  65. 32, /* bitsize */
  66. TRUE, /* pc_relative */
  67. 0, /* bitpos */
  68. complain_overflow_signed, /* complain_on_overflow */
  69. NULL, /* special_function */
  70. "MPPCR", /* name */
  71. TRUE, /* partial_inplace */
  72. 0xffffffff, /* src_mask */
  73. 0xffffffff, /* dst_mask */
  74. TRUE), /* pcrel_offset */
  75. HOWTO (R_ABS, /* type */
  76. 0, /* rightshift */
  77. 2, /* size (0 = byte, 1 = short, 2 = long) */
  78. 32, /* bitsize */
  79. FALSE, /* pc_relative */
  80. 0, /* bitpos */
  81. complain_overflow_bitfield, /* complain_on_overflow */
  82. NULL, /* special_function */
  83. "ABS", /* name */
  84. TRUE, /* partial_inplace */
  85. 0xffffffff, /* src_mask */
  86. 0xffffffff, /* dst_mask */
  87. FALSE), /* pcrel_offset */
  88. HOWTO (R_PPBASE, /* type */
  89. 0, /* rightshift */
  90. 2, /* size (0 = byte, 1 = short, 2 = long) */
  91. 32, /* bitsize */
  92. FALSE, /* pc_relative */
  93. 0, /* bitpos */
  94. complain_overflow_dont, /* complain_on_overflow */
  95. ppbase_reloc, /* special_function */
  96. "PPBASE", /* name */
  97. TRUE, /* partial_inplace */
  98. 0xffffffff, /* src_mask */
  99. 0xffffffff, /* dst_mask */
  100. FALSE), /* pcrel_offset */
  101. HOWTO (R_PPLBASE, /* type */
  102. 0, /* rightshift */
  103. 2, /* size (0 = byte, 1 = short, 2 = long) */
  104. 32, /* bitsize */
  105. FALSE, /* pc_relative */
  106. 0, /* bitpos */
  107. complain_overflow_dont, /* complain_on_overflow */
  108. ppbase_reloc, /* special_function */
  109. "PPLBASE", /* name */
  110. TRUE, /* partial_inplace */
  111. 0xffffffff, /* src_mask */
  112. 0xffffffff, /* dst_mask */
  113. FALSE), /* pcrel_offset */
  114. HOWTO (R_PP15, /* type */
  115. 0, /* rightshift */
  116. 2, /* size (0 = byte, 1 = short, 2 = long) */
  117. 15, /* bitsize */
  118. FALSE, /* pc_relative */
  119. 6, /* bitpos */
  120. complain_overflow_dont, /* complain_on_overflow */
  121. glob15_reloc, /* special_function */
  122. "PP15", /* name */
  123. TRUE, /* partial_inplace */
  124. 0x1ffc0, /* src_mask */
  125. 0x1ffc0, /* dst_mask */
  126. FALSE), /* pcrel_offset */
  127. HOWTO (R_PP15W, /* type */
  128. 2, /* rightshift */
  129. 2, /* size (0 = byte, 1 = short, 2 = long) */
  130. 15, /* bitsize */
  131. FALSE, /* pc_relative */
  132. 6, /* bitpos */
  133. complain_overflow_dont, /* complain_on_overflow */
  134. glob15_reloc, /* special_function */
  135. "PP15W", /* name */
  136. TRUE, /* partial_inplace */
  137. 0x1ffc0, /* src_mask */
  138. 0x1ffc0, /* dst_mask */
  139. FALSE), /* pcrel_offset */
  140. HOWTO (R_PP15H, /* type */
  141. 1, /* rightshift */
  142. 2, /* size (0 = byte, 1 = short, 2 = long) */
  143. 15, /* bitsize */
  144. FALSE, /* pc_relative */
  145. 6, /* bitpos */
  146. complain_overflow_dont, /* complain_on_overflow */
  147. glob15_reloc, /* special_function */
  148. "PP15H", /* name */
  149. TRUE, /* partial_inplace */
  150. 0x1ffc0, /* src_mask */
  151. 0x1ffc0, /* dst_mask */
  152. FALSE), /* pcrel_offset */
  153. HOWTO (R_PP16B, /* type */
  154. 0, /* rightshift */
  155. 2, /* size (0 = byte, 1 = short, 2 = long) */
  156. 16, /* bitsize */
  157. FALSE, /* pc_relative */
  158. 6, /* bitpos */
  159. complain_overflow_dont, /* complain_on_overflow */
  160. glob16_reloc, /* special_function */
  161. "PP16B", /* name */
  162. TRUE, /* partial_inplace */
  163. 0x3ffc0, /* src_mask */
  164. 0x3ffc0, /* dst_mask */
  165. FALSE), /* pcrel_offset */
  166. HOWTO (R_PPL15, /* type */
  167. 0, /* rightshift */
  168. 2, /* size (0 = byte, 1 = short, 2 = long) */
  169. 15, /* bitsize */
  170. FALSE, /* pc_relative */
  171. 0, /* bitpos */
  172. complain_overflow_dont, /* complain_on_overflow */
  173. NULL, /* special_function */
  174. "PPL15", /* name */
  175. TRUE, /* partial_inplace */
  176. 0x7fff, /* src_mask */
  177. 0x7fff, /* dst_mask */
  178. FALSE), /* pcrel_offset */
  179. HOWTO (R_PPL15W, /* type */
  180. 2, /* rightshift */
  181. 2, /* size (0 = byte, 1 = short, 2 = long) */
  182. 15, /* bitsize */
  183. FALSE, /* pc_relative */
  184. 0, /* bitpos */
  185. complain_overflow_dont, /* complain_on_overflow */
  186. NULL, /* special_function */
  187. "PPL15W", /* name */
  188. TRUE, /* partial_inplace */
  189. 0x7fff, /* src_mask */
  190. 0x7fff, /* dst_mask */
  191. FALSE), /* pcrel_offset */
  192. HOWTO (R_PPL15H, /* type */
  193. 1, /* rightshift */
  194. 2, /* size (0 = byte, 1 = short, 2 = long) */
  195. 15, /* bitsize */
  196. FALSE, /* pc_relative */
  197. 0, /* bitpos */
  198. complain_overflow_dont, /* complain_on_overflow */
  199. NULL, /* special_function */
  200. "PPL15H", /* name */
  201. TRUE, /* partial_inplace */
  202. 0x7fff, /* src_mask */
  203. 0x7fff, /* dst_mask */
  204. FALSE), /* pcrel_offset */
  205. HOWTO (R_PPL16B, /* type */
  206. 0, /* rightshift */
  207. 2, /* size (0 = byte, 1 = short, 2 = long) */
  208. 16, /* bitsize */
  209. FALSE, /* pc_relative */
  210. 0, /* bitpos */
  211. complain_overflow_dont, /* complain_on_overflow */
  212. local16_reloc, /* special_function */
  213. "PPL16B", /* name */
  214. TRUE, /* partial_inplace */
  215. 0xffff, /* src_mask */
  216. 0xffff, /* dst_mask */
  217. FALSE), /* pcrel_offset */
  218. HOWTO (R_PPN15, /* type */
  219. 0, /* rightshift */
  220. -2, /* size (0 = byte, 1 = short, 2 = long) */
  221. 15, /* bitsize */
  222. FALSE, /* pc_relative */
  223. 6, /* bitpos */
  224. complain_overflow_dont, /* complain_on_overflow */
  225. glob15_reloc, /* special_function */
  226. "PPN15", /* name */
  227. TRUE, /* partial_inplace */
  228. 0x1ffc0, /* src_mask */
  229. 0x1ffc0, /* dst_mask */
  230. FALSE), /* pcrel_offset */
  231. HOWTO (R_PPN15W, /* type */
  232. 2, /* rightshift */
  233. -2, /* size (0 = byte, 1 = short, 2 = long) */
  234. 15, /* bitsize */
  235. FALSE, /* pc_relative */
  236. 6, /* bitpos */
  237. complain_overflow_dont, /* complain_on_overflow */
  238. glob15_reloc, /* special_function */
  239. "PPN15W", /* name */
  240. TRUE, /* partial_inplace */
  241. 0x1ffc0, /* src_mask */
  242. 0x1ffc0, /* dst_mask */
  243. FALSE), /* pcrel_offset */
  244. HOWTO (R_PPN15H, /* type */
  245. 1, /* rightshift */
  246. -2, /* size (0 = byte, 1 = short, 2 = long) */
  247. 15, /* bitsize */
  248. FALSE, /* pc_relative */
  249. 6, /* bitpos */
  250. complain_overflow_dont, /* complain_on_overflow */
  251. glob15_reloc, /* special_function */
  252. "PPN15H", /* name */
  253. TRUE, /* partial_inplace */
  254. 0x1ffc0, /* src_mask */
  255. 0x1ffc0, /* dst_mask */
  256. FALSE), /* pcrel_offset */
  257. HOWTO (R_PPN16B, /* type */
  258. 0, /* rightshift */
  259. -2, /* size (0 = byte, 1 = short, 2 = long) */
  260. 16, /* bitsize */
  261. FALSE, /* pc_relative */
  262. 6, /* bitpos */
  263. complain_overflow_dont, /* complain_on_overflow */
  264. glob16_reloc, /* special_function */
  265. "PPN16B", /* name */
  266. TRUE, /* partial_inplace */
  267. 0x3ffc0, /* src_mask */
  268. 0x3ffc0, /* dst_mask */
  269. FALSE), /* pcrel_offset */
  270. HOWTO (R_PPLN15, /* type */
  271. 0, /* rightshift */
  272. -2, /* size (0 = byte, 1 = short, 2 = long) */
  273. 15, /* bitsize */
  274. FALSE, /* pc_relative */
  275. 0, /* bitpos */
  276. complain_overflow_dont, /* complain_on_overflow */
  277. NULL, /* special_function */
  278. "PPLN15", /* name */
  279. TRUE, /* partial_inplace */
  280. 0x7fff, /* src_mask */
  281. 0x7fff, /* dst_mask */
  282. FALSE), /* pcrel_offset */
  283. HOWTO (R_PPLN15W, /* type */
  284. 2, /* rightshift */
  285. -2, /* size (0 = byte, 1 = short, 2 = long) */
  286. 15, /* bitsize */
  287. FALSE, /* pc_relative */
  288. 0, /* bitpos */
  289. complain_overflow_dont, /* complain_on_overflow */
  290. NULL, /* special_function */
  291. "PPLN15W", /* name */
  292. TRUE, /* partial_inplace */
  293. 0x7fff, /* src_mask */
  294. 0x7fff, /* dst_mask */
  295. FALSE), /* pcrel_offset */
  296. HOWTO (R_PPLN15H, /* type */
  297. 1, /* rightshift */
  298. -2, /* size (0 = byte, 1 = short, 2 = long) */
  299. 15, /* bitsize */
  300. FALSE, /* pc_relative */
  301. 0, /* bitpos */
  302. complain_overflow_dont, /* complain_on_overflow */
  303. NULL, /* special_function */
  304. "PPLN15H", /* name */
  305. TRUE, /* partial_inplace */
  306. 0x7fff, /* src_mask */
  307. 0x7fff, /* dst_mask */
  308. FALSE), /* pcrel_offset */
  309. HOWTO (R_PPLN16B, /* type */
  310. 0, /* rightshift */
  311. -2, /* size (0 = byte, 1 = short, 2 = long) */
  312. 15, /* bitsize */
  313. FALSE, /* pc_relative */
  314. 0, /* bitpos */
  315. complain_overflow_dont, /* complain_on_overflow */
  316. local16_reloc, /* special_function */
  317. "PPLN16B", /* name */
  318. TRUE, /* partial_inplace */
  319. 0xffff, /* src_mask */
  320. 0xffff, /* dst_mask */
  321. FALSE) /* pcrel_offset */
  322. };
  323. /* Special relocation functions, used when the output file is not
  324. itself a COFF TIc80 file. */
  325. /* This special function is used for the base address type
  326. relocations. */
  327. static bfd_reloc_status_type
  328. ppbase_reloc (bfd *abfd ATTRIBUTE_UNUSED,
  329. arelent *reloc_entry ATTRIBUTE_UNUSED,
  330. asymbol *symbol_in ATTRIBUTE_UNUSED,
  331. void * data ATTRIBUTE_UNUSED,
  332. asection *input_section ATTRIBUTE_UNUSED,
  333. bfd *output_bfd ATTRIBUTE_UNUSED,
  334. char **error_message ATTRIBUTE_UNUSED)
  335. {
  336. /* FIXME. */
  337. abort ();
  338. }
  339. /* This special function is used for the global 15 bit relocations. */
  340. static bfd_reloc_status_type
  341. glob15_reloc (bfd *abfd ATTRIBUTE_UNUSED,
  342. arelent *reloc_entry ATTRIBUTE_UNUSED,
  343. asymbol *symbol_in ATTRIBUTE_UNUSED,
  344. void * data ATTRIBUTE_UNUSED,
  345. asection *input_section ATTRIBUTE_UNUSED,
  346. bfd *output_bfd ATTRIBUTE_UNUSED,
  347. char **error_message ATTRIBUTE_UNUSED)
  348. {
  349. /* FIXME. */
  350. abort ();
  351. }
  352. /* This special function is used for the global 16 bit relocations. */
  353. static bfd_reloc_status_type
  354. glob16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
  355. arelent *reloc_entry ATTRIBUTE_UNUSED,
  356. asymbol *symbol_in ATTRIBUTE_UNUSED,
  357. void * data ATTRIBUTE_UNUSED,
  358. asection *input_section ATTRIBUTE_UNUSED,
  359. bfd *output_bfd ATTRIBUTE_UNUSED,
  360. char **error_message ATTRIBUTE_UNUSED)
  361. {
  362. /* FIXME. */
  363. abort ();
  364. }
  365. /* This special function is used for the local 16 bit relocations. */
  366. static bfd_reloc_status_type
  367. local16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
  368. arelent *reloc_entry ATTRIBUTE_UNUSED,
  369. asymbol *symbol_in ATTRIBUTE_UNUSED,
  370. void * data ATTRIBUTE_UNUSED,
  371. asection *input_section ATTRIBUTE_UNUSED,
  372. bfd *output_bfd ATTRIBUTE_UNUSED,
  373. char **error_message ATTRIBUTE_UNUSED)
  374. {
  375. /* FIXME. */
  376. abort ();
  377. }
  378. /* Code to turn an external r_type into a pointer to an entry in the howto_table.
  379. If passed an r_type we don't recognize the abort rather than silently failing
  380. to generate an output file. */
  381. static void
  382. rtype2howto (arelent *cache_ptr, struct internal_reloc *dst)
  383. {
  384. unsigned int i;
  385. for (i = 0; i < sizeof tic80_howto_table / sizeof tic80_howto_table[0]; i++)
  386. {
  387. if (tic80_howto_table[i].type == dst->r_type)
  388. {
  389. cache_ptr->howto = tic80_howto_table + i;
  390. return;
  391. }
  392. }
  393. (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"),
  394. (unsigned int) dst->r_type);
  395. cache_ptr->howto = tic80_howto_table + 0;
  396. }
  397. #define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
  398. #define coff_rtype_to_howto coff_tic80_rtype_to_howto
  399. static reloc_howto_type *
  400. coff_tic80_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
  401. asection *sec,
  402. struct internal_reloc *rel,
  403. struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
  404. struct internal_syment *sym ATTRIBUTE_UNUSED,
  405. bfd_vma *addendp)
  406. {
  407. arelent genrel;
  408. if (rel -> r_symndx == -1 && addendp != NULL)
  409. {
  410. /* This is a TI "internal relocation", which means that the relocation
  411. amount is the amount by which the current section is being relocated
  412. in the output section. */
  413. *addendp = (sec -> output_section -> vma + sec -> output_offset) - sec -> vma;
  414. }
  415. RTYPE2HOWTO (&genrel, rel);
  416. return genrel.howto;
  417. }
  418. #ifndef BADMAG
  419. #define BADMAG(x) TIC80BADMAG(x)
  420. #endif
  421. #define coff_relocate_section coff_tic80_relocate_section
  422. /* We need a special relocation routine to handle the PP relocs. Most
  423. of this is a copy of _bfd_coff_generic_relocate_section. */
  424. static bfd_boolean
  425. coff_tic80_relocate_section (bfd *output_bfd,
  426. struct bfd_link_info *info,
  427. bfd *input_bfd,
  428. asection *input_section,
  429. bfd_byte *contents,
  430. struct internal_reloc *relocs,
  431. struct internal_syment *syms,
  432. asection **sections)
  433. {
  434. struct internal_reloc *rel;
  435. struct internal_reloc *relend;
  436. rel = relocs;
  437. relend = rel + input_section->reloc_count;
  438. for (; rel < relend; rel++)
  439. {
  440. long symndx;
  441. struct coff_link_hash_entry *h;
  442. struct internal_syment *sym;
  443. bfd_vma addend;
  444. bfd_vma val;
  445. reloc_howto_type *howto;
  446. bfd_reloc_status_type rstat;
  447. bfd_vma addr;
  448. symndx = rel->r_symndx;
  449. if (symndx == -1)
  450. {
  451. h = NULL;
  452. sym = NULL;
  453. }
  454. else
  455. {
  456. h = obj_coff_sym_hashes (input_bfd)[symndx];
  457. sym = syms + symndx;
  458. }
  459. /* COFF treats common symbols in one of two ways. Either the
  460. size of the symbol is included in the section contents, or it
  461. is not. We assume that the size is not included, and force
  462. the rtype_to_howto function to adjust the addend as needed. */
  463. if (sym != NULL && sym->n_scnum != 0)
  464. addend = - sym->n_value;
  465. else
  466. addend = 0;
  467. howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
  468. sym, &addend);
  469. if (howto == NULL)
  470. return FALSE;
  471. val = 0;
  472. if (h == NULL)
  473. {
  474. asection *sec;
  475. if (symndx == -1)
  476. {
  477. sec = bfd_abs_section_ptr;
  478. val = 0;
  479. }
  480. else
  481. {
  482. sec = sections[symndx];
  483. val = (sec->output_section->vma
  484. + sec->output_offset
  485. + sym->n_value);
  486. if (! obj_pe (output_bfd))
  487. val -= sec->vma;
  488. }
  489. }
  490. else
  491. {
  492. if (h->root.type == bfd_link_hash_defined
  493. || h->root.type == bfd_link_hash_defweak)
  494. {
  495. asection *sec;
  496. sec = h->root.u.def.section;
  497. val = (h->root.u.def.value
  498. + sec->output_section->vma
  499. + sec->output_offset);
  500. }
  501. else if (! bfd_link_relocatable (info))
  502. {
  503. if (! ((*info->callbacks->undefined_symbol)
  504. (info, h->root.root.string, input_bfd, input_section,
  505. rel->r_vaddr - input_section->vma, TRUE)))
  506. return FALSE;
  507. }
  508. }
  509. addr = rel->r_vaddr - input_section->vma;
  510. /* FIXME: This code assumes little endian, but the PP can
  511. apparently be bi-endian. I don't know if the bi-endianness
  512. applies to the instruction set or just to the data. */
  513. switch (howto->type)
  514. {
  515. default:
  516. case R_ABS:
  517. case R_RELLONGX:
  518. case R_PPL15:
  519. case R_PPL15W:
  520. case R_PPL15H:
  521. case R_PPLN15:
  522. case R_PPLN15W:
  523. case R_PPLN15H:
  524. rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
  525. contents, addr, val, addend);
  526. break;
  527. case R_PP15:
  528. case R_PP15W:
  529. case R_PP15H:
  530. case R_PPN15:
  531. case R_PPN15W:
  532. case R_PPN15H:
  533. /* Offset the address so that we can use 4 byte relocations. */
  534. rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
  535. contents + 2, addr, val, addend);
  536. break;
  537. case R_PP16B:
  538. case R_PPN16B:
  539. {
  540. /* The most significant bit is stored in bit 6. */
  541. bfd_byte hold;
  542. hold = contents[addr + 4];
  543. contents[addr + 4] &=~ 0x20;
  544. contents[addr + 4] |= (contents[addr] >> 1) & 0x20;
  545. rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
  546. contents + 2, addr,
  547. val, addend);
  548. contents[addr] &=~ 0x40;
  549. contents[addr] |= (contents[addr + 4] << 1) & 0x40;
  550. contents[addr + 4] &=~ 0x20;
  551. contents[addr + 4] |= hold & 0x20;
  552. break;
  553. }
  554. case R_PPL16B:
  555. case R_PPLN16B:
  556. {
  557. /* The most significant bit is stored in bit 28. */
  558. bfd_byte hold;
  559. hold = contents[addr + 1];
  560. contents[addr + 1] &=~ 0x80;
  561. contents[addr + 1] |= (contents[addr + 3] << 3) & 0x80;
  562. rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
  563. contents, addr,
  564. val, addend);
  565. contents[addr + 3] &= ~0x10;
  566. contents[addr + 3] |= (contents[addr + 1] >> 3) & 0x10;
  567. contents[addr + 1] &=~ 0x80;
  568. contents[addr + 1] |= hold & 0x80;
  569. break;
  570. }
  571. case R_PPBASE:
  572. /* Parameter RAM is from 0x1000000 to 0x1000800. */
  573. contents[addr] &=~ 0x3;
  574. if (val >= 0x1000000 && val < 0x1000800)
  575. contents[addr] |= 0x3;
  576. else
  577. contents[addr] |= 0x2;
  578. rstat = bfd_reloc_ok;
  579. break;
  580. case R_PPLBASE:
  581. /* Parameter RAM is from 0x1000000 to 0x1000800. */
  582. contents[addr + 2] &= ~0xc0;
  583. if (val >= 0x1000000 && val < 0x1000800)
  584. contents[addr + 2] |= 0xc0;
  585. else
  586. contents[addr + 2] |= 0x80;
  587. rstat = bfd_reloc_ok;
  588. break;
  589. }
  590. switch (rstat)
  591. {
  592. default:
  593. abort ();
  594. case bfd_reloc_ok:
  595. break;
  596. case bfd_reloc_outofrange:
  597. (*_bfd_error_handler)
  598. (_("%B: bad reloc address 0x%lx in section `%A'"),
  599. input_bfd, input_section, (unsigned long) rel->r_vaddr);
  600. return FALSE;
  601. case bfd_reloc_overflow:
  602. {
  603. const char *name;
  604. char buf[SYMNMLEN + 1];
  605. if (symndx == -1)
  606. name = "*ABS*";
  607. else if (h != NULL)
  608. name = NULL;
  609. else
  610. {
  611. name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
  612. if (name == NULL)
  613. return FALSE;
  614. }
  615. if (! ((*info->callbacks->reloc_overflow)
  616. (info, (h ? &h->root : NULL), name, howto->name,
  617. (bfd_vma) 0, input_bfd, input_section,
  618. rel->r_vaddr - input_section->vma)))
  619. return FALSE;
  620. }
  621. }
  622. }
  623. return TRUE;
  624. }
  625. #define TIC80COFF 1 /* Customize coffcode.h */
  626. #undef C_AUTOARG /* Clashes with TIc80's C_UEXT */
  627. #undef C_LASTENT /* Clashes with TIc80's C_STATLAB */
  628. #ifndef bfd_pe_print_pdata
  629. #define bfd_pe_print_pdata NULL
  630. #endif
  631. #include "coffcode.h"
  632. CREATE_LITTLE_COFF_TARGET_VEC (tic80_coff_vec, "coff-tic80", D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE)