forked from OSchip/llvm-project
[yaml2obj] - Change how we handle implicit sections.
Instead of having the special list of implicit sections, that are mixed with the sections read from YAML on late stages, I just create the placeholders and add them to the main sections list early. That allows to significantly simplify the code. Differential revision: https://reviews.llvm.org/D64999 llvm-svn: 366677
This commit is contained in:
parent
5d4bc1293c
commit
13a364e1cc
|
@ -148,7 +148,12 @@ struct Section {
|
|||
// content written.
|
||||
Optional<llvm::yaml::Hex64> ShSize;
|
||||
|
||||
Section(SectionKind Kind) : Kind(Kind) {}
|
||||
// Usually sections are not created implicitly, but loaded from YAML.
|
||||
// When they are, this flag is used to signal about that.
|
||||
bool IsImplicit;
|
||||
|
||||
Section(SectionKind Kind, bool IsImplicit = false)
|
||||
: Kind(Kind), IsImplicit(IsImplicit) {}
|
||||
virtual ~Section();
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "llvm/MC/StringTableBuilder.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/ObjectYAML/ELFYAML.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/Support/EndianStream.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/WithColor.h"
|
||||
|
@ -130,7 +131,7 @@ class ELFState {
|
|||
|
||||
NameToIdxMap SN2I;
|
||||
NameToIdxMap SymN2I;
|
||||
const ELFYAML::Object &Doc;
|
||||
ELFYAML::Object &Doc;
|
||||
|
||||
bool buildSectionIndex();
|
||||
bool buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols);
|
||||
|
@ -174,18 +175,40 @@ class ELFState {
|
|||
bool writeSectionContent(Elf_Shdr &SHeader,
|
||||
const ELFYAML::DynamicSection &Section,
|
||||
ContiguousBlobAccumulator &CBA);
|
||||
std::vector<StringRef> implicitSectionNames() const;
|
||||
|
||||
ELFState(const ELFYAML::Object &D) : Doc(D) {}
|
||||
ELFState(ELFYAML::Object &D);
|
||||
|
||||
public:
|
||||
static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc);
|
||||
static int writeELF(raw_ostream &OS, ELFYAML::Object &Doc);
|
||||
|
||||
private:
|
||||
void finalizeStrings();
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
template <class ELFT>
|
||||
ELFState<ELFT>::ELFState(ELFYAML::Object &D) : Doc(D) {
|
||||
StringSet<> DocSections;
|
||||
for (std::unique_ptr<ELFYAML::Section> &D : Doc.Sections)
|
||||
if (!D->Name.empty())
|
||||
DocSections.insert(D->Name);
|
||||
|
||||
std::vector<StringRef> ImplicitSections = {".symtab", ".strtab", ".shstrtab"};
|
||||
if (!Doc.DynamicSymbols.empty())
|
||||
ImplicitSections.insert(ImplicitSections.end(), {".dynsym", ".dynstr"});
|
||||
|
||||
// Insert placeholders for implicit sections that are not
|
||||
// defined explicitly in YAML.
|
||||
for (StringRef SecName : ImplicitSections) {
|
||||
if (DocSections.count(SecName))
|
||||
continue;
|
||||
|
||||
std::unique_ptr<ELFYAML::Section> Sec = llvm::make_unique<ELFYAML::Section>(
|
||||
ELFYAML::Section::SectionKind::RawContent, true /*IsImplicit*/);
|
||||
Sec->Name = SecName;
|
||||
Doc.Sections.push_back(std::move(Sec));
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void ELFState<ELFT>::initELFHeader(Elf_Ehdr &Header) {
|
||||
using namespace llvm::ELF;
|
||||
|
@ -292,36 +315,28 @@ template <class ELFT>
|
|||
bool ELFState<ELFT>::initSectionHeaders(ELFState<ELFT> &State,
|
||||
std::vector<Elf_Shdr> &SHeaders,
|
||||
ContiguousBlobAccumulator &CBA) {
|
||||
// Build a list of sections we are going to add implicitly.
|
||||
std::vector<StringRef> ImplicitSections;
|
||||
for (StringRef Name : State.implicitSectionNames())
|
||||
if (State.SN2I.get(Name) > Doc.Sections.size())
|
||||
ImplicitSections.push_back(Name);
|
||||
|
||||
// Ensure SHN_UNDEF entry is present. An all-zero section header is a
|
||||
// valid SHN_UNDEF entry since SHT_NULL == 0.
|
||||
SHeaders.resize(Doc.Sections.size() + ImplicitSections.size() + 1);
|
||||
SHeaders.resize(Doc.Sections.size() + 1);
|
||||
zero(SHeaders[0]);
|
||||
|
||||
for (size_t I = 1; I < Doc.Sections.size() + ImplicitSections.size() + 1; ++I) {
|
||||
for (size_t I = 1; I < Doc.Sections.size() + 1; ++I) {
|
||||
Elf_Shdr &SHeader = SHeaders[I];
|
||||
zero(SHeader);
|
||||
ELFYAML::Section *Sec =
|
||||
I > Doc.Sections.size() ? nullptr : Doc.Sections[I - 1].get();
|
||||
ELFYAML::Section *Sec = Doc.Sections[I - 1].get();
|
||||
|
||||
// We have a few sections like string or symbol tables that are usually
|
||||
// added implicitly to the end. However, if they are explicitly specified
|
||||
// in the YAML, we need to write them here. This ensures the file offset
|
||||
// remains correct.
|
||||
StringRef SecName =
|
||||
Sec ? Sec->Name : ImplicitSections[I - Doc.Sections.size() - 1];
|
||||
if (initImplicitHeader(State, CBA, SHeader, SecName, Sec))
|
||||
if (initImplicitHeader(State, CBA, SHeader, Sec->Name,
|
||||
Sec->IsImplicit ? nullptr : Sec))
|
||||
continue;
|
||||
|
||||
assert(Sec && "It can't be null unless it is an implicit section. But all "
|
||||
"implicit sections should already have been handled above.");
|
||||
|
||||
SHeader.sh_name = DotShStrtab.getOffset(dropUniqueSuffix(SecName));
|
||||
SHeader.sh_name = DotShStrtab.getOffset(dropUniqueSuffix(Sec->Name));
|
||||
SHeader.sh_type = Sec->Type;
|
||||
if (Sec->Flags)
|
||||
SHeader.sh_flags = *Sec->Flags;
|
||||
|
@ -940,15 +955,6 @@ template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
|
|||
}
|
||||
}
|
||||
|
||||
auto SecNo = 1 + Doc.Sections.size();
|
||||
// Add special sections after input sections, if necessary.
|
||||
for (StringRef Name : implicitSectionNames())
|
||||
if (SN2I.addName(Name, SecNo)) {
|
||||
// Account for this section, since it wasn't in the Doc
|
||||
++SecNo;
|
||||
DotShStrtab.add(Name);
|
||||
}
|
||||
|
||||
DotShStrtab.finalize();
|
||||
return true;
|
||||
}
|
||||
|
@ -1007,7 +1013,7 @@ template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
int ELFState<ELFT>::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
|
||||
int ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) {
|
||||
ELFState<ELFT> State(Doc);
|
||||
|
||||
// Finalize .strtab and .dynstr sections. We do that early because want to
|
||||
|
@ -1050,13 +1056,6 @@ int ELFState<ELFT>::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::vector<StringRef> ELFState<ELFT>::implicitSectionNames() const {
|
||||
if (Doc.DynamicSymbols.empty())
|
||||
return {".symtab", ".strtab", ".shstrtab"};
|
||||
return {".symtab", ".strtab", ".shstrtab", ".dynsym", ".dynstr"};
|
||||
}
|
||||
|
||||
int yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out) {
|
||||
bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
|
||||
bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
|
||||
|
|
Loading…
Reference in New Issue