Skip to content

Commit 312d28b

Browse files
author
grischka
committed
tccelf: avoid find_section() for known section
- remove calls to "find_..." for stuff that we know to exist and where. - rename find_section_create(s1,name,0) -> have_section(s1,name) Also: - call update_gnu_hash() from elf_output_file() gnu_hasn() functions could be moved down into an already existing !ELF_OBJ_ONLY clause, but in order to avoid too many diff lines I didn't. - avoid 'long' (elf_hash). sizeof (long) is host-dependent (4 or 8) - remove unnecessary checks (for dynsym, versym). Someone reading "if (dynsym == NULL) ..." must conclude that it actually can happen under certain circumstances, or otherwise, might conclude that the person who wrote that felt unsure what's going on exactly. arm64-gen.c: TCC_TARGET_MACHO instead of __APPLE__ (to support cross-compilers for the apple/M1 target)
1 parent 28fa4d3 commit 312d28b

File tree

2 files changed

+51
-65
lines changed

2 files changed

+51
-65
lines changed

arm64-gen.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
#include <assert.h>
5454

5555
ST_DATA const char * const target_machine_defs =
56-
#if defined(__APPLE__)
56+
#if defined(TCC_TARGET_MACHO)
5757
"__aarch64__\0"
5858
"__arm64__\0"
5959
#else
@@ -829,7 +829,7 @@ static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned l
829829
else
830830
size = type_size(type[i], &align);
831831

832-
#if defined(__APPLE__)
832+
#if defined(TCC_TARGET_MACHO)
833833
if (variadic && i == variadic) {
834834
nx = 8;
835835
nv = 8;
@@ -1202,7 +1202,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym)
12021202

12031203
arm64_func_va_list_stack = arm64_pcs(variadic ? var_nb_arg : 0, n - 1, t, a);
12041204

1205-
#if !defined(__APPLE__)
1205+
#if !defined(TCC_TARGET_MACHO)
12061206
if (variadic) {
12071207
use_x8 = 1;
12081208
last_int = 4;
@@ -1304,7 +1304,7 @@ ST_FUNC void gen_va_start(void)
13041304
o(0x910383be); // add x30,x29,#224
13051305
o(0xf900001e | r << 5); // str x30,[x(r)]
13061306

1307-
#if !defined(__APPLE__)
1307+
#if !defined(TCC_TARGET_MACHO)
13081308
if (arm64_func_va_list_gr_offs) {
13091309
if (arm64_func_va_list_stack)
13101310
o(0x910383be); // add x30,x29,#224
@@ -1345,7 +1345,7 @@ ST_FUNC void gen_va_arg(CType *t)
13451345

13461346
if (!hfa) {
13471347
uint32_t n = size > 16 ? 8 : (size + 7) & -8;
1348-
#if !defined(__APPLE__)
1348+
#if !defined(TCC_TARGET_MACHO)
13491349
o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs
13501350
if (align == 16) {
13511351
assert(0); // this path untested but needed for __uint128_t
@@ -1358,7 +1358,7 @@ ST_FUNC void gen_va_arg(CType *t)
13581358
o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
13591359
o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)
13601360
o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1361-
#if !defined(__APPLE__)
1361+
#if !defined(TCC_TARGET_MACHO)
13621362
o(0x14000004); // b .+16
13631363
o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs
13641364
o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top
@@ -1369,7 +1369,7 @@ ST_FUNC void gen_va_arg(CType *t)
13691369
}
13701370
else {
13711371
uint32_t ssz = (size + 7) & -(uint32_t)8;
1372-
#if !defined(__APPLE__)
1372+
#if !defined(TCC_TARGET_MACHO)
13731373
uint32_t rsz = hfa << 4;
13741374
uint32_t b1, b2;
13751375
o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
@@ -1383,7 +1383,7 @@ ST_FUNC void gen_va_arg(CType *t)
13831383
}
13841384
o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
13851385
o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1386-
#if !defined(__APPLE__)
1386+
#if !defined(TCC_TARGET_MACHO)
13871387
b2 = ind; o(0x14000000); // b lab2
13881388
// lab1:
13891389
write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);

tccelf.c

Lines changed: 43 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ static void section_reserve(Section *sec, unsigned long size)
325325
}
326326
#endif
327327

328-
static Section *find_section_create (TCCState *s1, const char *name, int create)
328+
static Section *have_section(TCCState *s1, const char *name)
329329
{
330330
Section *sec;
331331
int i;
@@ -334,15 +334,18 @@ static Section *find_section_create (TCCState *s1, const char *name, int create)
334334
if (!strcmp(name, sec->name))
335335
return sec;
336336
}
337-
/* sections are created as PROGBITS */
338-
return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
337+
return NULL;
339338
}
340339

341340
/* return a reference to a section, and create it if it does not
342341
exists */
343342
ST_FUNC Section *find_section(TCCState *s1, const char *name)
344343
{
345-
return find_section_create (s1, name, 1);
344+
Section *sec = have_section(s1, name);
345+
if (sec)
346+
return sec;
347+
/* sections are created as PROGBITS */
348+
return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
346349
}
347350

