forked from OSchip/llvm-project
Add support for creating the symbols __init_array_start and __init_array_end.
llvm-svn: 248604
This commit is contained in:
parent
33d6c0bbc5
commit
0e604f913a
|
@ -295,6 +295,8 @@ typename ELFFile<ELFT>::uintX_t
|
|||
lld::elf2::getSymVA(const ELFSymbolBody<ELFT> &S,
|
||||
const OutputSection<ELFT> &BssSec) {
|
||||
switch (S.kind()) {
|
||||
case SymbolBody::DefinedSyntheticKind:
|
||||
return cast<DefinedSynthetic<ELFT>>(S).Section.getVA() + S.Sym.st_value;
|
||||
case SymbolBody::DefinedAbsoluteKind:
|
||||
return S.Sym.st_value;
|
||||
case SymbolBody::DefinedRegularKind: {
|
||||
|
@ -434,6 +436,9 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
const InputSection<ELFT> *Section = nullptr;
|
||||
|
||||
switch (EBody.kind()) {
|
||||
case SymbolBody::DefinedSyntheticKind:
|
||||
Out = &cast<DefinedSynthetic<ELFT>>(Body)->Section;
|
||||
break;
|
||||
case SymbolBody::DefinedRegularKind:
|
||||
Section = &cast<DefinedRegular<ELFT>>(EBody).Section;
|
||||
break;
|
||||
|
|
|
@ -165,7 +165,7 @@ public:
|
|||
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
|
||||
const SymbolTable &getSymTable() const { return Table; }
|
||||
SymbolTable &getSymTable() const { return Table; }
|
||||
|
||||
void addSymbol(StringRef Name, bool isLocal = false) {
|
||||
StrTabSec.add(Name);
|
||||
|
|
|
@ -55,6 +55,17 @@ static TargetInfo *createTarget(uint16_t EMachine) {
|
|||
error("Unknown target machine");
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void SymbolTable::addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section,
|
||||
typename ELFFile<ELFT>::uintX_t Value) {
|
||||
typedef typename DefinedSynthetic<ELFT>::Elf_Sym Elf_Sym;
|
||||
auto ESym = new (Alloc) Elf_Sym;
|
||||
memset(ESym, 0, sizeof(Elf_Sym));
|
||||
ESym->st_value = Value;
|
||||
auto Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, *ESym, Section);
|
||||
resolve<ELFT>(Sym);
|
||||
}
|
||||
|
||||
template <class ELFT> void SymbolTable::init(uint16_t EMachine) {
|
||||
Target.reset(createTarget(EMachine));
|
||||
if (Config->Shared)
|
||||
|
@ -205,3 +216,20 @@ void SymbolTable::addMemberFile(Lazy *Body) {
|
|||
|
||||
addFile(std::move(File));
|
||||
}
|
||||
|
||||
namespace lld {
|
||||
namespace elf2 {
|
||||
template void SymbolTable::addSyntheticSym(StringRef Name,
|
||||
OutputSection<ELF32LE> &Section,
|
||||
ELFFile<ELF32LE>::uintX_t Value);
|
||||
template void SymbolTable::addSyntheticSym(StringRef Name,
|
||||
OutputSection<ELF32BE> &Section,
|
||||
ELFFile<ELF32BE>::uintX_t Value);
|
||||
template void SymbolTable::addSyntheticSym(StringRef Name,
|
||||
OutputSection<ELF64LE> &Section,
|
||||
ELFFile<ELF64LE>::uintX_t Value);
|
||||
template void SymbolTable::addSyntheticSym(StringRef Name,
|
||||
OutputSection<ELF64BE> &Section,
|
||||
ELFFile<ELF64BE>::uintX_t Value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,10 @@ public:
|
|||
return EntrySym->getReplacement();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section,
|
||||
typename llvm::object::ELFFile<ELFT>::uintX_t Value);
|
||||
|
||||
private:
|
||||
Symbol *insert(SymbolBody *New);
|
||||
template <class ELFT> void addELFFile(ELFFileBase *File);
|
||||
|
|
|
@ -41,10 +41,11 @@ public:
|
|||
DefinedRegularKind = 0,
|
||||
DefinedAbsoluteKind = 1,
|
||||
DefinedCommonKind = 2,
|
||||
SharedKind = 3,
|
||||
DefinedLast = 3,
|
||||
UndefinedKind = 4,
|
||||
LazyKind = 5,
|
||||
DefinedSyntheticKind = 3,
|
||||
SharedKind = 4,
|
||||
DefinedLast = 4,
|
||||
UndefinedKind = 5,
|
||||
LazyKind = 6,
|
||||
};
|
||||
|
||||
Kind kind() const { return static_cast<Kind>(SymbolKind); }
|
||||
|
@ -213,6 +214,22 @@ public:
|
|||
const InputSection<ELFT> &Section;
|
||||
};
|
||||
|
||||
template <class ELFT> class DefinedSynthetic : public Defined<ELFT> {
|
||||
typedef Defined<ELFT> Base;
|
||||
|
||||
public:
|
||||
typedef typename Base::Elf_Sym Elf_Sym;
|
||||
explicit DefinedSynthetic(StringRef N, const Elf_Sym &Sym,
|
||||
OutputSection<ELFT> &Section)
|
||||
: Defined<ELFT>(Base::DefinedSyntheticKind, N, Sym), Section(Section) {}
|
||||
|
||||
static bool classof(const SymbolBody *S) {
|
||||
return S->kind() == Base::DefinedSyntheticKind;
|
||||
}
|
||||
|
||||
const OutputSection<ELFT> &Section;
|
||||
};
|
||||
|
||||
// Undefined symbol.
|
||||
template <class ELFT> class Undefined : public ELFSymbolBody<ELFT> {
|
||||
typedef ELFSymbolBody<ELFT> Base;
|
||||
|
|
|
@ -295,7 +295,7 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
|||
OutputSections.push_back(&BssSec);
|
||||
Map[{BssSec.getName(), BssSec.getType(), BssSec.getFlags()}] = &BssSec;
|
||||
|
||||
const SymbolTable &Symtab = SymTabSec.getSymTable();
|
||||
SymbolTable &Symtab = SymTabSec.getSymTable();
|
||||
for (const std::unique_ptr<ObjectFileBase> &FileB : Symtab.getObjectFiles()) {
|
||||
auto &File = cast<ObjectFile<ELFT>>(*FileB);
|
||||
if (!Config->DiscardAll) {
|
||||
|
@ -323,6 +323,12 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
|||
}
|
||||
}
|
||||
|
||||
if (OutputSection<ELFT> *OS =
|
||||
Map.lookup({".init_array", SHT_INIT_ARRAY, SHF_WRITE | SHF_ALLOC})) {
|
||||
Symtab.addSyntheticSym<ELFT>("__init_array_start", *OS, 0);
|
||||
Symtab.addSyntheticSym<ELFT>("__init_array_end", *OS, OS->getSize());
|
||||
}
|
||||
|
||||
// FIXME: Try to avoid the extra walk over all global symbols.
|
||||
std::vector<DefinedCommon<ELFT> *> CommonSymbols;
|
||||
for (auto &P : Symtab.getSymbols()) {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||
// RUN: lld -flavor gnu2 %t -o %t2
|
||||
// RUN: llvm-readobj -symbols -sections %t2 | FileCheck %s
|
||||
// RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s
|
||||
// REQUIRES: x86
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
call __init_array_start
|
||||
call __init_array_end
|
||||
|
||||
|
||||
.section .init_array,"aw",@init_array
|
||||
.quad 0
|
||||
|
||||
|
||||
// CHECK: Name: .init_array
|
||||
// CHECK-NEXT: Type: SHT_INIT_ARRAY
|
||||
// CHECK-NEXT: Flags [
|
||||
// CHECK-NEXT: SHF_ALLOC
|
||||
// CHECK-NEXT: SHF_WRITE
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x12000
|
||||
// CHECK-NEXT: Offset:
|
||||
// CHECK-NEXT: Size: 8
|
||||
|
||||
// CHECK: Name: __init_array_end
|
||||
// CHECK-NEXT: Value: 0x12008
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Local
|
||||
// CHECK-NEXT: Type: None
|
||||
// CHECK-NEXT: Other: 0
|
||||
// CHECK-NEXT: Section: .init_array
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: Symbol {
|
||||
// CHECK-NEXT: Name: __init_array_start
|
||||
// CHECK-NEXT: Value: 0x12000
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Binding: Local
|
||||
// CHECK-NEXT: Type: None
|
||||
// CHECK-NEXT: Other: 0
|
||||
// CHECK-NEXT: Section: .init_array
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// 0x12000 - (0x11000 + 5) = 4091
|
||||
// 0x12008 - (0x11005 + 5) = 4094
|
||||
// DISASM: _start:
|
||||
// DISASM-NEXT: 11000: e8 fb 0f 00 00 callq 4091
|
||||
// DISASM-NEXT: 11005: e8 fe 0f 00 00 callq 4094
|
Loading…
Reference in New Issue