[PATCH] D33780: [ELF] - Linkerscript - do not emit multiple relocation sections when using --emit-relocs.
George Rimar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 1 07:56:30 PDT 2017
grimar created this revision.
Herald added a subscriber: emaste.
I tried to link head linux kernel and faced with fact that objcopy
refuses to proccess one of LLD linked binaries:
RELOCS arch/x86/realmode/rm/realmode.relocs
OBJCOPY arch/x86/realmode/rm/realmode.bin
objcopy:arch/x86/realmode/rm/realmode.elf: Bad value
That happens because using script LLD produces 2 relocation sections
that point to the same output section. For example without this patch
output for testcase would be:
[ 1] .foo PROGBITS 0000000000000000 00001000
000000000000000a 0000000000000000 AX 0 0 1
[ 3] .rela.foo RELA 0000000000000000 00001010
0000000000000018 0000000000000018 I 6 1 8
[ 4] .rela.bar RELA 0000000000000000 00001028
0000000000000018 0000000000000018 I 6 1 8
(both .rela.foo and .rela.bar points to .foo).
And implementation of objcopy does not like that. AFAIK it
generally tools does not support that. We already workaround this
for non-script case, so looks reasonable to do the same for script too,
since at least kernel uses it.
https://reviews.llvm.org/D33780
Files:
ELF/LinkerScript.cpp
test/ELF/linkerscript/emit-relocs-multiple.s
Index: test/ELF/linkerscript/emit-relocs-multiple.s
===================================================================
--- test/ELF/linkerscript/emit-relocs-multiple.s
+++ test/ELF/linkerscript/emit-relocs-multiple.s
@@ -0,0 +1,21 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { .foo : { *(.foo) *(.bar) } }" > %t.script
+# RUN: ld.lld --emit-relocs --script %t.script %t.o -o %t1
+# RUN: llvm-readobj -s -r %t1 | FileCheck %s
+
+# CHECK-NOT: .rela.bar
+# CHECK: Relocations [
+# CHECK-NEXT: Section {{.*}} .rela.foo {
+# CHECK-NEXT: 0x1 R_X86_64_32 .foo 0x0
+# CHECK-NEXT: 0x6 R_X86_64_32 .foo 0x5
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.section .foo,"ax", at progbits
+aaa:
+ movl $aaa, %edx
+
+.section .bar,"ax", at progbits
+bbb:
+ movl $bbb, %edx
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -484,11 +484,35 @@
Opt.Commands = std::move(Commands);
}
+// Imagine .boo : { *(.foo) *(.bar) } script. Both foo and bar may have
+// relocation sections .rela.foo and .rela.bar for example. Most tools does not
+// allow to have multiple REL[A] sections for output section. Hence we should
+// combine these relocation sections into single output.
+static void addRelocationSections(ArrayRef<InputSection *> Arr,
+ OutputSectionFactory &Factory) {
+ // Each regular output section may have single relocation section referenced
+ // by. This mapping allows to find relocation section by output section.
+ DenseMap<OutputSection *, OutputSection *> RelocationSections;
+ for (InputSection *Sec : Arr) {
+ OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
+ OutputSection *&RelocationSec = RelocationSections[Out];
+ StringRef Name = getOutputSectionName(Sec->Name);
+ Factory.addInputSec(Sec, Name, RelocationSec);
+ }
+}
+
// Add sections that didn't match any sections command.
void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
+ std::vector<InputSection *> RelocSections;
for (InputSectionBase *S : InputSections) {
if (!S->Live || S->Parent)
continue;
+ if (!isa<SyntheticSection>(S) &&
+ (S->Type == SHT_REL || S->Type == SHT_RELA)) {
+ RelocSections.push_back(cast<InputSection>(S));
+ continue;
+ }
+
StringRef Name = getOutputSectionName(S->Name);
auto I = std::find_if(
Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
@@ -512,6 +536,8 @@
Cmd->Commands.push_back(ISD);
}
}
+
+ addRelocationSections(RelocSections, Factory);
}
uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33780.101026.patch
Type: text/x-patch
Size: 2772 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170601/304e00b0/attachment.bin>
More information about the llvm-commits
mailing list