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
9191 NATIVE_DEFINES_$(CONFIG_riscv64) += -DTCC_TARGET_RISCV64
9292 NATIVE_DEFINES_$(CONFIG_BSD) += -DTARGETOS_$(TARGETOS)
9393 NATIVE_DEFINES_$(CONFIG_pie) += -DCONFIG_TCC_PIE
94+NATIVE_DEFINES_$(CONFIG_pic) += -DCONFIG_TCC_PIC
9495 NATIVE_DEFINES_no_$(CONFIG_bcheck) += -DCONFIG_TCC_BCHECK=0
9596 NATIVE_DEFINES_no_$(CONFIG_backtrace) += -DCONFIG_TCC_BACKTRACE=0
9697 NATIVE_DEFINES += $(NATIVE_DEFINES_yes) $(NATIVE_DEFINES_no_no)
@@ -275,7 +276,7 @@ libtcc.a: $(LIBTCC_OBJ) · 178 unmodified lines
275276
276277 # dynamic libtcc library
277278 libtcc.so: $(LIBTCC_OBJ)
278− $S$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
279+ $S$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LIBS) $(LDFLAGS)
279280
280281 libtcc.so: CFLAGS+=-fPIC
281282 libtcc.so: LDFLAGS+=-fPIC
arm-gen.c+1−1
@@ -543,7 +543,7 @@ static void load_value(SValue *sv, int r) · 542 unmodified lines
543543 {
544544 o(0xE59F0000|(intr(r)<<12)); /* ldr r, [pc] */
545545 o(0xEA000000); /* b $+4 */
546−#ifndef CONFIG_TCC_PIE
546+#ifndef CONFIG_TCC_PIC
547547 if(sv->r & VT_SYM)
548548 greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
549549 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
380380 return;
381381 case R_ARM_ABS32:
382382 case R_ARM_TARGET1:
383− if (s1->output_type == TCC_OUTPUT_DLL) {
383+ if (s1->output_type & TCC_OUTPUT_DYN) {
384384 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
385385 qrel->r_offset = rel->r_offset;
386386 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
177177
178178 switch(type) {
179179 case R_AARCH64_ABS64:
180− if (s1->output_type == TCC_OUTPUT_DLL) {
180+ if ((s1->output_type & TCC_OUTPUT_DYN)) {
181181 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
182182 qrel->r_offset = rel->r_offset;
183183 if (esym_index) {
@@ -194,7 +194,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 10 unmodified lines
194194 add64le(ptr, val);
195195 return;
196196 case R_AARCH64_ABS32:
197− if (s1->output_type == TCC_OUTPUT_DLL) {
197+ if (s1->output_type & TCC_OUTPUT_DYN) {
198198 /* XXX: this logic may depend on TCC's codegen
199199 now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */
200200 qrel->r_offset = rel->r_offset;
elf.h+1−0
@@ -825,6 +825,7 @@ typedef struct · 824 unmodified lines
825825 #define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */
826826 #define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */
827827 #define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */
828+#define DF_1_PIE 0x08000000
828829
829830 /* Flags for the feature selection in DT_FEATURE_1. */
830831 #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
100100 unsigned plt_offset, relofs;
101101
102102 /* 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)
104104 modrm = 0xa3;
105105 else
106106 modrm = 0x25;
@@ -148,7 +148,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 41 unmodified lines
148148 p = s1->plt->data;
149149 p_end = p + s1->plt->data_offset;
150150
151− if (s1->output_type != TCC_OUTPUT_DLL && p < p_end) {
151+ if (!(s1->output_type & TCC_OUTPUT_DYN) && p < p_end) {
152152 add32le(p + 2, s1->got->sh_addr);
153153 add32le(p + 8, s1->got->sh_addr);
154154 p += 16;
@@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 24 unmodified lines
179179
180180 switch (type) {
181181 case R_386_32:
182− if (s1->output_type == TCC_OUTPUT_DLL) {
182+ if (s1->output_type & TCC_OUTPUT_DYN) {
183183 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
184184 qrel->r_offset = rel->r_offset;
185185 if (esym_index) {
libtcc.c+13−5
@@ -862,6 +862,10 @@ LIBTCCAPI void tcc_delete(TCCState *s1) · 861 unmodified lines
862862
863863 LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
864864 {
865+#ifdef CONFIG_TCC_PIE
866+ if (output_type == TCC_OUTPUT_EXE)
867+ output_type |= TCC_OUTPUT_DYN;
868+#endif
865869 s->output_type = output_type;
866870
867871 if (!s->nostdinc) {
@@ -869,6 +873,10 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 1 unmodified line
869873 /* -isystem paths have already been handled */
870874 tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
871875 }
876+
877+ if (output_type == TCC_OUTPUT_PREPROCESS)
878+ return 0;
879+
872880 #ifdef CONFIG_TCC_BCHECK
873881 if (s->do_bounds_check) {
874882 /* 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
905913 #else
906914 /* paths for crt objects */
907915 tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
916+
908917 /* add libc crt1/crti objects */
909− if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
910− !s->nostdlib) {
918+ if (output_type != TCC_OUTPUT_MEMORY && !s->nostdlib) {
911919 #if TARGETOS_OpenBSD
912920 if (output_type != TCC_OUTPUT_DLL)
913921 tcc_add_crt(s, "crt0.o");
914− if (output_type == TCC_OUTPUT_DLL)
922+ if (output_type & TCC_OUTPUT_DYN)
915923 tcc_add_crt(s, "crtbeginS.o");
916924 else
917925 tcc_add_crt(s, "crtbegin.o");
@@ -921,7 +929,7 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 3 unmodified lines
921929 tcc_add_crt(s, "crti.o");
922930 if (s->static_link)
923931 tcc_add_crt(s, "crtbeginT.o");
924− else if (output_type == TCC_OUTPUT_DLL)
932+ else if (output_type & TCC_OUTPUT_DYN)
925933 tcc_add_crt(s, "crtbeginS.o");
926934 else
927935 tcc_add_crt(s, "crtbegin.o");
@@ -931,7 +939,7 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 3 unmodified lines
931939 tcc_add_crt(s, "crti.o");
932940 if (s->static_link)
933941 tcc_add_crt(s, "crtbeginT.o");
934− else if (output_type == TCC_OUTPUT_DLL)
942+ else if (output_type & TCC_OUTPUT_DYN)
935943 tcc_add_crt(s, "crtbeginS.o");
936944 else
937945 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
6565
6666 /* set output type. MUST BE CALLED before any compilation */
6767 LIBTCCAPI 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 */
6969 #define TCC_OUTPUT_EXE 2 /* executable file */
70−#define TCC_OUTPUT_DLL 3 /* dynamic library */
71−#define TCC_OUTPUT_OBJ 4 /* object file */
72−#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */
70+#define TCC_OUTPUT_DLL 4 /* dynamic library */
71+#define TCC_OUTPUT_OBJ 3 /* object file */
72+#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess */
7373
7474 /* equivalent to -Lpath option */
7575 LIBTCCAPI 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
284284 return;
285285
286286 case R_RISCV_32:
287− if (s1->output_type == TCC_OUTPUT_DLL) {
287+ if (s1->output_type & TCC_OUTPUT_DYN) {
288288 /* XXX: this logic may depend on TCC's codegen
289289 now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */
290290 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
296296 add32le(ptr, val);
297297 return;
298298 case R_RISCV_64:
299− if (s1->output_type == TCC_OUTPUT_DLL) {
299+ if (s1->output_type & TCC_OUTPUT_DYN) {
300300 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
301301 qrel->r_offset = rel->r_offset;
302302 if (esym_index) {
tcc.h+5−0
@@ -236,6 +236,10 @@ extern long double strtold (const char *__nptr, char **__endptr); · 235 unmodified lines
236236 # define TCC_USING_DOUBLE_FOR_LDOUBLE 1
237237 #endif
238238
239+#ifdef CONFIG_TCC_PIE
240+# define CONFIG_TCC_PIC 1
241+#endif
242+
239243 /* ------------ path configuration ------------ */
240244
241245 #ifndef CONFIG_SYSROOT
@@ -1485,6 +1489,7 @@ ST_DATA int func_bound_add_epilog; · 1243 unmodified lines
14851489 #define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */
14861490 #define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
14871491 #define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */
1492+#define TCC_OUTPUT_DYN TCC_OUTPUT_DLL
14881493
14891494 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
14901495
tccdbg.c+1−3
@@ -392,9 +392,7 @@ ST_FUNC void tcc_debug_new(TCCState *s1) · 391 unmodified lines
392392 #ifdef CONFIG_TCC_BACKTRACE
393393 /* include stab info with standalone backtrace support */
394394 if (s1->do_backtrace
395− && (s1->output_type == TCC_OUTPUT_EXE
396− || s1->output_type == TCC_OUTPUT_DLL)
397− )
395+ && (s1->output_type & (TCC_OUTPUT_EXE | TCC_OUTPUT_DLL)))
398396 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
399397 #endif
400398 if (s1->dwarf) {
tccelf.c+63−52
@@ -928,12 +928,16 @@ static void relocate_section(TCCState *s1, Section *s, Section *sr) · 927 unmodified lines
928928 /* if the relocation is allocated, we change its symbol table */
929929 if (sr->sh_flags & SHF_ALLOC) {
930930 sr->link = s1->dynsym;
931− if (s1->output_type == TCC_OUTPUT_DLL) {
931+ if (s1->output_type & TCC_OUTPUT_DYN) {
932932 size_t r = (uint8_t*)qrel - sr->data;
933933 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
934934 && 0 == strcmp(s->name, ".stab"))
935935 r = 0; /* cannot apply 64bit relocation to 32bit value */
936936 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
937941 }
938942 }
939943 #endif
@@ -1013,7 +1017,6 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 73 unmodified lines
10131017 case R_X86_64_PC32:
10141018 {
10151019 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1016−
10171020 /* Hidden defined symbols can and must be resolved locally.
10181021 We're misusing a PLT32 reloc for this, as that's always
10191022 resolved to its address even in shared libs. */
@@ -1026,6 +1029,8 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 6 unmodified lines
10261029 #elif defined(TCC_TARGET_ARM64)
10271030 case R_AARCH64_PREL32:
10281031 #endif
1032+ if (s1->output_type != TCC_OUTPUT_DLL)
1033+ break;
10291034 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
10301035 count++;
10311036 break;
@@ -1188,7 +1193,8 @@ redo: · 156 unmodified lines
11881193 if (sym->st_shndx == SHN_UNDEF) {
11891194 ElfW(Sym) *esym;
11901195 int dynindex;
1191− if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1196+ if (!PCRELATIVE_DLLPLT
1197+ && (s1->output_type & TCC_OUTPUT_DYN))
11921198 continue;
11931199 /* Relocations for UNDEF symbols would normally need
11941200 to be transferred into the executable or shared object.
@@ -1228,7 +1234,7 @@ redo: · 33 unmodified lines
12281234 sym->st_shndx != SHN_UNDEF &&
12291235 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
12301236 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1231− s1->output_type == TCC_OUTPUT_EXE)) {
1237+ s1->output_type & TCC_OUTPUT_EXE)) {
12321238 if (pass != 0)
12331239 continue;
12341240 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
14831489 #endif
14841490 #ifdef CONFIG_TCC_BACKTRACE
14851491 if (s1->do_backtrace) {
1486− if (s1->output_type == TCC_OUTPUT_EXE)
1492+ if (s1->output_type & TCC_OUTPUT_EXE)
14871493 tcc_add_support(s1, "bt-exe.o");
14881494 if (s1->output_type != TCC_OUTPUT_DLL)
14891495 tcc_add_support(s1, "bt-log.o");
@@ -1513,7 +1519,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 23 unmodified lines
15131519 #if defined TCC_TARGET_MACHO
15141520 /* nothing to do */
15151521 #elif TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1516− if (s1->output_type == TCC_OUTPUT_DLL)
1522+ if (s1->output_type & TCC_OUTPUT_DYN)
15171523 tcc_add_crt(s1, "crtendS.o");
15181524 else
15191525 tcc_add_crt(s1, "crtend.o");
@@ -1812,7 +1818,7 @@ static int set_sec_sizes(TCCState *s1) · 292 unmodified lines
18121818 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
18131819 /* when generating a DLL, we include relocations but
18141820 we may patch them */
1815− if (file_type == TCC_OUTPUT_DLL
1821+ if ((file_type & TCC_OUTPUT_DYN)
18161822 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
18171823 int count = prepare_dynamic_rel(s1, s);
18181824 if (count) {
@@ -1820,7 +1826,7 @@ static int set_sec_sizes(TCCState *s1) · 1 unmodified line
18201826 s->sh_flags |= SHF_ALLOC;
18211827 s->sh_size = count * sizeof(ElfW_Rel);
18221828 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1823− textrel = 1;
1829+ textrel += count;
18241830 }
18251831 }
18261832 } else if ((s->sh_flags & SHF_ALLOC)
@@ -1904,7 +1910,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 77 unmodified lines
19041910 a_offset += s_align;
19051911 file_offset += (a_offset - p_offset);
19061912 } else {
1907− if (file_type == TCC_OUTPUT_DLL)
1913+ if (file_type & TCC_OUTPUT_DYN)
19081914 addr = 0;
19091915 else
19101916 addr = ELF_START_ADDR;
@@ -1936,7 +1942,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 25 unmodified lines
19361942 symbol tables, relocations, progbits, nobits */
19371943 /* XXX: do faster and simpler sorting */
19381944 f = -1;
1939− for(k = 0; k < 7; k++) {
1945+ for(k = 0; k < 10; k++) {
19401946 for(i = 1; i < s1->nb_sections; i++) {
19411947 s = s1->sections[i];
19421948 /* compute if section should be included */
@@ -1970,9 +1976,6 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 27 unmodified lines
19701976 if (k != 2)
19711977 continue;
19721978 }
1973− } else if (s->sh_type == SHT_NOBITS) {
1974− if (k != 6)
1975− continue;
19761979 } else if ((s == rodata_section
19771980 #ifdef CONFIG_TCC_BCHECK
19781981 || s == bounds_section
@@ -1984,6 +1987,19 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 5 unmodified lines
19841987 /* Align next section on page size.
19851988 This is needed to remap roinf section ro. */
19861989 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;
19872003 } else {
19882004 if (k != 5)
19892005 continue;
@@ -2270,7 +2286,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 280 unmodified lines
22702286 #ifdef TCC_ARM_EABI
22712287 ehdr.e_ident[EI_OSABI] = 0;
22722288 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))
22742290 ehdr.e_flags |= EF_ARM_HASENTRY;
22752291 if (s1->float_abi == ARM_HARD_FLOAT)
22762292 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
22822298 #elif defined TCC_TARGET_RISCV64
22832299 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
22842300 #endif
2285− switch(file_type) {
2286− default:
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:
2301+
2302+ if (file_type == TCC_OUTPUT_OBJ) {
23022303 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;
23042315 }
2316+
23052317 ehdr.e_machine = EM_TCC_TARGET;
23062318 ehdr.e_version = EV_CURRENT;
23072319 ehdr.e_shoff = file_offset;
@@ -2530,7 +2542,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 222 unmodified lines
25302542 ElfW(Phdr) *phdr;
25312543 Section *interp, *dynamic, *dynstr, *note;
25322544 struct ro_inf *roinf_use = NULL;
2533− int textrel, got_sym;
2545+ int textrel, got_sym, dt_flags_1;
25342546
25352547 file_type = s1->output_type;
25362548 s1->nb_errors = 0;
@@ -2557,7 +2569,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 20 unmodified lines
25572569 resolve_common_syms(s1);
25582570
25592571 if (!s1->static_link) {
2560− if (file_type == TCC_OUTPUT_EXE) {
2572+ if (file_type & TCC_OUTPUT_EXE) {
25612573 char *ptr;
25622574 /* allow override the dynamic loader */
25632575 const char *elfint = getenv("LD_SO");
@@ -2590,7 +2602,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 26 unmodified lines
25902602 goto the_end;
25912603 }
25922604 build_got_entries(s1, got_sym);
2593− if (file_type == TCC_OUTPUT_EXE) {
2605+ if (file_type & TCC_OUTPUT_EXE) {
25942606 bind_libs_dynsyms(s1);
25952607 } else {
25962608 /* 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
26062618 alloc_sec_names(s1, 0);
26072619
26082620 if (!s1->static_link) {
2609− int i;
26102621 /* add a list of needed dlls */
26112622 for(i = 0; i < s1->nb_loaded_dlls; i++) {
26122623 DLLReference *dllref = s1->loaded_dlls[i];
@@ -2618,15 +2629,19 @@ static int elf_output_file(TCCState *s1, const char *filename) · 5 unmodified lines
26182629 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
26192630 put_elf_str(dynstr, s1->rpath));
26202631
2621− if (file_type == TCC_OUTPUT_DLL) {
2632+ dt_flags_1 = DF_1_NOW;
2633+ if (file_type & TCC_OUTPUT_DYN) {
26222634 if (s1->soname)
26232635 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
26242636 /* XXX: currently, since we do not handle PIC code, we
26252637 must relocate the readonly segments */
26262638 if (textrel)
26272639 put_dt(dynamic, DT_TEXTREL, 0);
2640+ if (file_type & TCC_OUTPUT_EXE)
2641+ dt_flags_1 = DF_1_NOW | DF_1_PIE;
26282642 }
2629−
2643+ put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
2644+ put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
26302645 if (s1->symbolic)
26312646 put_dt(dynamic, DT_SYMBOLIC, 0);
26322647
@@ -2639,20 +2654,16 @@ static int elf_output_file(TCCState *s1, const char *filename) · 6 unmodified lines
26392654 dynstr->sh_size = dynstr->data_offset;
26402655 }
26412656
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−
26462657 /* compute number of program headers */
2647− if (file_type == TCC_OUTPUT_DLL)
2648− phnum = 3;
2649− else if (s1->static_link)
2650− phnum = 3;
2651− else {
2652− phnum = 5 + (i < s1->nb_sections);
2653− }
2654−
2655− phnum += note != NULL;
2658+ phfill = 2;
2659+ for (i = 1; i < s1->nb_sections; i++)
2660+ if (s1->sections[i]->sh_flags & SHF_TLS)
2661+ phfill = 3;
2662+ phnum = 3;
2663+ if (interp)
2664+ phnum += phfill;
2665+ if (note)
2666+ phnum++;
26562667 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD
26572668 /* GNU_RELRO */
26582669 phnum++, roinf_use = &roinf;
@@ -2679,7 +2690,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 20 unmodified lines
26792690 /* put in GOT the dynamic section address and relocate PLT */
26802691 write32le(s1->got->data, dynamic->sh_addr);
26812692 if (file_type == TCC_OUTPUT_EXE
2682− || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2693+ || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
26832694 relocate_plt(s1);
26842695
26852696 /* 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
194194
195195 switch (type) {
196196 case R_X86_64_64:
197− if (s1->output_type == TCC_OUTPUT_DLL) {
197+ if (s1->output_type & TCC_OUTPUT_DYN) {
198198 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
199199 qrel->r_offset = rel->r_offset;
200200 if (esym_index) {
@@ -212,7 +212,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 11 unmodified lines
212212 break;
213213 case R_X86_64_32:
214214 case R_X86_64_32S:
215− if (s1->output_type == TCC_OUTPUT_DLL) {
215+ if (s1->output_type & TCC_OUTPUT_DYN) {
216216 /* XXX: this logic may depend on TCC's codegen
217217 now TCC uses R_X86_64_32 even for a 64bit pointer */
218218 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