[linker] Adds elf_compat.h, util.h, elf_util.h
authorMoritz Angermann <moritz.angermann@gmail.com>
Sun, 23 Apr 2017 14:02:21 +0000 (10:02 -0400)
committerBen Gamari <ben@smart-cactus.org>
Sun, 23 Apr 2017 15:05:48 +0000 (11:05 -0400)
Further cleanup of the linker, we'll add elf_compat.h for a more
complete set of relocations.

Also Util.h has been added as suggested in the code already.

Depends on D3444, D3445

Reviewers: bgamari, austin, erikd, simonmar

Reviewed By: simonmar

Subscribers: rwbarton, thomie

Differential Revision: https://phabricator.haskell.org/D3446

rts/linker/ELFRelocs/AArch64.def [new file with mode: 0644]
rts/linker/ELFRelocs/ARM.def [new file with mode: 0644]
rts/linker/ELFRelocs/LICENSE-LLVM.TXT [new file with mode: 0644]
rts/linker/ELFRelocs/i386.def [new file with mode: 0644]
rts/linker/ELFRelocs/x86_64.def [new file with mode: 0644]
rts/linker/Elf.c
rts/linker/elf_compat.h [new file with mode: 0644]
rts/linker/elf_util.c [new file with mode: 0644]
rts/linker/elf_util.h [new file with mode: 0644]
rts/linker/util.h [new file with mode: 0644]

