From fe6453f8f08b5c21a339b3169a837772a9864d62 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Sat, 10 Dec 2016 17:22:08 +0000 Subject: [PATCH] Use functions to get relocation info MSVC does not support array designator so cannot compile source using relocs_info. This commit replace the relocs_info array into a set of functions, each returning the value given by a given field of the struct reloc_info. --- arm-link.c | 97 +++++++++++++++++++++++++++++++++++++++------------ arm64-link.c | 76 +++++++++++++++++++++++++++++++--------- c67-link.c | 57 ++++++++++++++++++++++++------ i386-link.c | 70 ++++++++++++++++++++++++++++++------- tcc.h | 34 ++++++++---------- tccelf.c | 22 ++++++------ x86_64-link.c | 73 ++++++++++++++++++++++++++++++-------- 7 files changed, 320 insertions(+), 109 deletions(-) diff --git a/arm-link.c b/arm-link.c index c4d834c2..a92342af 100644 --- a/arm-link.c +++ b/arm-link.c @@ -26,29 +26,80 @@ enum float_abi { #include "tcc.h" -ST_DATA struct reloc_info relocs_info[R_NUM] = { - INIT_RELOC_INFO (R_ARM_PC24, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_CALL, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_JUMP24, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_PLT32, 1, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_THM_PC22, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_THM_JUMP24, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_MOVT_ABS, 0, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_MOVW_ABS_NC, 0, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_THM_MOVT_ABS, 0, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_THM_MOVW_ABS_NC, 0, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_PREL31, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_ABS32, 0, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_REL32, 0, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_GOTPC, 0, BUILD_GOT_ONLY) - INIT_RELOC_INFO (R_ARM_GOTOFF, 0, BUILD_GOT_ONLY) - INIT_RELOC_INFO (R_ARM_GOT32, 0, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_COPY, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_V4BX, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_GLOB_DAT, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_JUMP_SLOT, 1, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_ARM_NONE, 0, NO_GOTPLT_ENTRY) -}; +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_ABS32: + case R_ARM_REL32: + case R_ARM_GOTPC: + case R_ARM_GOTOFF: + case R_ARM_GOT32: + case R_ARM_COPY: + case R_ARM_GLOB_DAT: + case R_ARM_NONE: + return 0; + + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + case R_ARM_PLT32: + case R_ARM_THM_PC22: + case R_ARM_THM_JUMP24: + case R_ARM_PREL31: + case R_ARM_V4BX: + case R_ARM_JUMP_SLOT: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe wether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_ARM_NONE: + case R_ARM_COPY: + case R_ARM_GLOB_DAT: + case R_ARM_JUMP_SLOT: + return NO_GOTPLT_ENTRY; + + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: + case R_ARM_PLT32: + case R_ARM_THM_PC22: + case R_ARM_THM_JUMP24: + case R_ARM_MOVT_ABS: + case R_ARM_MOVW_ABS_NC: + case R_ARM_THM_MOVT_ABS: + case R_ARM_THM_MOVW_ABS_NC: + case R_ARM_PREL31: + case R_ARM_ABS32: + case R_ARM_REL32: + case R_ARM_V4BX: + return AUTO_GOTPLT_ENTRY; + + case R_ARM_GOTPC: + case R_ARM_GOTOFF: + return BUILD_GOT_ONLY; + + case R_ARM_GOT32: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} void relocate_init(Section *sr) {} diff --git a/arm64-link.c b/arm64-link.c index 76b4ceb9..08337461 100644 --- a/arm64-link.c +++ b/arm64-link.c @@ -20,22 +20,66 @@ #include "tcc.h" -ST_DATA struct reloc_info relocs_info[R_NUM] = { - INIT_RELOC_INFO (R_AARCH64_ABS32, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_ABS64, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G0_NC, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G1_NC, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G2_NC, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G3, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_ADR_PREL_PG_HI21, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_ADD_ABS_LO12_NC, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_JUMP26, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_CALL26, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_ADR_GOT_PAGE, 0, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_LD64_GOT_LO12_NC, 0, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_GLOB_DAT, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_AARCH64_JUMP_SLOT, 1, NO_GOTPLT_ENTRY) -}; +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_AARCH64_ABS32: + case R_AARCH64_ABS64: + case R_AARCH64_MOVW_UABS_G0_NC: + case R_AARCH64_MOVW_UABS_G1_NC: + case R_AARCH64_MOVW_UABS_G2_NC: + case R_AARCH64_MOVW_UABS_G3: + case R_AARCH64_ADR_PREL_PG_HI21: + case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_ADR_GOT_PAGE: + case R_AARCH64_LD64_GOT_LO12_NC: + case R_AARCH64_GLOB_DAT: + case R_AARCH64_COPY: + return 0; + + case R_AARCH64_JUMP26: + case R_AARCH64_CALL26: + case R_AARCH64_JUMP_SLOT: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe wether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_AARCH64_ABS32: + case R_AARCH64_ABS64: + case R_AARCH64_MOVW_UABS_G0_NC: + case R_AARCH64_MOVW_UABS_G1_NC: + case R_AARCH64_MOVW_UABS_G2_NC: + case R_AARCH64_MOVW_UABS_G3: + case R_AARCH64_ADR_PREL_PG_HI21: + case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_GLOB_DAT: + case R_AARCH64_JUMP_SLOT: + case R_AARCH64_COPY: + return NO_GOTPLT_ENTRY; + + case R_AARCH64_JUMP26: + case R_AARCH64_CALL26: + return AUTO_GOTPLT_ENTRY; + + case R_AARCH64_ADR_GOT_PAGE: + case R_AARCH64_LD64_GOT_LO12_NC: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} void relocate_init(Section *sr) {} diff --git a/c67-link.c b/c67-link.c index 1d80aff1..f3220cbb 100644 --- a/c67-link.c +++ b/c67-link.c @@ -21,17 +21,52 @@ #include "tcc.h" -ST_DATA struct reloc_info relocs_info[R_NUM] = { - INIT_RELOC_INFO (R_C60_32, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_C60LO16, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_C60HI16, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_C60_GOTOFF, 0, BUILD_GOT_ONLY) - INIT_RELOC_INFO (R_C60_GOTPC, 0, BUILD_GOT_ONLY) - INIT_RELOC_INFO (R_C60_GOT32, 0, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_C60_PLT32, 1, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_C60_GLOB_DAT, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_C60_JMP_SLOT, 1, NO_GOTPLT_ENTRY) -}; +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_C60_32: + case R_C60LO16: + case R_C60HI16: + case R_C60_GOT32: + case R_C60_GOTOFF: + case R_C60_GOTPC: + case R_C60_COPY: + return 0; + + case R_C60_PLT32: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe wether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_C60_32: + case R_C60LO16: + case R_C60HI16: + case R_C60_COPY: + return NO_GOTPLT_ENTRY; + + case R_C60_GOTOFF: + case R_C60_GOTPC: + return BUILD_GOT_ONLY; + + case R_C60_PLT32: + case R_C60_GOT32: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} void relocate_init(Section *sr) {} diff --git a/i386-link.c b/i386-link.c index 59d6fa74..5a0511c6 100644 --- a/i386-link.c +++ b/i386-link.c @@ -21,20 +21,64 @@ #include "tcc.h" +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_386_16: + case R_386_32: + case R_386_GOTPC: + case R_386_GOTOFF: + case R_386_GOT32: + case R_386_GOT32X: + case R_386_GLOB_DAT: + case R_386_COPY: + return 0; + + case R_386_PC16: + case R_386_PC32: + case R_386_PLT32: + case R_386_JMP_SLOT: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe wether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_386_16: + case R_386_32: + case R_386_GLOB_DAT: + case R_386_JMP_SLOT: + case R_386_COPY: + return NO_GOTPLT_ENTRY; + + case R_386_PC16: + case R_386_PC32: + return AUTO_GOTPLT_ENTRY; + + case R_386_GOTPC: + case R_386_GOTOFF: + return BUILD_GOT_ONLY; + + case R_386_GOT32: + case R_386_GOT32X: + case R_386_PLT32: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + static ElfW_Rel *qrel; /* ptr to next reloc entry reused */ -ST_DATA struct reloc_info relocs_info[R_NUM] = { - INIT_RELOC_INFO (R_386_32, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_386_PC32, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_386_PLT32, 1, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_386_GLOB_DAT, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_386_JMP_SLOT, 1, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_386_GOTPC, 0, BUILD_GOT_ONLY) - INIT_RELOC_INFO (R_386_GOTOFF, 0, BUILD_GOT_ONLY) - INIT_RELOC_INFO (R_386_GOT32, 0, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_386_GOT32X, 0, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_386_16, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_386_PC16, 1, AUTO_GOTPLT_ENTRY) -}; void relocate_init(Section *sr) { diff --git a/tcc.h b/tcc.h index 4f350ff9..310134ce 100644 --- a/tcc.h +++ b/tcc.h @@ -1312,26 +1312,6 @@ typedef struct { unsigned int n_value; /* value of symbol */ } Stab_Sym; -/* Wether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so - that unknown relocation don't create a GOT or PLT entry */ -enum gotplt_entry { - NO_GOTPLT_ENTRY, /* never generate (eg. GLOB_DAT & JMP_SLOT relocs) */ - BUILD_GOT_ONLY, /* only build GOT (eg. TPOFF relocs) */ - AUTO_GOTPLT_ENTRY, /* generate if sym is UNDEF */ - ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */ -}; - -/* what kind of relocation is it */ -struct reloc_info { - int known; /* true for known relocation */ - int code_reloc; /* if false, that's a data reloc */ - int gotplt_entry; /* wether and when to create a GOT/PLT entry */ -}; - -#define INIT_RELOC_INFO(rtype, code_reloc, gotplt_entry) \ - [rtype] = {1, code_reloc, gotplt_entry}, -ST_DATA struct reloc_info relocs_info[R_NUM]; - ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ ST_DATA Section *cur_text_section; /* current section where function code is generated */ #ifdef CONFIG_TCC_ASM @@ -1407,6 +1387,20 @@ ST_INLN void inp(void); ST_FUNC int handle_eob(void); #endif +/* ------------ xxx-link.c ------------ */ + +/* Wether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so + that unknown relocation don't create a GOT or PLT entry */ +enum gotplt_entry { + NO_GOTPLT_ENTRY, /* never generate (eg. GLOB_DAT & JMP_SLOT relocs) */ + BUILD_GOT_ONLY, /* only build GOT (eg. TPOFF relocs) */ + AUTO_GOTPLT_ENTRY, /* generate if sym is UNDEF */ + ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */ +}; + +ST_FUNC int code_reloc (int reloc_type); +ST_FUNC int gotplt_entry_type (int reloc_type); + /* ------------ xxx-gen.c ------------ */ ST_DATA const int reg_classes[NB_REGS]; diff --git a/tccelf.c b/tccelf.c index de792f4d..d806f7cc 100644 --- a/tccelf.c +++ b/tccelf.c @@ -721,8 +721,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) Note 1: in tcc -run mode we go through PLT to avoid range issues Note 2: symbols compiled with libtcc and later added with tcc_add_symbol are not dynamic and thus have symattr NULL */ - if (relocs_info[type].gotplt_entry != NO_GOTPLT_ENTRY && - relocs_info[type].code_reloc && symattr && symattr->plt_offset) + if (gotplt_entry_type(type) != NO_GOTPLT_ENTRY && + code_reloc(type) && symattr && symattr->plt_offset) tgt = s1->plt->sh_addr + symattr->plt_offset; #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) tgt += rel->r_addend; @@ -1010,7 +1010,7 @@ static unsigned long put_got_entry(TCCState *s1, int dyn_reloc_type, } else if (s1->output_type == TCC_OUTPUT_MEMORY || ELFW(ST_BIND)(sym->st_info) == STB_WEAK || - relocs_info[reloc_type].gotplt_entry == ALWAYS_GOTPLT_ENTRY) + gotplt_entry_type(reloc_type) == ALWAYS_GOTPLT_ENTRY) index = put_elf_sym(s1->dynsym, offset, size, info, 0, sym->st_shndx, name); else @@ -1032,7 +1032,7 @@ ST_FUNC void build_got_entries(TCCState *s1) Section *s; ElfW_Rel *rel; ElfW(Sym) *sym; - int i, type, reloc_type, sym_index; + int i, type, gotplt_entry, reloc_type, sym_index; for(i = 1; i < s1->nb_sections; i++) { s = s1->sections[i]; @@ -1043,13 +1043,11 @@ ST_FUNC void build_got_entries(TCCState *s1) continue; for_each_elem(s, 0, rel, ElfW_Rel) { type = ELFW(R_TYPE)(rel->r_info); + gotplt_entry = gotplt_entry_type(type); sym_index = ELFW(R_SYM)(rel->r_info); sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - if (type >= R_NUM || !relocs_info[type].known) - tcc_error("Unknown relocation: %d\n", type); - - if (relocs_info[type].gotplt_entry == NO_GOTPLT_ENTRY) + if (gotplt_entry == NO_GOTPLT_ENTRY) continue; /* Proceed with PLT/GOT [entry] creation if any of the following @@ -1061,7 +1059,7 @@ ST_FUNC void build_got_entries(TCCState *s1) ALWAYS_GOTPLT_ENTRY). */ if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS && - relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY) + gotplt_entry == AUTO_GOTPLT_ENTRY) continue; /* Building a dynamic library but target is not capable of PC @@ -1070,7 +1068,7 @@ ST_FUNC void build_got_entries(TCCState *s1) if (sym->st_shndx == SHN_UNDEF && s1->output_type == TCC_OUTPUT_DLL && !PCRELATIVE_DLLPLT && - relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY) + gotplt_entry == AUTO_GOTPLT_ENTRY) continue; #ifdef TCC_TARGET_X86_64 @@ -1084,10 +1082,10 @@ ST_FUNC void build_got_entries(TCCState *s1) if (!s1->got) build_got(s1); - if (relocs_info[type].gotplt_entry == BUILD_GOT_ONLY) + if (gotplt_entry == BUILD_GOT_ONLY) continue; - if (relocs_info[type].code_reloc) + if (code_reloc(type)) reloc_type = R_JMP_SLOT; else reloc_type = R_GLOB_DAT; diff --git a/x86_64-link.c b/x86_64-link.c index 6cbb4a12..92404e43 100644 --- a/x86_64-link.c +++ b/x86_64-link.c @@ -21,21 +21,66 @@ #include "tcc.h" +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + case R_X86_64_32: + case R_X86_64_32S: + case R_X86_64_64: + case R_X86_64_GOTPCREL: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: + case R_X86_64_GOTTPOFF: + case R_X86_64_GOT32: + case R_X86_64_GLOB_DAT: + case R_X86_64_COPY: + return 0; + + case R_X86_64_PC32: + case R_X86_64_PLT32: + case R_X86_64_JUMP_SLOT: + return 1; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe wether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: + case R_X86_64_COPY: + return NO_GOTPLT_ENTRY; + + case R_X86_64_32: + case R_X86_64_32S: + case R_X86_64_64: + case R_X86_64_PC32: + return AUTO_GOTPLT_ENTRY; + + case R_X86_64_GOTTPOFF: + return BUILD_GOT_ONLY; + + case R_X86_64_GOT32: + case R_X86_64_GOTPCREL: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: + case R_X86_64_PLT32: + return ALWAYS_GOTPLT_ENTRY; + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + static ElfW_Rel *qrel; /* ptr to next reloc entry reused */ -ST_DATA struct reloc_info relocs_info[R_NUM] = { - INIT_RELOC_INFO (R_X86_64_64, 0, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_32, 0, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_32S, 0, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_PC32, 1, AUTO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_PLT32, 1, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_GLOB_DAT, 0, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_JUMP_SLOT, 1, NO_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_GOTPCREL, 0, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_GOTPCRELX, 0, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_REX_GOTPCRELX, 0, ALWAYS_GOTPLT_ENTRY) - INIT_RELOC_INFO (R_X86_64_GOTTPOFF, 0, BUILD_GOT_ONLY) - INIT_RELOC_INFO (R_X86_64_GOT32, 0, ALWAYS_GOTPLT_ENTRY) -}; void relocate_init(Section *sr) {