348351
/* ------------------------------------------------------------------------- */
@@ -360,9 +363,9 @@ ST_FUNC int put_elf_str(Section *s, const char *sym)
360363
}
361364

362365
/* elf symbol hashing function */
363-
static unsigned long elf_hash(const unsigned char *name)
366+
static ElfW(Word) elf_hash(const unsigned char *name)
364367
{
365-
unsigned long h = 0, g;
368+
ElfW(Word) h = 0, g;
366369

367370
while (*name) {
368371
h = (h << 4) + *name++;
@@ -374,16 +377,6 @@ static unsigned long elf_hash(const unsigned char *name)
374377
return h;
375378
}
376379

377-
static unsigned long elf_gnu_hash (const unsigned char *name)
378-
{
379-
unsigned long h = 5381;
380-
unsigned char c;
381-
382-
while ((c = *name++))
383-
h = h * 33 + c;
384-
return h;
385-
}
386-
387380
/* rebuild hash table of section s */
388381
/* NOTE: we do factorize the hash table code to go faster */
389382
static void rebuild_hash(Section *s, unsigned int nb_buckets)
@@ -863,22 +856,18 @@ static void sort_syms(TCCState *s1, Section *s)
863856
tcc_free(old_to_new_syms);
864857
}
865858

859+
#ifndef ELF_OBJ_ONLY
866860
/* See: https://flapenguin.me/elf-dt-gnu-hash */
867-
868861
#define ELFCLASS_BITS (PTR_SIZE * 8)
869862

870-
#ifndef ELF_OBJ_ONLY
871-
static void create_gnu_hash(TCCState *s1)
863+
static Section *create_gnu_hash(TCCState *s1)
872864
{
873865
int nb_syms, i, ndef, nbuckets, symoffset, bloom_size, bloom_shift;
874866
ElfW(Sym) *p;
875867
Section *gnu_hash;
876868
Section *dynsym = s1->dynsym;
877869
Elf32_Word *ptr;
878870

879-
if (dynsym == NULL)
880-
return;
881-
882871
gnu_hash = new_section(s1, ".gnu.hash", SHT_GNU_HASH, SHF_ALLOC);
883872
gnu_hash->link = dynsym->hash->link;
884873

@@ -905,31 +894,33 @@ static void create_gnu_hash(TCCState *s1)
905894
ptr[1] = symoffset;
906895
ptr[2] = bloom_size;
907896
ptr[3] = bloom_shift;
897+
return gnu_hash;
908898
}
909-
#endif
910899