diff --git a/rts/linker/ELFRelocs/AArch64.def b/rts/linker/ELFRelocs/AArch64.def
new file mode 100644 (file)
index 0000000..c21df07
--- /dev/null
@@ -0,0 +1,201 @@
+
+#ifndef ELF_RELOC
+#error "ELF_RELOC must be defined"
+#endif
+
+// Based on ABI release 1.1-beta, dated 6 November 2013. NB: The cover page of
+// this document, IHI0056C_beta_aaelf64.pdf, on infocenter.arm.com, still
+// labels this as release 1.0.
+ELF_RELOC(R_AARCH64_NONE,                                0)
+ELF_RELOC(R_AARCH64_ABS64,                           0x101)
+ELF_RELOC(R_AARCH64_ABS32,                           0x102)
+ELF_RELOC(R_AARCH64_ABS16,                           0x103)
+ELF_RELOC(R_AARCH64_PREL64,                          0x104)
+ELF_RELOC(R_AARCH64_PREL32,                          0x105)
+ELF_RELOC(R_AARCH64_PREL16,                          0x106)
+ELF_RELOC(R_AARCH64_MOVW_UABS_G0,                    0x107)
+ELF_RELOC(R_AARCH64_MOVW_UABS_G0_NC,                 0x108)
+ELF_RELOC(R_AARCH64_MOVW_UABS_G1,                    0x109)
+ELF_RELOC(R_AARCH64_MOVW_UABS_G1_NC,                 0x10a)
+ELF_RELOC(R_AARCH64_MOVW_UABS_G2,                    0x10b)
+ELF_RELOC(R_AARCH64_MOVW_UABS_G2_NC,                 0x10c)
+ELF_RELOC(R_AARCH64_MOVW_UABS_G3,                    0x10d)
+ELF_RELOC(R_AARCH64_MOVW_SABS_G0,                    0x10e)
+ELF_RELOC(R_AARCH64_MOVW_SABS_G1,                    0x10f)
+ELF_RELOC(R_AARCH64_MOVW_SABS_G2,                    0x110)
+ELF_RELOC(R_AARCH64_LD_PREL_LO19,                    0x111)
+ELF_RELOC(R_AARCH64_ADR_PREL_LO21,                   0x112)
+ELF_RELOC(R_AARCH64_ADR_PREL_PG_HI21,                0x113)
+ELF_RELOC(R_AARCH64_ADR_PREL_PG_HI21_NC,             0x114)
+ELF_RELOC(R_AARCH64_ADD_ABS_LO12_NC,                 0x115)
+ELF_RELOC(R_AARCH64_LDST8_ABS_LO12_NC,               0x116)
+ELF_RELOC(R_AARCH64_TSTBR14,                         0x117)
+ELF_RELOC(R_AARCH64_CONDBR19,                        0x118)
+ELF_RELOC(R_AARCH64_JUMP26,                          0x11a)
+ELF_RELOC(R_AARCH64_CALL26,                          0x11b)
+ELF_RELOC(R_AARCH64_LDST16_ABS_LO12_NC,              0x11c)
+ELF_RELOC(R_AARCH64_LDST32_ABS_LO12_NC,              0x11d)
+ELF_RELOC(R_AARCH64_LDST64_ABS_LO12_NC,              0x11e)
+ELF_RELOC(R_AARCH64_MOVW_PREL_G0,                    0x11f)
+ELF_RELOC(R_AARCH64_MOVW_PREL_G0_NC,                 0x120)
+ELF_RELOC(R_AARCH64_MOVW_PREL_G1,                    0x121)
+ELF_RELOC(R_AARCH64_MOVW_PREL_G1_NC,                 0x122)
+ELF_RELOC(R_AARCH64_MOVW_PREL_G2,                    0x123)
+ELF_RELOC(R_AARCH64_MOVW_PREL_G2_NC,                 0x124)
+ELF_RELOC(R_AARCH64_MOVW_PREL_G3,                    0x125)
+ELF_RELOC(R_AARCH64_LDST128_ABS_LO12_NC,             0x12b)
+ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G0,                  0x12c)
+ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G0_NC,               0x12d)
+ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G1,                  0x12e)
+ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G1_NC,               0x12f)
+ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G2,                  0x130)
+ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G2_NC,               0x131)
+ELF_RELOC(R_AARCH64_MOVW_GOTOFF_G3,                  0x132)
+ELF_RELOC(R_AARCH64_GOTREL64,                        0x133)
+ELF_RELOC(R_AARCH64_GOTREL32,                        0x134)
+ELF_RELOC(R_AARCH64_GOT_LD_PREL19,                   0x135)
+ELF_RELOC(R_AARCH64_LD64_GOTOFF_LO15,                0x136)
+ELF_RELOC(R_AARCH64_ADR_GOT_PAGE,                    0x137)
+ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC,                0x138)
+ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15,               0x139)
+ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21,                0x200)
+ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21,                0x201)
+ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC,               0x202)
+ELF_RELOC(R_AARCH64_TLSGD_MOVW_G1,                   0x203)
+ELF_RELOC(R_AARCH64_TLSGD_MOVW_G0_NC,                0x204)
+ELF_RELOC(R_AARCH64_TLSLD_ADR_PREL21,                0x205)
+ELF_RELOC(R_AARCH64_TLSLD_ADR_PAGE21,                0x206)
+ELF_RELOC(R_AARCH64_TLSLD_ADD_LO12_NC,               0x207)
+ELF_RELOC(R_AARCH64_TLSLD_MOVW_G1,                   0x208)
+ELF_RELOC(R_AARCH64_TLSLD_MOVW_G0_NC,                0x209)
+ELF_RELOC(R_AARCH64_TLSLD_LD_PREL19,                 0x20a)
+ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G2,            0x20b)
+ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1,            0x20c)
+ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC,         0x20d)
+ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0,            0x20e)
+ELF_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC,         0x20f)
+ELF_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_HI12,           0x210)
+ELF_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_LO12,           0x211)
+ELF_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC,        0x212)
+ELF_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12,         0x213)
+ELF_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC,      0x214)
+ELF_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12,        0x215)
+ELF_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC,     0x216)
+ELF_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12,        0x217)
+ELF_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC,     0x218)
+ELF_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12,        0x219)
+ELF_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC,     0x21a)
+ELF_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1,          0x21b)
+ELF_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC,       0x21c)
+ELF_RELOC(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21,       0x21d)
+ELF_RELOC(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC,     0x21e)
+ELF_RELOC(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19,        0x21f)
+ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G2,             0x220)
+ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1,             0x221)
+ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC,          0x222)
+ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0,             0x223)
+ELF_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC,          0x224)
+ELF_RELOC(R_AARCH64_TLSLE_ADD_TPREL_HI12,            0x225)
+ELF_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12,            0x226)
+ELF_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC,         0x227)
+ELF_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12,          0x228)
+ELF_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC,       0x229)
+ELF_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12,         0x22a)
+ELF_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC,      0x22b)
+ELF_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12,         0x22c)
+ELF_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC,      0x22d)
+ELF_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12,         0x22e)
+ELF_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC,      0x22f)
+ELF_RELOC(R_AARCH64_TLSDESC_LD_PREL19,               0x230)
+ELF_RELOC(R_AARCH64_TLSDESC_ADR_PREL21,              0x231)
+ELF_RELOC(R_AARCH64_TLSDESC_ADR_PAGE21,              0x232)
+ELF_RELOC(R_AARCH64_TLSDESC_LD64_LO12_NC,            0x233)
+ELF_RELOC(R_AARCH64_TLSDESC_ADD_LO12_NC,             0x234)
+ELF_RELOC(R_AARCH64_TLSDESC_OFF_G1,                  0x235)
+ELF_RELOC(R_AARCH64_TLSDESC_OFF_G0_NC,               0x236)
+ELF_RELOC(R_AARCH64_TLSDESC_LDR,                     0x237)
+ELF_RELOC(R_AARCH64_TLSDESC_ADD,                     0x238)
+ELF_RELOC(R_AARCH64_TLSDESC_CALL,                    0x239)
+ELF_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12,        0x23a)
+ELF_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC,     0x23b)
+ELF_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12,       0x23c)
+ELF_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC,    0x23d)
+ELF_RELOC(R_AARCH64_COPY,                            0x400)
+ELF_RELOC(R_AARCH64_GLOB_DAT,                        0x401)
+ELF_RELOC(R_AARCH64_JUMP_SLOT,                       0x402)
+ELF_RELOC(R_AARCH64_RELATIVE,                        0x403)
+ELF_RELOC(R_AARCH64_TLS_DTPREL64,                    0x404)
+ELF_RELOC(R_AARCH64_TLS_DTPMOD64,                    0x405)
+ELF_RELOC(R_AARCH64_TLS_TPREL64,                     0x406)
+ELF_RELOC(R_AARCH64_TLSDESC,                         0x407)
+ELF_RELOC(R_AARCH64_IRELATIVE,                       0x408)
+
+// ELF_RELOC(R_AARCH64_P32_NONE,                         0)
+ELF_RELOC(R_AARCH64_P32_ABS32,                       0x001)
+ELF_RELOC(R_AARCH64_P32_ABS16,                       0x002)
+ELF_RELOC(R_AARCH64_P32_PREL32,                      0x003)
+ELF_RELOC(R_AARCH64_P32_PREL16,                      0x004)
+ELF_RELOC(R_AARCH64_P32_MOVW_UABS_G0,                0x005)
+ELF_RELOC(R_AARCH64_P32_MOVW_UABS_G0_NC,             0x006)
+ELF_RELOC(R_AARCH64_P32_MOVW_UABS_G1,                0x007)
+ELF_RELOC(R_AARCH64_P32_MOVW_SABS_G0,                0x008)
+ELF_RELOC(R_AARCH64_P32_LD_PREL_LO19,                0x009)
+ELF_RELOC(R_AARCH64_P32_ADR_PREL_LO21,               0x00a)
+ELF_RELOC(R_AARCH64_P32_ADR_PREL_PG_HI21,            0x00b)
+ELF_RELOC(R_AARCH64_P32_ADD_ABS_LO12_NC,             0x00c)
+ELF_RELOC(R_AARCH64_P32_LDST8_ABS_LO12_NC,           0x00d)
+ELF_RELOC(R_AARCH64_P32_TSTBR14,                     0x012)
+ELF_RELOC(R_AARCH64_P32_CONDBR19,                    0x013)
+ELF_RELOC(R_AARCH64_P32_JUMP26,                      0x014)
+ELF_RELOC(R_AARCH64_P32_CALL26,                      0x015)
+ELF_RELOC(R_AARCH64_P32_LDST16_ABS_LO12_NC,          0x00e)
+ELF_RELOC(R_AARCH64_P32_LDST32_ABS_LO12_NC,          0x00f)
+ELF_RELOC(R_AARCH64_P32_LDST64_ABS_LO12_NC,          0x010)
+ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G0,                0x016)
+ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G0_NC,             0x017)
+ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G1,                0x018)
+ELF_RELOC(R_AARCH64_P32_LDST128_ABS_LO12_NC,         0x011)
+ELF_RELOC(R_AARCH64_P32_GOT_LD_PREL19,               0x019)
+ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE,                0x01a)
+ELF_RELOC(R_AARCH64_P32_LD64_GOT_LO12_NC,            0x01b)
+ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14,           0x01c)
+ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G1,        0x057)
+ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0,        0x058)
+ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0_NC,     0x059)
+ELF_RELOC(R_AARCH64_P32_TLSLD_ADD_DTPREL_HI12,       0x05a)
+ELF_RELOC(R_AARCH64_P32_TLSLD_ADD_DTPREL_LO12,       0x05b)
+ELF_RELOC(R_AARCH64_P32_TLSLD_ADD_DTPREL_LO12_NC,    0x05c)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST8_DTPREL_LO12,     0x05d)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST8_DTPREL_LO12_NC,  0x05e)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST16_DTPREL_LO12,    0x05f)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST16_DTPREL_LO12_NC, 0x060)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST32_DTPREL_LO12,    0x061)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST32_DTPREL_LO12_NC, 0x062)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST64_DTPREL_LO12,    0x063)
+ELF_RELOC(R_AARCH64_P32_TLSLD_LDST64_DTPREL_LO12_NC, 0x064)
+ELF_RELOC(R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21,   0x067)
+ELF_RELOC(R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC, 0x068)
+ELF_RELOC(R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19,    0x069)
+ELF_RELOC(R_AARCH64_P32_TLSLE_MOVW_TPREL_G1,         0x06a)
+ELF_RELOC(R_AARCH64_P32_TLSLE_MOVW_TPREL_G0,         0x06b)
+ELF_RELOC(R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC,      0x06c)
+ELF_RELOC(R_AARCH64_P32_TLSLE_ADD_TPREL_HI12,        0x06d)
+ELF_RELOC(R_AARCH64_P32_TLSLE_ADD_TPREL_LO12,        0x06e)
+ELF_RELOC(R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC,     0x06f)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12,      0x070)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12_NC,   0x071)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12,     0x072)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12_NC,  0x073)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12,     0x074)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12_NC,  0x075)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12,     0x076)
+ELF_RELOC(R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12_NC,  0x077)
+ELF_RELOC(R_AARCH64_P32_TLSDESC_ADR_PAGE21,          0x051)
+ELF_RELOC(R_AARCH64_P32_TLSDESC_LD32_LO12_NC,        0x07d)
+ELF_RELOC(R_AARCH64_P32_TLSDESC_ADD_LO12_NC,         0x034)
+ELF_RELOC(R_AARCH64_P32_TLSDESC_CALL,                0x07f)
+ELF_RELOC(R_AARCH64_P32_COPY,                        0x0b4)
+ELF_RELOC(R_AARCH64_P32_GLOB_DAT,                    0x0b5)
+ELF_RELOC(R_AARCH64_P32_JUMP_SLOT,                   0x0b6)
+ELF_RELOC(R_AARCH64_P32_RELATIVE,                    0x0b7)
+ELF_RELOC(R_AARCH64_P32_IRELATIVE,                   0x0bc)
diff --git a/rts/linker/ELFRelocs/ARM.def b/rts/linker/ELFRelocs/ARM.def
new file mode 100644 (file)
index 0000000..730fc5b
--- /dev/null
@@ -0,0 +1,138 @@
+
+#ifndef ELF_RELOC
+#error "ELF_RELOC must be defined"
+#endif
+
+// Meets 2.09 ABI Specs.
+ELF_RELOC(R_ARM_NONE,                   0x00)
+ELF_RELOC(R_ARM_PC24,                   0x01)
+ELF_RELOC(R_ARM_ABS32,                  0x02)
+ELF_RELOC(R_ARM_REL32,                  0x03)
+ELF_RELOC(R_ARM_LDR_PC_G0,              0x04)
+ELF_RELOC(R_ARM_ABS16,                  0x05)
+ELF_RELOC(R_ARM_ABS12,                  0x06)
+ELF_RELOC(R_ARM_THM_ABS5,               0x07)
+ELF_RELOC(R_ARM_ABS8,                   0x08)
+ELF_RELOC(R_ARM_SBREL32,                0x09)
+ELF_RELOC(R_ARM_THM_CALL,               0x0a)
+ELF_RELOC(R_ARM_THM_PC8,                0x0b)
+ELF_RELOC(R_ARM_BREL_ADJ,               0x0c)
+ELF_RELOC(R_ARM_TLS_DESC,               0x0d)
+ELF_RELOC(R_ARM_THM_SWI8,               0x0e)
+ELF_RELOC(R_ARM_XPC25,                  0x0f)
+ELF_RELOC(R_ARM_THM_XPC22,              0x10)
+ELF_RELOC(R_ARM_TLS_DTPMOD32,           0x11)
+ELF_RELOC(R_ARM_TLS_DTPOFF32,           0x12)
+ELF_RELOC(R_ARM_TLS_TPOFF32,            0x13)
+ELF_RELOC(R_ARM_COPY,                   0x14)
+ELF_RELOC(R_ARM_GLOB_DAT,               0x15)
+ELF_RELOC(R_ARM_JUMP_SLOT,              0x16)
+ELF_RELOC(R_ARM_RELATIVE,               0x17)
+ELF_RELOC(R_ARM_GOTOFF32,               0x18)
+ELF_RELOC(R_ARM_BASE_PREL,              0x19)
+ELF_RELOC(R_ARM_GOT_BREL,               0x1a)
+ELF_RELOC(R_ARM_PLT32,                  0x1b)
+ELF_RELOC(R_ARM_CALL,                   0x1c)
+ELF_RELOC(R_ARM_JUMP24,                 0x1d)
+ELF_RELOC(R_ARM_THM_JUMP24,             0x1e)
+ELF_RELOC(R_ARM_BASE_ABS,               0x1f)
+ELF_RELOC(R_ARM_ALU_PCREL_7_0,          0x20)
+ELF_RELOC(R_ARM_ALU_PCREL_15_8,         0x21)
+ELF_RELOC(R_ARM_ALU_PCREL_23_15,        0x22)
+ELF_RELOC(R_ARM_LDR_SBREL_11_0_NC,      0x23)
+ELF_RELOC(R_ARM_ALU_SBREL_19_12_NC,     0x24)
+ELF_RELOC(R_ARM_ALU_SBREL_27_20_CK,     0x25)
+ELF_RELOC(R_ARM_TARGET1,                0x26)
+ELF_RELOC(R_ARM_SBREL31,                0x27)
+ELF_RELOC(R_ARM_V4BX,                   0x28)
+ELF_RELOC(R_ARM_TARGET2,                0x29)
+ELF_RELOC(R_ARM_PREL31,                 0x2a)
+ELF_RELOC(R_ARM_MOVW_ABS_NC,            0x2b)
+ELF_RELOC(R_ARM_MOVT_ABS,               0x2c)
+ELF_RELOC(R_ARM_MOVW_PREL_NC,           0x2d)
+ELF_RELOC(R_ARM_MOVT_PREL,              0x2e)
+ELF_RELOC(R_ARM_THM_MOVW_ABS_NC,        0x2f)
+ELF_RELOC(R_ARM_THM_MOVT_ABS,           0x30)
+ELF_RELOC(R_ARM_THM_MOVW_PREL_NC,       0x31)
+ELF_RELOC(R_ARM_THM_MOVT_PREL,          0x32)
+ELF_RELOC(R_ARM_THM_JUMP19,             0x33)
+ELF_RELOC(R_ARM_THM_JUMP6,              0x34)
+ELF_RELOC(R_ARM_THM_ALU_PREL_11_0,      0x35)
+ELF_RELOC(R_ARM_THM_PC12,               0x36)
+ELF_RELOC(R_ARM_ABS32_NOI,              0x37)
+ELF_RELOC(R_ARM_REL32_NOI,              0x38)
+ELF_RELOC(R_ARM_ALU_PC_G0_NC,           0x39)
+ELF_RELOC(R_ARM_ALU_PC_G0,              0x3a)
+ELF_RELOC(R_ARM_ALU_PC_G1_NC,           0x3b)
+ELF_RELOC(R_ARM_ALU_PC_G1,              0x3c)
+ELF_RELOC(R_ARM_ALU_PC_G2,              0x3d)
+ELF_RELOC(R_ARM_LDR_PC_G1,              0x3e)
+ELF_RELOC(R_ARM_LDR_PC_G2,              0x3f)
+ELF_RELOC(R_ARM_LDRS_PC_G0,             0x40)
+ELF_RELOC(R_ARM_LDRS_PC_G1,             0x41)
+ELF_RELOC(R_ARM_LDRS_PC_G2,             0x42)
+ELF_RELOC(R_ARM_LDC_PC_G0,              0x43)
+ELF_RELOC(R_ARM_LDC_PC_G1,              0x44)
+ELF_RELOC(R_ARM_LDC_PC_G2,              0x45)
+ELF_RELOC(R_ARM_ALU_SB_G0_NC,           0x46)
+ELF_RELOC(R_ARM_ALU_SB_G0,              0x47)
+ELF_RELOC(R_ARM_ALU_SB_G1_NC,           0x48)
+ELF_RELOC(R_ARM_ALU_SB_G1,              0x49)
+ELF_RELOC(R_ARM_ALU_SB_G2,              0x4a)
+ELF_RELOC(R_ARM_LDR_SB_G0,              0x4b)
+ELF_RELOC(R_ARM_LDR_SB_G1,              0x4c)
+ELF_RELOC(R_ARM_LDR_SB_G2,              0x4d)
+ELF_RELOC(R_ARM_LDRS_SB_G0,             0x4e)
+ELF_RELOC(R_ARM_LDRS_SB_G1,             0x4f)
+ELF_RELOC(R_ARM_LDRS_SB_G2,             0x50)
+ELF_RELOC(R_ARM_LDC_SB_G0,              0x51)
+ELF_RELOC(R_ARM_LDC_SB_G1,              0x52)
+ELF_RELOC(R_ARM_LDC_SB_G2,              0x53)
+ELF_RELOC(R_ARM_MOVW_BREL_NC,           0x54)
+ELF_RELOC(R_ARM_MOVT_BREL,              0x55)
+ELF_RELOC(R_ARM_MOVW_BREL,              0x56)
+ELF_RELOC(R_ARM_THM_MOVW_BREL_NC,       0x57)
+ELF_RELOC(R_ARM_THM_MOVT_BREL,          0x58)
+ELF_RELOC(R_ARM_THM_MOVW_BREL,          0x59)
+ELF_RELOC(R_ARM_TLS_GOTDESC,            0x5a)
+ELF_RELOC(R_ARM_TLS_CALL,               0x5b)
+ELF_RELOC(R_ARM_TLS_DESCSEQ,            0x5c)
+ELF_RELOC(R_ARM_THM_TLS_CALL,           0x5d)
+ELF_RELOC(R_ARM_PLT32_ABS,              0x5e)
+ELF_RELOC(R_ARM_GOT_ABS,                0x5f)
+ELF_RELOC(R_ARM_GOT_PREL,               0x60)
+ELF_RELOC(R_ARM_GOT_BREL12,             0x61)
+ELF_RELOC(R_ARM_GOTOFF12,               0x62)
+ELF_RELOC(R_ARM_GOTRELAX,               0x63)
+ELF_RELOC(R_ARM_GNU_VTENTRY,            0x64)
+ELF_RELOC(R_ARM_GNU_VTINHERIT,          0x65)
+ELF_RELOC(R_ARM_THM_JUMP11,             0x66)
+ELF_RELOC(R_ARM_THM_JUMP8,              0x67)
+ELF_RELOC(R_ARM_TLS_GD32,               0x68)
+ELF_RELOC(R_ARM_TLS_LDM32,              0x69)
+ELF_RELOC(R_ARM_TLS_LDO32,              0x6a)
+ELF_RELOC(R_ARM_TLS_IE32,               0x6b)
+ELF_RELOC(R_ARM_TLS_LE32,               0x6c)
+ELF_RELOC(R_ARM_TLS_LDO12,              0x6d)
+ELF_RELOC(R_ARM_TLS_LE12,               0x6e)
+ELF_RELOC(R_ARM_TLS_IE12GP,             0x6f)
+ELF_RELOC(R_ARM_PRIVATE_0,              0x70)
+ELF_RELOC(R_ARM_PRIVATE_1,              0x71)
+ELF_RELOC(R_ARM_PRIVATE_2,              0x72)
+ELF_RELOC(R_ARM_PRIVATE_3,              0x73)
+ELF_RELOC(R_ARM_PRIVATE_4,              0x74)
+ELF_RELOC(R_ARM_PRIVATE_5,              0x75)
+ELF_RELOC(R_ARM_PRIVATE_6,              0x76)
+ELF_RELOC(R_ARM_PRIVATE_7,              0x77)
+ELF_RELOC(R_ARM_PRIVATE_8,              0x78)
+ELF_RELOC(R_ARM_PRIVATE_9,              0x79)
+ELF_RELOC(R_ARM_PRIVATE_10,             0x7a)
+ELF_RELOC(R_ARM_PRIVATE_11,             0x7b)
+ELF_RELOC(R_ARM_PRIVATE_12,             0x7c)
+ELF_RELOC(R_ARM_PRIVATE_13,             0x7d)
+ELF_RELOC(R_ARM_PRIVATE_14,             0x7e)
+ELF_RELOC(R_ARM_PRIVATE_15,             0x7f)
+ELF_RELOC(R_ARM_ME_TOO,                 0x80)
+ELF_RELOC(R_ARM_THM_TLS_DESCSEQ16,      0x81)
+ELF_RELOC(R_ARM_THM_TLS_DESCSEQ32,      0x82)
+ELF_RELOC(R_ARM_IRELATIVE,              0xa0)
diff --git a/rts/linker/ELFRelocs/LICENSE-LLVM.TXT b/rts/linker/ELFRelocs/LICENSE-LLVM.TXT
new file mode 100644 (file)
index 0000000..ff63f2b
--- /dev/null
@@ -0,0 +1,68 @@
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2003-2017 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the LLVM Team, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used to
+      endorse or promote products derived from this Software without specific
+      prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The LLVM software contains code written by third parties.  Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+Google Test         llvm/utils/unittest/googletest
+OpenBSD regex       llvm/lib/Support/{reg*, COPYRIGHT.regex}
+pyyaml tests        llvm/test/YAMLParser/{*.data, LICENSE.TXT}
+ARM contributions   llvm/lib/Target/ARM/LICENSE.TXT
+md5 contributions   llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h
diff --git a/rts/linker/ELFRelocs/i386.def b/rts/linker/ELFRelocs/i386.def
new file mode 100644 (file)
index 0000000..1d28cf5
--- /dev/null
@@ -0,0 +1,47 @@
+
+#ifndef ELF_RELOC
+#error "ELF_RELOC must be defined"
+#endif
+
+// TODO: this is just a subset
+ELF_RELOC(R_386_NONE,           0)
+ELF_RELOC(R_386_32,             1)
+ELF_RELOC(R_386_PC32,           2)
+ELF_RELOC(R_386_GOT32,          3)
+ELF_RELOC(R_386_PLT32,          4)
+ELF_RELOC(R_386_COPY,           5)
+ELF_RELOC(R_386_GLOB_DAT,       6)
+ELF_RELOC(R_386_JUMP_SLOT,      7)
+ELF_RELOC(R_386_RELATIVE,       8)
+ELF_RELOC(R_386_GOTOFF,         9)
+ELF_RELOC(R_386_GOTPC,          10)
+ELF_RELOC(R_386_32PLT,          11)
+ELF_RELOC(R_386_TLS_TPOFF,      14)
+ELF_RELOC(R_386_TLS_IE,         15)
+ELF_RELOC(R_386_TLS_GOTIE,      16)
+ELF_RELOC(R_386_TLS_LE,         17)
+ELF_RELOC(R_386_TLS_GD,         18)
+ELF_RELOC(R_386_TLS_LDM,        19)
+ELF_RELOC(R_386_16,             20)
+ELF_RELOC(R_386_PC16,           21)
+ELF_RELOC(R_386_8,              22)
+ELF_RELOC(R_386_PC8,            23)
+ELF_RELOC(R_386_TLS_GD_32,      24)
+ELF_RELOC(R_386_TLS_GD_PUSH,    25)
+ELF_RELOC(R_386_TLS_GD_CALL,    26)
+ELF_RELOC(R_386_TLS_GD_POP,     27)
+ELF_RELOC(R_386_TLS_LDM_32,     28)
+ELF_RELOC(R_386_TLS_LDM_PUSH,   29)
+ELF_RELOC(R_386_TLS_LDM_CALL,   30)
+ELF_RELOC(R_386_TLS_LDM_POP,    31)
+ELF_RELOC(R_386_TLS_LDO_32,     32)
+ELF_RELOC(R_386_TLS_IE_32,      33)
+ELF_RELOC(R_386_TLS_LE_32,      34)
+ELF_RELOC(R_386_TLS_DTPMOD32,   35)
+ELF_RELOC(R_386_TLS_DTPOFF32,   36)
+ELF_RELOC(R_386_TLS_TPOFF32,    37)
+ELF_RELOC(R_386_TLS_GOTDESC,    39)
+ELF_RELOC(R_386_TLS_DESC_CALL,  40)
+ELF_RELOC(R_386_TLS_DESC,       41)
+ELF_RELOC(R_386_IRELATIVE,      42)
+ELF_RELOC(R_386_GOT32X,         43)
diff --git a/rts/linker/ELFRelocs/x86_64.def b/rts/linker/ELFRelocs/x86_64.def
new file mode 100644 (file)
index 0000000..18fdcf9
--- /dev/null
@@ -0,0 +1,45 @@
+
+#ifndef ELF_RELOC
+#error "ELF_RELOC must be defined"
+#endif
+
+ELF_RELOC(R_X86_64_NONE,        0)
+ELF_RELOC(R_X86_64_64,          1)
+ELF_RELOC(R_X86_64_PC32,        2)
+ELF_RELOC(R_X86_64_GOT32,       3)
+ELF_RELOC(R_X86_64_PLT32,       4)
+ELF_RELOC(R_X86_64_COPY,        5)
+ELF_RELOC(R_X86_64_GLOB_DAT,    6)
+ELF_RELOC(R_X86_64_JUMP_SLOT,   7)
+ELF_RELOC(R_X86_64_RELATIVE,    8)
+ELF_RELOC(R_X86_64_GOTPCREL,    9)
+ELF_RELOC(R_X86_64_32,          10)
+ELF_RELOC(R_X86_64_32S,         11)
+ELF_RELOC(R_X86_64_16,          12)
+ELF_RELOC(R_X86_64_PC16,        13)
+ELF_RELOC(R_X86_64_8,           14)
+ELF_RELOC(R_X86_64_PC8,         15)
+ELF_RELOC(R_X86_64_DTPMOD64,    16)
+ELF_RELOC(R_X86_64_DTPOFF64,    17)
+ELF_RELOC(R_X86_64_TPOFF64,     18)
+ELF_RELOC(R_X86_64_TLSGD,       19)
+ELF_RELOC(R_X86_64_TLSLD,       20)
+ELF_RELOC(R_X86_64_DTPOFF32,    21)
+ELF_RELOC(R_X86_64_GOTTPOFF,    22)
+ELF_RELOC(R_X86_64_TPOFF32,     23)
+ELF_RELOC(R_X86_64_PC64,        24)
+ELF_RELOC(R_X86_64_GOTOFF64,    25)
+ELF_RELOC(R_X86_64_GOTPC32,     26)
+ELF_RELOC(R_X86_64_GOT64,       27)
+ELF_RELOC(R_X86_64_GOTPCREL64,  28)
+ELF_RELOC(R_X86_64_GOTPC64,     29)
+ELF_RELOC(R_X86_64_GOTPLT64,    30)
+ELF_RELOC(R_X86_64_PLTOFF64,    31)
+ELF_RELOC(R_X86_64_SIZE32,      32)
+ELF_RELOC(R_X86_64_SIZE64,      33)
+ELF_RELOC(R_X86_64_GOTPC32_TLSDESC,  34)
+ELF_RELOC(R_X86_64_TLSDESC_CALL,     35)
+ELF_RELOC(R_X86_64_TLSDESC,     36)
+ELF_RELOC(R_X86_64_IRELATIVE,   37)
+ELF_RELOC(R_X86_64_GOTPCRELX,   41)
+ELF_RELOC(R_X86_64_REX_GOTPCRELX,    42)
index 5b67548..9d60b39 100644 (file)
@@ -6,6 +6,13 @@
 || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) \
 || defined(openbsd_HOST_OS) || defined(gnu_HOST_OS)
 
