aboutsummaryrefslogtreecommitdiff
path: root/tccelf.c
diff options
context:
space:
mode:
Diffstat (limited to 'tccelf.c')
-rw-r--r--tccelf.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/tccelf.c b/tccelf.c
index e166393..e20752c 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -1356,6 +1356,17 @@ void patch_dynsym_undef(TCCState *s1, Section *s)
#else
#define HAVE_PHDR 0
#define EXTRA_RELITEMS 9
+
+/* zero plt offsets of weak symbols in .dynsym */
+void patch_dynsym_undef(TCCState *s1, Section *s)
+{
+ ElfW(Sym) *sym, *sym_end;
+
+ sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
+ for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++)
+ if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
+ sym->st_value = 0;
+}
#endif
ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
@@ -1499,7 +1510,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
type = ELFW(ST_TYPE)(esym->st_info);
if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
put_got_entry(s1, R_JMP_SLOT, esym->st_size,
- esym->st_info,
+ ELFW(ST_INFO)(STB_GLOBAL,type),
sym - (ElfW(Sym) *)symtab_section->data);
} else if (type == STT_OBJECT) {
unsigned long offset;
@@ -2125,10 +2136,8 @@ static int elf_output_file(TCCState *s1, const char *filename)
for(i=1;i<s1->nb_sections;i++) {
s = s1->sections[section_order[i]];
if (s->sh_type != SHT_NOBITS) {
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (s->sh_type == SHT_DYNSYM)
patch_dynsym_undef(s1, s);
-#endif
while (offset < s->sh_offset) {
fputc(0, f);
offset++;