911-
static void update_gnu_hash(TCCState *s1)
900+
static Elf32_Word elf_gnu_hash (const unsigned char *name)
901+
{
902+
Elf32_Word h = 5381;
903+
unsigned char c;
904+
905+
while ((c = *name++))
906+
h = h * 33 + c;
907+
return h;
908+
}
909+
910+
static void update_gnu_hash(TCCState *s1, Section *gnu_hash)
912911
{
913912
int *old_to_new_syms;
914913
ElfW(Sym) *new_syms;
915914
int nb_syms, i, nbuckets, bloom_size, bloom_shift;
916915
ElfW(Sym) *p, *q;
917916
Section *vs;
918-
Section *gnu_hash;
919917
Section *dynsym = s1->dynsym;
920918
Elf32_Word *ptr, *buckets, *chain, *hash;
921919
unsigned int *nextbuck;
922920
addr_t *bloom;
923921
unsigned char *strtab;
924922
struct { int first, last; } *buck;
925923

926-
if (dynsym == NULL)
927-
return;
928-
929-
gnu_hash = find_section_create(s1, ".gnu.hash", 0);
930-
if (gnu_hash == NULL)
931-
return;
932-
933924
strtab = dynsym->link->data;
934925
nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
935926
new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
@@ -1012,11 +1003,11 @@ static void update_gnu_hash(TCCState *s1)
10121003
modify_reloctions_old_to_new(s1, dynsym, old_to_new_syms);
10131004

10141005
/* modify the versions */
1015-
vs = find_section_create(s1, ".gnu.version", 0);
1006+
vs = versym_section;
10161007
if (vs) {
10171008
ElfW(Half) *newver, *versym = (ElfW(Half) *)vs->data;
10181009

1019-
if (versym) {
1010+
if (1/*versym*/) {
10201011
newver = tcc_malloc(nb_syms * sizeof(*newver));
10211012
for (i = 0; i < nb_syms; i++)
10221013
newver[old_to_new_syms[i]] = versym[i];
@@ -1031,6 +1022,7 @@ static void update_gnu_hash(TCCState *s1)
10311022
ptr = (Elf32_Word *) dynsym->hash->data;
10321023
rebuild_hash(dynsym, ptr[0]);
10331024
}
1025+
#endif /* ELF_OBJ_ONLY */
10341026

10351027
/* relocate symbol table, resolve undefined symbols if do_resolve is
10361028
true and output error if undefined symbol. */
@@ -1043,6 +1035,8 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
10431035
for_each_elem(symtab, 1, sym, ElfW(Sym)) {
10441036
sh_num = sym->st_shndx;
10451037
if (sh_num == SHN_UNDEF) {
1038+
if (do_resolve == 2) /* relocating dynsym */
1039+
continue;
10461040
name = (char *) s1->symtab->link->data + sym->st_name;
10471041
/* Use ld.so to resolve symbol for us (for tcc -run) */
10481042
if (do_resolve) {
@@ -1486,7 +1480,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name)
14861480
Section *s;
14871481
addr_t end_offset;
14881482
char buf[1024];
1489-
s = find_section_create(s1, section_name, 0);
1483+
s = have_section(s1, section_name);
14901484
if (!s || !(s->sh_flags & SHF_ALLOC)) {
14911485
end_offset = 0;
14921486
s = data_section;
@@ -2067,6 +2061,7 @@ struct dyn_inf {
20672061
int phnum;
20682062
Section *interp;
20692063
Section *note;
2064+
Section *gnu_hash;
20702065

20712066
/* read only segment mapping for GNU_RELRO */
20722067
Section _roinf, *roinf;
@@ -2352,12 +2347,8 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
23522347
Section *s;
23532348

23542349
/* put dynamic section entries */
2355-
s = find_section_create (s1, ".hash", 0);
2356-
if (s && s->sh_flags == SHF_ALLOC)
2357-
put_dt(dynamic, DT_HASH, s->sh_addr);
2358-
s = find_section_create (s1, ".gnu.hash", 0);
2359-
if (s && s->sh_flags == SHF_ALLOC)
2360-
put_dt(dynamic, DT_GNU_HASH, s->sh_addr);
2350+
put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2351+
put_dt(dynamic, DT_GNU_HASH, dyninf->gnu_hash->sh_addr);
23612352
put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
23622353
put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
23632354
put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
@@ -2391,26 +2382,26 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
23912382
put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
23922383
put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
23932384
}
2394-
s = find_section_create (s1, ".preinit_array", 0);
2385+
s = have_section(s1, ".preinit_array");
23952386
if (s && s->data_offset) {
23962387
put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
23972388
put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
23982389
}
2399-
s = find_section_create (s1, ".init_array", 0);
2390+
s = have_section(s1, ".init_array");
24002391
if (s && s->data_offset) {
24012392
put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
24022393
put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
24032394
}
2404-
s = find_section_create (s1, ".fini_array", 0);
2395+
s = have_section(s1, ".fini_array");
24052396
if (s && s->data_offset) {
24062397
put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
24072398
put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
24082399
}
2409-
s = find_section_create (s1, ".init", 0);
2400+
s = have_section(s1, ".init");
24102401
if (s && s->data_offset) {
24112402
put_dt(dynamic, DT_INIT, s->sh_addr);
24122403
}
2413-
s = find_section_create (s1, ".fini", 0);
2404+
s = have_section(s1, ".fini");
24142405
if (s && s->data_offset) {
24152406
put_dt(dynamic, DT_FINI, s->sh_addr);
24162407
}
@@ -2530,7 +2521,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
25302521
offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
25312522

25322523
sort_syms(s1, symtab_section);
2533-
update_gnu_hash(s1);
2524+
25342525
for(i = 1; i < shnum; i++) {
25352526
s = s1->sections[sec_order ? sec_order[i] : i];
25362527
if (s->sh_type != SHT_NOBITS) {
@@ -2811,7 +2802,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
28112802
/* shared library case: simply export all global symbols */
28122803
export_global_syms(s1);
28132804
}
2814-
create_gnu_hash(s1);
2805+
dyninf.gnu_hash = create_gnu_hash(s1);
28152806
} else {
28162807
build_got_entries(s1, 0);
28172808
}
@@ -2863,21 +2854,13 @@ static int elf_output_file(TCCState *s1, const char *filename)
28632854
file_offset = layout_sections(s1, sec_order, &dyninf);
28642855

28652856
if (dynamic) {
2866-
ElfW(Sym) *sym;
2867-
28682857
/* put in GOT the dynamic section address and relocate PLT */
28692858
write32le(s1->got->data, dynamic->sh_addr);
28702859
if (file_type == TCC_OUTPUT_EXE
28712860
|| (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
28722861
relocate_plt(s1);
2873-
28742862
/* relocate symbols in .dynsym now that final addresses are known */
2875-
for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2876-
if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2877-
/* do symbol relocation */
2878-
sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2879-
}
2880-
}
2863+
relocate_syms(s1, s1->dynsym, 2);
28812864
}
28822865

28832866
/* if building executable or DLL, then relocate each section
@@ -2897,6 +2880,9 @@ static int elf_output_file(TCCState *s1, const char *filename)
28972880
else if (s1->got)
28982881
fill_local_got_entries(s1);
28992882

2883+
if (dyninf.gnu_hash)
2884+
update_gnu_hash(s1, dyninf.gnu_hash);
2885+
29002886
/* Create the ELF file with name 'filename' */
29012887
ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr, file_offset, sec_order);
29022888
the_end:

0 commit comments

Comments
 (0)