+// It is essential that this is included before any <elf.h> is included. <elf.h>
+// defines R_XXX relocations, which would interfere with the COMPAT_R_XXX
+// relocations we generate.  E.g. COMPAT_ ## R_ARM_ARM32 would end up as
+// const unsigned COMPAT_3 = 0x03; instead of
+// const unsigned COMPAT_R_ARM_ARM32 = 0x03;
+#include "elf_compat.h"
+
 #include "RtsUtils.h"
 #include "RtsSymbolInfo.h"
 #include "linker/Elf.h"
@@ -14,6 +21,8 @@
 #include "linker/SymbolExtras.h"
 #include "sm/OSMem.h"
 #include "GetEnv.h"
+#include "linker/util.h"
+#include "linker/elf_util.h"
 
 #include <stdlib.h>
 #include <string.h>
 #else
 /* openbsd elf has things in different places, with diff names */
 #  include <elf_abi.h>
-#  include <machine/reloc.h>
-#  define R_386_32    RELOC_32
-#  define R_386_PC32  RELOC_PC32
 #endif
 
-/* If elf.h doesn't define it */
-#  ifndef R_X86_64_PC64
-#    define R_X86_64_PC64 24
-#  endif
-
-/*
- * Workaround for libc implementations (e.g. eglibc) with incomplete
- * relocation lists
- */
-#ifndef R_ARM_THM_CALL
-#  define R_ARM_THM_CALL      10
-#endif
-#ifndef R_ARM_CALL
-#  define R_ARM_CALL      28
-#endif
-#ifndef R_ARM_JUMP24
-#  define R_ARM_JUMP24      29
-#endif
-#ifndef R_ARM_THM_JUMP24
-#  define R_ARM_THM_JUMP24      30
-#endif
-#ifndef R_ARM_TARGET1
-#  define R_ARM_TARGET1      38
-#endif
-#ifndef R_ARM_MOVW_ABS_NC
-#  define R_ARM_MOVW_ABS_NC      43
-#endif
-#ifndef R_ARM_MOVT_ABS
-#  define R_ARM_MOVT_ABS      44
-#endif
-#ifndef R_ARM_THM_MOVW_ABS_NC
-#  define R_ARM_THM_MOVW_ABS_NC   47
-#endif
-#ifndef R_ARM_THM_MOVT_ABS
-#  define R_ARM_THM_MOVT_ABS      48
-#endif
-#ifndef R_ARM_THM_JUMP11
-#  define R_ARM_THM_JUMP11      102
-#endif
-#ifndef R_ARM_THM_JUMP8
-#  define R_ARM_THM_JUMP8      103
-#endif
-
-
-
 /*
 
    Note [Many ELF Sections]
@@ -164,9 +125,9 @@ static Elf_Word elf_shnum(Elf_Ehdr* ehdr)
 
 static Elf_Word elf_shstrndx(Elf_Ehdr* ehdr)
 {
-   Elf_Shdr* shdr = (Elf_Shdr*) ((char*)ehdr + ehdr->e_shoff);
    Elf_Half shstrndx = ehdr->e_shstrndx;
 #if defined(SHN_XINDEX)
+   Elf_Shdr* shdr = (Elf_Shdr*) ((char*)ehdr + ehdr->e_shoff);
    return shstrndx != SHN_XINDEX ? shstrndx : shdr[0].sh_link;
 #else
    // some OSes do not support SHN_XINDEX yet, let's revert to
@@ -742,21 +703,6 @@ end:
    return result;
 }
 
-#if defined(arm_HOST_ARCH)
-// TODO: These likely belong in a library somewhere
-
-// Signed extend a number to a 32-bit int.
-static inline StgInt32 sign_extend32(uint32_t bits, StgWord32 x) {
-    return ((StgInt32) (x << (32 - bits))) >> (32 - bits);
-}
-
-// Does the given signed integer fit into the given bit width?
-static inline StgBool is_int(uint32_t bits, StgInt32 x) {
-    return bits > 32 || (-(1 << (bits-1)) <= x
-                         && x < (1 << (bits-1)));
-}
-#endif
-
 /* Do ELF relocations which lack an explicit addend.  All x86-linux
    and arm-linux relocations appear to be of this form. */
 static int
