return MipsReginfo;
}
- if (Name == ".eh_frame")
+ // We dont need special handling of .eh_frame sections if relocatable
+ // output was choosen. Proccess them as usual input sections.
+ if (!Config->Relocatable && Name == ".eh_frame")
return new (EHAlloc.Allocate()) EHInputSection<ELFT>(this, &Sec);
if (shouldMerge<ELFT>(Sec))
return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec);
RelType *P = reinterpret_cast<RelType *>(Buf);
Buf += sizeof(RelType);
- // Relocation for local symbol here means that it is probably
- // rel[a].eh_frame section which has references to
- // sections in r_info field. Also needs fix for addend.
- if (SymIndex < SymTab->sh_info)
- fatal("Relocation against local symbols is not supported yet");
+ // Relocation against local symbol here means that it is probably
+ // rel[a].eh_frame section which has references to sections in r_info field.
+ if (SymIndex < SymTab->sh_info) {
+ const Elf_Sym *Sym = this->File->getLocalSymbol(SymIndex);
+ uint32_t Idx = Out<ELFT>::SymTab->Locals[Sym];
+ P->r_offset = RelocatedSection->getOffset(Rel.r_offset);
+ P->setSymbolAndType(Idx, Type, Config->Mips64EL);
+ continue;
+ }
SymbolBody *Body = this->File->getSymbolBody(SymIndex)->repl();
P->r_offset = RelocatedSection->getOffset(Rel.r_offset);
unsigned NumLocals = 0;
StringTableSection<ELFT> &StrTabSec;
+ // Local symbol -> ID, filled only when producing relocatable output.
+ llvm::DenseMap<const Elf_Sym *, uint32_t> Locals;
+
private:
void writeLocalSymbols(uint8_t *&Buf);
void writeGlobalSymbols(uint8_t *Buf);
template <class ELFT>
static bool shouldKeepInSymtab(const ObjectFile<ELFT> &File, StringRef SymName,
const typename ELFFile<ELFT>::Elf_Sym &Sym) {
- if (Sym.getType() == STT_SECTION || Sym.getType() == STT_FILE)
+ if (Sym.getType() == STT_FILE)
return false;
+ // We keep sections in symtab for relocatable output.
+ if (Sym.getType() == STT_SECTION)
+ return Config->Relocatable;
+
InputSectionBase<ELFT> *Sec = File.getSection(Sym);
// If sym references a section in a discarded group, don't keep it.
if (Sec == InputSection<ELFT>::Discarded)
InputSectionBase<ELFT> *Section = F->getSection(Sym);
if (!Section->Live)
continue;
+ // That can happen if creating relocatable output.
+ if (Sym.getType() == STT_SECTION)
+ SymName = Section->getSectionName();
}
++Out<ELFT>::SymTab->NumLocals;
+ if (Config->Relocatable)
+ Out<ELFT>::SymTab->Locals[&Sym] = Out<ELFT>::SymTab->NumLocals;
F->KeptLocalSyms.push_back(std::make_pair(
&Sym, Out<ELFT>::SymTab->StrTabSec.addString(SymName)));
}
--- /dev/null
+.section foo1,"ax",@progbits\r
+.cfi_startproc\r
+ nop\r
+.cfi_endproc\r
+\r
+.section bar1,"ax",@progbits\r
+.cfi_startproc\r
+ nop\r
+.cfi_endproc\r
+\r
+.section dah1,"ax",@progbits\r
+.cfi_startproc\r
+ nop\r
+.cfi_endproc\r
--- /dev/null
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable-ehframe.s -o %t2.o
+# RUN: ld.lld -r %t1.o %t2.o -o %t
+# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
+# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section {{.*}} .rela.eh_frame {
+# CHECK-NEXT: 0x20 R_X86_64_PC32 foo 0x0
+# CHECK-NEXT: 0x34 R_X86_64_PC32 bar 0x0
+# CHECK-NEXT: 0x48 R_X86_64_PC32 dah 0x0
+# CHECK-NEXT: 0x78 R_X86_64_PC32 foo1 0x0
+# CHECK-NEXT: 0x8C R_X86_64_PC32 bar1 0x0
+# CHECK-NEXT: 0xA0 R_X86_64_PC32 dah1 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# CHECKTEXT: Contents of section .strtab:
+# CHECKTEXT-NEXT: 0000 00666f6f 00626172 00646168 00666f6f .foo.bar.dah.foo
+# CHECKTEXT-NEXT: 0010 31006261 72310064 61683100 5f737461 1.bar1.dah1._sta
+# CHECKTEXT-NEXT: 0020 727400 rt.
+
+.section foo,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section bar,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section dah,"ax",@progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.text
+.globl _start;
+_start:
+ nop