mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-16 20:41:44 +00:00
ELF: Move section merging before ICF. NFCI.
Differential Revision: https://reviews.llvm.org/D34093 llvm-svn: 305176
This commit is contained in:
parent
cf0e48ca01
commit
dc7936eced
@ -36,6 +36,7 @@
|
||||
#include "ScriptParser.h"
|
||||
#include "Strings.h"
|
||||
#include "SymbolTable.h"
|
||||
#include "SyntheticSections.h"
|
||||
#include "Target.h"
|
||||
#include "Threads.h"
|
||||
#include "Writer.h"
|
||||
@ -43,7 +44,6 @@
|
||||
#include "lld/Driver/Driver.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Object/Decompressor.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compression.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
@ -1001,24 +1001,20 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
||||
for (InputSectionBase *S : F->getSections())
|
||||
InputSections.push_back(cast<InputSection>(S));
|
||||
|
||||
// Do size optimizations: garbage collection and identical code folding.
|
||||
// This adds a .comment section containing a version string. We have to add it
|
||||
// before decompressAndMergeSections because the .comment section is a
|
||||
// mergeable section.
|
||||
if (!Config->Relocatable)
|
||||
InputSections.push_back(createCommentSection<ELFT>());
|
||||
|
||||
// Do size optimizations: garbage collection, merging of SHF_MERGE sections
|
||||
// and identical code folding.
|
||||
if (Config->GcSections)
|
||||
markLive<ELFT>();
|
||||
decompressAndMergeSections();
|
||||
if (Config->ICF)
|
||||
doIcf<ELFT>();
|
||||
|
||||
// MergeInputSection::splitIntoPieces needs to be called before
|
||||
// any call of MergeInputSection::getOffset. Do that.
|
||||
parallelForEach(InputSections.begin(), InputSections.end(),
|
||||
[](InputSectionBase *S) {
|
||||
if (!S->Live)
|
||||
return;
|
||||
if (Decompressor::isCompressedELFSection(S->Flags, S->Name))
|
||||
S->uncompress();
|
||||
if (auto *MS = dyn_cast<MergeInputSection>(S))
|
||||
MS->splitIntoPieces();
|
||||
});
|
||||
|
||||
// Write the result to the file.
|
||||
writeResult<ELFT>();
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "lld/Config/Version.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
|
||||
#include "llvm/Object/Decompressor.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/MD5.h"
|
||||
@ -2133,7 +2134,6 @@ MergeSyntheticSection::MergeSyntheticSection(StringRef Name, uint32_t Type,
|
||||
Builder(StringTableBuilder::RAW, Alignment) {}
|
||||
|
||||
void MergeSyntheticSection::addSection(MergeInputSection *MS) {
|
||||
assert(!Finalized);
|
||||
MS->Parent = this;
|
||||
Sections.push_back(MS);
|
||||
}
|
||||
@ -2178,9 +2178,6 @@ void MergeSyntheticSection::finalizeNoTailMerge() {
|
||||
}
|
||||
|
||||
void MergeSyntheticSection::finalizeContents() {
|
||||
if (Finalized)
|
||||
return;
|
||||
Finalized = true;
|
||||
if (shouldTailMerge())
|
||||
finalizeTailMerge();
|
||||
else
|
||||
@ -2188,11 +2185,65 @@ void MergeSyntheticSection::finalizeContents() {
|
||||
}
|
||||
|
||||
size_t MergeSyntheticSection::getSize() const {
|
||||
// We should finalize string builder to know the size.
|
||||
const_cast<MergeSyntheticSection *>(this)->finalizeContents();
|
||||
return Builder.getSize();
|
||||
}
|
||||
|
||||
// This function decompresses compressed sections and scans over the input
|
||||
// sections to create mergeable synthetic sections. It removes
|
||||
// MergeInputSections from the input section array and adds new synthetic
|
||||
// sections at the location of the first input section that it replaces. It then
|
||||
// finalizes each synthetic section in order to compute an output offset for
|
||||
// each piece of each input section.
|
||||
void elf::decompressAndMergeSections() {
|
||||
// splitIntoPieces needs to be called on each MergeInputSection before calling
|
||||
// finalizeContents(). Do that first.
|
||||
parallelForEach(InputSections.begin(), InputSections.end(),
|
||||
[](InputSectionBase *S) {
|
||||
if (!S->Live)
|
||||
return;
|
||||
if (Decompressor::isCompressedELFSection(S->Flags, S->Name))
|
||||
S->uncompress();
|
||||
if (auto *MS = dyn_cast<MergeInputSection>(S))
|
||||
MS->splitIntoPieces();
|
||||
});
|
||||
|
||||
std::vector<MergeSyntheticSection *> MergeSections;
|
||||
for (InputSectionBase *&S : InputSections) {
|
||||
MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
|
||||
if (!MS)
|
||||
continue;
|
||||
|
||||
// We do not want to handle sections that are not alive, so just remove
|
||||
// them instead of trying to merge.
|
||||
if (!MS->Live)
|
||||
continue;
|
||||
|
||||
StringRef OutsecName = getOutputSectionName(MS->Name);
|
||||
uint64_t Flags = MS->Flags & ~(uint64_t)SHF_GROUP;
|
||||
uint32_t Alignment = std::max<uint32_t>(MS->Alignment, MS->Entsize);
|
||||
|
||||
auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) {
|
||||
return Sec->Name == OutsecName && Sec->Flags == Flags &&
|
||||
Sec->Alignment == Alignment;
|
||||
});
|
||||
if (I == MergeSections.end()) {
|
||||
MergeSyntheticSection *Syn =
|
||||
make<MergeSyntheticSection>(OutsecName, MS->Type, Flags, Alignment);
|
||||
MergeSections.push_back(Syn);
|
||||
I = std::prev(MergeSections.end());
|
||||
S = Syn;
|
||||
} else {
|
||||
S = nullptr;
|
||||
}
|
||||
(*I)->addSection(MS);
|
||||
}
|
||||
for (auto *MS : MergeSections)
|
||||
MS->finalizeContents();
|
||||
|
||||
std::vector<InputSectionBase *> &V = InputSections;
|
||||
V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
|
||||
}
|
||||
|
||||
MipsRldMapSection::MipsRldMapSection()
|
||||
: SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
|
||||
".rld_map") {}
|
||||
|
@ -651,7 +651,6 @@ private:
|
||||
void finalizeTailMerge();
|
||||
void finalizeNoTailMerge();
|
||||
|
||||
bool Finalized = false;
|
||||
llvm::StringTableBuilder Builder;
|
||||
std::vector<MergeInputSection *> Sections;
|
||||
};
|
||||
@ -748,6 +747,7 @@ private:
|
||||
template <class ELFT> InputSection *createCommonSection();
|
||||
InputSection *createInterpSection();
|
||||
template <class ELFT> MergeInputSection *createCommentSection();
|
||||
void decompressAndMergeSections();
|
||||
|
||||
SymbolBody *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
|
||||
uint64_t Size, InputSectionBase *Section);
|
||||
|
@ -137,46 +137,6 @@ template <class ELFT> void Writer<ELFT>::removeEmptyPTLoad() {
|
||||
Phdrs.erase(I, Phdrs.end());
|
||||
}
|
||||
|
||||
// This function scans over the input sections and creates mergeable
|
||||
// synthetic sections. It removes MergeInputSections from array and
|
||||
// adds new synthetic ones. Each synthetic section is added to the
|
||||
// location of the first input section it replaces.
|
||||
static void combineMergableSections() {
|
||||
std::vector<MergeSyntheticSection *> MergeSections;
|
||||
for (InputSectionBase *&S : InputSections) {
|
||||
MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
|
||||
if (!MS)
|
||||
continue;
|
||||
|
||||
// We do not want to handle sections that are not alive, so just remove
|
||||
// them instead of trying to merge.
|
||||
if (!MS->Live)
|
||||
continue;
|
||||
|
||||
StringRef OutsecName = getOutputSectionName(MS->Name);
|
||||
uint64_t Flags = MS->Flags & ~(uint64_t)SHF_GROUP;
|
||||
uint32_t Alignment = std::max<uint32_t>(MS->Alignment, MS->Entsize);
|
||||
|
||||
auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) {
|
||||
return Sec->Name == OutsecName && Sec->Flags == Flags &&
|
||||
Sec->Alignment == Alignment;
|
||||
});
|
||||
if (I == MergeSections.end()) {
|
||||
MergeSyntheticSection *Syn =
|
||||
make<MergeSyntheticSection>(OutsecName, MS->Type, Flags, Alignment);
|
||||
MergeSections.push_back(Syn);
|
||||
I = std::prev(MergeSections.end());
|
||||
S = Syn;
|
||||
} else {
|
||||
S = nullptr;
|
||||
}
|
||||
(*I)->addSection(MS);
|
||||
}
|
||||
|
||||
std::vector<InputSectionBase *> &V = InputSections;
|
||||
V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
|
||||
}
|
||||
|
||||
template <class ELFT> static void combineEhFrameSections() {
|
||||
for (InputSectionBase *&S : InputSections) {
|
||||
EhInputSection *ES = dyn_cast<EhInputSection>(S);
|
||||
@ -205,7 +165,6 @@ template <class ELFT> void Writer<ELFT>::run() {
|
||||
// Create linker-synthesized sections such as .got or .plt.
|
||||
// Such sections are of type input section.
|
||||
createSyntheticSections();
|
||||
combineMergableSections();
|
||||
|
||||
if (!Config->Relocatable)
|
||||
combineEhFrameSections<ELFT>();
|
||||
@ -340,9 +299,6 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
||||
InX::Interp = nullptr;
|
||||
}
|
||||
|
||||
if (!Config->Relocatable)
|
||||
Add(createCommentSection<ELFT>());
|
||||
|
||||
if (Config->Strip != StripPolicy::All) {
|
||||
InX::StrTab = make<StringTableSection>(".strtab", false);
|
||||
InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
|
||||
|
Loading…
Reference in New Issue
Block a user