arm64-gen.c: Better explanation of relocation choice.

This commit is contained in:
Edmund Grimley Evans
2015-03-01 11:31:10 +00:00
parent fc119f9840
commit 883fd365c7

View File

@ -400,27 +400,30 @@ static void gen_fstore(int sz, int dst, int bas, uint64_t off)
static void gen_addr(int r, Sym *sym, unsigned long addend) static void gen_addr(int r, Sym *sym, unsigned long addend)
{ {
#if 0 // Currently TCC's linker does not generate COPY relocations for
// This is normally the right way to do it, I think, // STT_OBJECTs when tcc is invoked with "-run". This typically
// but it does not work with "-run" when stdin or stderr is // results in "R_AARCH64_ADR_PREL_PG_HI21 relocation failed" when
// used by the program: "R_AARCH64_ADR_PREL_PG_HI21 relocation failed". // a program refers to stdin. A workaround is to avoid that
greloca(cur_text_section, sym, ind, R_AARCH64_ADR_PREL_PG_HI21, addend); // relocation and use only relocations with unlimited range.
o(0x90000000 | r); int avoid_adrp = 1;
greloca(cur_text_section, sym, ind, R_AARCH64_ADD_ABS_LO12_NC, addend);
o(0x91000000 | r | r << 5); if (avoid_adrp || (sym->type.t & VT_WEAK)) {
#else // (GCC uses a R_AARCH64_ABS64 in this case.)
// This seems to work in all cases, unless you try to use an old buggy greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G0_NC, addend);
// GCC for linking, which says: "unresolvable R_AARCH64_MOVW_UABS_G0_NC o(0xd2800000 | r); // mov x(rt),#0,lsl #0
// relocation against symbol `stderr@@GLIBC_2.17'". greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G1_NC, addend);
greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G0_NC, addend); o(0xf2a00000 | r); // movk x(rt),#0,lsl #16
o(0xf2800000 | r); // movk x(rt),#...,lsl #0 greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G2_NC, addend);
greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G1_NC, addend); o(0xf2c00000 | r); // movk x(rt),#0,lsl #32
o(0xf2a00000 | r); // movk x(rt),#...,lsl #16 greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G3, addend);
greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G2_NC, addend); o(0xf2e00000 | r); // movk x(rt),#0,lsl #48
o(0xf2c00000 | r); // movk x(rt),#...,lsl #32 }
greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G3, addend); else {
o(0xf2e00000 | r); // movk x(rt),#...,lsl #48 greloca(cur_text_section, sym, ind, R_AARCH64_ADR_PREL_PG_HI21, addend);
#endif o(0x90000000 | r);
greloca(cur_text_section, sym, ind, R_AARCH64_ADD_ABS_LO12_NC, addend);
o(0x91000000 | r | r << 5);
}
} }
ST_FUNC void load(int r, SValue *sv) ST_FUNC void load(int r, SValue *sv)