forked from OSchip/llvm-project
ELF: Implement __attribute__((init_priority(N)) support.
llvm-svn: 260460
This commit is contained in:
parent
9ee9fb6571
commit
c418570db5
|
@ -750,6 +750,44 @@ void OutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
|
|||
this->Header.sh_size = Off;
|
||||
}
|
||||
|
||||
// If an input string is in the form of "foo.N" where N is a number,
|
||||
// return N. Otherwise, returns 65536, which is one greater than the
|
||||
// lowest priority.
|
||||
static int getPriority(StringRef S) {
|
||||
size_t Pos = S.rfind('.');
|
||||
if (Pos == StringRef::npos)
|
||||
return 65536;
|
||||
int V;
|
||||
if (S.substr(Pos + 1).getAsInteger(10, V))
|
||||
return 65536;
|
||||
return V;
|
||||
}
|
||||
|
||||
// Sorts input sections by section name suffixes, so that .foo.N comes
|
||||
// before .foo.M if N < M. Used to sort .{init,fini}_array.N sections.
|
||||
// For more detail, read the section of the GCC's manual about init_priority.
|
||||
template <class ELFT> void OutputSection<ELFT>::sortByPriority() {
|
||||
// Sort sections by priority.
|
||||
typedef std::pair<int, InputSection<ELFT> *> Pair;
|
||||
std::vector<Pair> V;
|
||||
for (InputSection<ELFT> *S : Sections)
|
||||
V.push_back({getPriority(S->getSectionName()), S});
|
||||
std::sort(V.begin(), V.end(),
|
||||
[](const Pair &A, const Pair &B) { return A.first < B.first; });
|
||||
Sections.clear();
|
||||
for (Pair &P : V)
|
||||
Sections.push_back(P.second);
|
||||
|
||||
// Reassign section addresses.
|
||||
uintX_t Off = 0;
|
||||
for (InputSection<ELFT> *S : Sections) {
|
||||
Off = alignTo(Off, S->getAlign());
|
||||
S->OutSecOff = Off;
|
||||
Off += S->getSize();
|
||||
}
|
||||
this->Header.sh_size = Off;
|
||||
}
|
||||
|
||||
// Returns a VA which a relocatin RI refers to. Used only for local symbols.
|
||||
// For non-local symbols, use SymbolBody::getVA instead.
|
||||
template <class ELFT, bool IsRela>
|
||||
|
|
|
@ -279,6 +279,7 @@ public:
|
|||
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
|
||||
OutputSection(StringRef Name, uint32_t sh_type, uintX_t sh_flags);
|
||||
void addSection(InputSectionBase<ELFT> *C) override;
|
||||
void sortByPriority();
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -735,6 +735,10 @@ StringRef Writer<ELFT>::getOutputSectionName(StringRef S) const {
|
|||
return ".data";
|
||||
if (S.startswith(".bss."))
|
||||
return ".bss";
|
||||
if (S.startswith(".init_array."))
|
||||
return ".init_array";
|
||||
if (S.startswith(".fini_array."))
|
||||
return ".fini_array";
|
||||
return S;
|
||||
}
|
||||
|
||||
|
@ -915,6 +919,13 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
|
|||
Symtab.addAbsolute("end", ElfSym<ELFT>::End);
|
||||
}
|
||||
|
||||
// Sort input sections by section name suffixes for
|
||||
// __attribute__((init_priority(N))).
|
||||
template <class ELFT> static void sortByPriority(OutputSectionBase<ELFT> *S) {
|
||||
if (S)
|
||||
reinterpret_cast<OutputSection<ELFT> *>(S)->sortByPriority();
|
||||
}
|
||||
|
||||
// Create output section objects and add them to OutputSections.
|
||||
template <class ELFT> bool Writer<ELFT>::createSections() {
|
||||
OutputSections.push_back(Out<ELFT>::ElfHeader);
|
||||
|
@ -962,6 +973,10 @@ template <class ELFT> bool Writer<ELFT>::createSections() {
|
|||
Out<ELFT>::Dynamic->FiniArraySec =
|
||||
Factory.lookup(".fini_array", SHT_FINI_ARRAY, SHF_WRITE | SHF_ALLOC);
|
||||
|
||||
// Sort section contents for __attribute__((init_priority(N)).
|
||||
sortByPriority(Out<ELFT>::Dynamic->InitArraySec);
|
||||
sortByPriority(Out<ELFT>::Dynamic->FiniArraySec);
|
||||
|
||||
// The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
|
||||
// symbols for sections, so that the runtime can get the start and end
|
||||
// addresses of each section by section name. Add such symbols.
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||
// RUN: ld.lld %t -o %t.exe
|
||||
// RUN: llvm-objdump -s %t.exe | FileCheck %s
|
||||
// REQUIRES: x86
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
nop
|
||||
|
||||
.section .init_array, "aw", @init_array
|
||||
.align 8
|
||||
.byte 1
|
||||
.section .init_array.100, "aw", @init_array
|
||||
.long 2
|
||||
.section .init_array.5, "aw", @init_array
|
||||
.byte 3
|
||||
|
||||
.section .fini_array, "aw", @fini_array
|
||||
.align 8
|
||||
.byte 4
|
||||
.section .fini_array.100, "aw", @fini_array
|
||||
.long 5
|
||||
.section .fini_array.5, "aw", @fini_array
|
||||
.byte 6
|
||||
|
||||
// CHECK: Contents of section .init_array:
|
||||
// CHECK-NEXT: 03020000 00000000 01
|
||||
// CHECK: Contents of section .fini_array:
|
||||
// CHECK-NEXT: 06050000 00000000 04
|
Loading…
Reference in New Issue