RelocationResolver.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines utilities to resolve relocations in object files.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Object/RelocationResolver.h"
  13. #include "llvm/ADT/Triple.h"
  14. #include "llvm/ADT/Twine.h"
  15. #include "llvm/BinaryFormat/COFF.h"
  16. #include "llvm/BinaryFormat/ELF.h"
  17. #include "llvm/BinaryFormat/MachO.h"
  18. #include "llvm/BinaryFormat/Wasm.h"
  19. #include "llvm/Object/ELFObjectFile.h"
  20. #include "llvm/Object/ELFTypes.h"
  21. #include "llvm/Object/ObjectFile.h"
  22. #include "llvm/Object/SymbolicFile.h"
  23. #include "llvm/Support/Casting.h"
  24. #include "llvm/Support/Error.h"
  25. #include "llvm/Support/ErrorHandling.h"
  26. #include <cassert>
  27. #include <vector>
  28. namespace llvm {
  29. namespace object {
  30. static int64_t getELFAddend(RelocationRef R) {
  31. Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
  32. handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
  33. report_fatal_error(Twine(EI.message()));
  34. });
  35. return *AddendOrErr;
  36. }
  37. static bool supportsX86_64(uint64_t Type) {
  38. switch (Type) {
  39. case ELF::R_X86_64_NONE:
  40. case ELF::R_X86_64_64:
  41. case ELF::R_X86_64_DTPOFF32:
  42. case ELF::R_X86_64_DTPOFF64:
  43. case ELF::R_X86_64_PC32:
  44. case ELF::R_X86_64_PC64:
  45. case ELF::R_X86_64_32:
  46. case ELF::R_X86_64_32S:
  47. return true;
  48. default:
  49. return false;
  50. }
  51. }
  52. static uint64_t resolveX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
  53. uint64_t LocData, int64_t Addend) {
  54. switch (Type) {
  55. case ELF::R_X86_64_NONE:
  56. return LocData;
  57. case ELF::R_X86_64_64:
  58. case ELF::R_X86_64_DTPOFF32:
  59. case ELF::R_X86_64_DTPOFF64:
  60. return S + Addend;
  61. case ELF::R_X86_64_PC32:
  62. case ELF::R_X86_64_PC64:
  63. return S + Addend - Offset;
  64. case ELF::R_X86_64_32:
  65. case ELF::R_X86_64_32S:
  66. return (S + Addend) & 0xFFFFFFFF;
  67. default:
  68. llvm_unreachable("Invalid relocation type");
  69. }
  70. }
  71. static bool supportsAArch64(uint64_t Type) {
  72. switch (Type) {
  73. case ELF::R_AARCH64_ABS32:
  74. case ELF::R_AARCH64_ABS64:
  75. case ELF::R_AARCH64_PREL16:
  76. case ELF::R_AARCH64_PREL32:
  77. case ELF::R_AARCH64_PREL64:
  78. return true;
  79. default:
  80. return false;
  81. }
  82. }
  83. static uint64_t resolveAArch64(uint64_t Type, uint64_t Offset, uint64_t S,
  84. uint64_t /*LocData*/, int64_t Addend) {
  85. switch (Type) {
  86. case ELF::R_AARCH64_ABS32:
  87. return (S + Addend) & 0xFFFFFFFF;
  88. case ELF::R_AARCH64_ABS64:
  89. return S + Addend;
  90. case ELF::R_AARCH64_PREL16:
  91. return (S + Addend - Offset) & 0xFFFF;
  92. case ELF::R_AARCH64_PREL32:
  93. return (S + Addend - Offset) & 0xFFFFFFFF;
  94. case ELF::R_AARCH64_PREL64:
  95. return S + Addend - Offset;
  96. default:
  97. llvm_unreachable("Invalid relocation type");
  98. }
  99. }
  100. static bool supportsBPF(uint64_t Type) {
  101. switch (Type) {
  102. case ELF::R_BPF_64_ABS32:
  103. case ELF::R_BPF_64_ABS64:
  104. return true;
  105. default:
  106. return false;
  107. }
  108. }
  109. static uint64_t resolveBPF(uint64_t Type, uint64_t Offset, uint64_t S,
  110. uint64_t LocData, int64_t /*Addend*/) {
  111. switch (Type) {
  112. case ELF::R_BPF_64_ABS32:
  113. return (S + LocData) & 0xFFFFFFFF;
  114. case ELF::R_BPF_64_ABS64:
  115. return S + LocData;
  116. default:
  117. llvm_unreachable("Invalid relocation type");
  118. }
  119. }
  120. static bool supportsMips64(uint64_t Type) {
  121. switch (Type) {
  122. case ELF::R_MIPS_32:
  123. case ELF::R_MIPS_64:
  124. case ELF::R_MIPS_TLS_DTPREL64:
  125. case ELF::R_MIPS_PC32:
  126. return true;
  127. default:
  128. return false;
  129. }
  130. }
  131. static uint64_t resolveMips64(uint64_t Type, uint64_t Offset, uint64_t S,
  132. uint64_t /*LocData*/, int64_t Addend) {
  133. switch (Type) {
  134. case ELF::R_MIPS_32:
  135. return (S + Addend) & 0xFFFFFFFF;
  136. case ELF::R_MIPS_64:
  137. return S + Addend;
  138. case ELF::R_MIPS_TLS_DTPREL64:
  139. return S + Addend - 0x8000;
  140. case ELF::R_MIPS_PC32:
  141. return S + Addend - Offset;
  142. default:
  143. llvm_unreachable("Invalid relocation type");
  144. }
  145. }
  146. static bool supportsMSP430(uint64_t Type) {
  147. switch (Type) {
  148. case ELF::R_MSP430_32:
  149. case ELF::R_MSP430_16_BYTE:
  150. return true;
  151. default:
  152. return false;
  153. }
  154. }
  155. static uint64_t resolveMSP430(uint64_t Type, uint64_t Offset, uint64_t S,
  156. uint64_t /*LocData*/, int64_t Addend) {
  157. switch (Type) {
  158. case ELF::R_MSP430_32:
  159. return (S + Addend) & 0xFFFFFFFF;
  160. case ELF::R_MSP430_16_BYTE:
  161. return (S + Addend) & 0xFFFF;
  162. default:
  163. llvm_unreachable("Invalid relocation type");
  164. }
  165. }
  166. static bool supportsPPC64(uint64_t Type) {
  167. switch (Type) {
  168. case ELF::R_PPC64_ADDR32:
  169. case ELF::R_PPC64_ADDR64:
  170. case ELF::R_PPC64_REL32:
  171. case ELF::R_PPC64_REL64:
  172. return true;
  173. default:
  174. return false;
  175. }
  176. }
  177. static uint64_t resolvePPC64(uint64_t Type, uint64_t Offset, uint64_t S,
  178. uint64_t /*LocData*/, int64_t Addend) {
  179. switch (Type) {
  180. case ELF::R_PPC64_ADDR32:
  181. return (S + Addend) & 0xFFFFFFFF;
  182. case ELF::R_PPC64_ADDR64:
  183. return S + Addend;
  184. case ELF::R_PPC64_REL32:
  185. return (S + Addend - Offset) & 0xFFFFFFFF;
  186. case ELF::R_PPC64_REL64:
  187. return S + Addend - Offset;
  188. default:
  189. llvm_unreachable("Invalid relocation type");
  190. }
  191. }
  192. static bool supportsSystemZ(uint64_t Type) {
  193. switch (Type) {
  194. case ELF::R_390_32:
  195. case ELF::R_390_64:
  196. return true;
  197. default:
  198. return false;
  199. }
  200. }
  201. static uint64_t resolveSystemZ(uint64_t Type, uint64_t Offset, uint64_t S,
  202. uint64_t /*LocData*/, int64_t Addend) {
  203. switch (Type) {
  204. case ELF::R_390_32:
  205. return (S + Addend) & 0xFFFFFFFF;
  206. case ELF::R_390_64:
  207. return S + Addend;
  208. default:
  209. llvm_unreachable("Invalid relocation type");
  210. }
  211. }
  212. static bool supportsSparc64(uint64_t Type) {
  213. switch (Type) {
  214. case ELF::R_SPARC_32:
  215. case ELF::R_SPARC_64:
  216. case ELF::R_SPARC_UA32:
  217. case ELF::R_SPARC_UA64:
  218. return true;
  219. default:
  220. return false;
  221. }
  222. }
  223. static uint64_t resolveSparc64(uint64_t Type, uint64_t Offset, uint64_t S,
  224. uint64_t /*LocData*/, int64_t Addend) {
  225. switch (Type) {
  226. case ELF::R_SPARC_32:
  227. case ELF::R_SPARC_64:
  228. case ELF::R_SPARC_UA32:
  229. case ELF::R_SPARC_UA64:
  230. return S + Addend;
  231. default:
  232. llvm_unreachable("Invalid relocation type");
  233. }
  234. }
  235. static bool supportsAmdgpu(uint64_t Type) {
  236. switch (Type) {
  237. case ELF::R_AMDGPU_ABS32:
  238. case ELF::R_AMDGPU_ABS64:
  239. return true;
  240. default:
  241. return false;
  242. }
  243. }
  244. static uint64_t resolveAmdgpu(uint64_t Type, uint64_t Offset, uint64_t S,
  245. uint64_t /*LocData*/, int64_t Addend) {
  246. switch (Type) {
  247. case ELF::R_AMDGPU_ABS32:
  248. case ELF::R_AMDGPU_ABS64:
  249. return S + Addend;
  250. default:
  251. llvm_unreachable("Invalid relocation type");
  252. }
  253. }
  254. static bool supportsX86(uint64_t Type) {
  255. switch (Type) {
  256. case ELF::R_386_NONE:
  257. case ELF::R_386_32:
  258. case ELF::R_386_PC32:
  259. return true;
  260. default:
  261. return false;
  262. }
  263. }
  264. static uint64_t resolveX86(uint64_t Type, uint64_t Offset, uint64_t S,
  265. uint64_t LocData, int64_t /*Addend*/) {
  266. switch (Type) {
  267. case ELF::R_386_NONE:
  268. return LocData;
  269. case ELF::R_386_32:
  270. return S + LocData;
  271. case ELF::R_386_PC32:
  272. return S - Offset + LocData;
  273. default:
  274. llvm_unreachable("Invalid relocation type");
  275. }
  276. }
  277. static bool supportsPPC32(uint64_t Type) {
  278. switch (Type) {
  279. case ELF::R_PPC_ADDR32:
  280. case ELF::R_PPC_REL32:
  281. return true;
  282. default:
  283. return false;
  284. }
  285. }
  286. static uint64_t resolvePPC32(uint64_t Type, uint64_t Offset, uint64_t S,
  287. uint64_t /*LocData*/, int64_t Addend) {
  288. switch (Type) {
  289. case ELF::R_PPC_ADDR32:
  290. return (S + Addend) & 0xFFFFFFFF;
  291. case ELF::R_PPC_REL32:
  292. return (S + Addend - Offset) & 0xFFFFFFFF;
  293. }
  294. llvm_unreachable("Invalid relocation type");
  295. }
  296. static bool supportsARM(uint64_t Type) {
  297. switch (Type) {
  298. case ELF::R_ARM_ABS32:
  299. case ELF::R_ARM_REL32:
  300. return true;
  301. default:
  302. return false;
  303. }
  304. }
  305. static uint64_t resolveARM(uint64_t Type, uint64_t Offset, uint64_t S,
  306. uint64_t LocData, int64_t Addend) {
  307. // Support both RELA and REL relocations. The caller is responsible
  308. // for supplying the correct values for LocData and Addend, i.e.
  309. // Addend == 0 for REL and LocData == 0 for RELA.
  310. assert((LocData == 0 || Addend == 0) &&
  311. "one of LocData and Addend must be 0");
  312. switch (Type) {
  313. case ELF::R_ARM_ABS32:
  314. return (S + LocData + Addend) & 0xFFFFFFFF;
  315. case ELF::R_ARM_REL32:
  316. return (S + LocData + Addend - Offset) & 0xFFFFFFFF;
  317. }
  318. llvm_unreachable("Invalid relocation type");
  319. }
  320. static bool supportsAVR(uint64_t Type) {
  321. switch (Type) {
  322. case ELF::R_AVR_16:
  323. case ELF::R_AVR_32:
  324. return true;
  325. default:
  326. return false;
  327. }
  328. }
  329. static uint64_t resolveAVR(uint64_t Type, uint64_t Offset, uint64_t S,
  330. uint64_t /*LocData*/, int64_t Addend) {
  331. switch (Type) {
  332. case ELF::R_AVR_16:
  333. return (S + Addend) & 0xFFFF;
  334. case ELF::R_AVR_32:
  335. return (S + Addend) & 0xFFFFFFFF;
  336. default:
  337. llvm_unreachable("Invalid relocation type");
  338. }
  339. }
  340. static bool supportsLanai(uint64_t Type) {
  341. return Type == ELF::R_LANAI_32;
  342. }
  343. static uint64_t resolveLanai(uint64_t Type, uint64_t Offset, uint64_t S,
  344. uint64_t /*LocData*/, int64_t Addend) {
  345. if (Type == ELF::R_LANAI_32)
  346. return (S + Addend) & 0xFFFFFFFF;
  347. llvm_unreachable("Invalid relocation type");
  348. }
  349. static bool supportsMips32(uint64_t Type) {
  350. switch (Type) {
  351. case ELF::R_MIPS_32:
  352. case ELF::R_MIPS_TLS_DTPREL32:
  353. return true;
  354. default:
  355. return false;
  356. }
  357. }
  358. static uint64_t resolveMips32(uint64_t Type, uint64_t Offset, uint64_t S,
  359. uint64_t LocData, int64_t /*Addend*/) {
  360. // FIXME: Take in account implicit addends to get correct results.
  361. if (Type == ELF::R_MIPS_32)
  362. return (S + LocData) & 0xFFFFFFFF;
  363. if (Type == ELF::R_MIPS_TLS_DTPREL32)
  364. return (S + LocData) & 0xFFFFFFFF;
  365. llvm_unreachable("Invalid relocation type");
  366. }
  367. static bool supportsSparc32(uint64_t Type) {
  368. switch (Type) {
  369. case ELF::R_SPARC_32:
  370. case ELF::R_SPARC_UA32:
  371. return true;
  372. default:
  373. return false;
  374. }
  375. }
  376. static uint64_t resolveSparc32(uint64_t Type, uint64_t Offset, uint64_t S,
  377. uint64_t LocData, int64_t Addend) {
  378. if (Type == ELF::R_SPARC_32 || Type == ELF::R_SPARC_UA32)
  379. return S + Addend;
  380. return LocData;
  381. }
  382. static bool supportsHexagon(uint64_t Type) {
  383. return Type == ELF::R_HEX_32;
  384. }
  385. static uint64_t resolveHexagon(uint64_t Type, uint64_t Offset, uint64_t S,
  386. uint64_t /*LocData*/, int64_t Addend) {
  387. if (Type == ELF::R_HEX_32)
  388. return S + Addend;
  389. llvm_unreachable("Invalid relocation type");
  390. }
  391. static bool supportsRISCV(uint64_t Type) {
  392. switch (Type) {
  393. case ELF::R_RISCV_NONE:
  394. case ELF::R_RISCV_32:
  395. case ELF::R_RISCV_32_PCREL:
  396. case ELF::R_RISCV_64:
  397. case ELF::R_RISCV_SET6:
  398. case ELF::R_RISCV_SET8:
  399. case ELF::R_RISCV_SUB6:
  400. case ELF::R_RISCV_ADD8:
  401. case ELF::R_RISCV_SUB8:
  402. case ELF::R_RISCV_SET16:
  403. case ELF::R_RISCV_ADD16:
  404. case ELF::R_RISCV_SUB16:
  405. case ELF::R_RISCV_SET32:
  406. case ELF::R_RISCV_ADD32:
  407. case ELF::R_RISCV_SUB32:
  408. case ELF::R_RISCV_ADD64:
  409. case ELF::R_RISCV_SUB64:
  410. return true;
  411. default:
  412. return false;
  413. }
  414. }
  415. static uint64_t resolveRISCV(uint64_t Type, uint64_t Offset, uint64_t S,
  416. uint64_t LocData, int64_t Addend) {
  417. int64_t RA = Addend;
  418. uint64_t A = LocData;
  419. switch (Type) {
  420. case ELF::R_RISCV_NONE:
  421. return LocData;
  422. case ELF::R_RISCV_32:
  423. return (S + RA) & 0xFFFFFFFF;
  424. case ELF::R_RISCV_32_PCREL:
  425. return (S + RA - Offset) & 0xFFFFFFFF;
  426. case ELF::R_RISCV_64:
  427. return S + RA;
  428. case ELF::R_RISCV_SET6:
  429. return (A & 0xC0) | ((S + RA) & 0x3F);
  430. case ELF::R_RISCV_SUB6:
  431. return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
  432. case ELF::R_RISCV_SET8:
  433. return (S + RA) & 0xFF;
  434. case ELF::R_RISCV_ADD8:
  435. return (A + (S + RA)) & 0xFF;
  436. case ELF::R_RISCV_SUB8:
  437. return (A - (S + RA)) & 0xFF;
  438. case ELF::R_RISCV_SET16:
  439. return (S + RA) & 0xFFFF;
  440. case ELF::R_RISCV_ADD16:
  441. return (A + (S + RA)) & 0xFFFF;
  442. case ELF::R_RISCV_SUB16:
  443. return (A - (S + RA)) & 0xFFFF;
  444. case ELF::R_RISCV_SET32:
  445. return (S + RA) & 0xFFFFFFFF;
  446. case ELF::R_RISCV_ADD32:
  447. return (A + (S + RA)) & 0xFFFFFFFF;
  448. case ELF::R_RISCV_SUB32:
  449. return (A - (S + RA)) & 0xFFFFFFFF;
  450. case ELF::R_RISCV_ADD64:
  451. return (A + (S + RA));
  452. case ELF::R_RISCV_SUB64:
  453. return (A - (S + RA));
  454. default:
  455. llvm_unreachable("Invalid relocation type");
  456. }
  457. }
  458. static bool supportsCSKY(uint64_t Type) {
  459. switch (Type) {
  460. case ELF::R_CKCORE_NONE:
  461. case ELF::R_CKCORE_ADDR32:
  462. case ELF::R_CKCORE_PCREL32:
  463. return true;
  464. default:
  465. return false;
  466. }
  467. }
  468. static uint64_t resolveCSKY(uint64_t Type, uint64_t Offset, uint64_t S,
  469. uint64_t LocData, int64_t Addend) {
  470. switch (Type) {
  471. case ELF::R_CKCORE_NONE:
  472. return LocData;
  473. case ELF::R_CKCORE_ADDR32:
  474. return (S + Addend) & 0xFFFFFFFF;
  475. case ELF::R_CKCORE_PCREL32:
  476. return (S + Addend - Offset) & 0xFFFFFFFF;
  477. default:
  478. llvm_unreachable("Invalid relocation type");
  479. }
  480. }
  481. static bool supportsLoongArch(uint64_t Type) {
  482. switch (Type) {
  483. case ELF::R_LARCH_NONE:
  484. case ELF::R_LARCH_32:
  485. case ELF::R_LARCH_32_PCREL:
  486. case ELF::R_LARCH_64:
  487. case ELF::R_LARCH_ADD8:
  488. case ELF::R_LARCH_SUB8:
  489. case ELF::R_LARCH_ADD16:
  490. case ELF::R_LARCH_SUB16:
  491. case ELF::R_LARCH_ADD32:
  492. case ELF::R_LARCH_SUB32:
  493. case ELF::R_LARCH_ADD64:
  494. case ELF::R_LARCH_SUB64:
  495. return true;
  496. default:
  497. return false;
  498. }
  499. }
  500. static uint64_t resolveLoongArch(uint64_t Type, uint64_t Offset, uint64_t S,
  501. uint64_t LocData, int64_t Addend) {
  502. switch (Type) {
  503. case ELF::R_LARCH_NONE:
  504. return LocData;
  505. case ELF::R_LARCH_32:
  506. return (S + Addend) & 0xFFFFFFFF;
  507. case ELF::R_LARCH_32_PCREL:
  508. return (S + Addend - Offset) & 0xFFFFFFFF;
  509. case ELF::R_LARCH_64:
  510. return S + Addend;
  511. case ELF::R_LARCH_ADD8:
  512. return (LocData + (S + Addend)) & 0xFF;
  513. case ELF::R_LARCH_SUB8:
  514. return (LocData - (S + Addend)) & 0xFF;
  515. case ELF::R_LARCH_ADD16:
  516. return (LocData + (S + Addend)) & 0xFFFF;
  517. case ELF::R_LARCH_SUB16:
  518. return (LocData - (S + Addend)) & 0xFFFF;
  519. case ELF::R_LARCH_ADD32:
  520. return (LocData + (S + Addend)) & 0xFFFFFFFF;
  521. case ELF::R_LARCH_SUB32:
  522. return (LocData - (S + Addend)) & 0xFFFFFFFF;
  523. case ELF::R_LARCH_ADD64:
  524. return (LocData + (S + Addend));
  525. case ELF::R_LARCH_SUB64:
  526. return (LocData - (S + Addend));
  527. default:
  528. llvm_unreachable("Invalid relocation type");
  529. }
  530. }
  531. static bool supportsCOFFX86(uint64_t Type) {
  532. switch (Type) {
  533. case COFF::IMAGE_REL_I386_SECREL:
  534. case COFF::IMAGE_REL_I386_DIR32:
  535. return true;
  536. default:
  537. return false;
  538. }
  539. }
  540. static uint64_t resolveCOFFX86(uint64_t Type, uint64_t Offset, uint64_t S,
  541. uint64_t LocData, int64_t /*Addend*/) {
  542. switch (Type) {
  543. case COFF::IMAGE_REL_I386_SECREL:
  544. case COFF::IMAGE_REL_I386_DIR32:
  545. return (S + LocData) & 0xFFFFFFFF;
  546. default:
  547. llvm_unreachable("Invalid relocation type");
  548. }
  549. }
  550. static bool supportsCOFFX86_64(uint64_t Type) {
  551. switch (Type) {
  552. case COFF::IMAGE_REL_AMD64_SECREL:
  553. case COFF::IMAGE_REL_AMD64_ADDR64:
  554. return true;
  555. default:
  556. return false;
  557. }
  558. }
  559. static uint64_t resolveCOFFX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
  560. uint64_t LocData, int64_t /*Addend*/) {
  561. switch (Type) {
  562. case COFF::IMAGE_REL_AMD64_SECREL:
  563. return (S + LocData) & 0xFFFFFFFF;
  564. case COFF::IMAGE_REL_AMD64_ADDR64:
  565. return S + LocData;
  566. default:
  567. llvm_unreachable("Invalid relocation type");
  568. }
  569. }
  570. static bool supportsCOFFARM(uint64_t Type) {
  571. switch (Type) {
  572. case COFF::IMAGE_REL_ARM_SECREL:
  573. case COFF::IMAGE_REL_ARM_ADDR32:
  574. return true;
  575. default:
  576. return false;
  577. }
  578. }
  579. static uint64_t resolveCOFFARM(uint64_t Type, uint64_t Offset, uint64_t S,
  580. uint64_t LocData, int64_t /*Addend*/) {
  581. switch (Type) {
  582. case COFF::IMAGE_REL_ARM_SECREL:
  583. case COFF::IMAGE_REL_ARM_ADDR32:
  584. return (S + LocData) & 0xFFFFFFFF;
  585. default:
  586. llvm_unreachable("Invalid relocation type");
  587. }
  588. }
  589. static bool supportsCOFFARM64(uint64_t Type) {
  590. switch (Type) {
  591. case COFF::IMAGE_REL_ARM64_SECREL:
  592. case COFF::IMAGE_REL_ARM64_ADDR64:
  593. return true;
  594. default:
  595. return false;
  596. }
  597. }
  598. static uint64_t resolveCOFFARM64(uint64_t Type, uint64_t Offset, uint64_t S,
  599. uint64_t LocData, int64_t /*Addend*/) {
  600. switch (Type) {
  601. case COFF::IMAGE_REL_ARM64_SECREL:
  602. return (S + LocData) & 0xFFFFFFFF;
  603. case COFF::IMAGE_REL_ARM64_ADDR64:
  604. return S + LocData;
  605. default:
  606. llvm_unreachable("Invalid relocation type");
  607. }
  608. }
  609. static bool supportsMachOX86_64(uint64_t Type) {
  610. return Type == MachO::X86_64_RELOC_UNSIGNED;
  611. }
  612. static uint64_t resolveMachOX86_64(uint64_t Type, uint64_t Offset, uint64_t S,
  613. uint64_t LocData, int64_t /*Addend*/) {
  614. if (Type == MachO::X86_64_RELOC_UNSIGNED)
  615. return S;
  616. llvm_unreachable("Invalid relocation type");
  617. }
  618. static bool supportsWasm32(uint64_t Type) {
  619. switch (Type) {
  620. case wasm::R_WASM_FUNCTION_INDEX_LEB:
  621. case wasm::R_WASM_TABLE_INDEX_SLEB:
  622. case wasm::R_WASM_TABLE_INDEX_I32:
  623. case wasm::R_WASM_MEMORY_ADDR_LEB:
  624. case wasm::R_WASM_MEMORY_ADDR_SLEB:
  625. case wasm::R_WASM_MEMORY_ADDR_I32:
  626. case wasm::R_WASM_TYPE_INDEX_LEB:
  627. case wasm::R_WASM_GLOBAL_INDEX_LEB:
  628. case wasm::R_WASM_FUNCTION_OFFSET_I32:
  629. case wasm::R_WASM_SECTION_OFFSET_I32:
  630. case wasm::R_WASM_TAG_INDEX_LEB:
  631. case wasm::R_WASM_GLOBAL_INDEX_I32:
  632. case wasm::R_WASM_TABLE_NUMBER_LEB:
  633. case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
  634. return true;
  635. default:
  636. return false;
  637. }
  638. }
  639. static bool supportsWasm64(uint64_t Type) {
  640. switch (Type) {
  641. case wasm::R_WASM_MEMORY_ADDR_LEB64:
  642. case wasm::R_WASM_MEMORY_ADDR_SLEB64:
  643. case wasm::R_WASM_MEMORY_ADDR_I64:
  644. case wasm::R_WASM_TABLE_INDEX_SLEB64:
  645. case wasm::R_WASM_TABLE_INDEX_I64:
  646. case wasm::R_WASM_FUNCTION_OFFSET_I64:
  647. return true;
  648. default:
  649. return supportsWasm32(Type);
  650. }
  651. }
  652. static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
  653. uint64_t LocData, int64_t /*Addend*/) {
  654. switch (Type) {
  655. case wasm::R_WASM_FUNCTION_INDEX_LEB:
  656. case wasm::R_WASM_TABLE_INDEX_SLEB:
  657. case wasm::R_WASM_TABLE_INDEX_I32:
  658. case wasm::R_WASM_MEMORY_ADDR_LEB:
  659. case wasm::R_WASM_MEMORY_ADDR_SLEB:
  660. case wasm::R_WASM_MEMORY_ADDR_I32:
  661. case wasm::R_WASM_TYPE_INDEX_LEB:
  662. case wasm::R_WASM_GLOBAL_INDEX_LEB:
  663. case wasm::R_WASM_FUNCTION_OFFSET_I32:
  664. case wasm::R_WASM_SECTION_OFFSET_I32:
  665. case wasm::R_WASM_TAG_INDEX_LEB:
  666. case wasm::R_WASM_GLOBAL_INDEX_I32:
  667. case wasm::R_WASM_TABLE_NUMBER_LEB:
  668. case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
  669. // For wasm section, its offset at 0 -- ignoring Value
  670. return LocData;
  671. default:
  672. llvm_unreachable("Invalid relocation type");
  673. }
  674. }
  675. static uint64_t resolveWasm64(uint64_t Type, uint64_t Offset, uint64_t S,
  676. uint64_t LocData, int64_t Addend) {
  677. switch (Type) {
  678. case wasm::R_WASM_MEMORY_ADDR_LEB64:
  679. case wasm::R_WASM_MEMORY_ADDR_SLEB64:
  680. case wasm::R_WASM_MEMORY_ADDR_I64:
  681. case wasm::R_WASM_TABLE_INDEX_SLEB64:
  682. case wasm::R_WASM_TABLE_INDEX_I64:
  683. case wasm::R_WASM_FUNCTION_OFFSET_I64:
  684. // For wasm section, its offset at 0 -- ignoring Value
  685. return LocData;
  686. default:
  687. return resolveWasm32(Type, Offset, S, LocData, Addend);
  688. }
  689. }
  690. std::pair<SupportsRelocation, RelocationResolver>
  691. getRelocationResolver(const ObjectFile &Obj) {
  692. if (Obj.isCOFF()) {
  693. switch (Obj.getArch()) {
  694. case Triple::x86_64:
  695. return {supportsCOFFX86_64, resolveCOFFX86_64};
  696. case Triple::x86:
  697. return {supportsCOFFX86, resolveCOFFX86};
  698. case Triple::arm:
  699. case Triple::thumb:
  700. return {supportsCOFFARM, resolveCOFFARM};
  701. case Triple::aarch64:
  702. return {supportsCOFFARM64, resolveCOFFARM64};
  703. default:
  704. return {nullptr, nullptr};
  705. }
  706. } else if (Obj.isELF()) {
  707. if (Obj.getBytesInAddress() == 8) {
  708. switch (Obj.getArch()) {
  709. case Triple::x86_64:
  710. return {supportsX86_64, resolveX86_64};
  711. case Triple::aarch64:
  712. case Triple::aarch64_be:
  713. return {supportsAArch64, resolveAArch64};
  714. case Triple::bpfel:
  715. case Triple::bpfeb:
  716. return {supportsBPF, resolveBPF};
  717. case Triple::loongarch64:
  718. return {supportsLoongArch, resolveLoongArch};
  719. case Triple::mips64el:
  720. case Triple::mips64:
  721. return {supportsMips64, resolveMips64};
  722. case Triple::ppc64le:
  723. case Triple::ppc64:
  724. return {supportsPPC64, resolvePPC64};
  725. case Triple::systemz:
  726. return {supportsSystemZ, resolveSystemZ};
  727. case Triple::sparcv9:
  728. return {supportsSparc64, resolveSparc64};
  729. case Triple::amdgcn:
  730. return {supportsAmdgpu, resolveAmdgpu};
  731. case Triple::riscv64:
  732. return {supportsRISCV, resolveRISCV};
  733. default:
  734. return {nullptr, nullptr};
  735. }
  736. }
  737. // 32-bit object file
  738. assert(Obj.getBytesInAddress() == 4 &&
  739. "Invalid word size in object file");
  740. switch (Obj.getArch()) {
  741. case Triple::x86:
  742. return {supportsX86, resolveX86};
  743. case Triple::ppcle:
  744. case Triple::ppc:
  745. return {supportsPPC32, resolvePPC32};
  746. case Triple::arm:
  747. case Triple::armeb:
  748. return {supportsARM, resolveARM};
  749. case Triple::avr:
  750. return {supportsAVR, resolveAVR};
  751. case Triple::lanai:
  752. return {supportsLanai, resolveLanai};
  753. case Triple::loongarch32:
  754. return {supportsLoongArch, resolveLoongArch};
  755. case Triple::mipsel:
  756. case Triple::mips:
  757. return {supportsMips32, resolveMips32};
  758. case Triple::msp430:
  759. return {supportsMSP430, resolveMSP430};
  760. case Triple::sparc:
  761. return {supportsSparc32, resolveSparc32};
  762. case Triple::hexagon:
  763. return {supportsHexagon, resolveHexagon};
  764. case Triple::riscv32:
  765. return {supportsRISCV, resolveRISCV};
  766. case Triple::csky:
  767. return {supportsCSKY, resolveCSKY};
  768. default:
  769. return {nullptr, nullptr};
  770. }
  771. } else if (Obj.isMachO()) {
  772. if (Obj.getArch() == Triple::x86_64)
  773. return {supportsMachOX86_64, resolveMachOX86_64};
  774. return {nullptr, nullptr};
  775. } else if (Obj.isWasm()) {
  776. if (Obj.getArch() == Triple::wasm32)
  777. return {supportsWasm32, resolveWasm32};
  778. if (Obj.getArch() == Triple::wasm64)
  779. return {supportsWasm64, resolveWasm64};
  780. return {nullptr, nullptr};
  781. }
  782. llvm_unreachable("Invalid object file");
  783. }
  784. uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
  785. uint64_t S, uint64_t LocData) {
  786. if (const ObjectFile *Obj = R.getObject()) {
  787. int64_t Addend = 0;
  788. if (Obj->isELF()) {
  789. auto GetRelSectionType = [&]() -> unsigned {
  790. if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
  791. return Elf32LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
  792. if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
  793. return Elf64LEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
  794. if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
  795. return Elf32BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
  796. auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj);
  797. return Elf64BEObj->getRelSection(R.getRawDataRefImpl())->sh_type;
  798. };
  799. if (GetRelSectionType() == ELF::SHT_RELA) {
  800. Addend = getELFAddend(R);
  801. // RISCV relocations use both LocData and Addend.
  802. if (Obj->getArch() != Triple::riscv32 &&
  803. Obj->getArch() != Triple::riscv64)
  804. LocData = 0;
  805. }
  806. }
  807. return Resolver(R.getType(), R.getOffset(), S, LocData, Addend);
  808. }
  809. // Sometimes the caller might want to use its own specific implementation of
  810. // the resolver function. E.g. this is used by LLD when it resolves debug
  811. // relocations and assumes that all of them have the same computation (S + A).
  812. // The relocation R has no owner object in this case and we don't need to
  813. // provide Type and Offset fields. It is also assumed the DataRefImpl.p
  814. // contains the addend, provided by the caller.
  815. return Resolver(/*Type=*/0, /*Offset=*/0, S, LocData,
  816. R.getRawDataRefImpl().p);
  817. }
  818. } // namespace object
  819. } // namespace llvm