1*8bcb0991SDimitry Andric //===- yaml2elf - Convert YAML to a ELF object file -----------------------===// 2*8bcb0991SDimitry Andric // 3*8bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*8bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*8bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*8bcb0991SDimitry Andric // 7*8bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 8*8bcb0991SDimitry Andric /// 9*8bcb0991SDimitry Andric /// \file 10*8bcb0991SDimitry Andric /// The ELF component of yaml2obj. 11*8bcb0991SDimitry Andric /// 12*8bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 13*8bcb0991SDimitry Andric 14*8bcb0991SDimitry Andric #include "llvm/ADT/ArrayRef.h" 15*8bcb0991SDimitry Andric #include "llvm/ADT/StringSet.h" 16*8bcb0991SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 17*8bcb0991SDimitry Andric #include "llvm/MC/StringTableBuilder.h" 18*8bcb0991SDimitry Andric #include "llvm/Object/ELFObjectFile.h" 19*8bcb0991SDimitry Andric #include "llvm/ObjectYAML/ELFYAML.h" 20*8bcb0991SDimitry Andric #include "llvm/ObjectYAML/yaml2obj.h" 21*8bcb0991SDimitry Andric #include "llvm/Support/EndianStream.h" 22*8bcb0991SDimitry Andric #include "llvm/Support/LEB128.h" 23*8bcb0991SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 24*8bcb0991SDimitry Andric #include "llvm/Support/WithColor.h" 25*8bcb0991SDimitry Andric #include "llvm/Support/YAMLTraits.h" 26*8bcb0991SDimitry Andric #include "llvm/Support/raw_ostream.h" 27*8bcb0991SDimitry Andric 28*8bcb0991SDimitry Andric using namespace llvm; 29*8bcb0991SDimitry Andric 30*8bcb0991SDimitry Andric // This class is used to build up a contiguous binary blob while keeping 31*8bcb0991SDimitry Andric // track of an offset in the output (which notionally begins at 32*8bcb0991SDimitry Andric // `InitialOffset`). 33*8bcb0991SDimitry Andric namespace { 34*8bcb0991SDimitry Andric class ContiguousBlobAccumulator { 35*8bcb0991SDimitry Andric const uint64_t InitialOffset; 36*8bcb0991SDimitry Andric SmallVector<char, 128> Buf; 37*8bcb0991SDimitry Andric raw_svector_ostream OS; 38*8bcb0991SDimitry Andric 39*8bcb0991SDimitry Andric /// \returns The new offset. 40*8bcb0991SDimitry Andric uint64_t padToAlignment(unsigned Align) { 41*8bcb0991SDimitry Andric if (Align == 0) 42*8bcb0991SDimitry Andric Align = 1; 43*8bcb0991SDimitry Andric uint64_t CurrentOffset = InitialOffset + OS.tell(); 44*8bcb0991SDimitry Andric uint64_t AlignedOffset = alignTo(CurrentOffset, Align); 45*8bcb0991SDimitry Andric OS.write_zeros(AlignedOffset - CurrentOffset); 46*8bcb0991SDimitry Andric return AlignedOffset; // == CurrentOffset; 47*8bcb0991SDimitry Andric } 48*8bcb0991SDimitry Andric 49*8bcb0991SDimitry Andric public: 50*8bcb0991SDimitry Andric ContiguousBlobAccumulator(uint64_t InitialOffset_) 51*8bcb0991SDimitry Andric : InitialOffset(InitialOffset_), Buf(), OS(Buf) {} 52*8bcb0991SDimitry Andric template <class Integer> 53*8bcb0991SDimitry Andric raw_ostream &getOSAndAlignedOffset(Integer &Offset, unsigned Align) { 54*8bcb0991SDimitry Andric Offset = padToAlignment(Align); 55*8bcb0991SDimitry Andric return OS; 56*8bcb0991SDimitry Andric } 57*8bcb0991SDimitry Andric void writeBlobToStream(raw_ostream &Out) { Out << OS.str(); } 58*8bcb0991SDimitry Andric }; 59*8bcb0991SDimitry Andric 60*8bcb0991SDimitry Andric // Used to keep track of section and symbol names, so that in the YAML file 61*8bcb0991SDimitry Andric // sections and symbols can be referenced by name instead of by index. 62*8bcb0991SDimitry Andric class NameToIdxMap { 63*8bcb0991SDimitry Andric StringMap<unsigned> Map; 64*8bcb0991SDimitry Andric 65*8bcb0991SDimitry Andric public: 66*8bcb0991SDimitry Andric /// \Returns false if name is already present in the map. 67*8bcb0991SDimitry Andric bool addName(StringRef Name, unsigned Ndx) { 68*8bcb0991SDimitry Andric return Map.insert({Name, Ndx}).second; 69*8bcb0991SDimitry Andric } 70*8bcb0991SDimitry Andric /// \Returns false if name is not present in the map. 71*8bcb0991SDimitry Andric bool lookup(StringRef Name, unsigned &Idx) const { 72*8bcb0991SDimitry Andric auto I = Map.find(Name); 73*8bcb0991SDimitry Andric if (I == Map.end()) 74*8bcb0991SDimitry Andric return false; 75*8bcb0991SDimitry Andric Idx = I->getValue(); 76*8bcb0991SDimitry Andric return true; 77*8bcb0991SDimitry Andric } 78*8bcb0991SDimitry Andric /// Asserts if name is not present in the map. 79*8bcb0991SDimitry Andric unsigned get(StringRef Name) const { 80*8bcb0991SDimitry Andric unsigned Idx; 81*8bcb0991SDimitry Andric if (lookup(Name, Idx)) 82*8bcb0991SDimitry Andric return Idx; 83*8bcb0991SDimitry Andric assert(false && "Expected section not found in index"); 84*8bcb0991SDimitry Andric return 0; 85*8bcb0991SDimitry Andric } 86*8bcb0991SDimitry Andric unsigned size() const { return Map.size(); } 87*8bcb0991SDimitry Andric }; 88*8bcb0991SDimitry Andric 89*8bcb0991SDimitry Andric /// "Single point of truth" for the ELF file construction. 90*8bcb0991SDimitry Andric /// TODO: This class still has a ways to go before it is truly a "single 91*8bcb0991SDimitry Andric /// point of truth". 92*8bcb0991SDimitry Andric template <class ELFT> class ELFState { 93*8bcb0991SDimitry Andric typedef typename ELFT::Ehdr Elf_Ehdr; 94*8bcb0991SDimitry Andric typedef typename ELFT::Phdr Elf_Phdr; 95*8bcb0991SDimitry Andric typedef typename ELFT::Shdr Elf_Shdr; 96*8bcb0991SDimitry Andric typedef typename ELFT::Sym Elf_Sym; 97*8bcb0991SDimitry Andric typedef typename ELFT::Rel Elf_Rel; 98*8bcb0991SDimitry Andric typedef typename ELFT::Rela Elf_Rela; 99*8bcb0991SDimitry Andric typedef typename ELFT::Relr Elf_Relr; 100*8bcb0991SDimitry Andric typedef typename ELFT::Dyn Elf_Dyn; 101*8bcb0991SDimitry Andric 102*8bcb0991SDimitry Andric enum class SymtabType { Static, Dynamic }; 103*8bcb0991SDimitry Andric 104*8bcb0991SDimitry Andric /// The future ".strtab" section. 105*8bcb0991SDimitry Andric StringTableBuilder DotStrtab{StringTableBuilder::ELF}; 106*8bcb0991SDimitry Andric 107*8bcb0991SDimitry Andric /// The future ".shstrtab" section. 108*8bcb0991SDimitry Andric StringTableBuilder DotShStrtab{StringTableBuilder::ELF}; 109*8bcb0991SDimitry Andric 110*8bcb0991SDimitry Andric /// The future ".dynstr" section. 111*8bcb0991SDimitry Andric StringTableBuilder DotDynstr{StringTableBuilder::ELF}; 112*8bcb0991SDimitry Andric 113*8bcb0991SDimitry Andric NameToIdxMap SN2I; 114*8bcb0991SDimitry Andric NameToIdxMap SymN2I; 115*8bcb0991SDimitry Andric NameToIdxMap DynSymN2I; 116*8bcb0991SDimitry Andric ELFYAML::Object &Doc; 117*8bcb0991SDimitry Andric 118*8bcb0991SDimitry Andric bool HasError = false; 119*8bcb0991SDimitry Andric yaml::ErrorHandler ErrHandler; 120*8bcb0991SDimitry Andric void reportError(const Twine &Msg); 121*8bcb0991SDimitry Andric 122*8bcb0991SDimitry Andric std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 123*8bcb0991SDimitry Andric const StringTableBuilder &Strtab); 124*8bcb0991SDimitry Andric unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = ""); 125*8bcb0991SDimitry Andric unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic); 126*8bcb0991SDimitry Andric 127*8bcb0991SDimitry Andric void buildSectionIndex(); 128*8bcb0991SDimitry Andric void buildSymbolIndexes(); 129*8bcb0991SDimitry Andric void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders); 130*8bcb0991SDimitry Andric bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header, 131*8bcb0991SDimitry Andric StringRef SecName, ELFYAML::Section *YAMLSec); 132*8bcb0991SDimitry Andric void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 133*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 134*8bcb0991SDimitry Andric void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType, 135*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 136*8bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 137*8bcb0991SDimitry Andric void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 138*8bcb0991SDimitry Andric StringTableBuilder &STB, 139*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 140*8bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 141*8bcb0991SDimitry Andric void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 142*8bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders); 143*8bcb0991SDimitry Andric void finalizeStrings(); 144*8bcb0991SDimitry Andric void writeELFHeader(ContiguousBlobAccumulator &CBA, raw_ostream &OS); 145*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 146*8bcb0991SDimitry Andric const ELFYAML::RawContentSection &Section, 147*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 148*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 149*8bcb0991SDimitry Andric const ELFYAML::RelocationSection &Section, 150*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 151*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group, 152*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 153*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 154*8bcb0991SDimitry Andric const ELFYAML::SymtabShndxSection &Shndx, 155*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 156*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 157*8bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 158*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 159*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 160*8bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 161*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 162*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 163*8bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 164*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 165*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 166*8bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 167*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 168*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 169*8bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 170*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 171*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 172*8bcb0991SDimitry Andric const ELFYAML::StackSizesSection &Section, 173*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 174*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 175*8bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 176*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 177*8bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 178*8bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 179*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 180*8bcb0991SDimitry Andric 181*8bcb0991SDimitry Andric ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH); 182*8bcb0991SDimitry Andric 183*8bcb0991SDimitry Andric public: 184*8bcb0991SDimitry Andric static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 185*8bcb0991SDimitry Andric yaml::ErrorHandler EH); 186*8bcb0991SDimitry Andric }; 187*8bcb0991SDimitry Andric } // end anonymous namespace 188*8bcb0991SDimitry Andric 189*8bcb0991SDimitry Andric template <class T> static size_t arrayDataSize(ArrayRef<T> A) { 190*8bcb0991SDimitry Andric return A.size() * sizeof(T); 191*8bcb0991SDimitry Andric } 192*8bcb0991SDimitry Andric 193*8bcb0991SDimitry Andric template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) { 194*8bcb0991SDimitry Andric OS.write((const char *)A.data(), arrayDataSize(A)); 195*8bcb0991SDimitry Andric } 196*8bcb0991SDimitry Andric 197*8bcb0991SDimitry Andric template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); } 198*8bcb0991SDimitry Andric 199*8bcb0991SDimitry Andric template <class ELFT> 200*8bcb0991SDimitry Andric ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH) 201*8bcb0991SDimitry Andric : Doc(D), ErrHandler(EH) { 202*8bcb0991SDimitry Andric StringSet<> DocSections; 203*8bcb0991SDimitry Andric for (std::unique_ptr<ELFYAML::Section> &D : Doc.Sections) { 204*8bcb0991SDimitry Andric if (!D->Name.empty()) 205*8bcb0991SDimitry Andric DocSections.insert(D->Name); 206*8bcb0991SDimitry Andric 207*8bcb0991SDimitry Andric // Some sections wants to link to .symtab by default. 208*8bcb0991SDimitry Andric // That means we want to create the symbol table for them. 209*8bcb0991SDimitry Andric if (D->Type == llvm::ELF::SHT_REL || D->Type == llvm::ELF::SHT_RELA) 210*8bcb0991SDimitry Andric if (!Doc.Symbols && D->Link.empty()) 211*8bcb0991SDimitry Andric Doc.Symbols.emplace(); 212*8bcb0991SDimitry Andric } 213*8bcb0991SDimitry Andric 214*8bcb0991SDimitry Andric // Insert SHT_NULL section implicitly when it is not defined in YAML. 215*8bcb0991SDimitry Andric if (Doc.Sections.empty() || Doc.Sections.front()->Type != ELF::SHT_NULL) 216*8bcb0991SDimitry Andric Doc.Sections.insert( 217*8bcb0991SDimitry Andric Doc.Sections.begin(), 218*8bcb0991SDimitry Andric std::make_unique<ELFYAML::Section>( 219*8bcb0991SDimitry Andric ELFYAML::Section::SectionKind::RawContent, /*IsImplicit=*/true)); 220*8bcb0991SDimitry Andric 221*8bcb0991SDimitry Andric std::vector<StringRef> ImplicitSections; 222*8bcb0991SDimitry Andric if (Doc.Symbols) 223*8bcb0991SDimitry Andric ImplicitSections.push_back(".symtab"); 224*8bcb0991SDimitry Andric ImplicitSections.insert(ImplicitSections.end(), {".strtab", ".shstrtab"}); 225*8bcb0991SDimitry Andric 226*8bcb0991SDimitry Andric if (!Doc.DynamicSymbols.empty()) 227*8bcb0991SDimitry Andric ImplicitSections.insert(ImplicitSections.end(), {".dynsym", ".dynstr"}); 228*8bcb0991SDimitry Andric 229*8bcb0991SDimitry Andric // Insert placeholders for implicit sections that are not 230*8bcb0991SDimitry Andric // defined explicitly in YAML. 231*8bcb0991SDimitry Andric for (StringRef SecName : ImplicitSections) { 232*8bcb0991SDimitry Andric if (DocSections.count(SecName)) 233*8bcb0991SDimitry Andric continue; 234*8bcb0991SDimitry Andric 235*8bcb0991SDimitry Andric std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>( 236*8bcb0991SDimitry Andric ELFYAML::Section::SectionKind::RawContent, true /*IsImplicit*/); 237*8bcb0991SDimitry Andric Sec->Name = SecName; 238*8bcb0991SDimitry Andric Doc.Sections.push_back(std::move(Sec)); 239*8bcb0991SDimitry Andric } 240*8bcb0991SDimitry Andric } 241*8bcb0991SDimitry Andric 242*8bcb0991SDimitry Andric template <class ELFT> 243*8bcb0991SDimitry Andric void ELFState<ELFT>::writeELFHeader(ContiguousBlobAccumulator &CBA, raw_ostream &OS) { 244*8bcb0991SDimitry Andric using namespace llvm::ELF; 245*8bcb0991SDimitry Andric 246*8bcb0991SDimitry Andric Elf_Ehdr Header; 247*8bcb0991SDimitry Andric zero(Header); 248*8bcb0991SDimitry Andric Header.e_ident[EI_MAG0] = 0x7f; 249*8bcb0991SDimitry Andric Header.e_ident[EI_MAG1] = 'E'; 250*8bcb0991SDimitry Andric Header.e_ident[EI_MAG2] = 'L'; 251*8bcb0991SDimitry Andric Header.e_ident[EI_MAG3] = 'F'; 252*8bcb0991SDimitry Andric Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; 253*8bcb0991SDimitry Andric Header.e_ident[EI_DATA] = Doc.Header.Data; 254*8bcb0991SDimitry Andric Header.e_ident[EI_VERSION] = EV_CURRENT; 255*8bcb0991SDimitry Andric Header.e_ident[EI_OSABI] = Doc.Header.OSABI; 256*8bcb0991SDimitry Andric Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion; 257*8bcb0991SDimitry Andric Header.e_type = Doc.Header.Type; 258*8bcb0991SDimitry Andric Header.e_machine = Doc.Header.Machine; 259*8bcb0991SDimitry Andric Header.e_version = EV_CURRENT; 260*8bcb0991SDimitry Andric Header.e_entry = Doc.Header.Entry; 261*8bcb0991SDimitry Andric Header.e_phoff = Doc.ProgramHeaders.size() ? sizeof(Header) : 0; 262*8bcb0991SDimitry Andric Header.e_flags = Doc.Header.Flags; 263*8bcb0991SDimitry Andric Header.e_ehsize = sizeof(Elf_Ehdr); 264*8bcb0991SDimitry Andric Header.e_phentsize = Doc.ProgramHeaders.size() ? sizeof(Elf_Phdr) : 0; 265*8bcb0991SDimitry Andric Header.e_phnum = Doc.ProgramHeaders.size(); 266*8bcb0991SDimitry Andric 267*8bcb0991SDimitry Andric Header.e_shentsize = 268*8bcb0991SDimitry Andric Doc.Header.SHEntSize ? (uint16_t)*Doc.Header.SHEntSize : sizeof(Elf_Shdr); 269*8bcb0991SDimitry Andric // Immediately following the ELF header and program headers. 270*8bcb0991SDimitry Andric // Align the start of the section header and write the ELF header. 271*8bcb0991SDimitry Andric uint64_t SHOff; 272*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHOff, sizeof(typename ELFT::uint)); 273*8bcb0991SDimitry Andric Header.e_shoff = 274*8bcb0991SDimitry Andric Doc.Header.SHOff ? typename ELFT::uint(*Doc.Header.SHOff) : SHOff; 275*8bcb0991SDimitry Andric Header.e_shnum = 276*8bcb0991SDimitry Andric Doc.Header.SHNum ? (uint16_t)*Doc.Header.SHNum : Doc.Sections.size(); 277*8bcb0991SDimitry Andric Header.e_shstrndx = Doc.Header.SHStrNdx ? (uint16_t)*Doc.Header.SHStrNdx 278*8bcb0991SDimitry Andric : SN2I.get(".shstrtab"); 279*8bcb0991SDimitry Andric 280*8bcb0991SDimitry Andric OS.write((const char *)&Header, sizeof(Header)); 281*8bcb0991SDimitry Andric } 282*8bcb0991SDimitry Andric 283*8bcb0991SDimitry Andric template <class ELFT> 284*8bcb0991SDimitry Andric void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) { 285*8bcb0991SDimitry Andric for (const auto &YamlPhdr : Doc.ProgramHeaders) { 286*8bcb0991SDimitry Andric Elf_Phdr Phdr; 287*8bcb0991SDimitry Andric Phdr.p_type = YamlPhdr.Type; 288*8bcb0991SDimitry Andric Phdr.p_flags = YamlPhdr.Flags; 289*8bcb0991SDimitry Andric Phdr.p_vaddr = YamlPhdr.VAddr; 290*8bcb0991SDimitry Andric Phdr.p_paddr = YamlPhdr.PAddr; 291*8bcb0991SDimitry Andric PHeaders.push_back(Phdr); 292*8bcb0991SDimitry Andric } 293*8bcb0991SDimitry Andric } 294*8bcb0991SDimitry Andric 295*8bcb0991SDimitry Andric template <class ELFT> 296*8bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec, 297*8bcb0991SDimitry Andric StringRef LocSym) { 298*8bcb0991SDimitry Andric unsigned Index; 299*8bcb0991SDimitry Andric if (SN2I.lookup(S, Index) || to_integer(S, Index)) 300*8bcb0991SDimitry Andric return Index; 301*8bcb0991SDimitry Andric 302*8bcb0991SDimitry Andric assert(LocSec.empty() || LocSym.empty()); 303*8bcb0991SDimitry Andric if (!LocSym.empty()) 304*8bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML symbol '" + 305*8bcb0991SDimitry Andric LocSym + "'"); 306*8bcb0991SDimitry Andric else 307*8bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML section '" + 308*8bcb0991SDimitry Andric LocSec + "'"); 309*8bcb0991SDimitry Andric return 0; 310*8bcb0991SDimitry Andric } 311*8bcb0991SDimitry Andric 312*8bcb0991SDimitry Andric template <class ELFT> 313*8bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSymbolIndex(StringRef S, StringRef LocSec, 314*8bcb0991SDimitry Andric bool IsDynamic) { 315*8bcb0991SDimitry Andric const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I; 316*8bcb0991SDimitry Andric unsigned Index; 317*8bcb0991SDimitry Andric // Here we try to look up S in the symbol table. If it is not there, 318*8bcb0991SDimitry Andric // treat its value as a symbol index. 319*8bcb0991SDimitry Andric if (!SymMap.lookup(S, Index) && !to_integer(S, Index)) { 320*8bcb0991SDimitry Andric reportError("unknown symbol referenced: '" + S + "' by YAML section '" + 321*8bcb0991SDimitry Andric LocSec + "'"); 322*8bcb0991SDimitry Andric return 0; 323*8bcb0991SDimitry Andric } 324*8bcb0991SDimitry Andric return Index; 325*8bcb0991SDimitry Andric } 326*8bcb0991SDimitry Andric 327*8bcb0991SDimitry Andric template <class ELFT> 328*8bcb0991SDimitry Andric bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA, 329*8bcb0991SDimitry Andric Elf_Shdr &Header, StringRef SecName, 330*8bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 331*8bcb0991SDimitry Andric // Check if the header was already initialized. 332*8bcb0991SDimitry Andric if (Header.sh_offset) 333*8bcb0991SDimitry Andric return false; 334*8bcb0991SDimitry Andric 335*8bcb0991SDimitry Andric if (SecName == ".symtab") 336*8bcb0991SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec); 337*8bcb0991SDimitry Andric else if (SecName == ".strtab") 338*8bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec); 339*8bcb0991SDimitry Andric else if (SecName == ".shstrtab") 340*8bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotShStrtab, CBA, YAMLSec); 341*8bcb0991SDimitry Andric else if (SecName == ".dynsym") 342*8bcb0991SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec); 343*8bcb0991SDimitry Andric else if (SecName == ".dynstr") 344*8bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec); 345*8bcb0991SDimitry Andric else 346*8bcb0991SDimitry Andric return false; 347*8bcb0991SDimitry Andric 348*8bcb0991SDimitry Andric // Override the fields if requested. 349*8bcb0991SDimitry Andric if (YAMLSec) { 350*8bcb0991SDimitry Andric if (YAMLSec->ShName) 351*8bcb0991SDimitry Andric Header.sh_name = *YAMLSec->ShName; 352*8bcb0991SDimitry Andric if (YAMLSec->ShOffset) 353*8bcb0991SDimitry Andric Header.sh_offset = *YAMLSec->ShOffset; 354*8bcb0991SDimitry Andric if (YAMLSec->ShSize) 355*8bcb0991SDimitry Andric Header.sh_size = *YAMLSec->ShSize; 356*8bcb0991SDimitry Andric } 357*8bcb0991SDimitry Andric 358*8bcb0991SDimitry Andric return true; 359*8bcb0991SDimitry Andric } 360*8bcb0991SDimitry Andric 361*8bcb0991SDimitry Andric StringRef llvm::ELFYAML::dropUniqueSuffix(StringRef S) { 362*8bcb0991SDimitry Andric size_t SuffixPos = S.rfind(" ["); 363*8bcb0991SDimitry Andric if (SuffixPos == StringRef::npos) 364*8bcb0991SDimitry Andric return S; 365*8bcb0991SDimitry Andric return S.substr(0, SuffixPos); 366*8bcb0991SDimitry Andric } 367*8bcb0991SDimitry Andric 368*8bcb0991SDimitry Andric template <class ELFT> 369*8bcb0991SDimitry Andric void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 370*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 371*8bcb0991SDimitry Andric // Ensure SHN_UNDEF entry is present. An all-zero section header is a 372*8bcb0991SDimitry Andric // valid SHN_UNDEF entry since SHT_NULL == 0. 373*8bcb0991SDimitry Andric SHeaders.resize(Doc.Sections.size()); 374*8bcb0991SDimitry Andric 375*8bcb0991SDimitry Andric for (size_t I = 0; I < Doc.Sections.size(); ++I) { 376*8bcb0991SDimitry Andric ELFYAML::Section *Sec = Doc.Sections[I].get(); 377*8bcb0991SDimitry Andric if (I == 0 && Sec->IsImplicit) 378*8bcb0991SDimitry Andric continue; 379*8bcb0991SDimitry Andric 380*8bcb0991SDimitry Andric // We have a few sections like string or symbol tables that are usually 381*8bcb0991SDimitry Andric // added implicitly to the end. However, if they are explicitly specified 382*8bcb0991SDimitry Andric // in the YAML, we need to write them here. This ensures the file offset 383*8bcb0991SDimitry Andric // remains correct. 384*8bcb0991SDimitry Andric Elf_Shdr &SHeader = SHeaders[I]; 385*8bcb0991SDimitry Andric if (initImplicitHeader(CBA, SHeader, Sec->Name, 386*8bcb0991SDimitry Andric Sec->IsImplicit ? nullptr : Sec)) 387*8bcb0991SDimitry Andric continue; 388*8bcb0991SDimitry Andric 389*8bcb0991SDimitry Andric assert(Sec && "It can't be null unless it is an implicit section. But all " 390*8bcb0991SDimitry Andric "implicit sections should already have been handled above."); 391*8bcb0991SDimitry Andric 392*8bcb0991SDimitry Andric SHeader.sh_name = 393*8bcb0991SDimitry Andric DotShStrtab.getOffset(ELFYAML::dropUniqueSuffix(Sec->Name)); 394*8bcb0991SDimitry Andric SHeader.sh_type = Sec->Type; 395*8bcb0991SDimitry Andric if (Sec->Flags) 396*8bcb0991SDimitry Andric SHeader.sh_flags = *Sec->Flags; 397*8bcb0991SDimitry Andric SHeader.sh_addr = Sec->Address; 398*8bcb0991SDimitry Andric SHeader.sh_addralign = Sec->AddressAlign; 399*8bcb0991SDimitry Andric 400*8bcb0991SDimitry Andric if (!Sec->Link.empty()) 401*8bcb0991SDimitry Andric SHeader.sh_link = toSectionIndex(Sec->Link, Sec->Name); 402*8bcb0991SDimitry Andric 403*8bcb0991SDimitry Andric if (I == 0) { 404*8bcb0991SDimitry Andric if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 405*8bcb0991SDimitry Andric // We do not write any content for special SHN_UNDEF section. 406*8bcb0991SDimitry Andric if (RawSec->Size) 407*8bcb0991SDimitry Andric SHeader.sh_size = *RawSec->Size; 408*8bcb0991SDimitry Andric if (RawSec->Info) 409*8bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 410*8bcb0991SDimitry Andric } 411*8bcb0991SDimitry Andric if (Sec->EntSize) 412*8bcb0991SDimitry Andric SHeader.sh_entsize = *Sec->EntSize; 413*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 414*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 415*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Sec)) { 416*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 417*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) { 418*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 419*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::Group>(Sec)) { 420*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 421*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) { 422*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 423*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec)) { 424*8bcb0991SDimitry Andric SHeader.sh_entsize = 0; 425*8bcb0991SDimitry Andric SHeader.sh_size = S->Size; 426*8bcb0991SDimitry Andric // SHT_NOBITS section does not have content 427*8bcb0991SDimitry Andric // so just to setup the section offset. 428*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 429*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec)) { 430*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 431*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec)) { 432*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 433*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec)) { 434*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 435*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec)) { 436*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 437*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Sec)) { 438*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 439*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) { 440*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 441*8bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) { 442*8bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 443*8bcb0991SDimitry Andric } else { 444*8bcb0991SDimitry Andric llvm_unreachable("Unknown section type"); 445*8bcb0991SDimitry Andric } 446*8bcb0991SDimitry Andric 447*8bcb0991SDimitry Andric // Override the fields if requested. 448*8bcb0991SDimitry Andric if (Sec) { 449*8bcb0991SDimitry Andric if (Sec->ShName) 450*8bcb0991SDimitry Andric SHeader.sh_name = *Sec->ShName; 451*8bcb0991SDimitry Andric if (Sec->ShOffset) 452*8bcb0991SDimitry Andric SHeader.sh_offset = *Sec->ShOffset; 453*8bcb0991SDimitry Andric if (Sec->ShSize) 454*8bcb0991SDimitry Andric SHeader.sh_size = *Sec->ShSize; 455*8bcb0991SDimitry Andric } 456*8bcb0991SDimitry Andric } 457*8bcb0991SDimitry Andric } 458*8bcb0991SDimitry Andric 459*8bcb0991SDimitry Andric static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) { 460*8bcb0991SDimitry Andric for (size_t I = 0; I < Symbols.size(); ++I) 461*8bcb0991SDimitry Andric if (Symbols[I].Binding.value != ELF::STB_LOCAL) 462*8bcb0991SDimitry Andric return I; 463*8bcb0991SDimitry Andric return Symbols.size(); 464*8bcb0991SDimitry Andric } 465*8bcb0991SDimitry Andric 466*8bcb0991SDimitry Andric static uint64_t writeContent(raw_ostream &OS, 467*8bcb0991SDimitry Andric const Optional<yaml::BinaryRef> &Content, 468*8bcb0991SDimitry Andric const Optional<llvm::yaml::Hex64> &Size) { 469*8bcb0991SDimitry Andric size_t ContentSize = 0; 470*8bcb0991SDimitry Andric if (Content) { 471*8bcb0991SDimitry Andric Content->writeAsBinary(OS); 472*8bcb0991SDimitry Andric ContentSize = Content->binary_size(); 473*8bcb0991SDimitry Andric } 474*8bcb0991SDimitry Andric 475*8bcb0991SDimitry Andric if (!Size) 476*8bcb0991SDimitry Andric return ContentSize; 477*8bcb0991SDimitry Andric 478*8bcb0991SDimitry Andric OS.write_zeros(*Size - ContentSize); 479*8bcb0991SDimitry Andric return *Size; 480*8bcb0991SDimitry Andric } 481*8bcb0991SDimitry Andric 482*8bcb0991SDimitry Andric template <class ELFT> 483*8bcb0991SDimitry Andric std::vector<typename ELFT::Sym> 484*8bcb0991SDimitry Andric ELFState<ELFT>::toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 485*8bcb0991SDimitry Andric const StringTableBuilder &Strtab) { 486*8bcb0991SDimitry Andric std::vector<Elf_Sym> Ret; 487*8bcb0991SDimitry Andric Ret.resize(Symbols.size() + 1); 488*8bcb0991SDimitry Andric 489*8bcb0991SDimitry Andric size_t I = 0; 490*8bcb0991SDimitry Andric for (const auto &Sym : Symbols) { 491*8bcb0991SDimitry Andric Elf_Sym &Symbol = Ret[++I]; 492*8bcb0991SDimitry Andric 493*8bcb0991SDimitry Andric // If NameIndex, which contains the name offset, is explicitly specified, we 494*8bcb0991SDimitry Andric // use it. This is useful for preparing broken objects. Otherwise, we add 495*8bcb0991SDimitry Andric // the specified Name to the string table builder to get its offset. 496*8bcb0991SDimitry Andric if (Sym.NameIndex) 497*8bcb0991SDimitry Andric Symbol.st_name = *Sym.NameIndex; 498*8bcb0991SDimitry Andric else if (!Sym.Name.empty()) 499*8bcb0991SDimitry Andric Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name)); 500*8bcb0991SDimitry Andric 501*8bcb0991SDimitry Andric Symbol.setBindingAndType(Sym.Binding, Sym.Type); 502*8bcb0991SDimitry Andric if (!Sym.Section.empty()) 503*8bcb0991SDimitry Andric Symbol.st_shndx = toSectionIndex(Sym.Section, "", Sym.Name); 504*8bcb0991SDimitry Andric else if (Sym.Index) 505*8bcb0991SDimitry Andric Symbol.st_shndx = *Sym.Index; 506*8bcb0991SDimitry Andric 507*8bcb0991SDimitry Andric Symbol.st_value = Sym.Value; 508*8bcb0991SDimitry Andric Symbol.st_other = Sym.Other ? *Sym.Other : 0; 509*8bcb0991SDimitry Andric Symbol.st_size = Sym.Size; 510*8bcb0991SDimitry Andric } 511*8bcb0991SDimitry Andric 512*8bcb0991SDimitry Andric return Ret; 513*8bcb0991SDimitry Andric } 514*8bcb0991SDimitry Andric 515*8bcb0991SDimitry Andric template <class ELFT> 516*8bcb0991SDimitry Andric void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader, 517*8bcb0991SDimitry Andric SymtabType STType, 518*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 519*8bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 520*8bcb0991SDimitry Andric 521*8bcb0991SDimitry Andric bool IsStatic = STType == SymtabType::Static; 522*8bcb0991SDimitry Andric ArrayRef<ELFYAML::Symbol> Symbols; 523*8bcb0991SDimitry Andric if (IsStatic && Doc.Symbols) 524*8bcb0991SDimitry Andric Symbols = *Doc.Symbols; 525*8bcb0991SDimitry Andric else if (!IsStatic) 526*8bcb0991SDimitry Andric Symbols = Doc.DynamicSymbols; 527*8bcb0991SDimitry Andric 528*8bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 529*8bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 530*8bcb0991SDimitry Andric if (RawSec && !Symbols.empty() && (RawSec->Content || RawSec->Size)) { 531*8bcb0991SDimitry Andric if (RawSec->Content) 532*8bcb0991SDimitry Andric reportError("cannot specify both `Content` and " + 533*8bcb0991SDimitry Andric (IsStatic ? Twine("`Symbols`") : Twine("`DynamicSymbols`")) + 534*8bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 535*8bcb0991SDimitry Andric if (RawSec->Size) 536*8bcb0991SDimitry Andric reportError("cannot specify both `Size` and " + 537*8bcb0991SDimitry Andric (IsStatic ? Twine("`Symbols`") : Twine("`DynamicSymbols`")) + 538*8bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 539*8bcb0991SDimitry Andric return; 540*8bcb0991SDimitry Andric } 541*8bcb0991SDimitry Andric 542*8bcb0991SDimitry Andric zero(SHeader); 543*8bcb0991SDimitry Andric SHeader.sh_name = DotShStrtab.getOffset(IsStatic ? ".symtab" : ".dynsym"); 544*8bcb0991SDimitry Andric 545*8bcb0991SDimitry Andric if (YAMLSec) 546*8bcb0991SDimitry Andric SHeader.sh_type = YAMLSec->Type; 547*8bcb0991SDimitry Andric else 548*8bcb0991SDimitry Andric SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM; 549*8bcb0991SDimitry Andric 550*8bcb0991SDimitry Andric if (RawSec && !RawSec->Link.empty()) { 551*8bcb0991SDimitry Andric // If the Link field is explicitly defined in the document, 552*8bcb0991SDimitry Andric // we should use it. 553*8bcb0991SDimitry Andric SHeader.sh_link = toSectionIndex(RawSec->Link, RawSec->Name); 554*8bcb0991SDimitry Andric } else { 555*8bcb0991SDimitry Andric // When we describe the .dynsym section in the document explicitly, it is 556*8bcb0991SDimitry Andric // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not 557*8bcb0991SDimitry Andric // added implicitly and we should be able to leave the Link zeroed if 558*8bcb0991SDimitry Andric // .dynstr is not defined. 559*8bcb0991SDimitry Andric unsigned Link = 0; 560*8bcb0991SDimitry Andric if (IsStatic) 561*8bcb0991SDimitry Andric Link = SN2I.get(".strtab"); 562*8bcb0991SDimitry Andric else 563*8bcb0991SDimitry Andric SN2I.lookup(".dynstr", Link); 564*8bcb0991SDimitry Andric SHeader.sh_link = Link; 565*8bcb0991SDimitry Andric } 566*8bcb0991SDimitry Andric 567*8bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 568*8bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 569*8bcb0991SDimitry Andric else if (!IsStatic) 570*8bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 571*8bcb0991SDimitry Andric 572*8bcb0991SDimitry Andric // If the symbol table section is explicitly described in the YAML 573*8bcb0991SDimitry Andric // then we should set the fields requested. 574*8bcb0991SDimitry Andric SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info) 575*8bcb0991SDimitry Andric : findFirstNonGlobal(Symbols) + 1; 576*8bcb0991SDimitry Andric SHeader.sh_entsize = (YAMLSec && YAMLSec->EntSize) 577*8bcb0991SDimitry Andric ? (uint64_t)(*YAMLSec->EntSize) 578*8bcb0991SDimitry Andric : sizeof(Elf_Sym); 579*8bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8; 580*8bcb0991SDimitry Andric SHeader.sh_addr = YAMLSec ? (uint64_t)YAMLSec->Address : 0; 581*8bcb0991SDimitry Andric 582*8bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 583*8bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 584*8bcb0991SDimitry Andric assert(Symbols.empty()); 585*8bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, RawSec->Content, RawSec->Size); 586*8bcb0991SDimitry Andric return; 587*8bcb0991SDimitry Andric } 588*8bcb0991SDimitry Andric 589*8bcb0991SDimitry Andric std::vector<Elf_Sym> Syms = 590*8bcb0991SDimitry Andric toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr); 591*8bcb0991SDimitry Andric writeArrayData(OS, makeArrayRef(Syms)); 592*8bcb0991SDimitry Andric SHeader.sh_size = arrayDataSize(makeArrayRef(Syms)); 593*8bcb0991SDimitry Andric } 594*8bcb0991SDimitry Andric 595*8bcb0991SDimitry Andric template <class ELFT> 596*8bcb0991SDimitry Andric void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 597*8bcb0991SDimitry Andric StringTableBuilder &STB, 598*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 599*8bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 600*8bcb0991SDimitry Andric zero(SHeader); 601*8bcb0991SDimitry Andric SHeader.sh_name = DotShStrtab.getOffset(Name); 602*8bcb0991SDimitry Andric SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB; 603*8bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; 604*8bcb0991SDimitry Andric 605*8bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 606*8bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 607*8bcb0991SDimitry Andric 608*8bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 609*8bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 610*8bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, RawSec->Content, RawSec->Size); 611*8bcb0991SDimitry Andric } else { 612*8bcb0991SDimitry Andric STB.write(OS); 613*8bcb0991SDimitry Andric SHeader.sh_size = STB.getSize(); 614*8bcb0991SDimitry Andric } 615*8bcb0991SDimitry Andric 616*8bcb0991SDimitry Andric if (YAMLSec && YAMLSec->EntSize) 617*8bcb0991SDimitry Andric SHeader.sh_entsize = *YAMLSec->EntSize; 618*8bcb0991SDimitry Andric 619*8bcb0991SDimitry Andric if (RawSec && RawSec->Info) 620*8bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 621*8bcb0991SDimitry Andric 622*8bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 623*8bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 624*8bcb0991SDimitry Andric else if (Name == ".dynstr") 625*8bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 626*8bcb0991SDimitry Andric 627*8bcb0991SDimitry Andric // If the section is explicitly described in the YAML 628*8bcb0991SDimitry Andric // then we want to use its section address. 629*8bcb0991SDimitry Andric if (YAMLSec) 630*8bcb0991SDimitry Andric SHeader.sh_addr = YAMLSec->Address; 631*8bcb0991SDimitry Andric } 632*8bcb0991SDimitry Andric 633*8bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) { 634*8bcb0991SDimitry Andric ErrHandler(Msg); 635*8bcb0991SDimitry Andric HasError = true; 636*8bcb0991SDimitry Andric } 637*8bcb0991SDimitry Andric 638*8bcb0991SDimitry Andric template <class ELFT> 639*8bcb0991SDimitry Andric void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 640*8bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders) { 641*8bcb0991SDimitry Andric uint32_t PhdrIdx = 0; 642*8bcb0991SDimitry Andric for (auto &YamlPhdr : Doc.ProgramHeaders) { 643*8bcb0991SDimitry Andric Elf_Phdr &PHeader = PHeaders[PhdrIdx++]; 644*8bcb0991SDimitry Andric 645*8bcb0991SDimitry Andric std::vector<Elf_Shdr *> Sections; 646*8bcb0991SDimitry Andric for (const ELFYAML::SectionName &SecName : YamlPhdr.Sections) { 647*8bcb0991SDimitry Andric unsigned Index; 648*8bcb0991SDimitry Andric if (!SN2I.lookup(SecName.Section, Index)) { 649*8bcb0991SDimitry Andric reportError("unknown section referenced: '" + SecName.Section + 650*8bcb0991SDimitry Andric "' by program header"); 651*8bcb0991SDimitry Andric continue; 652*8bcb0991SDimitry Andric } 653*8bcb0991SDimitry Andric Sections.push_back(&SHeaders[Index]); 654*8bcb0991SDimitry Andric } 655*8bcb0991SDimitry Andric 656*8bcb0991SDimitry Andric if (YamlPhdr.Offset) { 657*8bcb0991SDimitry Andric PHeader.p_offset = *YamlPhdr.Offset; 658*8bcb0991SDimitry Andric } else { 659*8bcb0991SDimitry Andric if (YamlPhdr.Sections.size()) 660*8bcb0991SDimitry Andric PHeader.p_offset = UINT32_MAX; 661*8bcb0991SDimitry Andric else 662*8bcb0991SDimitry Andric PHeader.p_offset = 0; 663*8bcb0991SDimitry Andric 664*8bcb0991SDimitry Andric // Find the minimum offset for the program header. 665*8bcb0991SDimitry Andric for (Elf_Shdr *SHeader : Sections) 666*8bcb0991SDimitry Andric PHeader.p_offset = std::min(PHeader.p_offset, SHeader->sh_offset); 667*8bcb0991SDimitry Andric } 668*8bcb0991SDimitry Andric 669*8bcb0991SDimitry Andric // Find the maximum offset of the end of a section in order to set p_filesz 670*8bcb0991SDimitry Andric // and p_memsz. When setting p_filesz, trailing SHT_NOBITS sections are not 671*8bcb0991SDimitry Andric // counted. 672*8bcb0991SDimitry Andric uint64_t FileOffset = PHeader.p_offset, MemOffset = PHeader.p_offset; 673*8bcb0991SDimitry Andric for (Elf_Shdr *SHeader : Sections) { 674*8bcb0991SDimitry Andric uint64_t End = SHeader->sh_offset + SHeader->sh_size; 675*8bcb0991SDimitry Andric MemOffset = std::max(MemOffset, End); 676*8bcb0991SDimitry Andric 677*8bcb0991SDimitry Andric if (SHeader->sh_type != llvm::ELF::SHT_NOBITS) 678*8bcb0991SDimitry Andric FileOffset = std::max(FileOffset, End); 679*8bcb0991SDimitry Andric } 680*8bcb0991SDimitry Andric 681*8bcb0991SDimitry Andric // Set the file size and the memory size if not set explicitly. 682*8bcb0991SDimitry Andric PHeader.p_filesz = YamlPhdr.FileSize ? uint64_t(*YamlPhdr.FileSize) 683*8bcb0991SDimitry Andric : FileOffset - PHeader.p_offset; 684*8bcb0991SDimitry Andric PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize) 685*8bcb0991SDimitry Andric : MemOffset - PHeader.p_offset; 686*8bcb0991SDimitry Andric 687*8bcb0991SDimitry Andric if (YamlPhdr.Align) { 688*8bcb0991SDimitry Andric PHeader.p_align = *YamlPhdr.Align; 689*8bcb0991SDimitry Andric } else { 690*8bcb0991SDimitry Andric // Set the alignment of the segment to be the maximum alignment of the 691*8bcb0991SDimitry Andric // sections so that by default the segment has a valid and sensible 692*8bcb0991SDimitry Andric // alignment. 693*8bcb0991SDimitry Andric PHeader.p_align = 1; 694*8bcb0991SDimitry Andric for (Elf_Shdr *SHeader : Sections) 695*8bcb0991SDimitry Andric PHeader.p_align = std::max(PHeader.p_align, SHeader->sh_addralign); 696*8bcb0991SDimitry Andric } 697*8bcb0991SDimitry Andric } 698*8bcb0991SDimitry Andric } 699*8bcb0991SDimitry Andric 700*8bcb0991SDimitry Andric template <class ELFT> 701*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 702*8bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, 703*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 704*8bcb0991SDimitry Andric raw_ostream &OS = 705*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 706*8bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, Section.Size); 707*8bcb0991SDimitry Andric 708*8bcb0991SDimitry Andric if (Section.EntSize) 709*8bcb0991SDimitry Andric SHeader.sh_entsize = *Section.EntSize; 710*8bcb0991SDimitry Andric else if (Section.Type == llvm::ELF::SHT_RELR) 711*8bcb0991SDimitry Andric SHeader.sh_entsize = sizeof(Elf_Relr); 712*8bcb0991SDimitry Andric else 713*8bcb0991SDimitry Andric SHeader.sh_entsize = 0; 714*8bcb0991SDimitry Andric 715*8bcb0991SDimitry Andric if (Section.Info) 716*8bcb0991SDimitry Andric SHeader.sh_info = *Section.Info; 717*8bcb0991SDimitry Andric } 718*8bcb0991SDimitry Andric 719*8bcb0991SDimitry Andric static bool isMips64EL(const ELFYAML::Object &Doc) { 720*8bcb0991SDimitry Andric return Doc.Header.Machine == ELFYAML::ELF_EM(llvm::ELF::EM_MIPS) && 721*8bcb0991SDimitry Andric Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) && 722*8bcb0991SDimitry Andric Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 723*8bcb0991SDimitry Andric } 724*8bcb0991SDimitry Andric 725*8bcb0991SDimitry Andric template <class ELFT> 726*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 727*8bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, 728*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 729*8bcb0991SDimitry Andric assert((Section.Type == llvm::ELF::SHT_REL || 730*8bcb0991SDimitry Andric Section.Type == llvm::ELF::SHT_RELA) && 731*8bcb0991SDimitry Andric "Section type is not SHT_REL nor SHT_RELA"); 732*8bcb0991SDimitry Andric 733*8bcb0991SDimitry Andric bool IsRela = Section.Type == llvm::ELF::SHT_RELA; 734*8bcb0991SDimitry Andric SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); 735*8bcb0991SDimitry Andric SHeader.sh_size = SHeader.sh_entsize * Section.Relocations.size(); 736*8bcb0991SDimitry Andric 737*8bcb0991SDimitry Andric // For relocation section set link to .symtab by default. 738*8bcb0991SDimitry Andric if (Section.Link.empty()) 739*8bcb0991SDimitry Andric SHeader.sh_link = SN2I.get(".symtab"); 740*8bcb0991SDimitry Andric 741*8bcb0991SDimitry Andric if (!Section.RelocatableSec.empty()) 742*8bcb0991SDimitry Andric SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name); 743*8bcb0991SDimitry Andric 744*8bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 745*8bcb0991SDimitry Andric for (const auto &Rel : Section.Relocations) { 746*8bcb0991SDimitry Andric unsigned SymIdx = Rel.Symbol ? toSymbolIndex(*Rel.Symbol, Section.Name, 747*8bcb0991SDimitry Andric Section.Link == ".dynsym") 748*8bcb0991SDimitry Andric : 0; 749*8bcb0991SDimitry Andric if (IsRela) { 750*8bcb0991SDimitry Andric Elf_Rela REntry; 751*8bcb0991SDimitry Andric zero(REntry); 752*8bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 753*8bcb0991SDimitry Andric REntry.r_addend = Rel.Addend; 754*8bcb0991SDimitry Andric REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); 755*8bcb0991SDimitry Andric OS.write((const char *)&REntry, sizeof(REntry)); 756*8bcb0991SDimitry Andric } else { 757*8bcb0991SDimitry Andric Elf_Rel REntry; 758*8bcb0991SDimitry Andric zero(REntry); 759*8bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 760*8bcb0991SDimitry Andric REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); 761*8bcb0991SDimitry Andric OS.write((const char *)&REntry, sizeof(REntry)); 762*8bcb0991SDimitry Andric } 763*8bcb0991SDimitry Andric } 764*8bcb0991SDimitry Andric } 765*8bcb0991SDimitry Andric 766*8bcb0991SDimitry Andric template <class ELFT> 767*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 768*8bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx, 769*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 770*8bcb0991SDimitry Andric raw_ostream &OS = 771*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 772*8bcb0991SDimitry Andric 773*8bcb0991SDimitry Andric for (uint32_t E : Shndx.Entries) 774*8bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, E, ELFT::TargetEndianness); 775*8bcb0991SDimitry Andric 776*8bcb0991SDimitry Andric SHeader.sh_entsize = Shndx.EntSize ? (uint64_t)*Shndx.EntSize : 4; 777*8bcb0991SDimitry Andric SHeader.sh_size = Shndx.Entries.size() * SHeader.sh_entsize; 778*8bcb0991SDimitry Andric } 779*8bcb0991SDimitry Andric 780*8bcb0991SDimitry Andric template <class ELFT> 781*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 782*8bcb0991SDimitry Andric const ELFYAML::Group &Section, 783*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 784*8bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_GROUP && 785*8bcb0991SDimitry Andric "Section type is not SHT_GROUP"); 786*8bcb0991SDimitry Andric 787*8bcb0991SDimitry Andric SHeader.sh_entsize = 4; 788*8bcb0991SDimitry Andric SHeader.sh_size = SHeader.sh_entsize * Section.Members.size(); 789*8bcb0991SDimitry Andric SHeader.sh_info = 790*8bcb0991SDimitry Andric toSymbolIndex(Section.Signature, Section.Name, /*IsDynamic=*/false); 791*8bcb0991SDimitry Andric 792*8bcb0991SDimitry Andric raw_ostream &OS = 793*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 794*8bcb0991SDimitry Andric 795*8bcb0991SDimitry Andric for (const ELFYAML::SectionOrType &Member : Section.Members) { 796*8bcb0991SDimitry Andric unsigned int SectionIndex = 0; 797*8bcb0991SDimitry Andric if (Member.sectionNameOrType == "GRP_COMDAT") 798*8bcb0991SDimitry Andric SectionIndex = llvm::ELF::GRP_COMDAT; 799*8bcb0991SDimitry Andric else 800*8bcb0991SDimitry Andric SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name); 801*8bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, SectionIndex, ELFT::TargetEndianness); 802*8bcb0991SDimitry Andric } 803*8bcb0991SDimitry Andric } 804*8bcb0991SDimitry Andric 805*8bcb0991SDimitry Andric template <class ELFT> 806*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 807*8bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 808*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 809*8bcb0991SDimitry Andric raw_ostream &OS = 810*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 811*8bcb0991SDimitry Andric for (uint16_t Version : Section.Entries) 812*8bcb0991SDimitry Andric support::endian::write<uint16_t>(OS, Version, ELFT::TargetEndianness); 813*8bcb0991SDimitry Andric 814*8bcb0991SDimitry Andric SHeader.sh_entsize = Section.EntSize ? (uint64_t)*Section.EntSize : 2; 815*8bcb0991SDimitry Andric SHeader.sh_size = Section.Entries.size() * SHeader.sh_entsize; 816*8bcb0991SDimitry Andric } 817*8bcb0991SDimitry Andric 818*8bcb0991SDimitry Andric template <class ELFT> 819*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 820*8bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section, 821*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 822*8bcb0991SDimitry Andric using uintX_t = typename ELFT::uint; 823*8bcb0991SDimitry Andric raw_ostream &OS = 824*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 825*8bcb0991SDimitry Andric 826*8bcb0991SDimitry Andric if (Section.Content || Section.Size) { 827*8bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, Section.Size); 828*8bcb0991SDimitry Andric return; 829*8bcb0991SDimitry Andric } 830*8bcb0991SDimitry Andric 831*8bcb0991SDimitry Andric for (const ELFYAML::StackSizeEntry &E : *Section.Entries) { 832*8bcb0991SDimitry Andric support::endian::write<uintX_t>(OS, E.Address, ELFT::TargetEndianness); 833*8bcb0991SDimitry Andric SHeader.sh_size += sizeof(uintX_t) + encodeULEB128(E.Size, OS); 834*8bcb0991SDimitry Andric } 835*8bcb0991SDimitry Andric } 836*8bcb0991SDimitry Andric 837*8bcb0991SDimitry Andric template <class ELFT> 838*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 839*8bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 840*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 841*8bcb0991SDimitry Andric raw_ostream &OS = 842*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 843*8bcb0991SDimitry Andric 844*8bcb0991SDimitry Andric unsigned Link = 0; 845*8bcb0991SDimitry Andric if (Section.Link.empty() && SN2I.lookup(".dynsym", Link)) 846*8bcb0991SDimitry Andric SHeader.sh_link = Link; 847*8bcb0991SDimitry Andric 848*8bcb0991SDimitry Andric if (Section.Content || Section.Size) { 849*8bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, Section.Size); 850*8bcb0991SDimitry Andric return; 851*8bcb0991SDimitry Andric } 852*8bcb0991SDimitry Andric 853*8bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, Section.Bucket->size(), 854*8bcb0991SDimitry Andric ELFT::TargetEndianness); 855*8bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, Section.Chain->size(), 856*8bcb0991SDimitry Andric ELFT::TargetEndianness); 857*8bcb0991SDimitry Andric for (uint32_t Val : *Section.Bucket) 858*8bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, Val, ELFT::TargetEndianness); 859*8bcb0991SDimitry Andric for (uint32_t Val : *Section.Chain) 860*8bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, Val, ELFT::TargetEndianness); 861*8bcb0991SDimitry Andric 862*8bcb0991SDimitry Andric SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4; 863*8bcb0991SDimitry Andric } 864*8bcb0991SDimitry Andric 865*8bcb0991SDimitry Andric template <class ELFT> 866*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 867*8bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 868*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 869*8bcb0991SDimitry Andric typedef typename ELFT::Verdef Elf_Verdef; 870*8bcb0991SDimitry Andric typedef typename ELFT::Verdaux Elf_Verdaux; 871*8bcb0991SDimitry Andric raw_ostream &OS = 872*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 873*8bcb0991SDimitry Andric 874*8bcb0991SDimitry Andric uint64_t AuxCnt = 0; 875*8bcb0991SDimitry Andric for (size_t I = 0; I < Section.Entries.size(); ++I) { 876*8bcb0991SDimitry Andric const ELFYAML::VerdefEntry &E = Section.Entries[I]; 877*8bcb0991SDimitry Andric 878*8bcb0991SDimitry Andric Elf_Verdef VerDef; 879*8bcb0991SDimitry Andric VerDef.vd_version = E.Version; 880*8bcb0991SDimitry Andric VerDef.vd_flags = E.Flags; 881*8bcb0991SDimitry Andric VerDef.vd_ndx = E.VersionNdx; 882*8bcb0991SDimitry Andric VerDef.vd_hash = E.Hash; 883*8bcb0991SDimitry Andric VerDef.vd_aux = sizeof(Elf_Verdef); 884*8bcb0991SDimitry Andric VerDef.vd_cnt = E.VerNames.size(); 885*8bcb0991SDimitry Andric if (I == Section.Entries.size() - 1) 886*8bcb0991SDimitry Andric VerDef.vd_next = 0; 887*8bcb0991SDimitry Andric else 888*8bcb0991SDimitry Andric VerDef.vd_next = 889*8bcb0991SDimitry Andric sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux); 890*8bcb0991SDimitry Andric OS.write((const char *)&VerDef, sizeof(Elf_Verdef)); 891*8bcb0991SDimitry Andric 892*8bcb0991SDimitry Andric for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) { 893*8bcb0991SDimitry Andric Elf_Verdaux VernAux; 894*8bcb0991SDimitry Andric VernAux.vda_name = DotDynstr.getOffset(E.VerNames[J]); 895*8bcb0991SDimitry Andric if (J == E.VerNames.size() - 1) 896*8bcb0991SDimitry Andric VernAux.vda_next = 0; 897*8bcb0991SDimitry Andric else 898*8bcb0991SDimitry Andric VernAux.vda_next = sizeof(Elf_Verdaux); 899*8bcb0991SDimitry Andric OS.write((const char *)&VernAux, sizeof(Elf_Verdaux)); 900*8bcb0991SDimitry Andric } 901*8bcb0991SDimitry Andric } 902*8bcb0991SDimitry Andric 903*8bcb0991SDimitry Andric SHeader.sh_size = Section.Entries.size() * sizeof(Elf_Verdef) + 904*8bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Verdaux); 905*8bcb0991SDimitry Andric SHeader.sh_info = Section.Info; 906*8bcb0991SDimitry Andric } 907*8bcb0991SDimitry Andric 908*8bcb0991SDimitry Andric template <class ELFT> 909*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 910*8bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 911*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 912*8bcb0991SDimitry Andric typedef typename ELFT::Verneed Elf_Verneed; 913*8bcb0991SDimitry Andric typedef typename ELFT::Vernaux Elf_Vernaux; 914*8bcb0991SDimitry Andric 915*8bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 916*8bcb0991SDimitry Andric 917*8bcb0991SDimitry Andric uint64_t AuxCnt = 0; 918*8bcb0991SDimitry Andric for (size_t I = 0; I < Section.VerneedV.size(); ++I) { 919*8bcb0991SDimitry Andric const ELFYAML::VerneedEntry &VE = Section.VerneedV[I]; 920*8bcb0991SDimitry Andric 921*8bcb0991SDimitry Andric Elf_Verneed VerNeed; 922*8bcb0991SDimitry Andric VerNeed.vn_version = VE.Version; 923*8bcb0991SDimitry Andric VerNeed.vn_file = DotDynstr.getOffset(VE.File); 924*8bcb0991SDimitry Andric if (I == Section.VerneedV.size() - 1) 925*8bcb0991SDimitry Andric VerNeed.vn_next = 0; 926*8bcb0991SDimitry Andric else 927*8bcb0991SDimitry Andric VerNeed.vn_next = 928*8bcb0991SDimitry Andric sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux); 929*8bcb0991SDimitry Andric VerNeed.vn_cnt = VE.AuxV.size(); 930*8bcb0991SDimitry Andric VerNeed.vn_aux = sizeof(Elf_Verneed); 931*8bcb0991SDimitry Andric OS.write((const char *)&VerNeed, sizeof(Elf_Verneed)); 932*8bcb0991SDimitry Andric 933*8bcb0991SDimitry Andric for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) { 934*8bcb0991SDimitry Andric const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J]; 935*8bcb0991SDimitry Andric 936*8bcb0991SDimitry Andric Elf_Vernaux VernAux; 937*8bcb0991SDimitry Andric VernAux.vna_hash = VAuxE.Hash; 938*8bcb0991SDimitry Andric VernAux.vna_flags = VAuxE.Flags; 939*8bcb0991SDimitry Andric VernAux.vna_other = VAuxE.Other; 940*8bcb0991SDimitry Andric VernAux.vna_name = DotDynstr.getOffset(VAuxE.Name); 941*8bcb0991SDimitry Andric if (J == VE.AuxV.size() - 1) 942*8bcb0991SDimitry Andric VernAux.vna_next = 0; 943*8bcb0991SDimitry Andric else 944*8bcb0991SDimitry Andric VernAux.vna_next = sizeof(Elf_Vernaux); 945*8bcb0991SDimitry Andric OS.write((const char *)&VernAux, sizeof(Elf_Vernaux)); 946*8bcb0991SDimitry Andric } 947*8bcb0991SDimitry Andric } 948*8bcb0991SDimitry Andric 949*8bcb0991SDimitry Andric SHeader.sh_size = Section.VerneedV.size() * sizeof(Elf_Verneed) + 950*8bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Vernaux); 951*8bcb0991SDimitry Andric SHeader.sh_info = Section.Info; 952*8bcb0991SDimitry Andric } 953*8bcb0991SDimitry Andric 954*8bcb0991SDimitry Andric template <class ELFT> 955*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 956*8bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 957*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 958*8bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS && 959*8bcb0991SDimitry Andric "Section type is not SHT_MIPS_ABIFLAGS"); 960*8bcb0991SDimitry Andric 961*8bcb0991SDimitry Andric object::Elf_Mips_ABIFlags<ELFT> Flags; 962*8bcb0991SDimitry Andric zero(Flags); 963*8bcb0991SDimitry Andric SHeader.sh_entsize = sizeof(Flags); 964*8bcb0991SDimitry Andric SHeader.sh_size = SHeader.sh_entsize; 965*8bcb0991SDimitry Andric 966*8bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 967*8bcb0991SDimitry Andric Flags.version = Section.Version; 968*8bcb0991SDimitry Andric Flags.isa_level = Section.ISALevel; 969*8bcb0991SDimitry Andric Flags.isa_rev = Section.ISARevision; 970*8bcb0991SDimitry Andric Flags.gpr_size = Section.GPRSize; 971*8bcb0991SDimitry Andric Flags.cpr1_size = Section.CPR1Size; 972*8bcb0991SDimitry Andric Flags.cpr2_size = Section.CPR2Size; 973*8bcb0991SDimitry Andric Flags.fp_abi = Section.FpABI; 974*8bcb0991SDimitry Andric Flags.isa_ext = Section.ISAExtension; 975*8bcb0991SDimitry Andric Flags.ases = Section.ASEs; 976*8bcb0991SDimitry Andric Flags.flags1 = Section.Flags1; 977*8bcb0991SDimitry Andric Flags.flags2 = Section.Flags2; 978*8bcb0991SDimitry Andric OS.write((const char *)&Flags, sizeof(Flags)); 979*8bcb0991SDimitry Andric } 980*8bcb0991SDimitry Andric 981*8bcb0991SDimitry Andric template <class ELFT> 982*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 983*8bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 984*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 985*8bcb0991SDimitry Andric typedef typename ELFT::uint uintX_t; 986*8bcb0991SDimitry Andric 987*8bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_DYNAMIC && 988*8bcb0991SDimitry Andric "Section type is not SHT_DYNAMIC"); 989*8bcb0991SDimitry Andric 990*8bcb0991SDimitry Andric if (!Section.Entries.empty() && Section.Content) 991*8bcb0991SDimitry Andric reportError("cannot specify both raw content and explicit entries " 992*8bcb0991SDimitry Andric "for dynamic section '" + 993*8bcb0991SDimitry Andric Section.Name + "'"); 994*8bcb0991SDimitry Andric 995*8bcb0991SDimitry Andric if (Section.Content) 996*8bcb0991SDimitry Andric SHeader.sh_size = Section.Content->binary_size(); 997*8bcb0991SDimitry Andric else 998*8bcb0991SDimitry Andric SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size(); 999*8bcb0991SDimitry Andric if (Section.EntSize) 1000*8bcb0991SDimitry Andric SHeader.sh_entsize = *Section.EntSize; 1001*8bcb0991SDimitry Andric else 1002*8bcb0991SDimitry Andric SHeader.sh_entsize = sizeof(Elf_Dyn); 1003*8bcb0991SDimitry Andric 1004*8bcb0991SDimitry Andric raw_ostream &OS = 1005*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 1006*8bcb0991SDimitry Andric for (const ELFYAML::DynamicEntry &DE : Section.Entries) { 1007*8bcb0991SDimitry Andric support::endian::write<uintX_t>(OS, DE.Tag, ELFT::TargetEndianness); 1008*8bcb0991SDimitry Andric support::endian::write<uintX_t>(OS, DE.Val, ELFT::TargetEndianness); 1009*8bcb0991SDimitry Andric } 1010*8bcb0991SDimitry Andric if (Section.Content) 1011*8bcb0991SDimitry Andric Section.Content->writeAsBinary(OS); 1012*8bcb0991SDimitry Andric } 1013*8bcb0991SDimitry Andric 1014*8bcb0991SDimitry Andric template <class ELFT> 1015*8bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1016*8bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 1017*8bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1018*8bcb0991SDimitry Andric raw_ostream &OS = 1019*8bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 1020*8bcb0991SDimitry Andric 1021*8bcb0991SDimitry Andric unsigned Link = 0; 1022*8bcb0991SDimitry Andric if (Section.Link.empty() && SN2I.lookup(".symtab", Link)) 1023*8bcb0991SDimitry Andric SHeader.sh_link = Link; 1024*8bcb0991SDimitry Andric 1025*8bcb0991SDimitry Andric if (Section.Content || Section.Size) { 1026*8bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, Section.Size); 1027*8bcb0991SDimitry Andric return; 1028*8bcb0991SDimitry Andric } 1029*8bcb0991SDimitry Andric 1030*8bcb0991SDimitry Andric for (const ELFYAML::AddrsigSymbol &Sym : *Section.Symbols) { 1031*8bcb0991SDimitry Andric uint64_t Val = 1032*8bcb0991SDimitry Andric Sym.Name ? toSymbolIndex(*Sym.Name, Section.Name, /*IsDynamic=*/false) 1033*8bcb0991SDimitry Andric : (uint32_t)*Sym.Index; 1034*8bcb0991SDimitry Andric SHeader.sh_size += encodeULEB128(Val, OS); 1035*8bcb0991SDimitry Andric } 1036*8bcb0991SDimitry Andric } 1037*8bcb0991SDimitry Andric 1038*8bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSectionIndex() { 1039*8bcb0991SDimitry Andric for (unsigned I = 0, E = Doc.Sections.size(); I != E; ++I) { 1040*8bcb0991SDimitry Andric StringRef Name = Doc.Sections[I]->Name; 1041*8bcb0991SDimitry Andric if (Name.empty()) 1042*8bcb0991SDimitry Andric continue; 1043*8bcb0991SDimitry Andric 1044*8bcb0991SDimitry Andric DotShStrtab.add(ELFYAML::dropUniqueSuffix(Name)); 1045*8bcb0991SDimitry Andric if (!SN2I.addName(Name, I)) 1046*8bcb0991SDimitry Andric reportError("repeated section name: '" + Name + 1047*8bcb0991SDimitry Andric "' at YAML section number " + Twine(I)); 1048*8bcb0991SDimitry Andric } 1049*8bcb0991SDimitry Andric 1050*8bcb0991SDimitry Andric DotShStrtab.finalize(); 1051*8bcb0991SDimitry Andric } 1052*8bcb0991SDimitry Andric 1053*8bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() { 1054*8bcb0991SDimitry Andric auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) { 1055*8bcb0991SDimitry Andric for (size_t I = 0, S = V.size(); I < S; ++I) { 1056*8bcb0991SDimitry Andric const ELFYAML::Symbol &Sym = V[I]; 1057*8bcb0991SDimitry Andric if (!Sym.Name.empty() && !Map.addName(Sym.Name, I + 1)) 1058*8bcb0991SDimitry Andric reportError("repeated symbol name: '" + Sym.Name + "'"); 1059*8bcb0991SDimitry Andric } 1060*8bcb0991SDimitry Andric }; 1061*8bcb0991SDimitry Andric 1062*8bcb0991SDimitry Andric if (Doc.Symbols) 1063*8bcb0991SDimitry Andric Build(*Doc.Symbols, SymN2I); 1064*8bcb0991SDimitry Andric Build(Doc.DynamicSymbols, DynSymN2I); 1065*8bcb0991SDimitry Andric } 1066*8bcb0991SDimitry Andric 1067*8bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::finalizeStrings() { 1068*8bcb0991SDimitry Andric // Add the regular symbol names to .strtab section. 1069*8bcb0991SDimitry Andric if (Doc.Symbols) 1070*8bcb0991SDimitry Andric for (const ELFYAML::Symbol &Sym : *Doc.Symbols) 1071*8bcb0991SDimitry Andric DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 1072*8bcb0991SDimitry Andric DotStrtab.finalize(); 1073*8bcb0991SDimitry Andric 1074*8bcb0991SDimitry Andric // Add the dynamic symbol names to .dynstr section. 1075*8bcb0991SDimitry Andric for (const ELFYAML::Symbol &Sym : Doc.DynamicSymbols) 1076*8bcb0991SDimitry Andric DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 1077*8bcb0991SDimitry Andric 1078*8bcb0991SDimitry Andric // SHT_GNU_verdef and SHT_GNU_verneed sections might also 1079*8bcb0991SDimitry Andric // add strings to .dynstr section. 1080*8bcb0991SDimitry Andric for (const std::unique_ptr<ELFYAML::Section> &Sec : Doc.Sections) { 1081*8bcb0991SDimitry Andric if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) { 1082*8bcb0991SDimitry Andric for (const ELFYAML::VerneedEntry &VE : VerNeed->VerneedV) { 1083*8bcb0991SDimitry Andric DotDynstr.add(VE.File); 1084*8bcb0991SDimitry Andric for (const ELFYAML::VernauxEntry &Aux : VE.AuxV) 1085*8bcb0991SDimitry Andric DotDynstr.add(Aux.Name); 1086*8bcb0991SDimitry Andric } 1087*8bcb0991SDimitry Andric } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec.get())) { 1088*8bcb0991SDimitry Andric for (const ELFYAML::VerdefEntry &E : VerDef->Entries) 1089*8bcb0991SDimitry Andric for (StringRef Name : E.VerNames) 1090*8bcb0991SDimitry Andric DotDynstr.add(Name); 1091*8bcb0991SDimitry Andric } 1092*8bcb0991SDimitry Andric } 1093*8bcb0991SDimitry Andric 1094*8bcb0991SDimitry Andric DotDynstr.finalize(); 1095*8bcb0991SDimitry Andric } 1096*8bcb0991SDimitry Andric 1097*8bcb0991SDimitry Andric template <class ELFT> 1098*8bcb0991SDimitry Andric bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 1099*8bcb0991SDimitry Andric yaml::ErrorHandler EH) { 1100*8bcb0991SDimitry Andric ELFState<ELFT> State(Doc, EH); 1101*8bcb0991SDimitry Andric 1102*8bcb0991SDimitry Andric // Finalize .strtab and .dynstr sections. We do that early because want to 1103*8bcb0991SDimitry Andric // finalize the string table builders before writing the content of the 1104*8bcb0991SDimitry Andric // sections that might want to use them. 1105*8bcb0991SDimitry Andric State.finalizeStrings(); 1106*8bcb0991SDimitry Andric 1107*8bcb0991SDimitry Andric State.buildSectionIndex(); 1108*8bcb0991SDimitry Andric State.buildSymbolIndexes(); 1109*8bcb0991SDimitry Andric 1110*8bcb0991SDimitry Andric std::vector<Elf_Phdr> PHeaders; 1111*8bcb0991SDimitry Andric State.initProgramHeaders(PHeaders); 1112*8bcb0991SDimitry Andric 1113*8bcb0991SDimitry Andric // XXX: This offset is tightly coupled with the order that we write 1114*8bcb0991SDimitry Andric // things to `OS`. 1115*8bcb0991SDimitry Andric const size_t SectionContentBeginOffset = 1116*8bcb0991SDimitry Andric sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size(); 1117*8bcb0991SDimitry Andric ContiguousBlobAccumulator CBA(SectionContentBeginOffset); 1118*8bcb0991SDimitry Andric 1119*8bcb0991SDimitry Andric std::vector<Elf_Shdr> SHeaders; 1120*8bcb0991SDimitry Andric State.initSectionHeaders(SHeaders, CBA); 1121*8bcb0991SDimitry Andric 1122*8bcb0991SDimitry Andric // Now we can decide segment offsets 1123*8bcb0991SDimitry Andric State.setProgramHeaderLayout(PHeaders, SHeaders); 1124*8bcb0991SDimitry Andric 1125*8bcb0991SDimitry Andric if (State.HasError) 1126*8bcb0991SDimitry Andric return false; 1127*8bcb0991SDimitry Andric 1128*8bcb0991SDimitry Andric State.writeELFHeader(CBA, OS); 1129*8bcb0991SDimitry Andric writeArrayData(OS, makeArrayRef(PHeaders)); 1130*8bcb0991SDimitry Andric CBA.writeBlobToStream(OS); 1131*8bcb0991SDimitry Andric writeArrayData(OS, makeArrayRef(SHeaders)); 1132*8bcb0991SDimitry Andric return true; 1133*8bcb0991SDimitry Andric } 1134*8bcb0991SDimitry Andric 1135*8bcb0991SDimitry Andric namespace llvm { 1136*8bcb0991SDimitry Andric namespace yaml { 1137*8bcb0991SDimitry Andric 1138*8bcb0991SDimitry Andric bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH) { 1139*8bcb0991SDimitry Andric bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 1140*8bcb0991SDimitry Andric bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); 1141*8bcb0991SDimitry Andric if (Is64Bit) { 1142*8bcb0991SDimitry Andric if (IsLE) 1143*8bcb0991SDimitry Andric return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH); 1144*8bcb0991SDimitry Andric return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH); 1145*8bcb0991SDimitry Andric } 1146*8bcb0991SDimitry Andric if (IsLE) 1147*8bcb0991SDimitry Andric return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH); 1148*8bcb0991SDimitry Andric return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH); 1149*8bcb0991SDimitry Andric } 1150*8bcb0991SDimitry Andric 1151*8bcb0991SDimitry Andric } // namespace yaml 1152*8bcb0991SDimitry Andric } // namespace llvm 1153