summaryrefslogtreecommitdiff
path: root/ELF/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/Writer.cpp')
-rw-r--r--ELF/Writer.cpp99
1 files changed, 48 insertions, 51 deletions
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index f68e07fc69d7..ad95a8acced4 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -93,21 +93,14 @@ private:
} // anonymous namespace
StringRef elf::getOutputSectionName(StringRef Name) {
+ // ".zdebug_" is a prefix for ZLIB-compressed sections.
+ // Because we decompressed input sections, we want to remove 'z'.
+ if (Name.startswith(".zdebug_"))
+ return Saver.save("." + Name.substr(2));
+
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.",
@@ -122,10 +115,6 @@ StringRef elf::getOutputSectionName(StringRef Name) {
if (Name == "COMMON")
return ".bss";
- // ".zdebug_" is a prefix for ZLIB-compressed sections.
- // Because we decompressed input sections, we want to remove 'z'.
- if (Name.startswith(".zdebug_"))
- return Saver.save("." + Name.substr(2));
return Name;
}
@@ -257,18 +246,7 @@ template <class ELFT> void Writer<ELFT>::run() {
if (ErrorCount)
return;
- if (!Script->Opt.HasSections)
- Script->fabricateDefaultCommands();
- else
- Script->synchronize();
-
- for (BaseCommand *Base : Script->Opt.Commands)
- if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
- OutputSectionCommands.push_back(Cmd);
-
- clearOutputSections();
-
- if (!Script->Opt.HasSections &&!Config->Relocatable)
+ if (!Script->Opt.HasSections && !Config->Relocatable)
fixSectionAlignments();
// If -compressed-debug-sections is specified, we need to compress
@@ -278,22 +256,24 @@ template <class ELFT> void Writer<ELFT>::run() {
OutputSectionCommands.begin(), OutputSectionCommands.end(),
[](OutputSectionCommand *Cmd) { Cmd->maybeCompress<ELFT>(); });
- if (Config->Relocatable) {
- assignFileOffsets();
- } else {
- Script->assignAddresses(Phdrs, OutputSectionCommands);
+ Script->assignAddresses(Phdrs, OutputSectionCommands);
- // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
- // 0 sized region. This has to be done late since only after assignAddresses
- // we know the size of the sections.
- removeEmptyPTLoad();
+ // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
+ // 0 sized region. This has to be done late since only after assignAddresses
+ // we know the size of the sections.
+ removeEmptyPTLoad();
- if (!Config->OFormatBinary)
- assignFileOffsets();
- else
- assignFileOffsetsBinary();
+ if (!Config->OFormatBinary)
+ assignFileOffsets();
+ else
+ assignFileOffsetsBinary();
+
+ setPhdrs();
- setPhdrs();
+ if (Config->Relocatable) {
+ for (OutputSectionCommand *Cmd : OutputSectionCommands)
+ Cmd->Sec->Addr = 0;
+ } else {
fixPredefinedSymbols();
}
@@ -915,7 +895,14 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
// this symbol unconditionally even when using a linker script, which
// differs from the behavior implemented by GNU linker which only define
// this symbol if ELF headers are in the memory mapped segment.
- addOptionalRegular<ELFT>("__ehdr_start", Out::ElfHeader, 0, STV_HIDDEN);
+ // __executable_start is not documented, but the expectation of at
+ // least the android libc is that it points to the elf header too.
+ // __dso_handle symbol is passed to cxa_finalize as a marker to identify
+ // each DSO. The address of the symbol doesn't matter as long as they are
+ // different in different DSOs, so we chose the start address of the DSO.
+ for (const char *Name :
+ {"__ehdr_start", "__executable_start", "__dso_handle"})
+ addOptionalRegular<ELFT>(Name, Out::ElfHeader, 0, STV_HIDDEN);
// If linker script do layout we do not need to create any standart symbols.
if (Script->Opt.HasSections)
@@ -1011,9 +998,6 @@ template <class ELFT> void Writer<ELFT>::createSections() {
sortInitFini(findSection(".fini_array"));
sortCtorsDtors(findSection(".ctors"));
sortCtorsDtors(findSection(".dtors"));
-
- for (OutputSection *Sec : OutputSections)
- Sec->assignOffsets();
}
// We want to find how similar two ranks are.
@@ -1116,10 +1100,8 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
static void applySynthetic(const std::vector<SyntheticSection *> &Sections,
std::function<void(SyntheticSection *)> Fn) {
for (SyntheticSection *SS : Sections)
- if (SS && SS->getParent() && !SS->empty()) {
+ if (SS && SS->getParent() && !SS->empty())
Fn(SS);
- SS->getParent()->assignOffsets();
- }
}
// We need to add input synthetic sections early in createSyntheticSections()
@@ -1225,6 +1207,12 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
Sec->ShName = InX::ShStrTab->addString(Sec->Name);
}
+ if (!Script->Opt.HasSections)
+ Script->fabricateDefaultCommands();
+ for (BaseCommand *Base : Script->Opt.Commands)
+ if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
+ OutputSectionCommands.push_back(Cmd);
+
// Binary and relocatable output does not have PHDRS.
// The headers have to be created before finalize as that can influence the
// image base and the dynamic section on mips includes the image base.
@@ -1234,6 +1222,14 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
}
+ clearOutputSections();
+
+ // Compute the size of .rela.dyn and .rela.plt early since we need
+ // them to populate .dynamic.
+ for (SyntheticSection *SS : {In<ELFT>::RelaDyn, In<ELFT>::RelaPlt})
+ if (SS->getParent() && !SS->empty())
+ SS->getParent()->assignOffsets();
+
// Dynamic section must be the last one in this list and dynamic
// symbol table section (DynSymTab) must be the first one.
applySynthetic({InX::DynSymTab, InX::Bss, InX::BssRelRo,
@@ -1257,15 +1253,16 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// are out of range. This will need to turn into a loop that converges
// when no more Thunks are added
ThunkCreator TC;
- if (TC.createThunks(OutputSections))
+ if (TC.createThunks(OutputSectionCommands))
applySynthetic({InX::MipsGot},
[](SyntheticSection *SS) { SS->updateAllocSize(); });
}
+
// Fill other section headers. The dynamic table is finalized
// at the end because some tags like RELSZ depend on result
// of finalizing other sections.
- for (OutputSection *Sec : OutputSections)
- Sec->finalize<ELFT>();
+ for (OutputSectionCommand *Cmd : OutputSectionCommands)
+ Cmd->finalize<ELFT>();
// createThunks may have added local symbols to the static symbol table
applySynthetic({InX::SymTab, InX::ShStrTab, InX::StrTab},