Page MenuHomePhabricator

[AArch64] Support .reloc *, R_AARCH64_NONE, *
ClosedPublic

Authored by MaskRay on May 15 2019, 6:46 PM.

Details

Summary

This can be used to create references among sections. When --gc-sections
is used, the referenced section will be retained if the origin section
is retained.

Diff Detail

Repository
rL LLVM

Event Timeline

MaskRay created this revision.May 15 2019, 6:46 PM
MaskRay updated this revision to Diff 199715.May 15 2019, 6:50 PM

Forgot to add test...

The commit message only mentions AArch64, but the commit appears to also add support for R_ARM_NONE. I tried using R_ARM_NONE, though, and was unsuccessful:

$ clang -target arm-linux-gnu test.s -c -mfloat-abi=soft
test.s:1:3: error: unsupported relocation on symbol
  .reloc 0, R_ARM_NONE, .text
  ^

I was able to use R_ARM_NONE with -fno-integrated-as, but then lld couldn't link the object file into a relobj with -Wl,-r:

$ clang -target armv7a-linux-gnueabi test.o -mfloat-abi=soft -o foo -Wl,-r -fuse-ld=lld -nostdlib
ld.lld: warning: lld uses blx instruction, no object with architecture supporting feature detected
ld.lld: error: test.o:(.rel.text+0x0): unrecognized reloc 0
MaskRay updated this revision to Diff 199749.May 15 2019, 10:39 PM

Discarded unintended lib/Target/ARM changes

The commit message only mentions AArch64, but the commit appears to also add support for R_ARM_NONE. I tried using R_ARM_NONE, though, and was unsuccessful:

$ clang -target arm-linux-gnu test.s -c -mfloat-abi=soft
test.s:1:3: error: unsupported relocation on symbol
  .reloc 0, R_ARM_NONE, .text
  ^
 

I was able to use R_ARM_NONE with -fno-integrated-as, but then lld couldn't link the object file into a relobj with -Wl,-r:

$ clang -target armv7a-linux-gnueabi test.o -mfloat-abi=soft -o foo -Wl,-r -fuse-ld=lld -nostdlib
ld.lld: warning: lld uses blx instruction, no object with architecture supporting feature detected
ld.lld: error: test.o:(.rel.text+0x0): unrecognized reloc 0

Sorry, lib/Target/ARM changed were unintended. I am indeed studying how to support R_ARM_NONE :)

FWIW: I noticed that the binutils assembler's .reloc directive can reference an arbitrary symbol whereas with this patch, a .reloc directive referencing a label turns into a section reference. e.g.:

$ cat test.s
  nop
foo:
  nop
bar:
  .reloc bar, R_AARCH64_NONE, foo
  .reloc bar, R_AARCH64_NONE, .text + 8

$ clang test.s -target aarch64-linux-gnu -c && readelf -r test.o

Relocation section '.rela.text' at offset 0xc0 contains 2 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000008  000400000000 R_AARCH64_NONE    0000000000000000 .text + 4
000000000008  000400000000 R_AARCH64_NONE    0000000000000000 .text + 8

$ clang test.s -target aarch64-linux-gnu -c -fno-integrated-as && readelf -r test.o

Relocation section '.rela.text' at offset 0x100 contains 2 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000008  000500000000 R_AARCH64_NONE    0000000000000004 foo + 0
000000000008  000100000000 R_AARCH64_NONE    0000000000000000 .text + 8

I see the same difference with the MIPS LLVM backend versus /usr/bin/mipsel-linux-gnu-as, so this is probably fine. I think referencing a section would be sufficient for the crtbegin usage described in D61825.

MaskRay updated this revision to Diff 199757.May 15 2019, 11:36 PM

Set shouldForceRelocation to allow 0 symbol index, e.g. .reloc 0, R_AARCH64_NONE, 8

peter.smith added a comment.EditedMay 16 2019, 6:11 AM

I have similar comments to D61992

The commit message only mentions AArch64, but the commit appears to also add support for R_ARM_NONE. I tried using R_ARM_NONE, though, and was unsuccessful:

$ clang -target arm-linux-gnu test.s -c -mfloat-abi=soft
test.s:1:3: error: unsupported relocation on symbol
  .reloc 0, R_ARM_NONE, .text
  ^
 

I was able to use R_ARM_NONE with -fno-integrated-as, but then lld couldn't link the object file into a relobj with -Wl,-r:

$ clang -target armv7a-linux-gnueabi test.o -mfloat-abi=soft -o foo -Wl,-r -fuse-ld=lld -nostdlib
ld.lld: warning: lld uses blx instruction, no object with architecture supporting feature detected
ld.lld: error: test.o:(.rel.text+0x0): unrecognized reloc 0

Sorry, lib/Target/ARM changed were unintended. I am indeed studying how to support R_ARM_NONE :)

I think Ryan has found a different problem here. My first thought was that R_ARM_NONE and R_AARCH64_NONE are supported in LLD as they map to R_NONE. In general LLD filters these out so they never get to relocateOne. It seems like there is a possibility of this happening with ld -r if the R_ARM_NONE is from a SHF_ALLOC section. In short the unrecognized reloc 0 is coming from relocateOne. The error seems to be specific to ARM, or at least to REL and not RELA as AArch64 and x86_64 -r work.

I think the ld -r failure with arm is due to InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) in particular:

if (RelTy::IsRela)
        P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr;
      else if (Config->Relocatable)
        Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym});

If we add a R_ABS with Type R_ARM_NONE then relocateOne will try to evaluate it and hence we get the unrecognized reloc error. My intuition is to skip adding the R_ABS when the relocation is the None relocation. I'm not going to get a chance to send a patch to fix it today though.

To get back to this patch. I think the non-bigendian comments I made on D61992 apply here as well. Generally looks good. Will be worth checking that the format is ELF before accepting R_AARCH64_NONE.

I checked what GNU as does about the ILP32 status as the code R_AARCH64_P32_NONE is also defined to be 0. Having said that it seems like GNU as will only accept R_AARCH64_NONE in both ilp32 and ilp64 modes and won't accept R_AARCH64_P32_NONE so I think what we have here is fine.

MaskRay updated this revision to Diff 199814.May 16 2019, 6:50 AM

Improve the tests as peter.smith suggested in the ARM patch.

peter.smith accepted this revision.May 16 2019, 8:09 AM

Thanks, looks good to me. Will be worth seeing if there are any further comments from the US Timezone.

This revision is now accepted and ready to land.May 16 2019, 8:09 AM

I think the ld -r failure with arm is due to InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) in particular:

if (RelTy::IsRela)
        P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr;
      else if (Config->Relocatable)
        Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym});

If we add a R_ABS with Type R_ARM_NONE then relocateOne will try to evaluate it and hence we get the unrecognized reloc error. My intuition is to skip adding the R_ABS when the relocation is the None relocation. I'm not going to get a chance to send a patch to fix it today though.

Probably just use

-      else if (Config->Relocatable)
+      else if (Config->Relocatable && Type != Target->NoneRel)

After .reloc *, R_386_NONE, * is supported, probably change relocation-none-i686.test (yaml2obj) to an assembly test and check ld.lld -r doesn't crash...

MaskRay updated this revision to Diff 199963.May 16 2019, 8:01 PM
MaskRay edited the summary of this revision. (Show Details)

Use generic FK_NONE

This revision was automatically updated to reflect the committed changes.