From 682ecc1745123d8c8cb324cce151accff2a311ed Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Fri, 14 Oct 2016 17:32:10 +0200 Subject: [PATCH] arm64: Fix -run With -run the call instruction and a defined function can be far away, if the function is defined in the executable itself, not in the to be compiled code. So we always need PLT slots for -run, not just for undefined symbols. --- arm64-gen.c | 16 ++-------------- tccelf.c | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/arm64-gen.c b/arm64-gen.c index 5f52e1f2..cd6faac5 100644 --- a/arm64-gen.c +++ b/arm64-gen.c @@ -592,22 +592,10 @@ ST_FUNC void store(int r, SValue *sv) static void arm64_gen_bl_or_b(int b) { - // Currently TCC's linker does not generate a PLT when TCC is invoked - // with "-run". This means functions can be out of range if we try to - // call them in the usual way. Until the linker is fixed, work around - // this by using R_AARCH64_MOVW_UABS_G* relocations; see arm64_sym. - int avoid_call26 = 1; - if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { assert(!b && (vtop->r & VT_SYM)); - if (avoid_call26) { - arm64_sym(30, vtop->sym, 0); - o(0xd63f03c0); // blr x30 - } - else { - greloc(cur_text_section, vtop->sym, ind, R_AARCH64_CALL26); - o(0x94000000); // bl . - } + greloc(cur_text_section, vtop->sym, ind, R_AARCH64_CALL26); + o(0x94000000); // bl . } else o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr diff --git a/tccelf.c b/tccelf.c index f0a32417..212ba08c 100644 --- a/tccelf.c +++ b/tccelf.c @@ -826,7 +826,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) case R_AARCH64_CALL26: /* This check must match the one in build_got_entries, testing if we really need a PLT slot. */ - if (sym->st_shndx == SHN_UNDEF) + if (sym->st_shndx == SHN_UNDEF || + s1->output_type == TCC_OUTPUT_MEMORY) /* We've put the PLT slot offset into r_addend when generating it, and that's what we must use as relocation value (adjusted by section offset of course). */ @@ -1423,19 +1424,20 @@ ST_FUNC void build_got_entries(TCCState *s1) case R_AARCH64_JUMP26: case R_AARCH64_CALL26: - if (!s1->got) - build_got(s1); - sym_index = ELFW(R_SYM)(rel->r_info); - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - if (sym->st_shndx == SHN_UNDEF) { + if (!s1->got) + build_got(s1); + sym_index = ELFW(R_SYM)(rel->r_info); + sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; + if (sym->st_shndx == SHN_UNDEF || + s1->output_type == TCC_OUTPUT_MEMORY) { unsigned long ofs; reloc_type = R_AARCH64_JUMP_SLOT; - ofs = put_got_entry(s1, reloc_type, sym->st_size, + ofs = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, sym_index); /* We store the place of the generated PLT slot in our addend. */ rel->r_addend += ofs; - } + } break; #elif defined(TCC_TARGET_C67) case R_C60_GOT32: