History

Make build_got_entries more target independent

Factor most of common logic between targets in build_got_entries by defining target specific info into structures in the backends.

Thomas Preud'homme committed 10 years ago

Commit 1c811a41 parent 523b55d11 files · +179 −211Browse files

Unified · Split

11 files
  1. arm-gen.c +1 −0
  2. arm-link.c +52 −2
  3. arm64-gen.c +1 −0
  4. arm64-link.c +18 −1
  5. c67-gen.c +1 −0
  6. i386-gen.c +1 −0
  7. i386-link.c +13 −0
  8. tcc.h +20 −0
  9. tccelf.c +57 −208
  10. x86_64-gen.c +1 −0
  11. x86_64-link.c +14 −0
arm-gen.c+1−0
@@ -138,6 +138,7 @@ enum { · 137 unmodified lines
138#define R_DATA_32 R_ARM_ABS32138#define R_DATA_32 R_ARM_ABS32
139#define R_DATA_PTR R_ARM_ABS32139#define R_DATA_PTR R_ARM_ABS32
140#define R_JMP_SLOT R_ARM_JUMP_SLOT140#define R_JMP_SLOT R_ARM_JUMP_SLOT
141#define R_GLOB_DAT R_ARM_GLOB_DAT
141#define R_COPY R_ARM_COPY142#define R_COPY R_ARM_COPY
142 143
143#define ELF_START_ADDR 0x00008000144#define ELF_START_ADDR 0x00008000
arm-link.c+52−2
@@ -1,6 +1,30 @@
1#include "tcc.h"1#include "tcc.h"
2#define HAVE_SECTION_RELOC2#define HAVE_SECTION_RELOC
3 3
4ST_DATA struct reloc_info relocs_info[] = {
5 INIT_RELOC_INFO (R_ARM_PC24, 1, AUTO_GOTPLT_ENTRY, 0)
6 INIT_RELOC_INFO (R_ARM_CALL, 1, AUTO_GOTPLT_ENTRY, 0)
7 INIT_RELOC_INFO (R_ARM_JUMP24, 1, AUTO_GOTPLT_ENTRY, 0)
8 INIT_RELOC_INFO (R_ARM_PLT32, 1, ALWAYS_GOTPLT_ENTRY, 0)
9 INIT_RELOC_INFO (R_ARM_THM_PC22, 1, AUTO_GOTPLT_ENTRY, 0)
10 INIT_RELOC_INFO (R_ARM_THM_JUMP24, 1, AUTO_GOTPLT_ENTRY, 0)
11 INIT_RELOC_INFO (R_ARM_MOVT_ABS, 0, AUTO_GOTPLT_ENTRY, 0)
12 INIT_RELOC_INFO (R_ARM_MOVW_ABS_NC, 0, AUTO_GOTPLT_ENTRY, 0)
13 INIT_RELOC_INFO (R_ARM_THM_MOVT_ABS, 0, AUTO_GOTPLT_ENTRY, 0)
14 INIT_RELOC_INFO (R_ARM_THM_MOVW_ABS_NC, 0, AUTO_GOTPLT_ENTRY, 0)
15 INIT_RELOC_INFO (R_ARM_PREL31, 1, AUTO_GOTPLT_ENTRY, 0)
16 INIT_RELOC_INFO (R_ARM_ABS32, 0, NO_GOTPLT_ENTRY, 0)
17 INIT_RELOC_INFO (R_ARM_REL32, 0, AUTO_GOTPLT_ENTRY, 0)
18 INIT_RELOC_INFO (R_ARM_GOTPC, 0, BUILD_GOT_ONLY, 0)
19 INIT_RELOC_INFO (R_ARM_GOTOFF, 0, BUILD_GOT_ONLY, 0)
20 INIT_RELOC_INFO (R_ARM_GOT32, 0, ALWAYS_GOTPLT_ENTRY, 0)
21 INIT_RELOC_INFO (R_ARM_COPY, 0, NO_GOTPLT_ENTRY, 0)
22 INIT_RELOC_INFO (R_ARM_V4BX, 1, AUTO_GOTPLT_ENTRY, 0)
23 INIT_RELOC_INFO (R_ARM_GLOB_DAT, 0, NO_GOTPLT_ENTRY, 0)
24 INIT_RELOC_INFO (R_ARM_JUMP_SLOT, 1, NO_GOTPLT_ENTRY, 0)
25 INIT_RELOC_INFO (R_ARM_NONE, 0, NO_GOTPLT_ENTRY, 0)
26};
27
4void relocate_init(Section *sr) {}28void relocate_init(Section *sr) {}
5 29
6void relocate(TCCState *s1, ElfW_Rel *rel, int type, char *ptr, addr_t addr, addr_t val)30void relocate(TCCState *s1, ElfW_Rel *rel, int type, char *ptr, addr_t addr, addr_t val)
@@ -19,8 +43,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, char *ptr, addr_t addr, add · 12 unmodified lines
19 {43 {
20 int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;44 int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
21 x = (*(int *) ptr) & 0xffffff;45 x = (*(int *) ptr) & 0xffffff;
22 if (sym->st_shndx == SHN_UNDEF ||46 if (sym->st_shndx == SHN_UNDEF || sym->st_shndx == SHN_ABS)
23 s1->output_type == TCC_OUTPUT_MEMORY)
24 val = s1->plt->sh_addr;47 val = s1->plt->sh_addr;
25#ifdef DEBUG_RELOC48#ifdef DEBUG_RELOC
26 printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);49 printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
@@ -89,6 +112,33 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, char *ptr, addr_t addr, add · 62 unmodified lines
89 (val < plt->sh_addr + plt->data_offset);112 (val < plt->sh_addr + plt->data_offset);
90 is_call = (type == R_ARM_THM_PC22);113 is_call = (type == R_ARM_THM_PC22);
91 114
115 if (!to_thumb && !to_plt && !is_call) {
116 int index;
117 uint8_t *p;
118 char *name, buf[1024];
119 Section *text_section;
120
121 name = (char *) symtab_section->link->data + sym->st_name;
122 text_section = s1->sections[sym->st_shndx];
123 /* Modify reloc to target a thumb stub to switch to ARM */
124 snprintf(buf, sizeof(buf), "%s_from_thumb", name);
125 index = put_elf_sym(symtab_section,
126 text_section->data_offset + 1,
127 sym->st_size, sym->st_info, 0,
128 sym->st_shndx, buf);
129 to_thumb = 1;
130 val = text_section->data_offset + 1;
131 rel->r_info = ELFW(R_INFO)(index, type);
132 /* Create a thumb stub function to switch to ARM mode */
133 put_elf_reloc(symtab_section, text_section,
134 text_section->data_offset + 4, R_ARM_JUMP24,
135 sym_index);
136 p = section_ptr_add(text_section, 8);
137 write32le(p, 0x4778); /* bx pc */
138 write32le(p+2, 0x46c0); /* nop */
139 write32le(p+4, 0xeafffffe); /* b $sym */
140 }
141
92 /* Compute final offset */142 /* Compute final offset */
93 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */143 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
94 x -= 4;144 x -= 4;
arm64-gen.c+1−0
@@ -48,6 +48,7 @@ · 47 unmodified lines
48#define R_DATA_32 R_AARCH64_ABS3248#define R_DATA_32 R_AARCH64_ABS32
49#define R_DATA_PTR R_AARCH64_ABS6449#define R_DATA_PTR R_AARCH64_ABS64
50#define R_JMP_SLOT R_AARCH64_JUMP_SLOT50#define R_JMP_SLOT R_AARCH64_JUMP_SLOT
51#define R_GLOB_DAT R_AARCH64_GLOB_DAT
51#define R_COPY R_AARCH64_COPY52#define R_COPY R_AARCH64_COPY
52 53
53#define ELF_START_ADDR 0x0040000054#define ELF_START_ADDR 0x00400000
arm64-link.c+18−1
@@ -1,6 +1,23 @@
1#include "tcc.h"1#include "tcc.h"
2#define HAVE_SECTION_RELOC2#define HAVE_SECTION_RELOC
3 3
4ST_DATA struct reloc_info relocs_info[] = {
5 INIT_RELOC_INFO (R_AARCH64_ABS32, 0, NO_GOTPLT_ENTRY, 0)
6 INIT_RELOC_INFO (R_AARCH64_ABS64, 0, NO_GOTPLT_ENTRY, 0)
7 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G0_NC, 0, NO_GOTPLT_ENTRY, 0)
8 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G1_NC, 0, NO_GOTPLT_ENTRY, 0)
9 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G2_NC, 0, NO_GOTPLT_ENTRY, 0)
10 INIT_RELOC_INFO (R_AARCH64_MOVW_UABS_G3, 0, NO_GOTPLT_ENTRY, 0)
11 INIT_RELOC_INFO (R_AARCH64_ADR_PREL_PG_HI21, 0, NO_GOTPLT_ENTRY, 0)
12 INIT_RELOC_INFO (R_AARCH64_ADD_ABS_LO12_NC, 0, NO_GOTPLT_ENTRY, 0)
13 INIT_RELOC_INFO (R_AARCH64_JUMP26, 1, AUTO_GOTPLT_ENTRY, 1)
14 INIT_RELOC_INFO (R_AARCH64_CALL26, 1, AUTO_GOTPLT_ENTRY, 1)
15 INIT_RELOC_INFO (R_AARCH64_ADR_GOT_PAGE, 0, ALWAYS_GOTPLT_ENTRY, 0)
16 INIT_RELOC_INFO (R_AARCH64_LD64_GOT_LO12_NC, 0, ALWAYS_GOTPLT_ENTRY, 0)
17 INIT_RELOC_INFO (R_AARCH64_GLOB_DAT, 0, NO_GOTPLT_ENTRY, 0)
18 INIT_RELOC_INFO (R_AARCH64_JUMP_SLOT, 1, NO_GOTPLT_ENTRY, 0)
19};
20
4void relocate_init(Section *sr) {}21void relocate_init(Section *sr) {}
5 22
6void relocate(TCCState *s1, ElfW_Rel *rel, int type, char *ptr, addr_t addr, addr_t val)23void relocate(TCCState *s1, ElfW_Rel *rel, int type, char *ptr, addr_t addr, addr_t val)
@@ -51,7 +68,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, char *ptr, addr_t addr, add · 44 unmodified lines
51 /* This check must match the one in build_got_entries, testing68 /* This check must match the one in build_got_entries, testing
52 if we really need a PLT slot. */69 if we really need a PLT slot. */
53 if (sym->st_shndx == SHN_UNDEF ||70 if (sym->st_shndx == SHN_UNDEF ||
54 s1->output_type == TCC_OUTPUT_MEMORY)71 sym->st_shndx == SHN_ABS)
55 /* We've put the PLT slot offset into r_addend when generating72 /* We've put the PLT slot offset into r_addend when generating
56 it, and that's what we must use as relocation value (adjusted73 it, and that's what we must use as relocation value (adjusted
57 by section offset of course). */74 by section offset of course). */
c67-gen.c+1−0
@@ -117,6 +117,7 @@ enum { · 116 unmodified lines
117#define R_DATA_32 R_C60_32117#define R_DATA_32 R_C60_32
118#define R_DATA_PTR R_C60_32118#define R_DATA_PTR R_C60_32
119#define R_JMP_SLOT R_C60_JMP_SLOT119#define R_JMP_SLOT R_C60_JMP_SLOT
120#define R_GLOB_DAT R_C60_GLOB_DAT
120#define R_COPY R_C60_COPY121#define R_COPY R_C60_COPY
121 122
122#define ELF_START_ADDR 0x00000400123#define ELF_START_ADDR 0x00000400
i386-gen.c+1−0
@@ -82,6 +82,7 @@ enum { · 81 unmodified lines
82#define R_DATA_32 R_386_3282#define R_DATA_32 R_386_32
83#define R_DATA_PTR R_386_3283#define R_DATA_PTR R_386_32
84#define R_JMP_SLOT R_386_JMP_SLOT84#define R_JMP_SLOT R_386_JMP_SLOT
85#define R_GLOB_DAT R_386_GLOB_DAT
85#define R_COPY R_386_COPY86#define R_COPY R_386_COPY
86 87
87#define ELF_START_ADDR 0x0804800088#define ELF_START_ADDR 0x08048000
i386-link.c+13−0
@@ -2,6 +2,19 @@ · 1 unmodified line
2#define HAVE_SECTION_RELOC2#define HAVE_SECTION_RELOC
3 3
4static ElfW_Rel *qrel; /* ptr to next reloc entry reused */4static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
5ST_DATA struct reloc_info relocs_info[] = {
6 INIT_RELOC_INFO (R_386_32, 0, NO_GOTPLT_ENTRY, 0)
7 INIT_RELOC_INFO (R_386_PC32, 1, AUTO_GOTPLT_ENTRY, 0)
8 INIT_RELOC_INFO (R_386_PLT32, 1, ALWAYS_GOTPLT_ENTRY, 0)
9 INIT_RELOC_INFO (R_386_GLOB_DAT, 0, NO_GOTPLT_ENTRY, 0)
10 INIT_RELOC_INFO (R_386_JMP_SLOT, 1, NO_GOTPLT_ENTRY, 0)
11 INIT_RELOC_INFO (R_386_GOTPC, 0, BUILD_GOT_ONLY, 0)
12 INIT_RELOC_INFO (R_386_GOTOFF, 0, BUILD_GOT_ONLY, 0)
13 INIT_RELOC_INFO (R_386_GOT32, 0, ALWAYS_GOTPLT_ENTRY, 0)
14 INIT_RELOC_INFO (R_386_GOT32X, 0, ALWAYS_GOTPLT_ENTRY, 0)
15 INIT_RELOC_INFO (R_386_16, 0, NO_GOTPLT_ENTRY, 0)
16 INIT_RELOC_INFO (R_386_PC16, 1, AUTO_GOTPLT_ENTRY, 0)
17};
5 18
6void relocate_init(Section *sr)19void relocate_init(Section *sr)
7{20{
tcc.h+20−0
@@ -1305,6 +1305,26 @@ typedef struct { · 1304 unmodified lines
1305 unsigned int n_value; /* value of symbol */1305 unsigned int n_value; /* value of symbol */
1306} Stab_Sym;1306} Stab_Sym;
1307 1307
1308/* Wether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so
1309 that unknown relocation don't create a GOT or PLT entry */
1310enum gotplt_entry {
1311 NO_GOTPLT_ENTRY, /* never generate (eg. GLOB_DAT & JMP_SLOT relocs) */
1312 BUILD_GOT_ONLY, /* only build GOT (eg. TPOFF relocs) */
1313 AUTO_GOTPLT_ENTRY, /* generate if sym is UNDEF */
1314 ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */
1315};
1316
1317/* what kind of relocation is it */
1318struct reloc_info {
1319 int code_reloc; /* if false, that's a data reloc */
1320 int gotplt_entry; /* wether and when to create a GOT/PLT entry */
1321 int pltoff_addend; /* wether to store the PLT offset in addend */
1322};
1323
1324#define INIT_RELOC_INFO(rtype, code_reloc, gotplt_entry, pltoff_addend) \
1325 [rtype] = {code_reloc, gotplt_entry, pltoff_addend},
1326ST_DATA struct reloc_info relocs_info[];
1327
1308ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */1328ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
1309ST_DATA Section *cur_text_section; /* current section where function code is generated */1329ST_DATA Section *cur_text_section; /* current section where function code is generated */
1310#ifdef CONFIG_TCC_ASM1330#ifdef CONFIG_TCC_ASM
tccelf.c+57−208
@@ -1022,6 +1022,7 @@ ST_FUNC void build_got_entries(TCCState *s1) · 1021 unmodified lines
1022 ElfW_Rel *rel;1022 ElfW_Rel *rel;
1023 ElfW(Sym) *sym;1023 ElfW(Sym) *sym;
1024 int i, type, reloc_type, sym_index;1024 int i, type, reloc_type, sym_index;
1025 unsigned long ofs;
1025 1026
1026 for(i = 1; i < s1->nb_sections; i++) {1027 for(i = 1; i < s1->nb_sections; i++) {
1027 s = s1->sections[i];1028 s = s1->sections[i];
@@ -1034,222 +1035,70 @@ ST_FUNC void build_got_entries(TCCState *s1) · 6 unmodified lines
1034 type = ELFW(R_TYPE)(rel->r_info);1035 type = ELFW(R_TYPE)(rel->r_info);
1035 sym_index = ELFW(R_SYM)(rel->r_info);1036 sym_index = ELFW(R_SYM)(rel->r_info);
1036 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];1037 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1037 switch(type) {1038 if (relocs_info[type].gotplt_entry == NO_GOTPLT_ENTRY)
1038#if defined(TCC_TARGET_I386)1039 continue;
1039 case R_386_PC16:
1040 case R_386_PC32:
1041 case R_386_GOT32:
1042 case R_386_GOT32X:
1043 case R_386_GOTOFF:
1044 case R_386_GOTPC:
1045 case R_386_PLT32:
1046 if (sym->st_shndx != SHN_UNDEF && type != R_386_GOT32 &&
1047 type != R_386_GOT32X && type != R_386_GOTOFF &&
1048 type != R_386_GOTPC && type != R_386_PLT32)
1049 break;
1050 1040
1051 if (!s1->got)1041 /* Proceed with PLT/GOT [entry] creation if any of the following
1052 build_got(s1);1042 condition is met:
1053 1043 - it is an undefined reference (dynamic relocation needed)
1054 if (type != R_386_GOTOFF && type != R_386_GOTPC) {1044 - symbol is absolute (probably created by tcc_add_symbol)
1055 /* look at the symbol got offset. If none, then add one */1045 - relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or
1056 if (type == R_386_GOT32 || type == R_386_GOT32X)1046 ALWAYS_GOTPLT_ENTRY). */
1057 reloc_type = R_386_GLOB_DAT;1047 if (sym->st_shndx != SHN_UNDEF &&
1058 else1048 sym->st_shndx != SHN_ABS &&
1059 reloc_type = R_386_JMP_SLOT;1049 relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
1060 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,1050 continue;
1061 sym_index);
1062 }
1063 break;
1064#elif defined(TCC_TARGET_ARM)
1065 case R_ARM_PC24:
1066 case R_ARM_CALL:
1067 case R_ARM_JUMP24:
1068 case R_ARM_PLT32:
1069 case R_ARM_THM_PC22:
1070 case R_ARM_MOVT_ABS:
1071 case R_ARM_MOVW_ABS_NC:
1072 case R_ARM_THM_MOVT_ABS:
1073 case R_ARM_THM_MOVW_ABS_NC:
1074 case R_ARM_PREL31:
1075 case R_ARM_REL32:
1076 case R_ARM_GOTPC:
1077 case R_ARM_GOTOFF:
1078 case R_ARM_GOT32:
1079 case R_ARM_V4BX:
1080 if (sym->st_shndx != SHN_UNDEF && type != R_ARM_GOT32 &&
1081 type != R_ARM_GOTOFF && type != R_ARM_GOTPC &&
1082 type != R_ARM_PLT32)
1083 break;
1084 1051
1085 if (!s1->got)1052#ifdef TCC_TARGET_X86_64
1086 build_got(s1);1053 if (type == R_X86_64_PLT32 &&
1087 if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC1054 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {
1088 && (sym->st_shndx == SHN_UNDEF1055 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1089 || s1->output_type == TCC_OUTPUT_MEMORY)) {1056 continue;
1090 unsigned long ofs;1057 }
1091 /* look at the symbol got offset. If none, then add one */
1092 if (type == R_ARM_GOT32 || type == R_ARM_MOVT_ABS ||
1093 type == R_ARM_MOVW_ABS_NC ||
1094 type == R_ARM_THM_MOVT_ABS ||
1095 type == R_ARM_THM_MOVW_ABS_NC || type == R_ARM_ABS32 ||
1096 type == R_ARM_REL32)
1097 reloc_type = R_ARM_GLOB_DAT;
1098 else
1099 reloc_type = R_ARM_JUMP_SLOT;
1100 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1101 sym->st_info, sym_index);
1102#ifdef DEBUG_RELOC
1103 printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
1104 (char *) symtab_section->link->data + sym->st_name,
1105 type, sym->st_shndx, ofs);
1106#endif
1107 if (type == R_ARM_PC24 || type == R_ARM_CALL ||
1108 type == R_ARM_JUMP24 || type == R_ARM_PLT32) {
1109 addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
1110 + rel->r_offset);
1111 /* x must be signed! */
1112 int x = *ptr & 0xffffff;
1113 x = (x << 8) >> 8;
1114 x <<= 2;
1115 x += ofs;
1116 x >>= 2;
1117#ifdef DEBUG_RELOC
1118 printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
1119 (*ptr & 0xff000000) | x, x);
1120#endif1058#endif
1121 *ptr = (*ptr & 0xff000000) | x;
1122 }
1123 }
1124 break;
1125 case R_ARM_THM_JUMP24:
1126 sym_index = ELFW(R_SYM)(rel->r_info);
1127 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1128 /* We are relocating a jump from thumb code to arm code */
1129 if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) {
1130 int index;
1131 uint8_t *p;
1132 char *name, buf[1024];
1133 Section *text_section;
1134
1135 name = (char *) symtab_section->link->data + sym->st_name;
1136 text_section = s1->sections[sym->st_shndx];
1137 /* Modify reloc to target a thumb stub to switch to ARM */
1138 snprintf(buf, sizeof(buf), "%s_from_thumb", name);
1139 index = put_elf_sym(symtab_section,
1140 text_section->data_offset + 1,
1141 sym->st_size, sym->st_info, 0,
1142 sym->st_shndx, buf);
1143 rel->r_info = ELFW(R_INFO)(index, type);
1144 /* Create a thumb stub fonction to switch to ARM mode */
1145 put_elf_reloc(symtab_section, text_section,
1146 text_section->data_offset + 4, R_ARM_JUMP24,
1147 sym_index);
1148 p = section_ptr_add(text_section, 8);
1149 write32le(p, 0x4778); /* bx pc */
1150 write32le(p+2, 0x46c0); /* nop */
1151 write32le(p+4, 0xeafffffe); /* b $sym */
1152 }
1153#elif defined(TCC_TARGET_ARM64)
1154 //xx Other cases may be required here:
1155 case R_AARCH64_ADR_GOT_PAGE:
1156 case R_AARCH64_LD64_GOT_LO12_NC:
1157 if (!s1->got)
1158 build_got(s1);
1159 sym_index = ELFW(R_SYM)(rel->r_info);
1160 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1161 reloc_type = R_AARCH64_GLOB_DAT;
1162 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1163 sym_index);
1164 break;
1165 1059
1166 case R_AARCH64_JUMP26:1060 if (!s1->got)
1167 case R_AARCH64_CALL26:1061 build_got(s1);
1168 if (!s1->got)
1169 build_got(s1);
1170 sym_index = ELFW(R_SYM)(rel->r_info);
1171 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1172 if (sym->st_shndx == SHN_UNDEF ||
1173 s1->output_type == TCC_OUTPUT_MEMORY) {
1174 unsigned long ofs;
1175 reloc_type = R_AARCH64_JUMP_SLOT;
1176 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1177 sym->st_info, sym_index);
1178 /* We store the place of the generated PLT slot
1179 in our addend. */
1180 rel->r_addend += ofs;
1181 }
1182 break;
1183#elif defined(TCC_TARGET_C67)
1184 case R_C60_GOT32:
1185 case R_C60_GOTOFF:
1186 case R_C60_GOTPC:
1187 case R_C60_PLT32:
1188 if (!s1->got)
1189 build_got(s1);
1190 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1191 sym_index = ELFW(R_SYM)(rel->r_info);
1192 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1193 /* look at the symbol got offset. If none, then add one */
1194 if (type == R_C60_GOT32)
1195 reloc_type = R_C60_GLOB_DAT;
1196 else
1197 reloc_type = R_C60_JMP_SLOT;
1198 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1199 sym_index);
1200 }
1201 break;
1202#elif defined(TCC_TARGET_X86_64)
1203 case R_X86_64_32:
1204 case R_X86_64_32S:
1205 case R_X86_64_64:
1206 case R_X86_64_PC32:
1207 case R_X86_64_GOT32:
1208 case R_X86_64_GOTTPOFF:
1209 case R_X86_64_GOTPCREL:
1210 case R_X86_64_GOTPCRELX:
1211 case R_X86_64_REX_GOTPCRELX:
1212 case R_X86_64_PLT32:
1213 sym_index = ELFW(R_SYM)(rel->r_info);
1214 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1215 if ((type == R_X86_64_32 || type == R_X86_64_32S ||
1216 type == R_X86_64_64 || type == R_X86_64_PC32) &&
1217 sym->st_shndx != SHN_UNDEF)
1218 break;
1219 1062
1220 if (type == R_X86_64_PLT32 &&1063 if (relocs_info[type].gotplt_entry == BUILD_GOT_ONLY)
1221 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {1064 continue;
1222 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1223 break;
1224 }
1225 1065
1226 if (!s1->got)1066 if (relocs_info[type].code_reloc)
1227 build_got(s1);1067 reloc_type = R_JMP_SLOT;
1228 if (type != R_X86_64_GOTTPOFF) {1068 else
1229 unsigned long ofs;1069 reloc_type = R_GLOB_DAT;
1230 /* look at the symbol got offset. If none, then add one */1070 ofs = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1231 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||1071 sym_index);
1232 type == R_X86_64_GOTPCRELX ||1072
1233 type == R_X86_64_REX_GOTPCRELX ||1073#ifdef DEBUG_RELOC
1234 type == R_X86_64_32 || type == R_X86_64_32S ||1074 printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
1235 type == R_X86_64_64)1075 (char *) symtab_section->link->data + sym->st_name, type,
1236 reloc_type = R_X86_64_GLOB_DAT;1076 sym->st_shndx, ofs);
1237 else
1238 reloc_type = R_X86_64_JUMP_SLOT;
1239 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1240 sym->st_info, sym_index);
1241 if (type == R_X86_64_PLT32)
1242 /* We store the place of the generated PLT slot
1243 in our addend. */
1244 rel->r_addend += ofs;
1245 }
1246 break;
1247#else
1248#error unsupported CPU
1249#endif1077#endif
1250 default:1078
1251 break;1079#if defined (TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
1080 /* We store the place of the generated PLT slot in our addend. */
1081 if (relocs_info[type].pltoff_addend)
1082 rel->r_addend += ofs;
1083
1084#elif defined (TCC_TARGET_ARM)
1085 if (type == R_ARM_PC24 || type == R_ARM_CALL ||
1086 type == R_ARM_JUMP24 || type == R_ARM_PLT32) {
1087 addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
1088 + rel->r_offset);
1089 /* x must be signed! */
1090 int x = *ptr & 0xffffff;
1091 x = (x << 8) >> 8;
1092 x <<= 2;
1093 x += ofs;
1094 x >>= 2;
1095#ifdef DEBUG_RELOC
1096 printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
1097 (*ptr & 0xff000000) | x, x);
1098#endif
1099 *ptr = (*ptr & 0xff000000) | x;
1252 }1100 }
1101#endif
1253 }1102 }
1254 }1103 }
1255}1104}
x86_64-gen.c+1−0
@@ -110,6 +110,7 @@ enum { · 109 unmodified lines
110#define R_DATA_32 R_X86_64_32110#define R_DATA_32 R_X86_64_32
111#define R_DATA_PTR R_X86_64_64111#define R_DATA_PTR R_X86_64_64
112#define R_JMP_SLOT R_X86_64_JUMP_SLOT112#define R_JMP_SLOT R_X86_64_JUMP_SLOT
113#define R_GLOB_DAT R_X86_64_GLOB_DAT
113#define R_COPY R_X86_64_COPY114#define R_COPY R_X86_64_COPY
114 115
115#define ELF_START_ADDR 0x400000116#define ELF_START_ADDR 0x400000
x86_64-link.c+14−0
@@ -2,6 +2,20 @@ · 1 unmodified line
2#define HAVE_SECTION_RELOC2#define HAVE_SECTION_RELOC
3 3
4static ElfW_Rel *qrel; /* ptr to next reloc entry reused */4static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
5ST_DATA struct reloc_info relocs_info[] = {
6 INIT_RELOC_INFO (R_X86_64_64, 0, AUTO_GOTPLT_ENTRY, 0)
7 INIT_RELOC_INFO (R_X86_64_32, 0, AUTO_GOTPLT_ENTRY, 0)
8 INIT_RELOC_INFO (R_X86_64_32S, 0, AUTO_GOTPLT_ENTRY, 0)
9 INIT_RELOC_INFO (R_X86_64_PC32, 1, AUTO_GOTPLT_ENTRY, 0)
10 INIT_RELOC_INFO (R_X86_64_PLT32, 1, ALWAYS_GOTPLT_ENTRY, 1)
11 INIT_RELOC_INFO (R_X86_64_GLOB_DAT, 0, NO_GOTPLT_ENTRY, 0)
12 INIT_RELOC_INFO (R_X86_64_JUMP_SLOT, 1, NO_GOTPLT_ENTRY, 0)
13 INIT_RELOC_INFO (R_X86_64_GOTPCREL, 0, ALWAYS_GOTPLT_ENTRY, 0)
14 INIT_RELOC_INFO (R_X86_64_GOTPCRELX, 0, ALWAYS_GOTPLT_ENTRY, 0)
15 INIT_RELOC_INFO (R_X86_64_REX_GOTPCRELX, 0, ALWAYS_GOTPLT_ENTRY, 0)
16 INIT_RELOC_INFO (R_X86_64_GOTTPOFF, 0, BUILD_GOT_ONLY, 0)
17 INIT_RELOC_INFO (R_X86_64_GOT32, 0, ALWAYS_GOTPLT_ENTRY, 0)
18};
5 19
6void relocate_init(Section *sr)20void relocate_init(Section *sr)
7{21{

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t