mirror of
https://github.com/frida/tinycc
synced 2025-01-11 14:19:19 +03:00
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.
This commit is contained in:
parent
d31226c873
commit
fe6453f8f0
97
arm-link.c
97
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) {}
|
||||
|
||||
|
76
arm64-link.c
76
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) {}
|
||||
|
||||
|
57
c67-link.c
57
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) {}
|
||||
|
||||
|
70
i386-link.c
70
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)
|
||||
{
|
||||
|
34
tcc.h
34
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];
|
||||
|
22
tccelf.c
22
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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user