#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"
NameToIdxMap SN2I;
NameToIdxMap SymN2I;
- const ELFYAML::Object &Doc;
+ ELFYAML::Object &Doc;
bool buildSectionIndex();
bool buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols);
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;
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;
}
}
- 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;
}
}
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
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);