[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