From fab8787b23643f108eec81add8252b3d65582590 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sun, 17 May 2020 04:39:40 +0200 Subject: [PATCH] macos: Fix GOT access to local defined symbols if a GOT slot is required (due to codegen, indicated by presence of some relocation types), then it needs to contain the address of the wanted symbol, also when it's local and defined, i.e. not overridable. For simplicity we use a GOT slot for that as well (other storage would require rewriting relocs and symbols, as resolving of GOT relocs is hardwired to be based on s1->got). But that means we need to fill in its indirect symbol mapping slot as well, for which Mach-O provides a mean to say "not symbol based, resolved locally". So this fixes this testcase: static int loc; int _start(void) { loc = 42; return loc - 42; } (where our codegen currently uses a GOT-based access for the write by accident) --- tccmacho.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tccmacho.c b/tccmacho.c index c350a19e..04c8780b 100644 --- a/tccmacho.c +++ b/tccmacho.c @@ -321,7 +321,17 @@ static void check_relocs(TCCState *s1, struct macho *mo) attr->got_offset = s1->got->data_offset; attr->plt_offset = 1; /* used as flag */ section_ptr_add(s1->got, PTR_SIZE); - *pi = mo->e2msym[sym_index]; + if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) { + if (sym->st_shndx == SHN_UNDEF) + tcc_error("undefined local symbol???"); + *pi = 0x80000000; /* INDIRECT_SYMBOL_LOCAL */ + /* The pointer slot we generated must point to the + symbol, whose address is only known after layout, + so register a simply relocation for that. */ + put_elf_reloc (s1->symtab, s1->got, attr->got_offset, + R_DATA_PTR, sym_index); + } else + *pi = mo->e2msym[sym_index]; } } }