@@ -886,25 +832,26 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
 
       switch (reloc_type) {
 #        ifdef i386_HOST_ARCH
-         case R_386_32:   *pP = value;     break;
-         case R_386_PC32: *pP = value - P; break;
+         case COMPAT_R_386_32:   *pP = value;     break;
+         case COMPAT_R_386_PC32: *pP = value - P; break;
 #        endif
 
 #        ifdef arm_HOST_ARCH
-         case R_ARM_ABS32:
-         case R_ARM_TARGET1:  // Specified by Linux ARM ABI to be equivalent to ABS32
+         case COMPAT_R_ARM_ABS32:
+         // Specified by Linux ARM ABI to be equivalent to ABS32
+         case COMPAT_R_ARM_TARGET1:
             *(Elf32_Word *)P += S;
             *(Elf32_Word *)P |= T;
             break;
 
-         case R_ARM_REL32:
+         case COMPAT_R_ARM_REL32:
             *(Elf32_Word *)P += S;
             *(Elf32_Word *)P |= T;
             *(Elf32_Word *)P -= P;
             break;
 
-         case R_ARM_CALL:
-         case R_ARM_JUMP24:
+         case COMPAT_R_ARM_CALL:
+         case COMPAT_R_ARM_JUMP24:
          {
             // N.B. LLVM's LLD linker's relocation implement is a fantastic
             // resource
@@ -923,30 +870,36 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
             StgWord32 result = ((S + imm) | T) - P;
 
             const StgBool overflow = !is_int(26, (StgInt32) result);
-
             // Handle overflow and Thumb interworking
-            const StgBool needs_veneer = (is_target_thm && ELF_R_TYPE(info) == R_ARM_JUMP24) || overflow;
+            const StgBool needs_veneer =
+                (is_target_thm && ELF_R_TYPE(info) == COMPAT_R_ARM_JUMP24)
+                || overflow;
+
             if (needs_veneer) {
                // Generate veneer
-               // The +8 below is to undo the PC-bias compensation done by the object producer
-               SymbolExtra *extra = makeArmSymbolExtra(oc, ELF_R_SYM(info), S+imm+8, 0, is_target_thm);
+               // The +8 below is to undo the PC-bias compensation done by the
+               // object producer
+               SymbolExtra *extra = makeArmSymbolExtra(oc, ELF_R_SYM(info),
+                                                       S+imm+8, 0,
+                                                       is_target_thm);
                // The -8 below is to compensate for PC bias
                result = (StgWord32) ((StgInt32) extra->jumpIsland - P - 8);
                result &= ~1; // Clear thumb indicator bit
                if (!is_int(26, (StgInt32) result)) {
-                  errorBelch("Unable to fixup overflow'd R_ARM_CALL: jump island=%p, reloc=%p\n",
+                  errorBelch("Unable to fixup overflow'd R_ARM_CALL: "
+                             "jump island=%p, reloc=%p\n",
                              (void*) extra->jumpIsland, (void*) P);
                   return 0;
                }
             }
-
             // Update the branch target
             const StgWord32 imm24 = (result & 0x03fffffc) >> 2;
             *word = (*word & ~0x00ffffff)
                   | (imm24 & 0x00ffffff);
 
             // Change the relocated branch into a BLX if necessary
-            const StgBool switch_mode = is_target_thm && (reloc_type == R_ARM_CALL);
+            const StgBool switch_mode =
+                is_target_thm && (reloc_type == COMPAT_R_ARM_CALL);
             if (!needs_veneer && switch_mode) {
                const StgWord32 hBit = (result & 0x2) >> 1;
                // Change instruction to BLX
@@ -956,8 +909,8 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
             break;
          }
 
-         case R_ARM_MOVT_ABS:
-         case R_ARM_MOVW_ABS_NC:
+         case COMPAT_R_ARM_MOVT_ABS:
+         case COMPAT_R_ARM_MOVW_ABS_NC:
          {
             StgWord32 *word = (StgWord32 *)P;
             StgWord32 imm12 = *word & 0xfff;
@@ -965,7 +918,7 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
             StgInt32 offset = imm4 << 12 | imm12;
             StgWord32 result = (S + offset) | T;
 
-            if (reloc_type == R_ARM_MOVT_ABS)
+            if (reloc_type == COMPAT_R_ARM_MOVT_ABS)
                 result = (result & 0xffff0000) >> 16;
 
             StgWord32 result12 = result & 0xfff;
@@ -974,8 +927,8 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
             break;
          }
 
-         case R_ARM_THM_CALL:
-         case R_ARM_THM_JUMP24:
+         case COMPAT_R_ARM_THM_CALL:
+         case COMPAT_R_ARM_THM_JUMP24:
          {
             StgWord16 *upper = (StgWord16 *)P;
             StgWord16 *lower = (StgWord16 *)(P + 2);
@@ -999,15 +952,20 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
                imm -= 0x02000000;
 
             offset = ((imm + S) | T) - P;
-            overflow = offset <= (StgWord32)0xff000000 || offset >= (StgWord32)0x01000000;
+            overflow = offset <= (StgWord32)0xff000000
+                    || offset >= (StgWord32)0x01000000;
 
-            if ((!is_target_thm && ELF_R_TYPE(info) == R_ARM_THM_JUMP24) || overflow) {
+            if ((!is_target_thm && ELF_R_TYPE(info) == COMPAT_R_ARM_THM_JUMP24)
+                || overflow) {
                // Generate veneer
-               SymbolExtra *extra = makeArmSymbolExtra(oc, ELF_R_SYM(info), S+imm+4, 1, is_target_thm);
+               SymbolExtra *extra = makeArmSymbolExtra(oc, ELF_R_SYM(info),
+                                                       S+imm+4, 1,
+                                                       is_target_thm);
                offset = (StgWord32) &extra->jumpIsland - P - 4;
                sign = offset >> 31;
                to_thm = 1;
-            } else if (!is_target_thm && ELF_R_TYPE(info) == R_ARM_THM_CALL) {
+            } else if (!is_target_thm
+                       && ELF_R_TYPE(info) == COMPAT_R_ARM_THM_CALL) {
                offset &= ~0x3;
                to_thm = 0;
             }
@@ -1026,8 +984,8 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
             break;
          }
 
-         case R_ARM_THM_MOVT_ABS:
-         case R_ARM_THM_MOVW_ABS_NC:
+         case COMPAT_R_ARM_THM_MOVT_ABS:
+         case COMPAT_R_ARM_THM_MOVW_ABS_NC:
          {
             StgWord16 *upper = (StgWord16 *)P;
             StgWord16 *lower = (StgWord16 *)(P + 2);
@@ -1038,9 +996,9 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
 
             offset = (offset ^ 0x8000) - 0x8000; // Sign extend
             offset += S;
-            if (ELF_R_TYPE(info) == R_ARM_THM_MOVW_ABS_NC)
+            if (ELF_R_TYPE(info) == COMPAT_R_ARM_THM_MOVW_ABS_NC)
                    offset |= T;
-            else if (ELF_R_TYPE(info) == R_ARM_THM_MOVT_ABS)
+            else if (ELF_R_TYPE(info) == COMPAT_R_ARM_THM_MOVT_ABS)
                    offset >>= 16;
 
             *upper = ( (*upper & 0xfbf0)
@@ -1052,13 +1010,14 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
             break;
          }
 
-         case R_ARM_THM_JUMP8:
+         case COMPAT_R_ARM_THM_JUMP8:
          {
             StgWord16 *word = (StgWord16 *)P;
             StgWord offset = *word & 0x01fe;
             offset += S - P;
             if (!is_target_thm) {
-               errorBelch("%s: Thumb to ARM transition with JUMP8 relocation not supported\n",
+               errorBelch("%s: Thumb to ARM transition with JUMP8 relocation "
+                          "not supported\n",
                      oc->fileName);
                return 0;
             }
@@ -1068,13 +1027,14 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
             break;
          }
 
-         case R_ARM_THM_JUMP11:
+         case COMPAT_R_ARM_THM_JUMP11:
          {
             StgWord16 *word = (StgWord16 *)P;
             StgWord offset = *word & 0x0ffe;
             offset += S - P;
             if (!is_target_thm) {
-               errorBelch("%s: Thumb to ARM transition with JUMP11 relocation not supported\n",
+               errorBelch("%s: Thumb to ARM transition with JUMP11 relocation "
+                          "not supported\n",
                      oc->fileName);
                return 0;
             }
@@ -1303,11 +1263,11 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
 #        endif
 
 #if defined(x86_64_HOST_ARCH)
-      case R_X86_64_64:
+      case COMPAT_R_X86_64_64:
           *(Elf64_Xword *)P = value;
           break;
 
-      case R_X86_64_PC32:
+      case COMPAT_R_X86_64_PC32:
       {
 #if defined(ALWAYS_PIC)
           barf("R_X86_64_PC32 relocation, but ALWAYS_PIC.");
@@ -1331,14 +1291,14 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
           break;
       }
 
-      case R_X86_64_PC64:
+      case COMPAT_R_X86_64_PC64:
       {
           StgInt64 off = value - P;
           *(Elf64_Word *)P = (Elf64_Word)off;
           break;
       }
 
-      case R_X86_64_32:
+      case COMPAT_R_X86_64_32:
 #if defined(ALWAYS_PIC)
           barf("R_X86_64_32 relocation, but ALWAYS_PIC.");
 #else
@@ -1359,7 +1319,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
 #endif
           break;
 
-      case R_X86_64_32S:
+      case COMPAT_R_X86_64_32S:
 #if defined(ALWAYS_PIC)
           barf("R_X86_64_32S relocation, but ALWAYS_PIC.");
 #else
@@ -1379,14 +1339,9 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
           *(Elf64_Sword *)P = (Elf64_Sword)value;
 #endif
           break;
-/* These two relocations were introduced in glibc 2.23 and binutils 2.26.
-    But in order to use them the system which compiles the bindist for GHC needs
-    to have glibc >= 2.23. So only use them if they're defined. */
-#if defined(R_X86_64_REX_GOTPCRELX) && defined(R_X86_64_GOTPCRELX)
-      case R_X86_64_REX_GOTPCRELX:
-      case R_X86_64_GOTPCRELX:
-#endif
-      case R_X86_64_GOTPCREL:
+      case COMPAT_R_X86_64_REX_GOTPCRELX:
+      case COMPAT_R_X86_64_GOTPCRELX:
+      case COMPAT_R_X86_64_GOTPCREL:
       {
           StgInt64 gotAddress = (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)->addr;
           StgInt64 off = gotAddress + A - P;
@@ -1394,7 +1349,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
           break;
       }
 #if defined(dragonfly_HOST_OS)
-      case R_X86_64_GOTTPOFF:
+      case COMPAT_R_X86_64_GOTTPOFF:
       {
 #if defined(ALWAYS_PIC)
           barf("R_X86_64_GOTTPOFF relocation, but ALWAYS_PIC.");
@@ -1413,9 +1368,7 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
       }
 #endif
 
-
-
-      case R_X86_64_PLT32:
+      case COMPAT_R_X86_64_PLT32:
       {
 #if defined(ALWAYS_PIC)
           barf("R_X86_64_PLT32 relocation, but ALWAYS_PIC.");
diff --git a/rts/linker/elf_compat.h b/rts/linker/elf_compat.h
new file mode 100644 (file)
index 0000000..c42f1f8
--- /dev/null
@@ -0,0 +1,35 @@
+// This file contains relocations, for various
+// architectures for the ELF format.  We include
+// to not have to depend on the (limited set of)
+// relocations provided by the system header.
+//
+// The files in ELFRelocs/ have been taken from
+// the LLVM project. See ELFRelocs/LICENSE-LLVM.TXT
+// for the University of Illinois Open Source License
+// under which it is distrubuted.
+//
+
+#ifndef RTS_ELF_COMPAT_H
+#define RTS_ELF_COMPAT_H
+
+#define PASTE(x,y) x ## y
+#define EVAL(x,y) PASTE(x,y)
+
+// generate COMPAT_R_<ARCH>_<REL> relocations to
+// prevent clashes with definitions in <elf.h>.
+#define ELF_RELOC(name, value)   PASTE(COMPAT_,name) = value,
+
+enum RelocAarch64 {
+#include "ELFRelocs/AArch64.def"
+};
+enum RelocARM {
+#include "ELFRelocs/ARM.def"
+};
+enum Reloci386 {
+#include "ELFRelocs/i386.def"
+};
+enum RelocX86_64 {
+#include "ELFRelocs/x86_64.def"
+};
+
+#endif //RTS_ELF_COMPAT_H
diff --git a/rts/linker/elf_util.c b/rts/linker/elf_util.c
new file mode 100644 (file)
index 0000000..bdfab22
--- /dev/null
@@ -0,0 +1,24 @@
+#include "linker/elf_util.h"
+#include "ElfTypes.h"
+
+#if defined(OBJFORMAT_ELF)
+
+ElfSymbolTable *
+find_symbol_table(ObjectCode * oc, unsigned symolTableIndex) {
+    for(ElfSymbolTable * t=oc->info->symbolTables; t != NULL; t = t->next)
+        if(t->index == symolTableIndex)
+            return t;
+    return NULL;
+}
+
+ElfSymbol *
+find_symbol(ObjectCode * oc, unsigned symbolTableIndex, unsigned long
+symbolIndex) {
+    ElfSymbolTable * t = find_symbol_table(oc, symbolTableIndex);
+    if(NULL != t && symbolIndex < t->n_symbols) {
+        return &t->symbols[symbolIndex];
+    }
+    return NULL;
+}
+
+#endif
diff --git a/rts/linker/elf_util.h b/rts/linker/elf_util.h
new file mode 100644 (file)
index 0000000..cae84a9
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef RTS_LINKER_ELF_UTIL_H
+#define RTS_LINKER_ELF_UTIL_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "LinkerInternals.h"
+
+#if defined(OBJFORMAT_ELF)
+
+ElfSymbolTable * find_symbol_table(ObjectCode * oc,
+                                   unsigned symbolTableIndex);
+
+ElfSymbol * find_symbol(ObjectCode * oc,
+                        unsigned symbolTableIndex,
+                        unsigned long symbolIndex);
+
+#endif
+#endif //RTS_LINKER_ELF_UTIL_H
diff --git a/rts/linker/util.h b/rts/linker/util.h
new file mode 100644 (file)
index 0000000..650e7f4
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef RTS_LINKER_UTIL_H
+#define RTS_LINKER_UTIL_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "LinkerInternals.h"
+
+// Signed extend a number to a 32-bit int.
+// Does the given signed integer fit into the given bit width?
+static inline int32_t
+sign_extend32(uint32_t bits, uint32_t x)
+{
+    return ((int32_t) (x << (32 - bits))) >> (32 - bits);
+}
+
+// Does the given signed integer fit into the given bit width?
+static inline bool
+is_int(uint32_t bits, int32_t x)
+{
+    return bits > 32 || (-(1 << (bits-1)) <= x
+                         && x < (1 << (bits-1)));
+}
+
+static inline bool
+is_int64(uint32_t bits, int64_t x) {
+    return bits > 64 || (-((int64_t)1 << (bits-1)) <= x
+                         && x < ((int64_t)1 << (bits-1)));
+}
+
+#endif //RTS_LINKER_UTIL_H