History

dynamic executables (PIE)

Allows to create dynamic executables, using the code path for TCC_OUTPUT_DLL but add an .interp header (plus a FLAGS_1 entry in the dynamic section to make 'readelf' say "PIE") Introduces TCC_OUTPUT_DYN as alias for TCC_OUTPUT_DLL. There is no runtime option, only one to configure: ./configure --config-pie 100 insertions(+), 76 deletions(-)

grischka committed 4 years ago

Commit ebaa5c81 parent e460f7d13 files · +100 −76Browse files

Unified · Split

13 files
  1. Makefile +2 −1
  2. arm-gen.c +1 −1
  3. arm-link.c +1 −1
  4. arm64-link.c +2 −2
  5. elf.h +1 −0
  6. i386-link.c +3 −3
  7. libtcc.c +13 −5
  8. libtcc.h +4 −4
  9. riscv64-link.c +2 −2
  10. tcc.h +5 −0
  11. tccdbg.c +1 −3
  12. tccelf.c +63 −52
  13. x86_64-link.c +2 −2
Makefile+2−1
@@ -91,6 +91,7 @@ NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64 · 90 unmodified lines
91NATIVE_DEFINES_$(CONFIG_riscv64) += -DTCC_TARGET_RISCV6491NATIVE_DEFINES_$(CONFIG_riscv64) += -DTCC_TARGET_RISCV64
92NATIVE_DEFINES_$(CONFIG_BSD) += -DTARGETOS_$(TARGETOS)92NATIVE_DEFINES_$(CONFIG_BSD) += -DTARGETOS_$(TARGETOS)
93NATIVE_DEFINES_$(CONFIG_pie) += -DCONFIG_TCC_PIE93NATIVE_DEFINES_$(CONFIG_pie) += -DCONFIG_TCC_PIE
94NATIVE_DEFINES_$(CONFIG_pic) += -DCONFIG_TCC_PIC
94NATIVE_DEFINES_no_$(CONFIG_bcheck) += -DCONFIG_TCC_BCHECK=095NATIVE_DEFINES_no_$(CONFIG_bcheck) += -DCONFIG_TCC_BCHECK=0
95NATIVE_DEFINES_no_$(CONFIG_backtrace) += -DCONFIG_TCC_BACKTRACE=096NATIVE_DEFINES_no_$(CONFIG_backtrace) += -DCONFIG_TCC_BACKTRACE=0
96NATIVE_DEFINES += $(NATIVE_DEFINES_yes) $(NATIVE_DEFINES_no_no)97NATIVE_DEFINES += $(NATIVE_DEFINES_yes) $(NATIVE_DEFINES_no_no)
@@ -275,7 +276,7 @@ libtcc.a: $(LIBTCC_OBJ) · 178 unmodified lines
275 276
276# dynamic libtcc library277# dynamic libtcc library
277libtcc.so: $(LIBTCC_OBJ)278libtcc.so: $(LIBTCC_OBJ)
278 $S$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)279 $S$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LIBS) $(LDFLAGS)
279 280
280libtcc.so: CFLAGS+=-fPIC281libtcc.so: CFLAGS+=-fPIC
281libtcc.so: LDFLAGS+=-fPIC282libtcc.so: LDFLAGS+=-fPIC
arm-gen.c+1−1
@@ -543,7 +543,7 @@ static void load_value(SValue *sv, int r) · 542 unmodified lines
543{543{
544 o(0xE59F0000|(intr(r)<<12)); /* ldr r, [pc] */544 o(0xE59F0000|(intr(r)<<12)); /* ldr r, [pc] */
545 o(0xEA000000); /* b $+4 */545 o(0xEA000000); /* b $+4 */
546#ifndef CONFIG_TCC_PIE546#ifndef CONFIG_TCC_PIC
547 if(sv->r & VT_SYM)547 if(sv->r & VT_SYM)
548 greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);548 greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
549 o(sv->c.i);549 o(sv->c.i);
arm-link.c+1−1
@@ -380,7 +380,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 379 unmodified lines
380 return;380 return;
381 case R_ARM_ABS32:381 case R_ARM_ABS32:
382 case R_ARM_TARGET1:382 case R_ARM_TARGET1:
383 if (s1->output_type == TCC_OUTPUT_DLL) {383 if (s1->output_type & TCC_OUTPUT_DYN) {
384 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;384 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
385 qrel->r_offset = rel->r_offset;385 qrel->r_offset = rel->r_offset;
386 if (esym_index) {386 if (esym_index) {
arm64-link.c+2−2
@@ -177,7 +177,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 176 unmodified lines
177 177
178 switch(type) {178 switch(type) {
179 case R_AARCH64_ABS64:179 case R_AARCH64_ABS64:
180 if (s1->output_type == TCC_OUTPUT_DLL) {180 if ((s1->output_type & TCC_OUTPUT_DYN)) {
181 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;181 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
182 qrel->r_offset = rel->r_offset;182 qrel->r_offset = rel->r_offset;
183 if (esym_index) {183 if (esym_index) {
@@ -194,7 +194,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 10 unmodified lines
194 add64le(ptr, val);194 add64le(ptr, val);
195 return;195 return;
196 case R_AARCH64_ABS32:196 case R_AARCH64_ABS32:
197 if (s1->output_type == TCC_OUTPUT_DLL) {197 if (s1->output_type & TCC_OUTPUT_DYN) {
198 /* XXX: this logic may depend on TCC's codegen198 /* XXX: this logic may depend on TCC's codegen
199 now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */199 now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */
200 qrel->r_offset = rel->r_offset;200 qrel->r_offset = rel->r_offset;
elf.h+1−0
@@ -825,6 +825,7 @@ typedef struct · 824 unmodified lines
825#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */825#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */
826#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */826#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */
827#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */827#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */
828#define DF_1_PIE 0x08000000
828 829
829/* Flags for the feature selection in DT_FEATURE_1. */830/* Flags for the feature selection in DT_FEATURE_1. */
830#define DTF_1_PARINIT 0x00000001831#define DTF_1_PARINIT 0x00000001
i386-link.c+3−3
@@ -100,7 +100,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 99 unmodified lines
100 unsigned plt_offset, relofs;100 unsigned plt_offset, relofs;
101 101
102 /* on i386 if we build a DLL, we add a %ebx offset */102 /* on i386 if we build a DLL, we add a %ebx offset */
103 if (s1->output_type == TCC_OUTPUT_DLL)103 if (s1->output_type & TCC_OUTPUT_DYN)
104 modrm = 0xa3;104 modrm = 0xa3;
105 else105 else
106 modrm = 0x25;106 modrm = 0x25;
@@ -148,7 +148,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 41 unmodified lines
148 p = s1->plt->data;148 p = s1->plt->data;
149 p_end = p + s1->plt->data_offset;149 p_end = p + s1->plt->data_offset;
150 150
151 if (s1->output_type != TCC_OUTPUT_DLL && p < p_end) {151 if (!(s1->output_type & TCC_OUTPUT_DYN) && p < p_end) {
152 add32le(p + 2, s1->got->sh_addr);152 add32le(p + 2, s1->got->sh_addr);
153 add32le(p + 8, s1->got->sh_addr);153 add32le(p + 8, s1->got->sh_addr);
154 p += 16;154 p += 16;
@@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 24 unmodified lines
179 179
180 switch (type) {180 switch (type) {
181 case R_386_32:181 case R_386_32:
182 if (s1->output_type == TCC_OUTPUT_DLL) {182 if (s1->output_type & TCC_OUTPUT_DYN) {
183 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;183 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
184 qrel->r_offset = rel->r_offset;184 qrel->r_offset = rel->r_offset;
185 if (esym_index) {185 if (esym_index) {
libtcc.c+13−5
@@ -862,6 +862,10 @@ LIBTCCAPI void tcc_delete(TCCState *s1) · 861 unmodified lines
862 862
863LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)863LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
864{864{
865#ifdef CONFIG_TCC_PIE
866 if (output_type == TCC_OUTPUT_EXE)
867 output_type |= TCC_OUTPUT_DYN;
868#endif
865 s->output_type = output_type;869 s->output_type = output_type;
866 870
867 if (!s->nostdinc) {871 if (!s->nostdinc) {
@@ -869,6 +873,10 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 1 unmodified line
869 /* -isystem paths have already been handled */873 /* -isystem paths have already been handled */
870 tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);874 tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
871 }875 }
876
877 if (output_type == TCC_OUTPUT_PREPROCESS)
878 return 0;
879
872#ifdef CONFIG_TCC_BCHECK880#ifdef CONFIG_TCC_BCHECK
873 if (s->do_bounds_check) {881 if (s->do_bounds_check) {
874 /* if bound checking, then add corresponding sections */882 /* if bound checking, then add corresponding sections */
@@ -905,13 +913,13 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 30 unmodified lines
905#else913#else
906 /* paths for crt objects */914 /* paths for crt objects */
907 tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);915 tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
916
908 /* add libc crt1/crti objects */917 /* add libc crt1/crti objects */
909 if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&918 if (output_type != TCC_OUTPUT_MEMORY && !s->nostdlib) {
910 !s->nostdlib) {
911#if TARGETOS_OpenBSD919#if TARGETOS_OpenBSD
912 if (output_type != TCC_OUTPUT_DLL)920 if (output_type != TCC_OUTPUT_DLL)
913 tcc_add_crt(s, "crt0.o");921 tcc_add_crt(s, "crt0.o");
914 if (output_type == TCC_OUTPUT_DLL)922 if (output_type & TCC_OUTPUT_DYN)
915 tcc_add_crt(s, "crtbeginS.o");923 tcc_add_crt(s, "crtbeginS.o");
916 else924 else
917 tcc_add_crt(s, "crtbegin.o");925 tcc_add_crt(s, "crtbegin.o");
@@ -921,7 +929,7 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 3 unmodified lines
921 tcc_add_crt(s, "crti.o");929 tcc_add_crt(s, "crti.o");
922 if (s->static_link)930 if (s->static_link)
923 tcc_add_crt(s, "crtbeginT.o");931 tcc_add_crt(s, "crtbeginT.o");
924 else if (output_type == TCC_OUTPUT_DLL)932 else if (output_type & TCC_OUTPUT_DYN)
925 tcc_add_crt(s, "crtbeginS.o");933 tcc_add_crt(s, "crtbeginS.o");
926 else934 else
927 tcc_add_crt(s, "crtbegin.o");935 tcc_add_crt(s, "crtbegin.o");
@@ -931,7 +939,7 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 3 unmodified lines
931 tcc_add_crt(s, "crti.o");939 tcc_add_crt(s, "crti.o");
932 if (s->static_link)940 if (s->static_link)
933 tcc_add_crt(s, "crtbeginT.o");941 tcc_add_crt(s, "crtbeginT.o");
934 else if (output_type == TCC_OUTPUT_DLL)942 else if (output_type & TCC_OUTPUT_DYN)
935 tcc_add_crt(s, "crtbeginS.o");943 tcc_add_crt(s, "crtbeginS.o");
936 else944 else
937 tcc_add_crt(s, "crtbegin.o");945 tcc_add_crt(s, "crtbegin.o");
libtcc.h+4−4
@@ -65,11 +65,11 @@ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf); · 64 unmodified lines
65 65
66/* set output type. MUST BE CALLED before any compilation */66/* set output type. MUST BE CALLED before any compilation */
67LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);67LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
68#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */68#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory */
69#define TCC_OUTPUT_EXE 2 /* executable file */69#define TCC_OUTPUT_EXE 2 /* executable file */
70#define TCC_OUTPUT_DLL 3 /* dynamic library */70#define TCC_OUTPUT_DLL 4 /* dynamic library */
71#define TCC_OUTPUT_OBJ 4 /* object file */71#define TCC_OUTPUT_OBJ 3 /* object file */
72#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */72#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess */
73 73
74/* equivalent to -Lpath option */74/* equivalent to -Lpath option */
75LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);75LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
riscv64-link.c+2−2
@@ -284,7 +284,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 283 unmodified lines
284 return;284 return;
285 285
286 case R_RISCV_32:286 case R_RISCV_32:
287 if (s1->output_type == TCC_OUTPUT_DLL) {287 if (s1->output_type & TCC_OUTPUT_DYN) {
288 /* XXX: this logic may depend on TCC's codegen288 /* XXX: this logic may depend on TCC's codegen
289 now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */289 now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */
290 qrel->r_offset = rel->r_offset;290 qrel->r_offset = rel->r_offset;
@@ -296,7 +296,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines
296 add32le(ptr, val);296 add32le(ptr, val);
297 return;297 return;
298 case R_RISCV_64:298 case R_RISCV_64:
299 if (s1->output_type == TCC_OUTPUT_DLL) {299 if (s1->output_type & TCC_OUTPUT_DYN) {
300 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;300 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
301 qrel->r_offset = rel->r_offset;301 qrel->r_offset = rel->r_offset;
302 if (esym_index) {302 if (esym_index) {
tcc.h+5−0
@@ -236,6 +236,10 @@ extern long double strtold (const char *__nptr, char **__endptr); · 235 unmodified lines
236# define TCC_USING_DOUBLE_FOR_LDOUBLE 1236# define TCC_USING_DOUBLE_FOR_LDOUBLE 1
237#endif237#endif
238 238
239#ifdef CONFIG_TCC_PIE
240# define CONFIG_TCC_PIC 1
241#endif
242
239/* ------------ path configuration ------------ */243/* ------------ path configuration ------------ */
240 244
241#ifndef CONFIG_SYSROOT245#ifndef CONFIG_SYSROOT
@@ -1485,6 +1489,7 @@ ST_DATA int func_bound_add_epilog; · 1243 unmodified lines
1485#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */1489#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */
1486#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */1490#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
1487#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */1491#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */
1492#define TCC_OUTPUT_DYN TCC_OUTPUT_DLL
1488 1493
1489#define ARMAG "!<arch>\012" /* For COFF and a.out archives */1494#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1490 1495
tccdbg.c+1−3
@@ -392,9 +392,7 @@ ST_FUNC void tcc_debug_new(TCCState *s1) · 391 unmodified lines
392#ifdef CONFIG_TCC_BACKTRACE392#ifdef CONFIG_TCC_BACKTRACE
393 /* include stab info with standalone backtrace support */393 /* include stab info with standalone backtrace support */
394 if (s1->do_backtrace394 if (s1->do_backtrace
395 && (s1->output_type == TCC_OUTPUT_EXE395 && (s1->output_type & (TCC_OUTPUT_EXE | TCC_OUTPUT_DLL)))
396 || s1->output_type == TCC_OUTPUT_DLL)
397 )
398 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX396 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
399#endif397#endif
400 if (s1->dwarf) {398 if (s1->dwarf) {
tccelf.c+63−52
@@ -928,12 +928,16 @@ static void relocate_section(TCCState *s1, Section *s, Section *sr) · 927 unmodified lines
928 /* if the relocation is allocated, we change its symbol table */928 /* if the relocation is allocated, we change its symbol table */
929 if (sr->sh_flags & SHF_ALLOC) {929 if (sr->sh_flags & SHF_ALLOC) {
930 sr->link = s1->dynsym;930 sr->link = s1->dynsym;
931 if (s1->output_type == TCC_OUTPUT_DLL) {931 if (s1->output_type & TCC_OUTPUT_DYN) {
932 size_t r = (uint8_t*)qrel - sr->data;932 size_t r = (uint8_t*)qrel - sr->data;
933 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE933 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
934 && 0 == strcmp(s->name, ".stab"))934 && 0 == strcmp(s->name, ".stab"))
935 r = 0; /* cannot apply 64bit relocation to 32bit value */935 r = 0; /* cannot apply 64bit relocation to 32bit value */
936 sr->data_offset = sr->sh_size = r;936 sr->data_offset = sr->sh_size = r;
937#ifdef CONFIG_TCC_PIE
938 if (r && 0 == (s->sh_flags & SHF_WRITE))
939 tcc_warning("%d relocations to ro-section %s", (unsigned)(r / sizeof *qrel), s->name);
940#endif
937 }941 }
938 }942 }
939#endif943#endif
@@ -1013,7 +1017,6 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 73 unmodified lines
1013 case R_X86_64_PC32:1017 case R_X86_64_PC32:
1014 {1018 {
1015 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];1019 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1016
1017 /* Hidden defined symbols can and must be resolved locally.1020 /* Hidden defined symbols can and must be resolved locally.
1018 We're misusing a PLT32 reloc for this, as that's always1021 We're misusing a PLT32 reloc for this, as that's always
1019 resolved to its address even in shared libs. */1022 resolved to its address even in shared libs. */
@@ -1026,6 +1029,8 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 6 unmodified lines
1026#elif defined(TCC_TARGET_ARM64)1029#elif defined(TCC_TARGET_ARM64)
1027 case R_AARCH64_PREL32:1030 case R_AARCH64_PREL32:
1028#endif1031#endif
1032 if (s1->output_type != TCC_OUTPUT_DLL)
1033 break;
1029 if (get_sym_attr(s1, sym_index, 0)->dyn_index)1034 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1030 count++;1035 count++;
1031 break;1036 break;
@@ -1188,7 +1193,8 @@ redo: · 156 unmodified lines
1188 if (sym->st_shndx == SHN_UNDEF) {1193 if (sym->st_shndx == SHN_UNDEF) {
1189 ElfW(Sym) *esym;1194 ElfW(Sym) *esym;
1190 int dynindex;1195 int dynindex;
1191 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)1196 if (!PCRELATIVE_DLLPLT
1197 && (s1->output_type & TCC_OUTPUT_DYN))
1192 continue;1198 continue;
1193 /* Relocations for UNDEF symbols would normally need1199 /* Relocations for UNDEF symbols would normally need
1194 to be transferred into the executable or shared object.1200 to be transferred into the executable or shared object.
@@ -1228,7 +1234,7 @@ redo: · 33 unmodified lines
1228 sym->st_shndx != SHN_UNDEF &&1234 sym->st_shndx != SHN_UNDEF &&
1229 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||1235 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1230 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||1236 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1231 s1->output_type == TCC_OUTPUT_EXE)) {1237 s1->output_type & TCC_OUTPUT_EXE)) {
1232 if (pass != 0)1238 if (pass != 0)
1233 continue;1239 continue;
1234 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);1240 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
@@ -1483,7 +1489,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 248 unmodified lines
1483#endif1489#endif
1484#ifdef CONFIG_TCC_BACKTRACE1490#ifdef CONFIG_TCC_BACKTRACE
1485 if (s1->do_backtrace) {1491 if (s1->do_backtrace) {
1486 if (s1->output_type == TCC_OUTPUT_EXE)1492 if (s1->output_type & TCC_OUTPUT_EXE)
1487 tcc_add_support(s1, "bt-exe.o");1493 tcc_add_support(s1, "bt-exe.o");
1488 if (s1->output_type != TCC_OUTPUT_DLL)1494 if (s1->output_type != TCC_OUTPUT_DLL)
1489 tcc_add_support(s1, "bt-log.o");1495 tcc_add_support(s1, "bt-log.o");
@@ -1513,7 +1519,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 23 unmodified lines
1513#if defined TCC_TARGET_MACHO1519#if defined TCC_TARGET_MACHO
1514 /* nothing to do */1520 /* nothing to do */
1515#elif TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD1521#elif TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1516 if (s1->output_type == TCC_OUTPUT_DLL)1522 if (s1->output_type & TCC_OUTPUT_DYN)
1517 tcc_add_crt(s1, "crtendS.o");1523 tcc_add_crt(s1, "crtendS.o");
1518 else1524 else
1519 tcc_add_crt(s1, "crtend.o");1525 tcc_add_crt(s1, "crtend.o");
@@ -1812,7 +1818,7 @@ static int set_sec_sizes(TCCState *s1) · 292 unmodified lines
1812 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {1818 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
1813 /* when generating a DLL, we include relocations but1819 /* when generating a DLL, we include relocations but
1814 we may patch them */1820 we may patch them */
1815 if (file_type == TCC_OUTPUT_DLL1821 if ((file_type & TCC_OUTPUT_DYN)
1816 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {1822 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
1817 int count = prepare_dynamic_rel(s1, s);1823 int count = prepare_dynamic_rel(s1, s);
1818 if (count) {1824 if (count) {
@@ -1820,7 +1826,7 @@ static int set_sec_sizes(TCCState *s1) · 1 unmodified line
1820 s->sh_flags |= SHF_ALLOC;1826 s->sh_flags |= SHF_ALLOC;
1821 s->sh_size = count * sizeof(ElfW_Rel);1827 s->sh_size = count * sizeof(ElfW_Rel);
1822 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))1828 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1823 textrel = 1;1829 textrel += count;
1824 }1830 }
1825 }1831 }
1826 } else if ((s->sh_flags & SHF_ALLOC)1832 } else if ((s->sh_flags & SHF_ALLOC)
@@ -1904,7 +1910,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 77 unmodified lines
1904 a_offset += s_align;1910 a_offset += s_align;
1905 file_offset += (a_offset - p_offset);1911 file_offset += (a_offset - p_offset);
1906 } else {1912 } else {
1907 if (file_type == TCC_OUTPUT_DLL)1913 if (file_type & TCC_OUTPUT_DYN)
1908 addr = 0;1914 addr = 0;
1909 else1915 else
1910 addr = ELF_START_ADDR;1916 addr = ELF_START_ADDR;
@@ -1936,7 +1942,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 25 unmodified lines
1936 symbol tables, relocations, progbits, nobits */1942 symbol tables, relocations, progbits, nobits */
1937 /* XXX: do faster and simpler sorting */1943 /* XXX: do faster and simpler sorting */
1938 f = -1;1944 f = -1;
1939 for(k = 0; k < 7; k++) {1945 for(k = 0; k < 10; k++) {
1940 for(i = 1; i < s1->nb_sections; i++) {1946 for(i = 1; i < s1->nb_sections; i++) {
1941 s = s1->sections[i];1947 s = s1->sections[i];
1942 /* compute if section should be included */1948 /* compute if section should be included */
@@ -1970,9 +1976,6 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 27 unmodified lines
1970 if (k != 2)1976 if (k != 2)
1971 continue;1977 continue;
1972 }1978 }
1973 } else if (s->sh_type == SHT_NOBITS) {
1974 if (k != 6)
1975 continue;
1976 } else if ((s == rodata_section1979 } else if ((s == rodata_section
1977#ifdef CONFIG_TCC_BCHECK1980#ifdef CONFIG_TCC_BCHECK
1978 || s == bounds_section1981 || s == bounds_section
@@ -1984,6 +1987,19 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 5 unmodified lines
1984 /* Align next section on page size.1987 /* Align next section on page size.
1985 This is needed to remap roinf section ro. */1988 This is needed to remap roinf section ro. */
1986 f = 1;1989 f = 1;
1990
1991 } else if (s->sh_type == SHT_PREINIT_ARRAY) {
1992 if (k != 6)
1993 continue;
1994 } else if (s->sh_type == SHT_INIT_ARRAY) {
1995 if (k != 7)
1996 continue;
1997 } else if (s->sh_type == SHT_FINI_ARRAY) {
1998 if (k != 8)
1999 continue;
2000 } else if (s->sh_type == SHT_NOBITS) {
2001 if (k != 9)
2002 continue;
1987 } else {2003 } else {
1988 if (k != 5)2004 if (k != 5)
1989 continue;2005 continue;
@@ -2270,7 +2286,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 280 unmodified lines
2270#ifdef TCC_ARM_EABI2286#ifdef TCC_ARM_EABI
2271 ehdr.e_ident[EI_OSABI] = 0;2287 ehdr.e_ident[EI_OSABI] = 0;
2272 ehdr.e_flags = EF_ARM_EABI_VER4;2288 ehdr.e_flags = EF_ARM_EABI_VER4;
2273 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)2289 if (file_type & (TCC_OUTPUT_EXE | TCC_OUTPUT_DLL))
2274 ehdr.e_flags |= EF_ARM_HASENTRY;2290 ehdr.e_flags |= EF_ARM_HASENTRY;
2275 if (s1->float_abi == ARM_HARD_FLOAT)2291 if (s1->float_abi == ARM_HARD_FLOAT)
2276 ehdr.e_flags |= EF_ARM_VFP_FLOAT;2292 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
@@ -2282,26 +2298,22 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 5 unmodified lines
2282#elif defined TCC_TARGET_RISCV642298#elif defined TCC_TARGET_RISCV64
2283 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;2299 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2284#endif2300#endif
2285 switch(file_type) {2301
2286 default:2302 if (file_type == TCC_OUTPUT_OBJ) {
2287 case TCC_OUTPUT_EXE:
2288 ehdr.e_type = ET_EXEC;
2289 ehdr.e_entry = get_sym_addr(s1,
2290 s1->elf_entryname ?
2291 s1->elf_entryname : "_start",
2292 1, 0);
2293 break;
2294 case TCC_OUTPUT_DLL:
2295 ehdr.e_type = ET_DYN;
2296 ehdr.e_entry = s1->elf_entryname ?
2297 get_sym_addr(s1,s1->elf_entryname,1,0) :
2298 text_section->sh_addr;
2299 /* XXX: is it correct ? */
2300 break;
2301 case TCC_OUTPUT_OBJ:
2302 ehdr.e_type = ET_REL;2303 ehdr.e_type = ET_REL;
2303 break;2304 } else {
2305 if (file_type & TCC_OUTPUT_DYN)
2306 ehdr.e_type = ET_DYN;
2307 else
2308 ehdr.e_type = ET_EXEC;
2309 if (s1->elf_entryname)
2310 ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
2311 else
2312 ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
2313 if (ehdr.e_entry == (addr_t)-1)
2314 ehdr.e_entry = text_section->sh_addr;
2304 }2315 }
2316
2305 ehdr.e_machine = EM_TCC_TARGET;2317 ehdr.e_machine = EM_TCC_TARGET;
2306 ehdr.e_version = EV_CURRENT;2318 ehdr.e_version = EV_CURRENT;
2307 ehdr.e_shoff = file_offset;2319 ehdr.e_shoff = file_offset;
@@ -2530,7 +2542,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 222 unmodified lines
2530 ElfW(Phdr) *phdr;2542 ElfW(Phdr) *phdr;
2531 Section *interp, *dynamic, *dynstr, *note;2543 Section *interp, *dynamic, *dynstr, *note;
2532 struct ro_inf *roinf_use = NULL;2544 struct ro_inf *roinf_use = NULL;
2533 int textrel, got_sym;2545 int textrel, got_sym, dt_flags_1;
2534 2546
2535 file_type = s1->output_type;2547 file_type = s1->output_type;
2536 s1->nb_errors = 0;2548 s1->nb_errors = 0;
@@ -2557,7 +2569,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 20 unmodified lines
2557 resolve_common_syms(s1);2569 resolve_common_syms(s1);
2558 2570
2559 if (!s1->static_link) {2571 if (!s1->static_link) {
2560 if (file_type == TCC_OUTPUT_EXE) {2572 if (file_type & TCC_OUTPUT_EXE) {
2561 char *ptr;2573 char *ptr;
2562 /* allow override the dynamic loader */2574 /* allow override the dynamic loader */
2563 const char *elfint = getenv("LD_SO");2575 const char *elfint = getenv("LD_SO");
@@ -2590,7 +2602,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 26 unmodified lines
2590 goto the_end;2602 goto the_end;
2591 }2603 }
2592 build_got_entries(s1, got_sym);2604 build_got_entries(s1, got_sym);
2593 if (file_type == TCC_OUTPUT_EXE) {2605 if (file_type & TCC_OUTPUT_EXE) {
2594 bind_libs_dynsyms(s1);2606 bind_libs_dynsyms(s1);
2595 } else {2607 } else {
2596 /* shared library case: simply export all global symbols */2608 /* shared library case: simply export all global symbols */
@@ -2606,7 +2618,6 @@ static int elf_output_file(TCCState *s1, const char *filename) · 9 unmodified lines
2606 alloc_sec_names(s1, 0);2618 alloc_sec_names(s1, 0);
2607 2619
2608 if (!s1->static_link) {2620 if (!s1->static_link) {
2609 int i;
2610 /* add a list of needed dlls */2621 /* add a list of needed dlls */
2611 for(i = 0; i < s1->nb_loaded_dlls; i++) {2622 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2612 DLLReference *dllref = s1->loaded_dlls[i];2623 DLLReference *dllref = s1->loaded_dlls[i];
@@ -2618,15 +2629,19 @@ static int elf_output_file(TCCState *s1, const char *filename) · 5 unmodified lines
2618 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,2629 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2619 put_elf_str(dynstr, s1->rpath));2630 put_elf_str(dynstr, s1->rpath));
2620 2631
2621 if (file_type == TCC_OUTPUT_DLL) {2632 dt_flags_1 = DF_1_NOW;
2633 if (file_type & TCC_OUTPUT_DYN) {
2622 if (s1->soname)2634 if (s1->soname)
2623 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));2635 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2624 /* XXX: currently, since we do not handle PIC code, we2636 /* XXX: currently, since we do not handle PIC code, we
2625 must relocate the readonly segments */2637 must relocate the readonly segments */
2626 if (textrel)2638 if (textrel)
2627 put_dt(dynamic, DT_TEXTREL, 0);2639 put_dt(dynamic, DT_TEXTREL, 0);
2640 if (file_type & TCC_OUTPUT_EXE)
2641 dt_flags_1 = DF_1_NOW | DF_1_PIE;
2628 }2642 }
2629 2643 put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
2644 put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
2630 if (s1->symbolic)2645 if (s1->symbolic)
2631 put_dt(dynamic, DT_SYMBOLIC, 0);2646 put_dt(dynamic, DT_SYMBOLIC, 0);
2632 2647
@@ -2639,20 +2654,16 @@ static int elf_output_file(TCCState *s1, const char *filename) · 6 unmodified lines
2639 dynstr->sh_size = dynstr->data_offset;2654 dynstr->sh_size = dynstr->data_offset;
2640 }2655 }
2641 2656
2642 for (i = 1; i < s1->nb_sections &&
2643 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2644 phfill = 2 + (i < s1->nb_sections);
2645
2646 /* compute number of program headers */2657 /* compute number of program headers */
2647 if (file_type == TCC_OUTPUT_DLL)2658 phfill = 2;
2648 phnum = 3;2659 for (i = 1; i < s1->nb_sections; i++)
2649 else if (s1->static_link)2660 if (s1->sections[i]->sh_flags & SHF_TLS)
2650 phnum = 3;2661 phfill = 3;
2651 else {2662 phnum = 3;
2652 phnum = 5 + (i < s1->nb_sections);2663 if (interp)
2653 }2664 phnum += phfill;
2654 2665 if (note)
2655 phnum += note != NULL;2666 phnum++;
2656#if !TARGETOS_FreeBSD && !TARGETOS_NetBSD2667#if !TARGETOS_FreeBSD && !TARGETOS_NetBSD
2657 /* GNU_RELRO */2668 /* GNU_RELRO */
2658 phnum++, roinf_use = &roinf;2669 phnum++, roinf_use = &roinf;
@@ -2679,7 +2690,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 20 unmodified lines
2679 /* put in GOT the dynamic section address and relocate PLT */2690 /* put in GOT the dynamic section address and relocate PLT */
2680 write32le(s1->got->data, dynamic->sh_addr);2691 write32le(s1->got->data, dynamic->sh_addr);
2681 if (file_type == TCC_OUTPUT_EXE2692 if (file_type == TCC_OUTPUT_EXE
2682 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))2693 || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
2683 relocate_plt(s1);2694 relocate_plt(s1);
2684 2695
2685 /* relocate symbols in .dynsym now that final addresses are known */2696 /* relocate symbols in .dynsym now that final addresses are known */
x86_64-link.c+2−2
@@ -194,7 +194,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 193 unmodified lines
194 194
195 switch (type) {195 switch (type) {
196 case R_X86_64_64:196 case R_X86_64_64:
197 if (s1->output_type == TCC_OUTPUT_DLL) {197 if (s1->output_type & TCC_OUTPUT_DYN) {
198 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;198 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
199 qrel->r_offset = rel->r_offset;199 qrel->r_offset = rel->r_offset;
200 if (esym_index) {200 if (esym_index) {
@@ -212,7 +212,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 11 unmodified lines
212 break;212 break;
213 case R_X86_64_32:213 case R_X86_64_32:
214 case R_X86_64_32S:214 case R_X86_64_32S:
215 if (s1->output_type == TCC_OUTPUT_DLL) {215 if (s1->output_type & TCC_OUTPUT_DYN) {
216 /* XXX: this logic may depend on TCC's codegen216 /* XXX: this logic may depend on TCC's codegen
217 now TCC uses R_X86_64_32 even for a 64bit pointer */217 now TCC uses R_X86_64_32 even for a 64bit pointer */
218 qrel->r_offset = rel->r_offset;218 qrel->r_offset = rel->r_offset;

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