elf32-arc.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697
  1. /* ARC-specific support for 32-bit ELF
  2. Copyright (C) 1994-2015 Free Software Foundation, Inc.
  3. Contributed by Cupertino Miranda (cmiranda@synopsys.com).
  4. This file is part of BFD, the Binary File Descriptor library.
  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. #include "sysdep.h"
  18. #include "bfd.h"
  19. #include "libbfd.h"
  20. #include "elf-bfd.h"
  21. #include "elf/arc.h"
  22. #include "libiberty.h"
  23. #include "opcode/arc-func.h"
  24. #define ARC_DEBUG(...)
  25. #define DEBUG(...) printf (__ARGV__)
  26. #define DEBUG_ARC_RELOC(A)
  27. struct arc_local_data
  28. {
  29. bfd_vma sdata_begin_symbol_vma;
  30. asection * sdata_output_section;
  31. bfd_vma got_symbol_vma;
  32. };
  33. struct arc_local_data global_arc_data =
  34. {
  35. .sdata_begin_symbol_vma = 0,
  36. .sdata_output_section = NULL,
  37. .got_symbol_vma = 0,
  38. };
  39. struct dynamic_sections
  40. {
  41. bfd_boolean initialized;
  42. asection * sgot;
  43. asection * srelgot;
  44. asection * sgotplt;
  45. asection * sdyn;
  46. asection * splt;
  47. asection * srelplt;
  48. };
  49. static struct dynamic_sections
  50. arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info);
  51. enum dyn_section_types
  52. {
  53. got = 0,
  54. relgot,
  55. gotplt,
  56. dyn,
  57. plt,
  58. relplt,
  59. DYN_SECTION_TYPES_END
  60. };
  61. const char * dyn_section_names[DYN_SECTION_TYPES_END] =
  62. {
  63. ".got",
  64. ".rela.got",
  65. ".got.plt",
  66. ".dynamic",
  67. ".plt",
  68. ".rela.plt"
  69. };
  70. /* The default symbols representing the init and fini dyn values.
  71. TODO: Check what is the relation of those strings with arclinux.em
  72. and DT_INIT. */
  73. #define INIT_SYM_STRING "_init"
  74. #define FINI_SYM_STRING "_fini"
  75. char * init_str = INIT_SYM_STRING;
  76. char * fini_str = FINI_SYM_STRING;
  77. #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
  78. case VALUE: \
  79. return #TYPE; \
  80. break;
  81. static ATTRIBUTE_UNUSED const char *
  82. reloc_type_to_name (unsigned int type)
  83. {
  84. switch (type)
  85. {
  86. #include "elf/arc-reloc.def"
  87. default:
  88. return "UNKNOWN";
  89. break;
  90. }
  91. }
  92. #undef ARC_RELOC_HOWTO
  93. /* Try to minimize the amount of space occupied by relocation tables
  94. on the ROM (not that the ROM won't be swamped by other ELF overhead). */
  95. #define USE_REL 1
  96. static ATTRIBUTE_UNUSED bfd_boolean
  97. is_reloc_PC_relative (reloc_howto_type *howto)
  98. {
  99. return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
  100. }
  101. static bfd_boolean
  102. is_reloc_SDA_relative (reloc_howto_type *howto)
  103. {
  104. return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
  105. }
  106. static bfd_boolean
  107. is_reloc_for_GOT (reloc_howto_type * howto)
  108. {
  109. return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
  110. }
  111. static bfd_boolean
  112. is_reloc_for_PLT (reloc_howto_type * howto)
  113. {
  114. return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
  115. }
  116. #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
  117. #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
  118. #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
  119. #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
  120. static long
  121. arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section)
  122. {
  123. long insn = bfd_get_32 (abfd, loc);
  124. if (!bfd_big_endian (abfd)
  125. && input_section
  126. && (input_section->flags & SEC_CODE))
  127. insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
  128. return insn;
  129. }
  130. static void
  131. arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section)
  132. {
  133. if (!bfd_big_endian (abfd)
  134. && input_section
  135. && (input_section->flags & SEC_CODE))
  136. insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
  137. bfd_put_32 (abfd, insn, loc);
  138. }
  139. static bfd_reloc_status_type
  140. arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
  141. arelent *reloc_entry,
  142. asymbol *symbol_in,
  143. void *data ATTRIBUTE_UNUSED,
  144. asection *input_section,
  145. bfd *output_bfd,
  146. char ** error_message ATTRIBUTE_UNUSED)
  147. {
  148. if (output_bfd != NULL)
  149. {
  150. reloc_entry->address += input_section->output_offset;
  151. /* In case of relocateable link and if the reloc is against a
  152. section symbol, the addend needs to be adjusted according to
  153. where the section symbol winds up in the output section. */
  154. if ((symbol_in->flags & BSF_SECTION_SYM) && symbol_in->section)
  155. reloc_entry->addend += symbol_in->section->output_offset;
  156. return bfd_reloc_ok;
  157. }
  158. return bfd_reloc_continue;
  159. }
  160. #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
  161. TYPE = VALUE,
  162. enum howto_list
  163. {
  164. #include "elf/arc-reloc.def"
  165. HOWTO_LIST_LAST
  166. };
  167. #undef ARC_RELOC_HOWTO
  168. #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
  169. [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, #TYPE, FALSE, 0, 0, FALSE),
  170. static struct reloc_howto_struct elf_arc_howto_table[] =
  171. {
  172. #include "elf/arc-reloc.def"
  173. /* Example of what is generated by the preprocessor. Currently kept as an example.
  174. HOWTO (R_ARC_NONE, // Type.
  175. 0, // Rightshift.
  176. 2, // Size (0 = byte, 1 = short, 2 = long).
  177. 32, // Bitsize.
  178. FALSE, // PC_relative.
  179. 0, // Bitpos.
  180. complain_overflow_bitfield, // Complain_on_overflow.
  181. bfd_elf_generic_reloc, // Special_function.
  182. "R_ARC_NONE", // Name.
  183. TRUE, // Partial_inplace.
  184. 0, // Src_mask.
  185. 0, // Dst_mask.
  186. FALSE), // PCrel_offset.
  187. */
  188. };
  189. #undef ARC_RELOC_HOWTO
  190. static void arc_elf_howto_init (void)
  191. {
  192. #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
  193. elf_arc_howto_table[TYPE].pc_relative = (strstr (#FORMULA, " P ") != NULL);
  194. #include "elf/arc-reloc.def"
  195. }
  196. #undef ARC_RELOC_HOWTO
  197. #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
  198. [TYPE] = VALUE,
  199. const int howto_table_lookup[] =
  200. {
  201. #include "elf/arc-reloc.def"
  202. };
  203. #undef ARC_RELOC_HOWTO
  204. #define ARC_ELF_HOWTO(r_type) \
  205. (&elf_arc_howto_table[r_type])
  206. /* Map BFD reloc types to ARC ELF reloc types. */
  207. struct arc_reloc_map
  208. {
  209. bfd_reloc_code_real_type bfd_reloc_val;
  210. unsigned char elf_reloc_val;
  211. };
  212. #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
  213. { BFD_RELOC_##TYPE, R_##TYPE },
  214. static const struct arc_reloc_map arc_reloc_map[] =
  215. {
  216. #include "elf/arc-reloc.def"
  217. {BFD_RELOC_NONE, R_ARC_NONE},
  218. {BFD_RELOC_8, R_ARC_8},
  219. {BFD_RELOC_16, R_ARC_16},
  220. {BFD_RELOC_24, R_ARC_24},
  221. {BFD_RELOC_32, R_ARC_32},
  222. };
  223. #undef ARC_RELOC_HOWTO
  224. static reloc_howto_type *
  225. bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
  226. bfd_reloc_code_real_type code)
  227. {
  228. unsigned int i;
  229. static int fully_initialized = FALSE;
  230. if (fully_initialized == FALSE)
  231. {
  232. arc_elf_howto_init ();
  233. fully_initialized = TRUE; /* TODO: CHECK THIS IF IT STOPS WORKING. */
  234. }
  235. for (i = ARRAY_SIZE (arc_reloc_map); i--;)
  236. {
  237. if (arc_reloc_map[i].bfd_reloc_val == code)
  238. return elf_arc_howto_table + arc_reloc_map[i].elf_reloc_val;
  239. }
  240. return NULL;
  241. }
  242. static reloc_howto_type *
  243. bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char *r_name)
  244. {
  245. unsigned int i;
  246. for (i = 0; i < ARRAY_SIZE (elf_arc_howto_table); i++)
  247. if (elf_arc_howto_table[i].name != NULL
  248. && strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
  249. return elf_arc_howto_table + i;
  250. return NULL;
  251. }
  252. /* Set the howto pointer for an ARC ELF reloc. */
  253. static void
  254. arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
  255. arelent * cache_ptr,
  256. Elf_Internal_Rela * dst)
  257. {
  258. unsigned int r_type;
  259. r_type = ELF32_R_TYPE (dst->r_info);
  260. BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
  261. cache_ptr->howto = &elf_arc_howto_table[r_type];
  262. }
  263. /* Set the right machine number for an ARC ELF file. */
  264. static bfd_boolean
  265. arc_elf_object_p (bfd * abfd)
  266. {
  267. /* Make sure this is initialised, or you'll have the potential of passing
  268. garbage---or misleading values---into the call to
  269. bfd_default_set_arch_mach (). */
  270. int mach = bfd_mach_arc_arc700;
  271. unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
  272. unsigned e_machine = elf_elfheader (abfd)->e_machine;
  273. if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
  274. {
  275. switch (arch)
  276. {
  277. case E_ARC_MACH_ARC600:
  278. mach = bfd_mach_arc_arc600;
  279. break;
  280. case E_ARC_MACH_ARC601:
  281. mach = bfd_mach_arc_arc601;
  282. break;
  283. case E_ARC_MACH_ARC700:
  284. mach = bfd_mach_arc_arc700;
  285. break;
  286. case EF_ARC_CPU_ARCV2HS:
  287. case EF_ARC_CPU_ARCV2EM:
  288. mach = bfd_mach_arc_arcv2;
  289. break;
  290. default:
  291. mach = (e_machine == EM_ARC_COMPACT) ?
  292. bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
  293. break;
  294. }
  295. }
  296. else
  297. {
  298. if (e_machine == EM_ARC)
  299. {
  300. (*_bfd_error_handler)
  301. (_("Error: The ARC4 architecture is no longer supported.\n"));
  302. return FALSE;
  303. }
  304. else
  305. {
  306. (*_bfd_error_handler)
  307. (_("Warning: unset or old architecture flags. \n"
  308. " Use default machine.\n"));
  309. }
  310. }
  311. return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
  312. }
  313. /* The final processing done just before writing out an ARC ELF object file.
  314. This gets the ARC architecture right based on the machine number. */
  315. static void
  316. arc_elf_final_write_processing (bfd * abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
  317. {
  318. unsigned long val;
  319. unsigned long emf;
  320. switch (bfd_get_mach (abfd))
  321. {
  322. case bfd_mach_arc_arc600:
  323. val = E_ARC_MACH_ARC600;
  324. emf = EM_ARC_COMPACT;
  325. break;
  326. case bfd_mach_arc_arc601:
  327. val = E_ARC_MACH_ARC601;
  328. emf = EM_ARC_COMPACT;
  329. break;
  330. case bfd_mach_arc_arc700:
  331. val = E_ARC_MACH_ARC700;
  332. emf = EM_ARC_COMPACT;
  333. break;
  334. case bfd_mach_arc_arcv2:
  335. val = EF_ARC_CPU_GENERIC;
  336. emf = EM_ARC_COMPACT2;
  337. /* TODO: Check validity of this. It can also be ARCV2EM here.
  338. Previous version sets the e_machine here. */
  339. break;
  340. default:
  341. abort ();
  342. }
  343. elf_elfheader (abfd)->e_flags &= ~EF_ARC_MACH;
  344. elf_elfheader (abfd)->e_flags |= val;
  345. elf_elfheader (abfd)->e_machine = emf;
  346. /* Record whatever is the current syscall ABI version. */
  347. elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
  348. }
  349. #define BFD_DEBUG_PIC(...)
  350. struct arc_relocation_data
  351. {
  352. bfd_vma reloc_offset;
  353. bfd_vma reloc_addend;
  354. bfd_vma got_offset_value;
  355. bfd_vma sym_value;
  356. asection * sym_section;
  357. reloc_howto_type *howto;
  358. asection * input_section;
  359. bfd_vma sdata_begin_symbol_vma;
  360. bfd_boolean sdata_begin_symbol_vma_set;
  361. bfd_vma got_symbol_vma;
  362. bfd_boolean should_relocate;
  363. };
  364. static void
  365. debug_arc_reloc (struct arc_relocation_data reloc_data)
  366. {
  367. fprintf (stderr, "Reloc type=%s, should_relocate = %s\n",
  368. reloc_data.howto->name,
  369. reloc_data.should_relocate ? "true" : "false");
  370. fprintf (stderr, " offset = 0x%x, addend = 0x%x\n",
  371. (unsigned int) reloc_data.reloc_offset,
  372. (unsigned int) reloc_data.reloc_addend);
  373. fprintf (stderr, " Symbol:\n");
  374. fprintf (stderr, " value = 0x%08x\n",
  375. (unsigned int) reloc_data.sym_value);
  376. if (reloc_data.sym_section != NULL)
  377. {
  378. fprintf (stderr, "IN IF\n");
  379. fprintf (stderr,
  380. " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
  381. reloc_data.sym_section->name,
  382. (unsigned int) reloc_data.sym_section->output_offset,
  383. (unsigned int) reloc_data.sym_section->output_section->vma);
  384. }
  385. else
  386. fprintf (stderr, " symbol section is NULL\n");
  387. fprintf (stderr, " Input_section:\n");
  388. if (reloc_data.input_section != NULL)
  389. {
  390. fprintf (stderr,
  391. " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
  392. reloc_data.input_section->name,
  393. (unsigned int) reloc_data.input_section->output_offset,
  394. (unsigned int) reloc_data.input_section->output_section->vma);
  395. fprintf (stderr, " changed_address = 0x%08x\n",
  396. (unsigned int) (reloc_data.input_section->output_section->vma +
  397. reloc_data.input_section->output_offset +
  398. reloc_data.reloc_offset));
  399. }
  400. else
  401. fprintf (stderr, " input section is NULL\n");
  402. }
  403. #define S (reloc_data.sym_value \
  404. + reloc_data.sym_section->output_offset \
  405. + reloc_data.sym_section->output_section->vma)
  406. #define A (reloc_data.reloc_addend)
  407. #define B (0)
  408. #define G (reloc_data.got_offset_value)
  409. #define GOT (reloc_data.got_symbol_vma + 12)
  410. #define L (reloc_data.sym_value \
  411. + reloc_data.sym_section->output_section->vma \
  412. + reloc_data.sym_section->output_offset)
  413. #define MES (0)
  414. /* P: relative offset to PCL The offset should be to the current location
  415. aligned to 32 bits. */
  416. #define P ( \
  417. (reloc_data.input_section->output_section->vma \
  418. + reloc_data.input_section->output_offset \
  419. + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)) \
  420. ) & ~0x3)
  421. #define SECTSTAR (reloc_data.input_section->output_offset)
  422. #define SECTSTART (reloc_data.input_section->output_offset)
  423. #define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
  424. #define none (0)
  425. #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
  426. case R_##TYPE: \
  427. { \
  428. bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
  429. relocation = FORMULA ; \
  430. insn = RELOC_FUNCTION (insn, relocation); \
  431. } \
  432. break;
  433. static bfd_reloc_status_type
  434. arc_do_relocation (bfd_byte * contents, struct arc_relocation_data reloc_data)
  435. {
  436. bfd_vma relocation = 0;
  437. bfd_vma insn;
  438. bfd_vma orig_insn ATTRIBUTE_UNUSED;
  439. if (reloc_data.should_relocate == FALSE)
  440. return bfd_reloc_notsupported;
  441. switch (reloc_data.howto->size)
  442. {
  443. case 2:
  444. insn = arc_bfd_get_32 (reloc_data.input_section->owner,
  445. contents + reloc_data.reloc_offset,
  446. reloc_data.input_section);
  447. break;
  448. case 1:
  449. case 0:
  450. insn = arc_bfd_get_16 (reloc_data.input_section->owner,
  451. contents + reloc_data.reloc_offset,
  452. reloc_data.input_section);
  453. break;
  454. default:
  455. insn = 0;
  456. BFD_ASSERT (0);
  457. break;
  458. }
  459. orig_insn = insn;
  460. switch (reloc_data.howto->type)
  461. {
  462. #include "elf/arc-reloc.def"
  463. default:
  464. BFD_ASSERT (0);
  465. break;
  466. }
  467. /* Check for relocation overflow. */
  468. if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
  469. {
  470. bfd_reloc_status_type flag;
  471. flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
  472. reloc_data.howto->bitsize,
  473. reloc_data.howto->rightshift,
  474. bfd_arch_bits_per_address (reloc_data.input_section->owner),
  475. relocation);
  476. #undef DEBUG_ARC_RELOC
  477. #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
  478. if (flag != bfd_reloc_ok)
  479. {
  480. fprintf (stderr, "Relocation overflows !!!!\n");
  481. DEBUG_ARC_RELOC (reloc_data);
  482. fprintf (stderr,
  483. "Relocation value = signed -> %d, unsigned -> %u, hex -> (0x%08x)\n",
  484. (int) relocation,
  485. (unsigned int) relocation,
  486. (unsigned int) relocation);
  487. return flag;
  488. }
  489. }
  490. #undef DEBUG_ARC_RELOC
  491. #define DEBUG_ARC_RELOC(A)
  492. switch (reloc_data.howto->size)
  493. {
  494. case 2:
  495. arc_bfd_put_32 (reloc_data.input_section->owner, insn,
  496. contents + reloc_data.reloc_offset,
  497. reloc_data.input_section);
  498. break;
  499. case 1:
  500. case 0:
  501. arc_bfd_put_16 (reloc_data.input_section->owner, insn,
  502. contents + reloc_data.reloc_offset,
  503. reloc_data.input_section);
  504. break;
  505. default:
  506. ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
  507. BFD_ASSERT (0);
  508. break;
  509. }
  510. return bfd_reloc_ok;
  511. }
  512. #undef S
  513. #undef A
  514. #undef B
  515. #undef G
  516. #undef GOT
  517. #undef L
  518. #undef MES
  519. #undef P
  520. #undef SECTSTAR
  521. #undef SECTSTART
  522. #undef _SDA_BASE_
  523. #undef none
  524. #undef ARC_RELOC_HOWTO
  525. static bfd_vma *
  526. arc_get_local_got_offsets (bfd * abfd)
  527. {
  528. static bfd_vma *local_got_offsets = NULL;
  529. if (local_got_offsets == NULL)
  530. {
  531. size_t size;
  532. unsigned int i;
  533. Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
  534. size = symtab_hdr->sh_info * sizeof (bfd_vma);
  535. local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
  536. if (local_got_offsets == NULL)
  537. return FALSE;
  538. elf_local_got_offsets (abfd) = local_got_offsets;
  539. for (i = 0; i < symtab_hdr->sh_info; i++)
  540. local_got_offsets[i] = (bfd_vma) - 1;
  541. }
  542. return local_got_offsets;
  543. }
  544. /* Relocate an arc ELF section.
  545. Function : elf_arc_relocate_section
  546. Brief : Relocate an arc section, by handling all the relocations
  547. appearing in that section.
  548. Args : output_bfd : The bfd being written to.
  549. info : Link information.
  550. input_bfd : The input bfd.
  551. input_section : The section being relocated.
  552. contents : contents of the section being relocated.
  553. relocs : List of relocations in the section.
  554. local_syms : is a pointer to the swapped in local symbols.
  555. local_section : is an array giving the section in the input file
  556. corresponding to the st_shndx field of each
  557. local symbol. */
  558. static bfd_boolean
  559. elf_arc_relocate_section (bfd * output_bfd,
  560. struct bfd_link_info * info,
  561. bfd * input_bfd,
  562. asection * input_section,
  563. bfd_byte * contents,
  564. Elf_Internal_Rela * relocs,
  565. Elf_Internal_Sym * local_syms,
  566. asection ** local_sections)
  567. {
  568. Elf_Internal_Shdr * symtab_hdr;
  569. struct elf_link_hash_entry ** sym_hashes;
  570. bfd_vma * local_got_offsets;
  571. Elf_Internal_Rela * rel;
  572. Elf_Internal_Rela * relend;
  573. symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
  574. sym_hashes = elf_sym_hashes (input_bfd);
  575. rel = relocs;
  576. relend = relocs + input_section->reloc_count;
  577. for (; rel < relend; rel++)
  578. {
  579. enum elf_arc_reloc_type r_type;
  580. reloc_howto_type * howto;
  581. unsigned long r_symndx;
  582. struct elf_link_hash_entry * h;
  583. Elf_Internal_Sym * sym;
  584. asection * sec;
  585. struct arc_relocation_data reloc_data =
  586. {
  587. .reloc_offset = 0, /* bfd_vma reloc_offset; */
  588. .reloc_addend = 0, /* bfd_vma reloc_addend; */
  589. .got_offset_value = 0, /* bfd_vma got_offset_value; */
  590. .sym_value = 0, /* bfd_vma sym_value; */
  591. .sym_section = NULL, /* asection *sym_section; */
  592. .howto = NULL, /* reloc_howto_type *howto; */
  593. .input_section = NULL, /* asection *input_section; */
  594. .sdata_begin_symbol_vma = 0, /* bfd_vma sdata_begin_symbol_vma; */
  595. .sdata_begin_symbol_vma_set = FALSE, /* bfd_vma sdata_begin_symbol_vma_set; */
  596. .got_symbol_vma = 0, /* bfd_vma got_symbol_vma; */
  597. .should_relocate = FALSE /* bfd_boolean should_relocate; */
  598. };
  599. struct elf_link_hash_entry *h2;
  600. h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
  601. FALSE, FALSE, TRUE);
  602. if (reloc_data.sdata_begin_symbol_vma_set == FALSE
  603. && h2 != NULL && h2->root.type != bfd_link_hash_undefined)
  604. {
  605. reloc_data.sdata_begin_symbol_vma =
  606. (h2->root.u.def.value +
  607. h2->root.u.def.section->output_section->vma);
  608. reloc_data.sdata_begin_symbol_vma_set = TRUE;
  609. }
  610. h2 = elf_link_hash_lookup (elf_hash_table (info),
  611. "_GLOBAL_OFFSET_TABLE_", FALSE, FALSE,
  612. TRUE);
  613. if (h2 != NULL && h2->root.type != bfd_link_hash_undefined)
  614. {
  615. reloc_data.got_symbol_vma =
  616. (h2->root.u.def.value +
  617. h2->root.u.def.section->output_section->vma);
  618. }
  619. r_type = ELF32_R_TYPE (rel->r_info);
  620. if (r_type >= (int) R_ARC_max)
  621. {
  622. bfd_set_error (bfd_error_bad_value);
  623. return FALSE;
  624. }
  625. howto = &elf_arc_howto_table[r_type];
  626. reloc_data.input_section = input_section;
  627. reloc_data.howto = howto;
  628. reloc_data.reloc_offset = rel->r_offset;
  629. reloc_data.reloc_addend = rel->r_addend;
  630. r_symndx = ELF32_R_SYM (rel->r_info);
  631. /* This is a final link. */
  632. h = NULL;
  633. sym = NULL;
  634. sec = NULL;
  635. if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
  636. {
  637. sym = local_syms + r_symndx;
  638. sec = local_sections[r_symndx];
  639. reloc_data.sym_value = sym->st_value;
  640. reloc_data.sym_section = sec;
  641. if (is_reloc_for_GOT (reloc_data.howto))
  642. {
  643. local_got_offsets = arc_get_local_got_offsets (output_bfd);
  644. reloc_data.got_offset_value = local_got_offsets[r_symndx];
  645. }
  646. reloc_data.should_relocate = TRUE;
  647. }
  648. else /* Global symbol. */
  649. {
  650. /* Get the symbol's entry in the symtab. */
  651. h = sym_hashes[r_symndx - symtab_hdr->sh_info];
  652. while (h->root.type == bfd_link_hash_indirect
  653. || h->root.type == bfd_link_hash_warning)
  654. h = (struct elf_link_hash_entry *) h->root.u.i.link;
  655. BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0));
  656. /* If we have encountered a definition for this symbol. */
  657. if (h->root.type == bfd_link_hash_defined
  658. || h->root.type == bfd_link_hash_defweak)
  659. {
  660. reloc_data.sym_value = h->root.u.def.value;
  661. reloc_data.sym_section = h->root.u.def.section;
  662. reloc_data.should_relocate = TRUE;
  663. if (is_reloc_for_GOT (howto))
  664. {
  665. struct dynamic_sections ds =
  666. arc_create_dynamic_sections (output_bfd, info);
  667. /* TODO: Change it to use arc_do_relocation with ARC_32
  668. reloc. */
  669. bfd_vma relocation =
  670. reloc_data.sym_value + reloc_data.reloc_addend
  671. + reloc_data.sym_section->output_offset
  672. + reloc_data.sym_section->output_section->vma;
  673. bfd_put_32 (output_bfd, relocation, ds.sgot->contents + h->got.offset);
  674. }
  675. }
  676. else if (h->root.type == bfd_link_hash_undefweak)
  677. {
  678. /* Is weak symbol and has no definition. */
  679. continue;
  680. }
  681. else
  682. {
  683. if (is_reloc_for_GOT (howto))
  684. {
  685. struct dynamic_sections ds =
  686. arc_create_dynamic_sections (output_bfd, info);
  687. reloc_data.sym_value = h->root.u.def.value;
  688. reloc_data.sym_section = ds.sgot;
  689. reloc_data.should_relocate = TRUE;
  690. }
  691. else if (is_reloc_for_PLT (howto))
  692. {
  693. struct dynamic_sections ds =
  694. arc_create_dynamic_sections (output_bfd, info);
  695. reloc_data.sym_value = h->plt.offset;
  696. reloc_data.sym_section = ds.splt;
  697. reloc_data.should_relocate = TRUE;
  698. }
  699. else if (!(*info->callbacks->undefined_symbol)
  700. (info, h->root.root.string, input_bfd, input_section,
  701. rel->r_offset,!bfd_link_pic (info)))
  702. {
  703. return FALSE;
  704. }
  705. }
  706. reloc_data.got_offset_value = h->got.offset;
  707. }
  708. if (is_reloc_SDA_relative (howto) && reloc_data.sdata_begin_symbol_vma_set == FALSE)
  709. {
  710. (*_bfd_error_handler)
  711. ("Error: Linker symbol __SDATA_BEGIN__ not found");
  712. bfd_set_error (bfd_error_bad_value);
  713. return FALSE;
  714. }
  715. DEBUG_ARC_RELOC (reloc_data);
  716. if (arc_do_relocation (contents, reloc_data) != bfd_reloc_ok)
  717. return FALSE;
  718. }
  719. return TRUE;
  720. }
  721. static struct dynamic_sections
  722. arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
  723. {
  724. static bfd * dynobj = NULL;
  725. struct dynamic_sections ds =
  726. {
  727. .initialized = FALSE,
  728. .sgot = NULL,
  729. .srelgot = NULL,
  730. .sgotplt = NULL,
  731. .sdyn = NULL,
  732. .splt = NULL,
  733. .srelplt = NULL
  734. };
  735. if (dynobj == NULL)
  736. {
  737. elf_hash_table (info)->dynobj = dynobj = abfd;
  738. if (!_bfd_elf_create_got_section (dynobj, info))
  739. return ds;
  740. }
  741. else
  742. dynobj = (elf_hash_table (info))->dynobj;
  743. ds.sgot = bfd_get_section_by_name (dynobj, ".got");
  744. ds.srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
  745. if (ds.srelgot == NULL)
  746. {
  747. ds.srelgot = bfd_make_section_with_flags (dynobj, ".rela.got",
  748. SEC_ALLOC
  749. | SEC_LOAD
  750. | SEC_HAS_CONTENTS
  751. | SEC_IN_MEMORY
  752. | SEC_LINKER_CREATED
  753. | SEC_READONLY);
  754. if (ds.srelgot == NULL
  755. || !bfd_set_section_alignment (dynobj, ds.srelgot, 2))
  756. return ds;
  757. }
  758. ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
  759. ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
  760. ds.splt = bfd_get_section_by_name (dynobj, ".plt");
  761. ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
  762. ds.initialized = TRUE;
  763. return ds;
  764. }
  765. #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \
  766. ds.s##SECNAME->size; \
  767. { \
  768. if (COND_FOR_RELOC) ds.srel##SECNAME->size += sizeof (Elf32_External_Rela); \
  769. if (H) \
  770. if (h->dynindx == -1 && !h->forced_local) \
  771. if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
  772. return FALSE; \
  773. ds.s##SECNAME->size += 4; \
  774. }
  775. static bfd_boolean
  776. elf_arc_check_relocs (bfd * abfd,
  777. struct bfd_link_info * info,
  778. asection * sec,
  779. const Elf_Internal_Rela * relocs)
  780. {
  781. Elf_Internal_Shdr * symtab_hdr;
  782. struct elf_link_hash_entry ** sym_hashes;
  783. bfd_vma * local_got_offsets;
  784. const Elf_Internal_Rela * rel;
  785. const Elf_Internal_Rela * rel_end;
  786. bfd * dynobj ATTRIBUTE_UNUSED;
  787. dynobj = (elf_hash_table (info))->dynobj;
  788. symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
  789. sym_hashes = elf_sym_hashes (abfd);
  790. local_got_offsets = arc_get_local_got_offsets (abfd);
  791. struct dynamic_sections ds = arc_create_dynamic_sections (abfd, info);
  792. rel_end = relocs + sec->reloc_count;
  793. for (rel = relocs; rel < rel_end; rel++)
  794. {
  795. enum elf_arc_reloc_type r_type;
  796. reloc_howto_type *howto;
  797. unsigned long r_symndx;
  798. struct elf_link_hash_entry *h;
  799. r_type = ELF32_R_TYPE (rel->r_info);
  800. if (r_type >= (int) R_ARC_max)
  801. {
  802. bfd_set_error (bfd_error_bad_value);
  803. return FALSE;
  804. }
  805. howto = &elf_arc_howto_table[r_type];
  806. /* Load symbol information. */
  807. r_symndx = ELF32_R_SYM (rel->r_info);
  808. if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */
  809. h = NULL;
  810. else /* Global one. */
  811. h = sym_hashes[r_symndx - symtab_hdr->sh_info];
  812. if (is_reloc_for_PLT (howto) == TRUE)
  813. {
  814. if (h == NULL)
  815. continue;
  816. else
  817. h->needs_plt = 1;
  818. }
  819. if (is_reloc_for_GOT (howto) == TRUE)
  820. {
  821. if (h == NULL)
  822. {
  823. /* Local symbol. */
  824. local_got_offsets[r_symndx] =
  825. ADD_SYMBOL_REF_SEC_AND_RELOC (got, bfd_link_pic (info), NULL);
  826. }
  827. else
  828. {
  829. /* Global symbol. */
  830. h = sym_hashes[r_symndx - symtab_hdr->sh_info];
  831. h->got.offset =
  832. ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
  833. }
  834. }
  835. }
  836. return TRUE;
  837. }
  838. #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
  839. /* Size of one plt entry in bytes. */
  840. #define PLT_ENTRY_SIZE 12
  841. #define PLT_ENTRY_SIZE_V2 16
  842. /* Instructions appear in memory as a sequence of half-words (16 bit);
  843. individual half-words are represented on the target in target byte order.
  844. We use 'unsigned short' on the host to represent the PLT templates,
  845. and translate to target byte order as we copy to the target. */
  846. typedef unsigned short insn_hword;
  847. /* TODO: Make this PLT entry code be in a separate object file. */
  848. /* TODO: This is a linker BTW, we should be able to link. :) */
  849. /* The zeroth entry in the absolute plt entry. */
  850. static const insn_hword elf_arc_abs_plt0_entry[2 * PLT_ENTRY_SIZE / 2] =
  851. {
  852. 0x1600, /* ld %r11, [0] */
  853. 0x700b,
  854. 0x0000,
  855. 0x0000,
  856. 0x1600, /* ld %r10, [0] */
  857. 0x700a, /* */
  858. 0,
  859. 0,
  860. 0x2020, /* j [%r10] */
  861. 0x0280, /* ---"---- */
  862. 0x0000, /* pad */
  863. 0x0000 /* pad */
  864. };
  865. /* Contents of the subsequent entries in the absolute plt. */
  866. static const insn_hword elf_arc_abs_pltn_entry[PLT_ENTRY_SIZE / 2] =
  867. {
  868. 0x2730, /* ld %r12, [%pc,func@gotpc] */
  869. 0x7f8c, /* ------ " " -------------- */
  870. 0x0000, /* ------ " " -------------- */
  871. 0x0000, /* ------ " " -------------- */
  872. 0x7c20, /* j_s.d [%r12] */
  873. 0x74ef /* mov_s %r12, %pcl */
  874. };
  875. /* The zeroth entry in the absolute plt entry for ARCv2. */
  876. static const insn_hword elf_arcV2_abs_plt0_entry[2 * PLT_ENTRY_SIZE_V2 / 2] =
  877. {
  878. 0x1600, 0x700b, 0, 0, /* ld %r11, [0] */
  879. 0x1600, 0x700a, 0, 0, /* ld %r10, [0] */
  880. 0x2020, 0x0280, /* j [%r10] */
  881. 0x0000, 0x0000, /* -> RELOCATED TO ABS ADDRESS OF GOT <- */
  882. 0x0000, /* pad */
  883. 0x0000, /* pad */
  884. 0x0000, /* pad */
  885. 0x0000 /* pad */
  886. };
  887. /* Contents of the subsequent entries in the absolute plt for ARCv2. */
  888. static const insn_hword elf_arcV2_abs_pltn_entry[PLT_ENTRY_SIZE_V2 / 2] =
  889. {
  890. 0x2730, /* ld %r12, [%pcl,func@gotpc] */
  891. 0x7f8c, /* ------ " " -------------- */
  892. 0x0000, /* ------ " " -------------- */
  893. 0x0000, /* ------ " " -------------- */
  894. 0x2021, /* j.d [%r12] */
  895. 0x0300, /* ------ " " -------------- */
  896. 0x240a, /* mov %r12, %pcl */
  897. 0x1fc0 /* ------ " " -------------- */
  898. };
  899. /* The zeroth entry in the pic plt entry. */
  900. static const insn_hword elf_arc_pic_plt0_entry[2 * PLT_ENTRY_SIZE / 2] =
  901. {
  902. 0x2730, /* ld %r11, [pcl,0] : 0 to be replaced by
  903. _DYNAMIC@GOTPC+4 */
  904. 0x7f8b,
  905. 0x0000,
  906. 0x0000,
  907. 0x2730, /* ld %r10, [pcl,0] : 0 to be replaced by
  908. -DYNAMIC@GOTPC+8 */
  909. 0x7f8a, /* */
  910. 0,
  911. 0,
  912. 0x2020, /* j [%r10] */
  913. 0x0280, /* ---"---- */
  914. 0x0000, /* pad */
  915. 0x0000 /* pad */
  916. };
  917. /* Contents of the subsequent entries in the pic plt. */
  918. static const insn_hword elf_arc_pic_pltn_entry[PLT_ENTRY_SIZE / 2] =
  919. {
  920. 0x2730, /* ld %r12, [%pc,func@got] */
  921. 0x7f8c, /* ------ " " -------------- */
  922. 0x0000, /* ------ " " -------------- */
  923. 0x0000, /* ------ " " -------------- */
  924. 0x7c20, /* j_s.d [%r12] */
  925. 0x74ef, /* mov_s %r12, %pcl */
  926. };
  927. /* The zeroth entry in the pic plt entry for ARCv2. */
  928. static const insn_hword elf_arcV2_pic_plt0_entry[2 * PLT_ENTRY_SIZE_V2 / 2] =
  929. {
  930. 0x2730, /* ld %r11, [pcl,0] : 0 to be replaced by
  931. _DYNAMIC@GOTPC+4 */
  932. 0x7f8b,
  933. 0x0000,
  934. 0x0000,
  935. 0x2730, /* ld %r10, [pcl,0] : 0 to be replaced by
  936. -DYNAMIC@GOTPC+8 */
  937. 0x7f8a, /* */
  938. 0,
  939. 0,
  940. 0x2020, /* j [%r10] */
  941. 0x0280, /* ---"---- */
  942. 0x0000, /* pad */
  943. 0x0000, /* pad */
  944. 0x0000, /* pad */
  945. 0x0000, /* pad */
  946. 0x0000, /* pad */
  947. 0x0000 /* pad */
  948. };
  949. #define elf_arcV2_pic_PLT0_ENTRY_SIZE (2 * PLT_ENTRY_SIZE_V2/2)
  950. /* Contents of the subsequent entries in the pic plt for ARCv2. */
  951. static const insn_hword elf_arcV2_pic_pltn_entry[PLT_ENTRY_SIZE_V2 / 2] =
  952. {
  953. 0x2730, /* ld %r12, [%pc,func@got] */
  954. 0x7f8c, /* ------ " " -------------- */
  955. 0x0000, /* ------ " " -------------- */
  956. 0x0000, /* ------ " " -------------- */
  957. 0x2021, /* j.d [%r12] */
  958. 0x0300, /* ------ " " -------------- */
  959. 0x240a, /* mov %r12, %pcl */
  960. 0x1fc0 /* ------ " " -------------- */
  961. };
  962. #define elf_arcV2_pic_PLTN_ENTRY_SIZE (PLT_ENTRY_SIZE_V2/2)
  963. enum plt_reloc_symbol
  964. {
  965. LAST_RELOC = 0,
  966. SGOT = 1,
  967. RELATIVE = (1 << 8),
  968. MIDDLE_ENDIAN = (1 << 9)
  969. };
  970. #define IS_RELATIVE(S) ((S & RELATIVE) != 0)
  971. #define IS_MIDDLE_ENDIAN(S) ((S & MIDDLE_ENDIAN) != 0)
  972. #define SYM_ONLY(S) (S & 0xFF)
  973. struct plt_reloc
  974. {
  975. bfd_vma offset;
  976. bfd_vma size;
  977. bfd_vma mask;
  978. enum plt_reloc_symbol symbol;
  979. bfd_vma addend;
  980. };
  981. struct plt_version_t
  982. {
  983. const insn_hword * entry;
  984. const bfd_vma entry_size;
  985. const insn_hword * elem;
  986. const bfd_vma elem_size;
  987. struct plt_reloc entry_relocs[5];
  988. struct plt_reloc elem_relocs[5];
  989. };
  990. #define PLT_DATA(NAME, ...) \
  991. .entry = NAME##_plt0_entry, \
  992. .entry_size = NAME##_PLT0_ENTRY_SIZE, \
  993. .elem = NAME##_pltn_entry, \
  994. .elem_size = NAME##_PLTN_ENTRY_SIZE
  995. struct plt_version_t plt_versions[] =
  996. {
  997. {
  998. PLT_DATA (elf_arcV2_pic),
  999. .entry_relocs =
  1000. {
  1001. {4, 32, 0xFFFFFFFF, SGOT | RELATIVE | MIDDLE_ENDIAN, 4},
  1002. {12, 32, 0xFFFFFFFF, SGOT | RELATIVE | MIDDLE_ENDIAN, 8},
  1003. {20, 32, 0xFFFFFFFF, SGOT, 0},
  1004. {0, 0, 0, LAST_RELOC, 0}
  1005. },
  1006. .elem_relocs =
  1007. {
  1008. {4, 32, 0xFFFFFFFF, SGOT, 0},
  1009. {0, 0, 0, LAST_RELOC, 0}
  1010. }
  1011. }
  1012. };
  1013. #undef PLT_DATA
  1014. static struct plt_version_t *
  1015. arc_get_plt_version (void)
  1016. {
  1017. return &(plt_versions[0]);
  1018. }
  1019. static bfd_vma
  1020. add_symbol_to_plt (struct bfd_link_info *info)
  1021. {
  1022. bfd *dynobj = (elf_hash_table (info))->dynobj;
  1023. struct dynamic_sections ds = arc_create_dynamic_sections (dynobj, info);
  1024. bfd_vma ret;
  1025. /* If this is the first .plt entry, make room for the special first entry. */
  1026. if (ds.splt->size == 0)
  1027. ds.splt->size += 2 *
  1028. (bfd_get_mach (dynobj) == bfd_mach_arc_arcv2
  1029. ? PLT_ENTRY_SIZE_V2 : PLT_ENTRY_SIZE);
  1030. ret = ds.splt->size;
  1031. ds.splt->size += (bfd_get_mach (dynobj) == bfd_mach_arc_arcv2
  1032. ? PLT_ENTRY_SIZE_V2
  1033. : PLT_ENTRY_SIZE
  1034. );
  1035. ds.sgotplt->size += 4;
  1036. ds.srelplt->size += sizeof (Elf32_External_Rela);
  1037. return ret;
  1038. }
  1039. #define PLT_DO_RELOCS_FOR_ENTRY(DS, RELOCS) \
  1040. plt_do_relocs_for_symbol (DS, RELOCS, 0, 0)
  1041. static void
  1042. plt_do_relocs_for_symbol (struct dynamic_sections *ds,
  1043. struct plt_reloc *reloc,
  1044. bfd_vma plt_offset,
  1045. bfd_vma symbol_got_offset)
  1046. {
  1047. while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
  1048. {
  1049. bfd_vma relocation = 0;
  1050. switch (SYM_ONLY (reloc->symbol))
  1051. {
  1052. case SGOT:
  1053. relocation =
  1054. ds->sgotplt->output_section->vma +
  1055. ds->sgotplt->output_offset + symbol_got_offset;
  1056. break;
  1057. }
  1058. relocation += reloc->addend;
  1059. relocation -= (IS_RELATIVE (reloc->symbol))
  1060. ? ds->splt->output_section->vma + ds->splt->output_offset +
  1061. plt_offset + reloc->offset : 0;
  1062. if (IS_MIDDLE_ENDIAN (reloc->symbol))
  1063. {
  1064. relocation =
  1065. ((relocation & 0xffff0000) >> 16) |
  1066. ((relocation & 0xffff) << 16);
  1067. }
  1068. switch (reloc->size)
  1069. {
  1070. case 32:
  1071. bfd_put_32 (ds->splt->output_section->owner,
  1072. relocation,
  1073. ds->splt->contents + plt_offset + reloc->offset);
  1074. break;
  1075. }
  1076. reloc = &(reloc[1]); /* Jump to next relocation. */
  1077. }
  1078. }
  1079. static void
  1080. relocate_plt_for_symbol (struct bfd_link_info *info,
  1081. struct elf_link_hash_entry *h)
  1082. {
  1083. bfd * dynobj = elf_hash_table (info)->dynobj;
  1084. struct plt_version_t *plt_data = arc_get_plt_version ();
  1085. struct dynamic_sections ds = arc_create_dynamic_sections (dynobj, info);
  1086. bfd_vma plt_index = h->plt.offset / plt_data->elem_size;
  1087. bfd_vma got_offset = (plt_index + 3) * 4;
  1088. memcpy (ds.splt->contents + h->plt.offset, plt_data->elem,
  1089. plt_data->elem_size * sizeof (insn_hword));
  1090. plt_do_relocs_for_symbol (&ds, plt_data->elem_relocs, h->plt.offset,
  1091. got_offset);
  1092. }
  1093. static void
  1094. relocate_plt_for_entry (struct bfd_link_info *info)
  1095. {
  1096. bfd * dynobj = (elf_hash_table (info))->dynobj;
  1097. struct plt_version_t *plt_data = arc_get_plt_version ();
  1098. struct dynamic_sections ds = arc_create_dynamic_sections (dynobj, info);
  1099. memcpy (ds.splt->contents, plt_data->entry,
  1100. plt_data->entry_size * sizeof (insn_hword));
  1101. PLT_DO_RELOCS_FOR_ENTRY (&ds, plt_data->entry_relocs);
  1102. }
  1103. /* Desc : Adjust a symbol defined by a dynamic object and referenced by a
  1104. regular object. The current definition is in some section of the
  1105. dynamic object, but we're not including those sections. We have to
  1106. change the definition to something the rest of the link can
  1107. understand. */
  1108. static bfd_boolean
  1109. elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
  1110. struct elf_link_hash_entry *h)
  1111. {
  1112. bfd *dynobj = (elf_hash_table (info))->dynobj;
  1113. struct dynamic_sections ds = arc_create_dynamic_sections (dynobj, info);
  1114. if (h->needs_plt == 1)
  1115. {
  1116. if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
  1117. {
  1118. /* This case can occur if we saw a PLT32 reloc in an input
  1119. file, but the symbol was never referred to by a dynamic
  1120. object. In such a case, we don't actually need to build
  1121. a procedure linkage table, and we can just do a PC32
  1122. reloc instead. */
  1123. BFD_ASSERT (h->needs_plt);
  1124. return TRUE;
  1125. }
  1126. /* Make sure this symbol is output as a dynamic symbol. */
  1127. if (h->dynindx == -1 && !h->forced_local
  1128. && !bfd_elf_link_record_dynamic_symbol (info, h))
  1129. return FALSE;
  1130. if (bfd_link_pic (info) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
  1131. {
  1132. bfd_vma loc = add_symbol_to_plt (info);
  1133. if (!bfd_link_pic (info) && !h->def_regular)
  1134. {
  1135. h->root.u.def.section = ds.splt;
  1136. h->root.u.def.value = loc;
  1137. }
  1138. h->plt.offset = loc;
  1139. }
  1140. }
  1141. else
  1142. {
  1143. h->plt.offset = (bfd_vma) - 1;
  1144. h->needs_plt = 0;
  1145. }
  1146. return TRUE;
  1147. }
  1148. #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND) \
  1149. {\
  1150. struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info); \
  1151. bfd_byte * rloc = ds.srel##SECTION->contents + \
  1152. ((ds.srel##SECTION->reloc_count++) * sizeof (Elf32_External_Rela)); \
  1153. Elf_Internal_Rela rel; \
  1154. bfd_put_32 (output_bfd, (bfd_vma) 0, ds.s##SECTION->contents + OFFSET); \
  1155. rel.r_addend = ADDEND; \
  1156. rel.r_offset = (ds.s##SECTION)->output_section->vma + (ds.s##SECTION)->output_offset + OFFSET; \
  1157. rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE); \
  1158. bfd_elf32_swap_reloca_out (BFD, &rel, rloc); \
  1159. }
  1160. /* Function : elf_arc_finish_dynamic_symbol
  1161. Brief : Finish up dynamic symbol handling. We set the
  1162. contents of various dynamic sections here.
  1163. Args : output_bfd :
  1164. info :
  1165. h :
  1166. sym :
  1167. Returns : True/False as the return status. */
  1168. static bfd_boolean
  1169. elf_arc_finish_dynamic_symbol (bfd * output_bfd,
  1170. struct bfd_link_info *info,
  1171. struct elf_link_hash_entry *h,
  1172. Elf_Internal_Sym * sym)
  1173. {
  1174. if (h->plt.offset != (bfd_vma) - 1)
  1175. relocate_plt_for_symbol (info, h);
  1176. if (h->got.offset != (bfd_vma) - 1)
  1177. {
  1178. if (bfd_link_pic (info) && (info->symbolic || h->dynindx == -1)
  1179. && h->def_regular)
  1180. {
  1181. ADD_RELA (output_bfd, got, h->got.offset, 0, R_ARC_RELATIVE, 0);
  1182. }
  1183. else
  1184. {
  1185. ADD_RELA (output_bfd, got, h->got.offset, h->dynindx,
  1186. R_ARC_GLOB_DAT, 0);
  1187. }
  1188. }
  1189. /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
  1190. if (strcmp (h->root.root.string, "_DYNAMIC") == 0
  1191. || strcmp (h->root.root.string, "__DYNAMIC") == 0
  1192. || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
  1193. sym->st_shndx = SHN_ABS;
  1194. return TRUE;
  1195. }
  1196. #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION) \
  1197. case TAG: \
  1198. if (SYMBOL != NULL) \
  1199. { \
  1200. h = elf_link_hash_lookup (elf_hash_table (info), SYMBOL, FALSE, FALSE, TRUE); \
  1201. } \
  1202. else if (SECTION != NULL) \
  1203. { \
  1204. s = bfd_get_section_by_name (output_bfd, SECTION); \
  1205. BFD_ASSERT (s != NULL); \
  1206. do_it = TRUE; \
  1207. } \
  1208. break;
  1209. /* Function : elf_arc_finish_dynamic_sections
  1210. Brief : Finish up the dynamic sections handling.
  1211. Args : output_bfd :
  1212. info :
  1213. h :
  1214. sym :
  1215. Returns : True/False as the return status. */
  1216. static bfd_boolean
  1217. elf_arc_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info *info)
  1218. {
  1219. struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
  1220. bfd *dynobj = (elf_hash_table (info))->dynobj;
  1221. if (ds.sdyn)
  1222. {
  1223. Elf32_External_Dyn *dyncon, *dynconend;
  1224. dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
  1225. dynconend =
  1226. (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
  1227. for (; dyncon < dynconend; dyncon++)
  1228. {
  1229. Elf_Internal_Dyn internal_dyn;
  1230. bfd_boolean do_it = FALSE;
  1231. struct elf_link_hash_entry *h = NULL;
  1232. asection *s = NULL;
  1233. bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
  1234. switch (internal_dyn.d_tag)
  1235. {
  1236. GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL)
  1237. GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL)
  1238. GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt")
  1239. GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt")
  1240. GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt")
  1241. GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt")
  1242. default:
  1243. break;
  1244. }
  1245. /* In case the dynamic symbols should be updated with a
  1246. symbol. */
  1247. if (h != NULL
  1248. && (h->root.type == bfd_link_hash_defined
  1249. || h->root.type == bfd_link_hash_defweak)
  1250. )
  1251. {
  1252. asection *asec_ptr;
  1253. internal_dyn.d_un.d_val = h->root.u.def.value;
  1254. asec_ptr = h->root.u.def.section;
  1255. if (asec_ptr->output_section != NULL)
  1256. {
  1257. internal_dyn.d_un.d_val +=
  1258. (asec_ptr->output_section->vma +
  1259. asec_ptr->output_offset);
  1260. }
  1261. else
  1262. {
  1263. /* The symbol is imported from another
  1264. shared library and does not apply to this
  1265. one. */
  1266. internal_dyn.d_un.d_val = 0;
  1267. }
  1268. do_it = TRUE;
  1269. }
  1270. else if (s != NULL) /* With a section information. */
  1271. {
  1272. switch (internal_dyn.d_tag)
  1273. {
  1274. case DT_PLTGOT:
  1275. case DT_JMPREL:
  1276. internal_dyn.d_un.d_ptr = s->vma;
  1277. do_it = TRUE;
  1278. break;
  1279. case DT_PLTRELSZ:
  1280. internal_dyn.d_un.d_val = s->size;
  1281. do_it = TRUE;
  1282. break;
  1283. case DT_RELASZ:
  1284. internal_dyn.d_un.d_val -= s->size;
  1285. do_it = TRUE;
  1286. break;
  1287. default:
  1288. break;
  1289. }
  1290. }
  1291. if (do_it == TRUE)
  1292. bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
  1293. }
  1294. if (ds.splt->size > 0)
  1295. {
  1296. relocate_plt_for_entry (info);
  1297. }
  1298. elf_section_data (ds.srelplt->output_section)->this_hdr.sh_entsize = 0xc;
  1299. }
  1300. /* Fill in the first three entries in the global offset table. */
  1301. if (ds.sgot)
  1302. {
  1303. if (ds.sgot->size > 0)
  1304. {
  1305. if (ds.sdyn == NULL)
  1306. bfd_put_32 (output_bfd, (bfd_vma) 0,
  1307. ds.sgotplt->contents);
  1308. else
  1309. bfd_put_32 (output_bfd,
  1310. ds.sdyn->output_section->vma + ds.sdyn->output_offset,
  1311. ds.sgotplt->contents);
  1312. bfd_put_32 (output_bfd, (bfd_vma) 0, ds.sgotplt->contents + 4);
  1313. bfd_put_32 (output_bfd, (bfd_vma) 0, ds.sgotplt->contents + 8);
  1314. elf_section_data (ds.sgot->output_section)->this_hdr.sh_entsize = 4;
  1315. }
  1316. }
  1317. if (ds.srelgot
  1318. /* Check that the linker script has not dumped the .srelgot section. */
  1319. && ds.srelgot->output_section
  1320. && elf_section_data (ds.srelgot->output_section))
  1321. {
  1322. /* TODO: Make it work even if I remove this. */
  1323. elf_section_data (ds.srelgot->output_section)->this_hdr.sh_entsize = 0xc;
  1324. }
  1325. return TRUE;
  1326. }
  1327. #define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
  1328. h = elf_link_hash_lookup (elf_hash_table (info), NAME, FALSE, FALSE, FALSE); \
  1329. if ((h != NULL && (h->ref_regular || h->def_regular))) \
  1330. if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
  1331. return FALSE;
  1332. /* Set the sizes of the dynamic sections. */
  1333. static bfd_boolean
  1334. elf_arc_size_dynamic_sections (bfd * output_bfd, struct bfd_link_info *info)
  1335. {
  1336. bfd * dynobj;
  1337. asection * s;
  1338. bfd_boolean relocs_exist;
  1339. bfd_boolean reltext_exist;
  1340. struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
  1341. dynobj = (elf_hash_table (info))->dynobj;
  1342. BFD_ASSERT (dynobj != NULL);
  1343. if ((elf_hash_table (info))->dynamic_sections_created)
  1344. {
  1345. struct elf_link_hash_entry *h;
  1346. /* Set the contents of the .interp section to the interpreter. */
  1347. if (!bfd_link_pic (info))
  1348. {
  1349. s = bfd_get_section_by_name (dynobj, ".interp");
  1350. BFD_ASSERT (s != NULL);
  1351. s->size = sizeof ELF_DYNAMIC_INTERPRETER;
  1352. s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
  1353. }
  1354. /* Add some entries to the .dynamic section. We fill in some of the
  1355. values later, in elf_bfd_final_link, but we must add the entries
  1356. now so that we know the final size of the .dynamic section.
  1357. Checking if the .init section is present. We also create DT_INIT
  1358. and DT_FINI entries if the init_str has been changed by the user. */
  1359. ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
  1360. ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
  1361. }
  1362. else
  1363. {
  1364. /* We may have created entries in the .rela.got section. However, if
  1365. we are not creating the dynamic sections, we will not actually
  1366. use these entries. Reset the size of .rela.got, which will cause
  1367. it to get stripped from the output file below. */
  1368. ds.srelgot->size = 0;
  1369. }
  1370. for (s = dynobj->sections; s != NULL; s = s->next)
  1371. {
  1372. bfd_boolean is_dynamic_section = FALSE;
  1373. /* Skip any non dynamic section. */
  1374. if (strstr (s->name, ".plt") != NULL
  1375. || strstr (s->name, ".got") != NULL
  1376. || strstr (s->name, ".rel") != NULL)
  1377. is_dynamic_section = TRUE;
  1378. /* Allocate memory for the section contents. */
  1379. if (!is_dynamic_section)
  1380. continue;
  1381. s->contents = (bfd_byte *) bfd_alloc (dynobj, s->size);
  1382. if (s->contents == NULL && s->size != 0)
  1383. return FALSE;
  1384. if (s->size == 0)
  1385. {
  1386. s->flags |= SEC_EXCLUDE;
  1387. continue;
  1388. }
  1389. if (strcmp (s->name, ".rela.plt") != 0)
  1390. {
  1391. const char *outname = bfd_get_section_name (output_bfd,
  1392. s->output_section);
  1393. asection *target = bfd_get_section_by_name (output_bfd,
  1394. outname + 4);
  1395. relocs_exist = TRUE;
  1396. if (target != NULL && target->size != 0
  1397. && (target->flags & SEC_READONLY) != 0
  1398. && (target->flags & SEC_ALLOC) != 0)
  1399. reltext_exist = TRUE;
  1400. }
  1401. }
  1402. if (ds.sdyn)
  1403. {
  1404. if (ds.splt && ds.splt->size != 0)
  1405. if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
  1406. || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
  1407. || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
  1408. || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
  1409. )
  1410. return FALSE;
  1411. if (relocs_exist == TRUE)
  1412. if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
  1413. || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
  1414. || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
  1415. sizeof (Elf32_External_Rela))
  1416. )
  1417. return FALSE;
  1418. if (reltext_exist == TRUE)
  1419. if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
  1420. return FALSE;
  1421. }
  1422. return TRUE;
  1423. }
  1424. #define TARGET_LITTLE_SYM arc_elf32_le_vec
  1425. #define TARGET_LITTLE_NAME "elf32-littlearc"
  1426. #define TARGET_BIG_SYM arc_elf32_be_vec
  1427. #define TARGET_BIG_NAME "elf32-bigarc"
  1428. #define ELF_ARCH bfd_arch_arc
  1429. #define ELF_MACHINE_CODE EM_ARC_COMPACT
  1430. #define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
  1431. #define ELF_MAXPAGESIZE 0x2000
  1432. #define elf_info_to_howto_rel arc_info_to_howto_rel
  1433. #define elf_backend_object_p arc_elf_object_p
  1434. #define elf_backend_final_write_processing arc_elf_final_write_processing
  1435. #define elf_backend_relocate_section elf_arc_relocate_section
  1436. #define elf_backend_check_relocs elf_arc_check_relocs
  1437. #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
  1438. #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
  1439. #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
  1440. #define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
  1441. #define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
  1442. #define elf_backend_can_gc_sections 1
  1443. #define elf_backend_want_got_plt 1
  1444. #define elf_backend_plt_readonly 1
  1445. #define elf_backend_want_plt_sym 0
  1446. #define elf_backend_got_header_size 12
  1447. #define elf_backend_may_use_rel_p 0
  1448. #define elf_backend_may_use_rela_p 1
  1449. #define elf_backend_default_use_rela_p 1
  1450. #include "elf32-target.h"