forked from OSchip/llvm-project
[ELF] - Do not merge relocation sections by name when using --emit-relocs.
Previously we would merge relocation sections by name. That did not work in some cases, like testcase shows. Patch implements logic to merge relocation sections if their target sections were merged into the same output section. Differential revision: https://reviews.llvm.org/D33824 llvm-svn: 304886
This commit is contained in:
parent
8445858a93
commit
990c9cb2bf
|
@ -283,6 +283,20 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS,
|
|||
return;
|
||||
}
|
||||
|
||||
// Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
|
||||
// relocation sections .rela.foo and .rela.bar for example. Most tools do
|
||||
// not allow multiple REL[A] sections for output section. Hence we
|
||||
// should combine these relocation sections into single output.
|
||||
// We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
|
||||
// other REL[A] sections created by linker itself.
|
||||
if (!isa<SyntheticSection>(IS) &&
|
||||
(IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
|
||||
auto *Sec = cast<InputSection>(IS);
|
||||
OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
|
||||
addInputSec(IS, OutsecName, Out->RelocationSection);
|
||||
return;
|
||||
}
|
||||
|
||||
SectionKey Key = createKey(IS, OutsecName);
|
||||
OutputSection *&Sec = Map[Key];
|
||||
return addInputSec(IS, OutsecName, Sec);
|
||||
|
|
|
@ -67,6 +67,11 @@ public:
|
|||
// formula: Off = Off_first + VA - VA_first.
|
||||
OutputSection *FirstInPtLoad = nullptr;
|
||||
|
||||
// Pointer to a relocation section for this section. Usually nullptr because
|
||||
// we consume relocations, but if --emit-relocs is specified (which is rare),
|
||||
// it may have a non-null value.
|
||||
OutputSection *RelocationSection = nullptr;
|
||||
|
||||
// The following fields correspond to Elf_Shdr members.
|
||||
uint64_t Size = 0;
|
||||
uint64_t Offset = 0;
|
||||
|
|
|
@ -101,18 +101,6 @@ StringRef elf::getOutputSectionName(StringRef Name) {
|
|||
if (Config->Relocatable)
|
||||
return Name;
|
||||
|
||||
// If -emit-relocs is given (which is rare), we need to copy
|
||||
// relocation sections to the output. If input section .foo is
|
||||
// output as .bar, we want to rename .rel.foo .rel.bar as well.
|
||||
if (Config->EmitRelocs) {
|
||||
for (StringRef V : {".rel.", ".rela."}) {
|
||||
if (Name.startswith(V)) {
|
||||
StringRef Inner = getOutputSectionName(Name.substr(V.size() - 1));
|
||||
return Saver.save(V.drop_back() + Inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (StringRef V :
|
||||
{".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
|
||||
".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0
|
||||
# CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section ({{.*}}) .rela.data {
|
||||
# CHECK-NEXT: Section ({{.*}}) .rela.data.foo {
|
||||
# CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0
|
||||
# CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0
|
||||
# CHECK-NEXT: }
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
|
||||
# RUN: echo "SECTIONS { .zed : { *(.foo) *(.bar) } }" > %t.script
|
||||
# RUN: ld.lld --emit-relocs --script %t.script %t.o -o %t1
|
||||
# RUN: llvm-readobj -r %t1 | FileCheck %s
|
||||
|
||||
# CHECK: Relocations [
|
||||
# CHECK-NEXT: Section {{.*}} .rela.foo {
|
||||
# CHECK-NEXT: 0x1 R_X86_64_32 .zed 0x0
|
||||
# CHECK-NEXT: 0x6 R_X86_64_32 .zed 0x5
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
.section .foo,"ax",@progbits
|
||||
aaa:
|
||||
movl $aaa, %edx
|
||||
|
||||
.section .bar,"ax",@progbits
|
||||
bbb:
|
||||
movl $bbb, %edx
|
Loading…
Reference in New Issue