2184 lines · cpp
1//===- yaml2elf - Convert YAML to a ELF object file -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// The ELF component of yaml2obj.11///12//===----------------------------------------------------------------------===//13 14#include "llvm/ADT/ArrayRef.h"15#include "llvm/ADT/DenseMap.h"16#include "llvm/ADT/SetVector.h"17#include "llvm/ADT/StringSet.h"18#include "llvm/BinaryFormat/ELF.h"19#include "llvm/MC/StringTableBuilder.h"20#include "llvm/Object/ELFTypes.h"21#include "llvm/ObjectYAML/DWARFEmitter.h"22#include "llvm/ObjectYAML/DWARFYAML.h"23#include "llvm/ObjectYAML/ELFYAML.h"24#include "llvm/ObjectYAML/yaml2obj.h"25#include "llvm/Support/EndianStream.h"26#include "llvm/Support/Errc.h"27#include "llvm/Support/Error.h"28#include "llvm/Support/LEB128.h"29#include "llvm/Support/WithColor.h"30#include "llvm/Support/YAMLTraits.h"31#include "llvm/Support/raw_ostream.h"32#include <optional>33 34using namespace llvm;35 36// This class is used to build up a contiguous binary blob while keeping37// track of an offset in the output (which notionally begins at38// `InitialOffset`).39// The blob might be limited to an arbitrary size. All attempts to write data40// are ignored and the error condition is remembered once the limit is reached.41// Such an approach allows us to simplify the code by delaying error reporting42// and doing it at a convenient time.43namespace {44class ContiguousBlobAccumulator {45 const uint64_t InitialOffset;46 const uint64_t MaxSize;47 48 SmallVector<char, 128> Buf;49 raw_svector_ostream OS;50 Error ReachedLimitErr = Error::success();51 52 bool checkLimit(uint64_t Size) {53 if (!ReachedLimitErr && getOffset() + Size <= MaxSize)54 return true;55 if (!ReachedLimitErr)56 ReachedLimitErr = createStringError(errc::invalid_argument,57 "reached the output size limit");58 return false;59 }60 61public:62 ContiguousBlobAccumulator(uint64_t BaseOffset, uint64_t SizeLimit)63 : InitialOffset(BaseOffset), MaxSize(SizeLimit), OS(Buf) {}64 65 uint64_t tell() const { return OS.tell(); }66 uint64_t getOffset() const { return InitialOffset + OS.tell(); }67 void writeBlobToStream(raw_ostream &Out) const { Out << OS.str(); }68 69 Error takeLimitError() {70 // Request to write 0 bytes to check we did not reach the limit.71 checkLimit(0);72 return std::move(ReachedLimitErr);73 }74 75 /// \returns The new offset.76 uint64_t padToAlignment(unsigned Align) {77 uint64_t CurrentOffset = getOffset();78 if (ReachedLimitErr)79 return CurrentOffset;80 81 uint64_t AlignedOffset = alignTo(CurrentOffset, Align == 0 ? 1 : Align);82 uint64_t PaddingSize = AlignedOffset - CurrentOffset;83 if (!checkLimit(PaddingSize))84 return CurrentOffset;85 86 writeZeros(PaddingSize);87 return AlignedOffset;88 }89 90 raw_ostream *getRawOS(uint64_t Size) {91 if (checkLimit(Size))92 return &OS;93 return nullptr;94 }95 96 void writeAsBinary(const yaml::BinaryRef &Bin, uint64_t N = UINT64_MAX) {97 if (!checkLimit(Bin.binary_size()))98 return;99 Bin.writeAsBinary(OS, N);100 }101 102 void writeZeros(uint64_t Num) {103 if (checkLimit(Num))104 OS.write_zeros(Num);105 }106 107 void write(const char *Ptr, size_t Size) {108 if (checkLimit(Size))109 OS.write(Ptr, Size);110 }111 112 void write(unsigned char C) {113 if (checkLimit(1))114 OS.write(C);115 }116 117 unsigned writeULEB128(uint64_t Val) {118 if (!checkLimit(sizeof(uint64_t)))119 return 0;120 return encodeULEB128(Val, OS);121 }122 123 unsigned writeSLEB128(int64_t Val) {124 if (!checkLimit(10))125 return 0;126 return encodeSLEB128(Val, OS);127 }128 129 template <typename T> void write(T Val, llvm::endianness E) {130 if (checkLimit(sizeof(T)))131 support::endian::write<T>(OS, Val, E);132 }133 134 void updateDataAt(uint64_t Pos, void *Data, size_t Size) {135 assert(Pos >= InitialOffset && Pos + Size <= getOffset());136 memcpy(&Buf[Pos - InitialOffset], Data, Size);137 }138};139 140// Used to keep track of section and symbol names, so that in the YAML file141// sections and symbols can be referenced by name instead of by index.142class NameToIdxMap {143 StringMap<unsigned> Map;144 145public:146 /// \Returns false if name is already present in the map.147 bool addName(StringRef Name, unsigned Ndx) {148 return Map.insert({Name, Ndx}).second;149 }150 /// \Returns false if name is not present in the map.151 bool lookup(StringRef Name, unsigned &Idx) const {152 auto I = Map.find(Name);153 if (I == Map.end())154 return false;155 Idx = I->getValue();156 return true;157 }158 /// Asserts if name is not present in the map.159 unsigned get(StringRef Name) const {160 unsigned Idx;161 if (lookup(Name, Idx))162 return Idx;163 assert(false && "Expected section not found in index");164 return 0;165 }166 unsigned size() const { return Map.size(); }167};168 169namespace {170struct Fragment {171 uint64_t Offset;172 uint64_t Size;173 uint32_t Type;174 uint64_t AddrAlign;175};176} // namespace177 178/// "Single point of truth" for the ELF file construction.179/// TODO: This class still has a ways to go before it is truly a "single180/// point of truth".181template <class ELFT> class ELFState {182 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)183 184 enum class SymtabType { Static, Dynamic };185 186 /// The future symbol table string section.187 StringTableBuilder DotStrtab{StringTableBuilder::ELF};188 189 /// The future section header string table section, if a unique string table190 /// is needed. Don't reference this variable direectly: use the191 /// ShStrtabStrings member instead.192 StringTableBuilder DotShStrtab{StringTableBuilder::ELF};193 194 /// The future dynamic symbol string section.195 StringTableBuilder DotDynstr{StringTableBuilder::ELF};196 197 /// The name of the section header string table section. If it is .strtab or198 /// .dynstr, the section header strings will be written to the same string199 /// table as the static/dynamic symbols respectively. Otherwise a dedicated200 /// section will be created with that name.201 StringRef SectionHeaderStringTableName = ".shstrtab";202 StringTableBuilder *ShStrtabStrings = &DotShStrtab;203 204 NameToIdxMap SN2I;205 NameToIdxMap SymN2I;206 NameToIdxMap DynSymN2I;207 ELFYAML::Object &Doc;208 209 std::vector<std::pair<Elf_Shdr *, ELFYAML::Section>>210 SectionHeadersOverrideHelper;211 212 StringSet<> ExcludedSectionHeaders;213 214 uint64_t LocationCounter = 0;215 bool HasError = false;216 yaml::ErrorHandler ErrHandler;217 void reportError(const Twine &Msg);218 void reportError(Error Err);219 220 std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,221 const StringTableBuilder &Strtab);222 unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = "");223 unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic);224 225 void buildSectionIndex();226 void buildSymbolIndexes();227 void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders);228 bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header,229 StringRef SecName, ELFYAML::Section *YAMLSec);230 void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,231 ContiguousBlobAccumulator &CBA);232 void overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders);233 void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType,234 ContiguousBlobAccumulator &CBA,235 ELFYAML::Section *YAMLSec);236 void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,237 StringTableBuilder &STB,238 ContiguousBlobAccumulator &CBA,239 ELFYAML::Section *YAMLSec);240 void initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,241 ContiguousBlobAccumulator &CBA,242 ELFYAML::Section *YAMLSec);243 void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,244 std::vector<Elf_Shdr> &SHeaders);245 246 std::vector<Fragment>247 getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,248 ArrayRef<typename ELFT::Shdr> SHeaders);249 250 void finalizeStrings();251 void writeELFHeader(raw_ostream &OS);252 void writeSectionContent(Elf_Shdr &SHeader,253 const ELFYAML::NoBitsSection &Section,254 ContiguousBlobAccumulator &CBA);255 void writeSectionContent(Elf_Shdr &SHeader,256 const ELFYAML::RawContentSection &Section,257 ContiguousBlobAccumulator &CBA);258 void writeSectionContent(Elf_Shdr &SHeader,259 const ELFYAML::RelocationSection &Section,260 ContiguousBlobAccumulator &CBA);261 void writeSectionContent(Elf_Shdr &SHeader,262 const ELFYAML::RelrSection &Section,263 ContiguousBlobAccumulator &CBA);264 void writeSectionContent(Elf_Shdr &SHeader,265 const ELFYAML::GroupSection &Group,266 ContiguousBlobAccumulator &CBA);267 void writeSectionContent(Elf_Shdr &SHeader,268 const ELFYAML::SymtabShndxSection &Shndx,269 ContiguousBlobAccumulator &CBA);270 void writeSectionContent(Elf_Shdr &SHeader,271 const ELFYAML::SymverSection &Section,272 ContiguousBlobAccumulator &CBA);273 void writeSectionContent(Elf_Shdr &SHeader,274 const ELFYAML::VerneedSection &Section,275 ContiguousBlobAccumulator &CBA);276 void writeSectionContent(Elf_Shdr &SHeader,277 const ELFYAML::VerdefSection &Section,278 ContiguousBlobAccumulator &CBA);279 void writeSectionContent(Elf_Shdr &SHeader,280 const ELFYAML::ARMIndexTableSection &Section,281 ContiguousBlobAccumulator &CBA);282 void writeSectionContent(Elf_Shdr &SHeader,283 const ELFYAML::MipsABIFlags &Section,284 ContiguousBlobAccumulator &CBA);285 void writeSectionContent(Elf_Shdr &SHeader,286 const ELFYAML::DynamicSection &Section,287 ContiguousBlobAccumulator &CBA);288 void writeSectionContent(Elf_Shdr &SHeader,289 const ELFYAML::StackSizesSection &Section,290 ContiguousBlobAccumulator &CBA);291 void writeSectionContent(Elf_Shdr &SHeader,292 const ELFYAML::BBAddrMapSection &Section,293 ContiguousBlobAccumulator &CBA);294 void writeSectionContent(Elf_Shdr &SHeader,295 const ELFYAML::HashSection &Section,296 ContiguousBlobAccumulator &CBA);297 void writeSectionContent(Elf_Shdr &SHeader,298 const ELFYAML::AddrsigSection &Section,299 ContiguousBlobAccumulator &CBA);300 void writeSectionContent(Elf_Shdr &SHeader,301 const ELFYAML::NoteSection &Section,302 ContiguousBlobAccumulator &CBA);303 void writeSectionContent(Elf_Shdr &SHeader,304 const ELFYAML::GnuHashSection &Section,305 ContiguousBlobAccumulator &CBA);306 void writeSectionContent(Elf_Shdr &SHeader,307 const ELFYAML::LinkerOptionsSection &Section,308 ContiguousBlobAccumulator &CBA);309 void writeSectionContent(Elf_Shdr &SHeader,310 const ELFYAML::DependentLibrariesSection &Section,311 ContiguousBlobAccumulator &CBA);312 void writeSectionContent(Elf_Shdr &SHeader,313 const ELFYAML::CallGraphProfileSection &Section,314 ContiguousBlobAccumulator &CBA);315 316 void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA);317 318 ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH);319 320 void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec);321 322 DenseMap<StringRef, size_t> buildSectionHeaderReorderMap();323 324 BumpPtrAllocator StringAlloc;325 uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,326 std::optional<llvm::yaml::Hex64> Offset);327 328 uint64_t getSectionNameOffset(StringRef Name);329 330public:331 static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc,332 yaml::ErrorHandler EH, uint64_t MaxSize);333};334} // end anonymous namespace335 336template <class T> static size_t arrayDataSize(ArrayRef<T> A) {337 return A.size() * sizeof(T);338}339 340template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) {341 OS.write((const char *)A.data(), arrayDataSize(A));342}343 344template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }345 346template <class ELFT>347ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)348 : Doc(D), ErrHandler(EH) {349 // The input may explicitly request to store the section header table strings350 // in the same string table as dynamic or static symbol names. Set the351 // ShStrtabStrings member accordingly.352 if (Doc.Header.SectionHeaderStringTable) {353 SectionHeaderStringTableName = *Doc.Header.SectionHeaderStringTable;354 if (*Doc.Header.SectionHeaderStringTable == ".strtab")355 ShStrtabStrings = &DotStrtab;356 else if (*Doc.Header.SectionHeaderStringTable == ".dynstr")357 ShStrtabStrings = &DotDynstr;358 // Otherwise, the unique table will be used.359 }360 361 std::vector<ELFYAML::Section *> Sections = Doc.getSections();362 // Insert SHT_NULL section implicitly when it is not defined in YAML.363 if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL)364 Doc.Chunks.insert(365 Doc.Chunks.begin(),366 std::make_unique<ELFYAML::Section>(367 ELFYAML::Chunk::ChunkKind::RawContent, /*IsImplicit=*/true));368 369 StringSet<> DocSections;370 ELFYAML::SectionHeaderTable *SecHdrTable = nullptr;371 for (size_t I = 0; I < Doc.Chunks.size(); ++I) {372 const std::unique_ptr<ELFYAML::Chunk> &C = Doc.Chunks[I];373 374 // We might have an explicit section header table declaration.375 if (auto S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) {376 if (SecHdrTable)377 reportError("multiple section header tables are not allowed");378 SecHdrTable = S;379 continue;380 }381 382 // We add a technical suffix for each unnamed section/fill. It does not383 // affect the output, but allows us to map them by name in the code and384 // report better error messages.385 if (C->Name.empty()) {386 std::string NewName = ELFYAML::appendUniqueSuffix(387 /*Name=*/"", "index " + Twine(I));388 C->Name = StringRef(NewName).copy(StringAlloc);389 assert(ELFYAML::dropUniqueSuffix(C->Name).empty());390 }391 392 if (!DocSections.insert(C->Name).second)393 reportError("repeated section/fill name: '" + C->Name +394 "' at YAML section/fill number " + Twine(I));395 }396 397 SmallSetVector<StringRef, 8> ImplicitSections;398 if (Doc.DynamicSymbols) {399 if (SectionHeaderStringTableName == ".dynsym")400 reportError("cannot use '.dynsym' as the section header name table when "401 "there are dynamic symbols");402 ImplicitSections.insert(".dynsym");403 ImplicitSections.insert(".dynstr");404 }405 if (Doc.Symbols) {406 if (SectionHeaderStringTableName == ".symtab")407 reportError("cannot use '.symtab' as the section header name table when "408 "there are symbols");409 ImplicitSections.insert(".symtab");410 }411 if (Doc.DWARF)412 for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) {413 std::string SecName = ("." + DebugSecName).str();414 // TODO: For .debug_str it should be possible to share the string table,415 // in the same manner as the symbol string tables.416 if (SectionHeaderStringTableName == SecName)417 reportError("cannot use '" + SecName +418 "' as the section header name table when it is needed for "419 "DWARF output");420 ImplicitSections.insert(StringRef(SecName).copy(StringAlloc));421 }422 // TODO: Only create the .strtab here if any symbols have been requested.423 ImplicitSections.insert(".strtab");424 if (!SecHdrTable || !SecHdrTable->NoHeaders.value_or(false))425 ImplicitSections.insert(SectionHeaderStringTableName);426 427 // Insert placeholders for implicit sections that are not428 // defined explicitly in YAML.429 for (StringRef SecName : ImplicitSections) {430 if (DocSections.count(SecName))431 continue;432 433 std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>(434 ELFYAML::Chunk::ChunkKind::RawContent, true /*IsImplicit*/);435 Sec->Name = SecName;436 437 if (SecName == SectionHeaderStringTableName)438 Sec->Type = ELF::SHT_STRTAB;439 else if (SecName == ".dynsym")440 Sec->Type = ELF::SHT_DYNSYM;441 else if (SecName == ".symtab")442 Sec->Type = ELF::SHT_SYMTAB;443 else444 Sec->Type = ELF::SHT_STRTAB;445 446 // When the section header table is explicitly defined at the end of the447 // sections list, it is reasonable to assume that the user wants to reorder448 // section headers, but still wants to place the section header table after449 // all sections, like it normally happens. In this case we want to insert450 // other implicit sections right before the section header table.451 if (Doc.Chunks.back().get() == SecHdrTable)452 Doc.Chunks.insert(Doc.Chunks.end() - 1, std::move(Sec));453 else454 Doc.Chunks.push_back(std::move(Sec));455 }456 457 // Insert the section header table implicitly at the end, when it is not458 // explicitly defined.459 if (!SecHdrTable)460 Doc.Chunks.push_back(461 std::make_unique<ELFYAML::SectionHeaderTable>(/*IsImplicit=*/true));462}463 464template <class ELFT>465void ELFState<ELFT>::writeELFHeader(raw_ostream &OS) {466 using namespace llvm::ELF;467 468 Elf_Ehdr Header;469 zero(Header);470 Header.e_ident[EI_MAG0] = 0x7f;471 Header.e_ident[EI_MAG1] = 'E';472 Header.e_ident[EI_MAG2] = 'L';473 Header.e_ident[EI_MAG3] = 'F';474 Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;475 Header.e_ident[EI_DATA] = Doc.Header.Data;476 Header.e_ident[EI_VERSION] = EV_CURRENT;477 Header.e_ident[EI_OSABI] = Doc.Header.OSABI;478 Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion;479 Header.e_type = Doc.Header.Type;480 481 if (Doc.Header.Machine)482 Header.e_machine = *Doc.Header.Machine;483 else484 Header.e_machine = EM_NONE;485 486 Header.e_version = EV_CURRENT;487 Header.e_entry = Doc.Header.Entry;488 if (Doc.Header.Flags)489 Header.e_flags = *Doc.Header.Flags;490 else491 Header.e_flags = 0;492 493 Header.e_ehsize = sizeof(Elf_Ehdr);494 495 if (Doc.Header.EPhOff)496 Header.e_phoff = *Doc.Header.EPhOff;497 else if (!Doc.ProgramHeaders.empty())498 Header.e_phoff = sizeof(Header);499 else500 Header.e_phoff = 0;501 502 if (Doc.Header.EPhEntSize)503 Header.e_phentsize = *Doc.Header.EPhEntSize;504 else if (!Doc.ProgramHeaders.empty())505 Header.e_phentsize = sizeof(Elf_Phdr);506 else507 Header.e_phentsize = 0;508 509 if (Doc.Header.EPhNum)510 Header.e_phnum = *Doc.Header.EPhNum;511 else if (!Doc.ProgramHeaders.empty())512 Header.e_phnum = Doc.ProgramHeaders.size();513 else514 Header.e_phnum = 0;515 516 Header.e_shentsize = Doc.Header.EShEntSize ? (uint16_t)*Doc.Header.EShEntSize517 : sizeof(Elf_Shdr);518 519 const ELFYAML::SectionHeaderTable &SectionHeaders =520 Doc.getSectionHeaderTable();521 522 if (Doc.Header.EShOff)523 Header.e_shoff = *Doc.Header.EShOff;524 else if (SectionHeaders.Offset)525 Header.e_shoff = *SectionHeaders.Offset;526 else527 Header.e_shoff = 0;528 529 if (Doc.Header.EShNum)530 Header.e_shnum = *Doc.Header.EShNum;531 else532 Header.e_shnum = SectionHeaders.getNumHeaders(Doc.getSections().size());533 534 if (Doc.Header.EShStrNdx)535 Header.e_shstrndx = *Doc.Header.EShStrNdx;536 else if (SectionHeaders.Offset &&537 !ExcludedSectionHeaders.count(SectionHeaderStringTableName))538 Header.e_shstrndx = SN2I.get(SectionHeaderStringTableName);539 else540 Header.e_shstrndx = 0;541 542 OS.write((const char *)&Header, sizeof(Header));543}544 545template <class ELFT>546void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) {547 DenseMap<StringRef, size_t> NameToIndex;548 for (size_t I = 0, E = Doc.Chunks.size(); I != E; ++I) {549 NameToIndex[Doc.Chunks[I]->Name] = I + 1;550 }551 552 for (size_t I = 0, E = Doc.ProgramHeaders.size(); I != E; ++I) {553 ELFYAML::ProgramHeader &YamlPhdr = Doc.ProgramHeaders[I];554 Elf_Phdr Phdr;555 zero(Phdr);556 Phdr.p_type = YamlPhdr.Type;557 Phdr.p_flags = YamlPhdr.Flags;558 Phdr.p_vaddr = YamlPhdr.VAddr;559 Phdr.p_paddr = YamlPhdr.PAddr;560 PHeaders.push_back(Phdr);561 562 if (!YamlPhdr.FirstSec && !YamlPhdr.LastSec)563 continue;564 565 // Get the index of the section, or 0 in the case when the section doesn't exist.566 size_t First = NameToIndex[*YamlPhdr.FirstSec];567 if (!First)568 reportError("unknown section or fill referenced: '" + *YamlPhdr.FirstSec +569 "' by the 'FirstSec' key of the program header with index " +570 Twine(I));571 size_t Last = NameToIndex[*YamlPhdr.LastSec];572 if (!Last)573 reportError("unknown section or fill referenced: '" + *YamlPhdr.LastSec +574 "' by the 'LastSec' key of the program header with index " +575 Twine(I));576 if (!First || !Last)577 continue;578 579 if (First > Last)580 reportError("program header with index " + Twine(I) +581 ": the section index of " + *YamlPhdr.FirstSec +582 " is greater than the index of " + *YamlPhdr.LastSec);583 584 for (size_t I = First; I <= Last; ++I)585 YamlPhdr.Chunks.push_back(Doc.Chunks[I - 1].get());586 }587}588 589template <class ELFT>590unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec,591 StringRef LocSym) {592 assert(LocSec.empty() || LocSym.empty());593 594 unsigned Index;595 if (!SN2I.lookup(S, Index) && !to_integer(S, Index)) {596 if (!LocSym.empty())597 reportError("unknown section referenced: '" + S + "' by YAML symbol '" +598 LocSym + "'");599 else600 reportError("unknown section referenced: '" + S + "' by YAML section '" +601 LocSec + "'");602 return 0;603 }604 605 const ELFYAML::SectionHeaderTable &SectionHeaders =606 Doc.getSectionHeaderTable();607 if (SectionHeaders.IsImplicit ||608 (SectionHeaders.NoHeaders && !*SectionHeaders.NoHeaders) ||609 SectionHeaders.isDefault())610 return Index;611 612 assert(!SectionHeaders.NoHeaders.value_or(false) || !SectionHeaders.Sections);613 size_t FirstExcluded =614 SectionHeaders.Sections ? SectionHeaders.Sections->size() : 0;615 if (Index > FirstExcluded) {616 if (LocSym.empty())617 reportError("unable to link '" + LocSec + "' to excluded section '" + S +618 "'");619 else620 reportError("excluded section referenced: '" + S + "' by symbol '" +621 LocSym + "'");622 }623 return Index;624}625 626template <class ELFT>627unsigned ELFState<ELFT>::toSymbolIndex(StringRef S, StringRef LocSec,628 bool IsDynamic) {629 const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I;630 unsigned Index;631 // Here we try to look up S in the symbol table. If it is not there,632 // treat its value as a symbol index.633 if (!SymMap.lookup(S, Index) && !to_integer(S, Index)) {634 reportError("unknown symbol referenced: '" + S + "' by YAML section '" +635 LocSec + "'");636 return 0;637 }638 return Index;639}640 641template <class ELFT>642static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) {643 if (!From)644 return;645 if (From->ShAddrAlign)646 To.sh_addralign = *From->ShAddrAlign;647 if (From->ShFlags)648 To.sh_flags = *From->ShFlags;649 if (From->ShName)650 To.sh_name = *From->ShName;651 if (From->ShOffset)652 To.sh_offset = *From->ShOffset;653 if (From->ShSize)654 To.sh_size = *From->ShSize;655 if (From->ShType)656 To.sh_type = *From->ShType;657}658 659template <class ELFT>660bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA,661 Elf_Shdr &Header, StringRef SecName,662 ELFYAML::Section *YAMLSec) {663 // Check if the header was already initialized.664 if (Header.sh_offset)665 return false;666 667 if (SecName == ".strtab")668 initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec);669 else if (SecName == ".dynstr")670 initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec);671 else if (SecName == SectionHeaderStringTableName)672 initStrtabSectionHeader(Header, SecName, *ShStrtabStrings, CBA, YAMLSec);673 else if (SecName == ".symtab")674 initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec);675 else if (SecName == ".dynsym")676 initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec);677 else if (SecName.starts_with(".debug_")) {678 // If a ".debug_*" section's type is a preserved one, e.g., SHT_DYNAMIC, we679 // will not treat it as a debug section.680 if (YAMLSec && !isa<ELFYAML::RawContentSection>(YAMLSec))681 return false;682 initDWARFSectionHeader(Header, SecName, CBA, YAMLSec);683 } else684 return false;685 686 LocationCounter += Header.sh_size;687 688 // Override section fields if requested.689 overrideFields<ELFT>(YAMLSec, Header);690 return true;691}692 693constexpr char SuffixStart = '(';694constexpr char SuffixEnd = ')';695 696std::string llvm::ELFYAML::appendUniqueSuffix(StringRef Name,697 const Twine &Msg) {698 // Do not add a space when a Name is empty.699 std::string Ret = Name.empty() ? "" : Name.str() + ' ';700 return Ret + (Twine(SuffixStart) + Msg + Twine(SuffixEnd)).str();701}702 703StringRef llvm::ELFYAML::dropUniqueSuffix(StringRef S) {704 if (S.empty() || S.back() != SuffixEnd)705 return S;706 707 // A special case for empty names. See appendUniqueSuffix() above.708 size_t SuffixPos = S.rfind(SuffixStart);709 if (SuffixPos == 0)710 return "";711 712 if (SuffixPos == StringRef::npos || S[SuffixPos - 1] != ' ')713 return S;714 return S.substr(0, SuffixPos - 1);715}716 717template <class ELFT>718uint64_t ELFState<ELFT>::getSectionNameOffset(StringRef Name) {719 // If a section is excluded from section headers, we do not save its name in720 // the string table.721 if (ExcludedSectionHeaders.count(Name))722 return 0;723 return ShStrtabStrings->getOffset(Name);724}725 726static uint64_t writeContent(ContiguousBlobAccumulator &CBA,727 const std::optional<yaml::BinaryRef> &Content,728 const std::optional<llvm::yaml::Hex64> &Size) {729 size_t ContentSize = 0;730 if (Content) {731 CBA.writeAsBinary(*Content);732 ContentSize = Content->binary_size();733 }734 735 if (!Size)736 return ContentSize;737 738 CBA.writeZeros(*Size - ContentSize);739 return *Size;740}741 742static StringRef getDefaultLinkSec(unsigned SecType) {743 switch (SecType) {744 case ELF::SHT_REL:745 case ELF::SHT_RELA:746 case ELF::SHT_GROUP:747 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:748 case ELF::SHT_LLVM_ADDRSIG:749 return ".symtab";750 case ELF::SHT_GNU_versym:751 case ELF::SHT_HASH:752 case ELF::SHT_GNU_HASH:753 return ".dynsym";754 case ELF::SHT_DYNSYM:755 case ELF::SHT_GNU_verdef:756 case ELF::SHT_GNU_verneed:757 return ".dynstr";758 case ELF::SHT_SYMTAB:759 return ".strtab";760 default:761 return "";762 }763}764 765template <class ELFT>766void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,767 ContiguousBlobAccumulator &CBA) {768 // Ensure SHN_UNDEF entry is present. An all-zero section header is a769 // valid SHN_UNDEF entry since SHT_NULL == 0.770 SHeaders.resize(Doc.getSections().size());771 772 for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) {773 if (ELFYAML::Fill *S = dyn_cast<ELFYAML::Fill>(D.get())) {774 S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset);775 writeFill(*S, CBA);776 LocationCounter += S->Size;777 continue;778 }779 780 if (ELFYAML::SectionHeaderTable *S =781 dyn_cast<ELFYAML::SectionHeaderTable>(D.get())) {782 if (S->NoHeaders.value_or(false))783 continue;784 785 if (!S->Offset)786 S->Offset = alignToOffset(CBA, sizeof(typename ELFT::uint),787 /*Offset=*/std::nullopt);788 else789 S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset);790 791 uint64_t Size = S->getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr);792 // The full section header information might be not available here, so793 // fill the space with zeroes as a placeholder.794 CBA.writeZeros(Size);795 LocationCounter += Size;796 continue;797 }798 799 ELFYAML::Section *Sec = cast<ELFYAML::Section>(D.get());800 bool IsFirstUndefSection = Sec == Doc.getSections().front();801 if (IsFirstUndefSection && Sec->IsImplicit)802 continue;803 804 Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->Name)];805 if (Sec->Link) {806 SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name);807 } else {808 StringRef LinkSec = getDefaultLinkSec(Sec->Type);809 unsigned Link = 0;810 if (!LinkSec.empty() && !ExcludedSectionHeaders.count(LinkSec) &&811 SN2I.lookup(LinkSec, Link))812 SHeader.sh_link = Link;813 }814 815 if (Sec->EntSize)816 SHeader.sh_entsize = *Sec->EntSize;817 else818 SHeader.sh_entsize = ELFYAML::getDefaultShEntSize<ELFT>(819 Doc.Header.Machine.value_or(ELF::EM_NONE), Sec->Type, Sec->Name);820 821 // We have a few sections like string or symbol tables that are usually822 // added implicitly to the end. However, if they are explicitly specified823 // in the YAML, we need to write them here. This ensures the file offset824 // remains correct.825 if (initImplicitHeader(CBA, SHeader, Sec->Name,826 Sec->IsImplicit ? nullptr : Sec))827 continue;828 829 assert(Sec && "It can't be null unless it is an implicit section. But all "830 "implicit sections should already have been handled above.");831 832 SHeader.sh_name =833 getSectionNameOffset(ELFYAML::dropUniqueSuffix(Sec->Name));834 SHeader.sh_type = Sec->Type;835 if (Sec->Flags)836 SHeader.sh_flags = *Sec->Flags;837 SHeader.sh_addralign = Sec->AddressAlign;838 839 // Set the offset for all sections, except the SHN_UNDEF section with index840 // 0 when not explicitly requested.841 if (!IsFirstUndefSection || Sec->Offset)842 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, Sec->Offset);843 844 assignSectionAddress(SHeader, Sec);845 846 if (IsFirstUndefSection) {847 if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Sec)) {848 // We do not write any content for special SHN_UNDEF section.849 if (RawSec->Size)850 SHeader.sh_size = *RawSec->Size;851 if (RawSec->Info)852 SHeader.sh_info = *RawSec->Info;853 }854 855 LocationCounter += SHeader.sh_size;856 SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});857 continue;858 }859 860 if (!isa<ELFYAML::NoBitsSection>(Sec) && (Sec->Content || Sec->Size))861 SHeader.sh_size = writeContent(CBA, Sec->Content, Sec->Size);862 863 if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) {864 writeSectionContent(SHeader, *S, CBA);865 } else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Sec)) {866 writeSectionContent(SHeader, *S, CBA);867 } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) {868 writeSectionContent(SHeader, *S, CBA);869 } else if (auto S = dyn_cast<ELFYAML::RelrSection>(Sec)) {870 writeSectionContent(SHeader, *S, CBA);871 } else if (auto S = dyn_cast<ELFYAML::GroupSection>(Sec)) {872 writeSectionContent(SHeader, *S, CBA);873 } else if (auto S = dyn_cast<ELFYAML::ARMIndexTableSection>(Sec)) {874 writeSectionContent(SHeader, *S, CBA);875 } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) {876 writeSectionContent(SHeader, *S, CBA);877 } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec)) {878 writeSectionContent(SHeader, *S, CBA);879 } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec)) {880 writeSectionContent(SHeader, *S, CBA);881 } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec)) {882 writeSectionContent(SHeader, *S, CBA);883 } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec)) {884 writeSectionContent(SHeader, *S, CBA);885 } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec)) {886 writeSectionContent(SHeader, *S, CBA);887 } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Sec)) {888 writeSectionContent(SHeader, *S, CBA);889 } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) {890 writeSectionContent(SHeader, *S, CBA);891 } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) {892 writeSectionContent(SHeader, *S, CBA);893 } else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Sec)) {894 writeSectionContent(SHeader, *S, CBA);895 } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) {896 writeSectionContent(SHeader, *S, CBA);897 } else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Sec)) {898 writeSectionContent(SHeader, *S, CBA);899 } else if (auto S = dyn_cast<ELFYAML::DependentLibrariesSection>(Sec)) {900 writeSectionContent(SHeader, *S, CBA);901 } else if (auto S = dyn_cast<ELFYAML::CallGraphProfileSection>(Sec)) {902 writeSectionContent(SHeader, *S, CBA);903 } else if (auto S = dyn_cast<ELFYAML::BBAddrMapSection>(Sec)) {904 writeSectionContent(SHeader, *S, CBA);905 } else {906 llvm_unreachable("Unknown section type");907 }908 909 LocationCounter += SHeader.sh_size;910 SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});911 }912}913 914template <class ELFT>915void ELFState<ELFT>::overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders) {916 for (std::pair<Elf_Shdr *, ELFYAML::Section> &HeaderAndSec :917 SectionHeadersOverrideHelper)918 overrideFields<ELFT>(&HeaderAndSec.second, *HeaderAndSec.first);919}920 921template <class ELFT>922void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader,923 ELFYAML::Section *YAMLSec) {924 if (YAMLSec && YAMLSec->Address) {925 SHeader.sh_addr = *YAMLSec->Address;926 LocationCounter = *YAMLSec->Address;927 return;928 }929 930 // sh_addr represents the address in the memory image of a process. Sections931 // in a relocatable object file or non-allocatable sections do not need932 // sh_addr assignment.933 if (Doc.Header.Type.value == ELF::ET_REL ||934 !(SHeader.sh_flags & ELF::SHF_ALLOC))935 return;936 937 LocationCounter =938 alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1);939 SHeader.sh_addr = LocationCounter;940}941 942static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) {943 for (size_t I = 0; I < Symbols.size(); ++I)944 if (Symbols[I].Binding.value != ELF::STB_LOCAL)945 return I;946 return Symbols.size();947}948 949template <class ELFT>950std::vector<typename ELFT::Sym>951ELFState<ELFT>::toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,952 const StringTableBuilder &Strtab) {953 std::vector<Elf_Sym> Ret;954 Ret.resize(Symbols.size() + 1);955 956 size_t I = 0;957 for (const ELFYAML::Symbol &Sym : Symbols) {958 Elf_Sym &Symbol = Ret[++I];959 960 // If NameIndex, which contains the name offset, is explicitly specified, we961 // use it. This is useful for preparing broken objects. Otherwise, we add962 // the specified Name to the string table builder to get its offset.963 if (Sym.StName)964 Symbol.st_name = *Sym.StName;965 else if (!Sym.Name.empty())966 Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name));967 968 Symbol.setBindingAndType(Sym.Binding, Sym.Type);969 if (Sym.Section)970 Symbol.st_shndx = toSectionIndex(*Sym.Section, "", Sym.Name);971 else if (Sym.Index)972 Symbol.st_shndx = *Sym.Index;973 974 Symbol.st_value = Sym.Value.value_or(yaml::Hex64(0));975 Symbol.st_other = Sym.Other.value_or(0);976 Symbol.st_size = Sym.Size.value_or(yaml::Hex64(0));977 }978 979 return Ret;980}981 982template <class ELFT>983void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,984 SymtabType STType,985 ContiguousBlobAccumulator &CBA,986 ELFYAML::Section *YAMLSec) {987 988 bool IsStatic = STType == SymtabType::Static;989 ArrayRef<ELFYAML::Symbol> Symbols;990 if (IsStatic && Doc.Symbols)991 Symbols = *Doc.Symbols;992 else if (!IsStatic && Doc.DynamicSymbols)993 Symbols = *Doc.DynamicSymbols;994 995 ELFYAML::RawContentSection *RawSec =996 dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);997 if (RawSec && (RawSec->Content || RawSec->Size)) {998 bool HasSymbolsDescription =999 (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols);1000 if (HasSymbolsDescription) {1001 StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`");1002 if (RawSec->Content)1003 reportError("cannot specify both `Content` and " + Property +1004 " for symbol table section '" + RawSec->Name + "'");1005 if (RawSec->Size)1006 reportError("cannot specify both `Size` and " + Property +1007 " for symbol table section '" + RawSec->Name + "'");1008 return;1009 }1010 }1011 1012 SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym");1013 1014 if (YAMLSec)1015 SHeader.sh_type = YAMLSec->Type;1016 else1017 SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM;1018 1019 if (YAMLSec && YAMLSec->Flags)1020 SHeader.sh_flags = *YAMLSec->Flags;1021 else if (!IsStatic)1022 SHeader.sh_flags = ELF::SHF_ALLOC;1023 1024 // If the symbol table section is explicitly described in the YAML1025 // then we should set the fields requested.1026 SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info)1027 : findFirstNonGlobal(Symbols) + 1;1028 SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8;1029 1030 assignSectionAddress(SHeader, YAMLSec);1031 1032 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,1033 RawSec ? RawSec->Offset : std::nullopt);1034 1035 if (RawSec && (RawSec->Content || RawSec->Size)) {1036 assert(Symbols.empty());1037 SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size);1038 return;1039 }1040 1041 std::vector<Elf_Sym> Syms =1042 toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr);1043 SHeader.sh_size = Syms.size() * sizeof(Elf_Sym);1044 CBA.write((const char *)Syms.data(), SHeader.sh_size);1045}1046 1047template <class ELFT>1048void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,1049 StringTableBuilder &STB,1050 ContiguousBlobAccumulator &CBA,1051 ELFYAML::Section *YAMLSec) {1052 SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name));1053 SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB;1054 SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1;1055 1056 ELFYAML::RawContentSection *RawSec =1057 dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);1058 1059 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,1060 YAMLSec ? YAMLSec->Offset : std::nullopt);1061 1062 if (RawSec && (RawSec->Content || RawSec->Size)) {1063 SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size);1064 } else {1065 if (raw_ostream *OS = CBA.getRawOS(STB.getSize()))1066 STB.write(*OS);1067 SHeader.sh_size = STB.getSize();1068 }1069 1070 if (RawSec && RawSec->Info)1071 SHeader.sh_info = *RawSec->Info;1072 1073 if (YAMLSec && YAMLSec->Flags)1074 SHeader.sh_flags = *YAMLSec->Flags;1075 else if (Name == ".dynstr")1076 SHeader.sh_flags = ELF::SHF_ALLOC;1077 1078 assignSectionAddress(SHeader, YAMLSec);1079}1080 1081static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) {1082 SetVector<StringRef> DebugSecNames = DWARF.getNonEmptySectionNames();1083 return Name.consume_front(".") && DebugSecNames.count(Name);1084}1085 1086template <class ELFT>1087Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name,1088 const DWARFYAML::Data &DWARF,1089 ContiguousBlobAccumulator &CBA) {1090 // We are unable to predict the size of debug data, so we request to write 01091 // bytes. This should always return us an output stream unless CBA is already1092 // in an error state.1093 raw_ostream *OS = CBA.getRawOS(0);1094 if (!OS)1095 return 0;1096 1097 uint64_t BeginOffset = CBA.tell();1098 1099 auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name.substr(1));1100 if (Error Err = EmitFunc(*OS, DWARF))1101 return std::move(Err);1102 1103 return CBA.tell() - BeginOffset;1104}1105 1106template <class ELFT>1107void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,1108 ContiguousBlobAccumulator &CBA,1109 ELFYAML::Section *YAMLSec) {1110 SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name));1111 SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS;1112 SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1;1113 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,1114 YAMLSec ? YAMLSec->Offset : std::nullopt);1115 1116 ELFYAML::RawContentSection *RawSec =1117 dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);1118 if (Doc.DWARF && shouldEmitDWARF(*Doc.DWARF, Name)) {1119 if (RawSec && (RawSec->Content || RawSec->Size))1120 reportError("cannot specify section '" + Name +1121 "' contents in the 'DWARF' entry and the 'Content' "1122 "or 'Size' in the 'Sections' entry at the same time");1123 else {1124 if (Expected<uint64_t> ShSizeOrErr =1125 emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA))1126 SHeader.sh_size = *ShSizeOrErr;1127 else1128 reportError(ShSizeOrErr.takeError());1129 }1130 } else if (RawSec)1131 SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size);1132 else1133 llvm_unreachable("debug sections can only be initialized via the 'DWARF' "1134 "entry or a RawContentSection");1135 1136 if (RawSec && RawSec->Info)1137 SHeader.sh_info = *RawSec->Info;1138 1139 if (YAMLSec && YAMLSec->Flags)1140 SHeader.sh_flags = *YAMLSec->Flags;1141 else if (Name == ".debug_str")1142 SHeader.sh_flags = ELF::SHF_MERGE | ELF::SHF_STRINGS;1143 1144 assignSectionAddress(SHeader, YAMLSec);1145}1146 1147template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {1148 ErrHandler(Msg);1149 HasError = true;1150}1151 1152template <class ELFT> void ELFState<ELFT>::reportError(Error Err) {1153 handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) {1154 reportError(Err.message());1155 });1156}1157 1158template <class ELFT>1159std::vector<Fragment>1160ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,1161 ArrayRef<Elf_Shdr> SHeaders) {1162 std::vector<Fragment> Ret;1163 for (const ELFYAML::Chunk *C : Phdr.Chunks) {1164 if (const ELFYAML::Fill *F = dyn_cast<ELFYAML::Fill>(C)) {1165 Ret.push_back({*F->Offset, F->Size, llvm::ELF::SHT_PROGBITS,1166 /*ShAddrAlign=*/1});1167 continue;1168 }1169 1170 const ELFYAML::Section *S = cast<ELFYAML::Section>(C);1171 const Elf_Shdr &H = SHeaders[SN2I.get(S->Name)];1172 Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign});1173 }1174 return Ret;1175}1176 1177template <class ELFT>1178void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,1179 std::vector<Elf_Shdr> &SHeaders) {1180 uint32_t PhdrIdx = 0;1181 for (auto &YamlPhdr : Doc.ProgramHeaders) {1182 Elf_Phdr &PHeader = PHeaders[PhdrIdx++];1183 std::vector<Fragment> Fragments = getPhdrFragments(YamlPhdr, SHeaders);1184 if (!llvm::is_sorted(Fragments, [](const Fragment &A, const Fragment &B) {1185 return A.Offset < B.Offset;1186 }))1187 reportError("sections in the program header with index " +1188 Twine(PhdrIdx) + " are not sorted by their file offset");1189 1190 if (YamlPhdr.Offset) {1191 if (!Fragments.empty() && *YamlPhdr.Offset > Fragments.front().Offset)1192 reportError("'Offset' for segment with index " + Twine(PhdrIdx) +1193 " must be less than or equal to the minimum file offset of "1194 "all included sections (0x" +1195 Twine::utohexstr(Fragments.front().Offset) + ")");1196 PHeader.p_offset = *YamlPhdr.Offset;1197 } else if (!Fragments.empty()) {1198 PHeader.p_offset = Fragments.front().Offset;1199 }1200 1201 // Set the file size if not set explicitly.1202 if (YamlPhdr.FileSize) {1203 PHeader.p_filesz = *YamlPhdr.FileSize;1204 } else if (!Fragments.empty()) {1205 uint64_t FileSize = Fragments.back().Offset - PHeader.p_offset;1206 // SHT_NOBITS sections occupy no physical space in a file, we should not1207 // take their sizes into account when calculating the file size of a1208 // segment.1209 if (Fragments.back().Type != llvm::ELF::SHT_NOBITS)1210 FileSize += Fragments.back().Size;1211 PHeader.p_filesz = FileSize;1212 }1213 1214 // Find the maximum offset of the end of a section in order to set p_memsz.1215 uint64_t MemOffset = PHeader.p_offset;1216 for (const Fragment &F : Fragments)1217 MemOffset = std::max(MemOffset, F.Offset + F.Size);1218 // Set the memory size if not set explicitly.1219 PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize)1220 : MemOffset - PHeader.p_offset;1221 1222 if (YamlPhdr.Align) {1223 PHeader.p_align = *YamlPhdr.Align;1224 } else {1225 // Set the alignment of the segment to be the maximum alignment of the1226 // sections so that by default the segment has a valid and sensible1227 // alignment.1228 PHeader.p_align = 1;1229 for (const Fragment &F : Fragments)1230 PHeader.p_align = std::max((uint64_t)PHeader.p_align, F.AddrAlign);1231 }1232 }1233}1234 1235bool llvm::ELFYAML::shouldAllocateFileSpace(1236 ArrayRef<ELFYAML::ProgramHeader> Phdrs, const ELFYAML::NoBitsSection &S) {1237 for (const ELFYAML::ProgramHeader &PH : Phdrs) {1238 auto It = llvm::find_if(1239 PH.Chunks, [&](ELFYAML::Chunk *C) { return C->Name == S.Name; });1240 if (std::any_of(It, PH.Chunks.end(), [](ELFYAML::Chunk *C) {1241 return (isa<ELFYAML::Fill>(C) ||1242 cast<ELFYAML::Section>(C)->Type != ELF::SHT_NOBITS);1243 }))1244 return true;1245 }1246 return false;1247}1248 1249template <class ELFT>1250void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1251 const ELFYAML::NoBitsSection &S,1252 ContiguousBlobAccumulator &CBA) {1253 if (!S.Size)1254 return;1255 1256 SHeader.sh_size = *S.Size;1257 1258 // When a nobits section is followed by a non-nobits section or fill1259 // in the same segment, we allocate the file space for it. This behavior1260 // matches linkers.1261 if (shouldAllocateFileSpace(Doc.ProgramHeaders, S))1262 CBA.writeZeros(*S.Size);1263}1264 1265template <class ELFT>1266void ELFState<ELFT>::writeSectionContent(1267 Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section,1268 ContiguousBlobAccumulator &CBA) {1269 if (Section.Info)1270 SHeader.sh_info = *Section.Info;1271}1272 1273static bool isMips64EL(const ELFYAML::Object &Obj) {1274 return Obj.getMachine() == llvm::ELF::EM_MIPS &&1275 Obj.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) &&1276 Obj.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);1277}1278 1279template <class ELFT>1280void ELFState<ELFT>::writeSectionContent(1281 Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section,1282 ContiguousBlobAccumulator &CBA) {1283 assert((Section.Type == llvm::ELF::SHT_REL ||1284 Section.Type == llvm::ELF::SHT_RELA ||1285 Section.Type == llvm::ELF::SHT_CREL) &&1286 "Section type is not SHT_REL nor SHT_RELA");1287 1288 if (!Section.RelocatableSec.empty())1289 SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name);1290 1291 if (!Section.Relocations)1292 return;1293 1294 const bool IsCrel = Section.Type == llvm::ELF::SHT_CREL;1295 const bool IsRela = Section.Type == llvm::ELF::SHT_RELA;1296 typename ELFT::uint OffsetMask = 8, Offset = 0, Addend = 0;1297 uint32_t SymIdx = 0, Type = 0;1298 uint64_t CurrentOffset = CBA.getOffset();1299 if (IsCrel)1300 for (const ELFYAML::Relocation &Rel : *Section.Relocations)1301 OffsetMask |= Rel.Offset;1302 const int Shift = llvm::countr_zero(OffsetMask);1303 if (IsCrel)1304 CBA.writeULEB128(Section.Relocations->size() * 8 + ELF::CREL_HDR_ADDEND +1305 Shift);1306 for (const ELFYAML::Relocation &Rel : *Section.Relocations) {1307 const bool IsDynamic = Section.Link && (*Section.Link == ".dynsym");1308 uint32_t CurSymIdx =1309 Rel.Symbol ? toSymbolIndex(*Rel.Symbol, Section.Name, IsDynamic) : 0;1310 if (IsCrel) {1311 // The delta offset and flags member may be larger than uint64_t. Special1312 // case the first byte (3 flag bits and 4 offset bits). Other ULEB1281313 // bytes encode the remaining delta offset bits.1314 auto DeltaOffset =1315 (static_cast<typename ELFT::uint>(Rel.Offset) - Offset) >> Shift;1316 Offset = Rel.Offset;1317 uint8_t B =1318 DeltaOffset * 8 + (SymIdx != CurSymIdx) + (Type != Rel.Type ? 2 : 0) +1319 (Addend != static_cast<typename ELFT::uint>(Rel.Addend) ? 4 : 0);1320 if (DeltaOffset < 0x10) {1321 CBA.write(B);1322 } else {1323 CBA.write(B | 0x80);1324 CBA.writeULEB128(DeltaOffset >> 4);1325 }1326 // Delta symidx/type/addend members (SLEB128).1327 if (B & 1) {1328 CBA.writeSLEB128(1329 std::make_signed_t<typename ELFT::uint>(CurSymIdx - SymIdx));1330 SymIdx = CurSymIdx;1331 }1332 if (B & 2) {1333 CBA.writeSLEB128(static_cast<int32_t>(Rel.Type - Type));1334 Type = Rel.Type;1335 }1336 if (B & 4) {1337 CBA.writeSLEB128(1338 std::make_signed_t<typename ELFT::uint>(Rel.Addend - Addend));1339 Addend = Rel.Addend;1340 }1341 } else if (IsRela) {1342 Elf_Rela REntry;1343 zero(REntry);1344 REntry.r_offset = Rel.Offset;1345 REntry.r_addend = Rel.Addend;1346 REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Doc));1347 CBA.write((const char *)&REntry, sizeof(REntry));1348 } else {1349 Elf_Rel REntry;1350 zero(REntry);1351 REntry.r_offset = Rel.Offset;1352 REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Doc));1353 CBA.write((const char *)&REntry, sizeof(REntry));1354 }1355 }1356 1357 SHeader.sh_size = CBA.getOffset() - CurrentOffset;1358}1359 1360template <class ELFT>1361void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1362 const ELFYAML::RelrSection &Section,1363 ContiguousBlobAccumulator &CBA) {1364 if (!Section.Entries)1365 return;1366 1367 for (llvm::yaml::Hex64 E : *Section.Entries) {1368 if (!ELFT::Is64Bits && E > UINT32_MAX)1369 reportError(Section.Name + ": the value is too large for 32-bits: 0x" +1370 Twine::utohexstr(E));1371 CBA.write<uintX_t>(E, ELFT::Endianness);1372 }1373 1374 SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size();1375}1376 1377template <class ELFT>1378void ELFState<ELFT>::writeSectionContent(1379 Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx,1380 ContiguousBlobAccumulator &CBA) {1381 if (Shndx.Content || Shndx.Size) {1382 SHeader.sh_size = writeContent(CBA, Shndx.Content, Shndx.Size);1383 return;1384 }1385 1386 if (!Shndx.Entries)1387 return;1388 1389 for (uint32_t E : *Shndx.Entries)1390 CBA.write<uint32_t>(E, ELFT::Endianness);1391 SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize;1392}1393 1394template <class ELFT>1395void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1396 const ELFYAML::GroupSection &Section,1397 ContiguousBlobAccumulator &CBA) {1398 assert(Section.Type == llvm::ELF::SHT_GROUP &&1399 "Section type is not SHT_GROUP");1400 1401 if (Section.Signature)1402 SHeader.sh_info =1403 toSymbolIndex(*Section.Signature, Section.Name, /*IsDynamic=*/false);1404 1405 if (!Section.Members)1406 return;1407 1408 for (const ELFYAML::SectionOrType &Member : *Section.Members) {1409 unsigned int SectionIndex = 0;1410 if (Member.sectionNameOrType == "GRP_COMDAT")1411 SectionIndex = llvm::ELF::GRP_COMDAT;1412 else1413 SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name);1414 CBA.write<uint32_t>(SectionIndex, ELFT::Endianness);1415 }1416 SHeader.sh_size = SHeader.sh_entsize * Section.Members->size();1417}1418 1419template <class ELFT>1420void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1421 const ELFYAML::SymverSection &Section,1422 ContiguousBlobAccumulator &CBA) {1423 if (!Section.Entries)1424 return;1425 1426 for (uint16_t Version : *Section.Entries)1427 CBA.write<uint16_t>(Version, ELFT::Endianness);1428 SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize;1429}1430 1431template <class ELFT>1432void ELFState<ELFT>::writeSectionContent(1433 Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section,1434 ContiguousBlobAccumulator &CBA) {1435 if (!Section.Entries)1436 return;1437 1438 for (const ELFYAML::StackSizeEntry &E : *Section.Entries) {1439 CBA.write<uintX_t>(E.Address, ELFT::Endianness);1440 SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(E.Size);1441 }1442}1443 1444template <class ELFT>1445void ELFState<ELFT>::writeSectionContent(1446 Elf_Shdr &SHeader, const ELFYAML::BBAddrMapSection &Section,1447 ContiguousBlobAccumulator &CBA) {1448 if (!Section.Entries) {1449 if (Section.PGOAnalyses)1450 WithColor::warning()1451 << "PGOAnalyses should not exist in SHT_LLVM_BB_ADDR_MAP when "1452 "Entries does not exist";1453 return;1454 }1455 1456 const std::vector<ELFYAML::PGOAnalysisMapEntry> *PGOAnalyses = nullptr;1457 if (Section.PGOAnalyses) {1458 if (Section.Entries->size() != Section.PGOAnalyses->size())1459 WithColor::warning() << "PGOAnalyses must be the same length as Entries "1460 "in SHT_LLVM_BB_ADDR_MAP";1461 else1462 PGOAnalyses = &Section.PGOAnalyses.value();1463 }1464 1465 for (const auto &[Idx, E] : llvm::enumerate(*Section.Entries)) {1466 // Write version and feature values.1467 if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP) {1468 if (E.Version > 5)1469 WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: "1470 << static_cast<int>(E.Version)1471 << "; encoding using the most recent version";1472 CBA.write(E.Version);1473 SHeader.sh_size += 1;1474 if (E.Version < 5) {1475 CBA.write(static_cast<uint8_t>(E.Feature));1476 SHeader.sh_size += 1;1477 } else {1478 CBA.write<uint16_t>(E.Feature, ELFT::Endianness);1479 SHeader.sh_size += 2;1480 }1481 }1482 auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(E.Feature);1483 bool MultiBBRangeFeatureEnabled = false;1484 if (!FeatureOrErr)1485 WithColor::warning() << toString(FeatureOrErr.takeError());1486 else1487 MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;1488 bool MultiBBRange =1489 MultiBBRangeFeatureEnabled ||1490 (E.NumBBRanges.has_value() && E.NumBBRanges.value() != 1) ||1491 (E.BBRanges && E.BBRanges->size() != 1);1492 if (MultiBBRange && !MultiBBRangeFeatureEnabled)1493 WithColor::warning() << "feature value(" << E.Feature1494 << ") does not support multiple BB ranges.";1495 if (MultiBBRange) {1496 // Write the number of basic block ranges, which is overridden by the1497 // 'NumBBRanges' field when specified.1498 uint64_t NumBBRanges =1499 E.NumBBRanges.value_or(E.BBRanges ? E.BBRanges->size() : 0);1500 SHeader.sh_size += CBA.writeULEB128(NumBBRanges);1501 }1502 if (!E.BBRanges)1503 continue;1504 uint64_t TotalNumBlocks = 0;1505 bool EmitCallsiteEndOffsets =1506 FeatureOrErr->CallsiteEndOffsets || E.hasAnyCallsiteEndOffsets();1507 for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) {1508 // Write the base address of the range.1509 CBA.write<uintX_t>(BBR.BaseAddress, ELFT::Endianness);1510 // Write number of BBEntries (number of basic blocks in this basic block1511 // range). This is overridden by the 'NumBlocks' YAML field when1512 // specified.1513 uint64_t NumBlocks =1514 BBR.NumBlocks.value_or(BBR.BBEntries ? BBR.BBEntries->size() : 0);1515 SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(NumBlocks);1516 // Write all BBEntries in this BBRange.1517 if (!BBR.BBEntries || FeatureOrErr->OmitBBEntries)1518 continue;1519 for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries) {1520 ++TotalNumBlocks;1521 if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP && E.Version > 1)1522 SHeader.sh_size += CBA.writeULEB128(BBE.ID);1523 SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset);1524 if (EmitCallsiteEndOffsets) {1525 size_t NumCallsiteEndOffsets =1526 BBE.CallsiteEndOffsets ? BBE.CallsiteEndOffsets->size() : 0;1527 SHeader.sh_size += CBA.writeULEB128(NumCallsiteEndOffsets);1528 if (BBE.CallsiteEndOffsets) {1529 for (uint32_t Offset : *BBE.CallsiteEndOffsets)1530 SHeader.sh_size += CBA.writeULEB128(Offset);1531 }1532 }1533 SHeader.sh_size += CBA.writeULEB128(BBE.Size);1534 SHeader.sh_size += CBA.writeULEB128(BBE.Metadata);1535 if (FeatureOrErr->BBHash || BBE.Hash.has_value()) {1536 uint64_t Hash =1537 BBE.Hash.has_value() ? BBE.Hash.value() : llvm::yaml::Hex64(0);1538 CBA.write<uint64_t>(Hash, ELFT::Endianness);1539 SHeader.sh_size += 8;1540 }1541 }1542 }1543 if (!PGOAnalyses)1544 continue;1545 const ELFYAML::PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx);1546 1547 if (PGOEntry.FuncEntryCount)1548 SHeader.sh_size += CBA.writeULEB128(*PGOEntry.FuncEntryCount);1549 1550 if (!PGOEntry.PGOBBEntries)1551 continue;1552 1553 const auto &PGOBBEntries = PGOEntry.PGOBBEntries.value();1554 if (TotalNumBlocks != PGOBBEntries.size()) {1555 WithColor::warning() << "PBOBBEntries must be the same length as "1556 "BBEntries in SHT_LLVM_BB_ADDR_MAP.\n"1557 << "Mismatch on function with address: "1558 << E.getFunctionAddress();1559 continue;1560 }1561 1562 for (const auto &PGOBBE : PGOBBEntries) {1563 if (PGOBBE.BBFreq)1564 SHeader.sh_size += CBA.writeULEB128(*PGOBBE.BBFreq);1565 if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())1566 SHeader.sh_size += CBA.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));1567 if (PGOBBE.Successors) {1568 SHeader.sh_size += CBA.writeULEB128(PGOBBE.Successors->size());1569 for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {1570 SHeader.sh_size += CBA.writeULEB128(ID);1571 SHeader.sh_size += CBA.writeULEB128(BrProb);1572 if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())1573 SHeader.sh_size += CBA.writeULEB128(PostLinkBrFreq.value_or(0));1574 }1575 }1576 }1577 }1578}1579 1580template <class ELFT>1581void ELFState<ELFT>::writeSectionContent(1582 Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section,1583 ContiguousBlobAccumulator &CBA) {1584 if (!Section.Options)1585 return;1586 1587 for (const ELFYAML::LinkerOption &LO : *Section.Options) {1588 CBA.write(LO.Key.data(), LO.Key.size());1589 CBA.write('\0');1590 CBA.write(LO.Value.data(), LO.Value.size());1591 CBA.write('\0');1592 SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2);1593 }1594}1595 1596template <class ELFT>1597void ELFState<ELFT>::writeSectionContent(1598 Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section,1599 ContiguousBlobAccumulator &CBA) {1600 if (!Section.Libs)1601 return;1602 1603 for (StringRef Lib : *Section.Libs) {1604 CBA.write(Lib.data(), Lib.size());1605 CBA.write('\0');1606 SHeader.sh_size += Lib.size() + 1;1607 }1608}1609 1610template <class ELFT>1611uint64_t1612ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,1613 std::optional<llvm::yaml::Hex64> Offset) {1614 uint64_t CurrentOffset = CBA.getOffset();1615 uint64_t AlignedOffset;1616 1617 if (Offset) {1618 if ((uint64_t)*Offset < CurrentOffset) {1619 reportError("the 'Offset' value (0x" +1620 Twine::utohexstr((uint64_t)*Offset) + ") goes backward");1621 return CurrentOffset;1622 }1623 1624 // We ignore an alignment when an explicit offset has been requested.1625 AlignedOffset = *Offset;1626 } else {1627 AlignedOffset = alignTo(CurrentOffset, std::max(Align, (uint64_t)1));1628 }1629 1630 CBA.writeZeros(AlignedOffset - CurrentOffset);1631 return AlignedOffset;1632}1633 1634template <class ELFT>1635void ELFState<ELFT>::writeSectionContent(1636 Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section,1637 ContiguousBlobAccumulator &CBA) {1638 if (!Section.Entries)1639 return;1640 1641 for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) {1642 CBA.write<uint64_t>(E.Weight, ELFT::Endianness);1643 SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl<ELFT>);1644 }1645}1646 1647template <class ELFT>1648void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1649 const ELFYAML::HashSection &Section,1650 ContiguousBlobAccumulator &CBA) {1651 if (!Section.Bucket)1652 return;1653 1654 CBA.write<uint32_t>(1655 Section.NBucket.value_or(llvm::yaml::Hex64(Section.Bucket->size())),1656 ELFT::Endianness);1657 CBA.write<uint32_t>(1658 Section.NChain.value_or(llvm::yaml::Hex64(Section.Chain->size())),1659 ELFT::Endianness);1660 1661 for (uint32_t Val : *Section.Bucket)1662 CBA.write<uint32_t>(Val, ELFT::Endianness);1663 for (uint32_t Val : *Section.Chain)1664 CBA.write<uint32_t>(Val, ELFT::Endianness);1665 1666 SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4;1667}1668 1669template <class ELFT>1670void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1671 const ELFYAML::VerdefSection &Section,1672 ContiguousBlobAccumulator &CBA) {1673 1674 if (Section.Info)1675 SHeader.sh_info = *Section.Info;1676 else if (Section.Entries)1677 SHeader.sh_info = Section.Entries->size();1678 1679 if (!Section.Entries)1680 return;1681 1682 uint64_t AuxCnt = 0;1683 for (size_t I = 0; I < Section.Entries->size(); ++I) {1684 const ELFYAML::VerdefEntry &E = (*Section.Entries)[I];1685 1686 Elf_Verdef VerDef;1687 VerDef.vd_version = E.Version.value_or(1);1688 VerDef.vd_flags = E.Flags.value_or(0);1689 VerDef.vd_ndx = E.VersionNdx.value_or(0);1690 VerDef.vd_hash = E.Hash.value_or(0);1691 VerDef.vd_aux = E.VDAux.value_or(sizeof(Elf_Verdef));1692 VerDef.vd_cnt = E.VerNames.size();1693 if (I == Section.Entries->size() - 1)1694 VerDef.vd_next = 0;1695 else1696 VerDef.vd_next =1697 sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux);1698 CBA.write((const char *)&VerDef, sizeof(Elf_Verdef));1699 1700 for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) {1701 Elf_Verdaux VerdAux;1702 VerdAux.vda_name = DotDynstr.getOffset(E.VerNames[J]);1703 if (J == E.VerNames.size() - 1)1704 VerdAux.vda_next = 0;1705 else1706 VerdAux.vda_next = sizeof(Elf_Verdaux);1707 CBA.write((const char *)&VerdAux, sizeof(Elf_Verdaux));1708 }1709 }1710 1711 SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) +1712 AuxCnt * sizeof(Elf_Verdaux);1713}1714 1715template <class ELFT>1716void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1717 const ELFYAML::VerneedSection &Section,1718 ContiguousBlobAccumulator &CBA) {1719 if (Section.Info)1720 SHeader.sh_info = *Section.Info;1721 else if (Section.VerneedV)1722 SHeader.sh_info = Section.VerneedV->size();1723 1724 if (!Section.VerneedV)1725 return;1726 1727 uint64_t AuxCnt = 0;1728 for (size_t I = 0; I < Section.VerneedV->size(); ++I) {1729 const ELFYAML::VerneedEntry &VE = (*Section.VerneedV)[I];1730 1731 Elf_Verneed VerNeed;1732 VerNeed.vn_version = VE.Version;1733 VerNeed.vn_file = DotDynstr.getOffset(VE.File);1734 if (I == Section.VerneedV->size() - 1)1735 VerNeed.vn_next = 0;1736 else1737 VerNeed.vn_next =1738 sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux);1739 VerNeed.vn_cnt = VE.AuxV.size();1740 VerNeed.vn_aux = sizeof(Elf_Verneed);1741 CBA.write((const char *)&VerNeed, sizeof(Elf_Verneed));1742 1743 for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) {1744 const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J];1745 1746 Elf_Vernaux VernAux;1747 VernAux.vna_hash = VAuxE.Hash;1748 VernAux.vna_flags = VAuxE.Flags;1749 VernAux.vna_other = VAuxE.Other;1750 VernAux.vna_name = DotDynstr.getOffset(VAuxE.Name);1751 if (J == VE.AuxV.size() - 1)1752 VernAux.vna_next = 0;1753 else1754 VernAux.vna_next = sizeof(Elf_Vernaux);1755 CBA.write((const char *)&VernAux, sizeof(Elf_Vernaux));1756 }1757 }1758 1759 SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) +1760 AuxCnt * sizeof(Elf_Vernaux);1761}1762 1763template <class ELFT>1764void ELFState<ELFT>::writeSectionContent(1765 Elf_Shdr &SHeader, const ELFYAML::ARMIndexTableSection &Section,1766 ContiguousBlobAccumulator &CBA) {1767 if (!Section.Entries)1768 return;1769 1770 for (const ELFYAML::ARMIndexTableEntry &E : *Section.Entries) {1771 CBA.write<uint32_t>(E.Offset, ELFT::Endianness);1772 CBA.write<uint32_t>(E.Value, ELFT::Endianness);1773 }1774 SHeader.sh_size = Section.Entries->size() * 8;1775}1776 1777template <class ELFT>1778void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1779 const ELFYAML::MipsABIFlags &Section,1780 ContiguousBlobAccumulator &CBA) {1781 assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS &&1782 "Section type is not SHT_MIPS_ABIFLAGS");1783 1784 object::Elf_Mips_ABIFlags<ELFT> Flags;1785 zero(Flags);1786 SHeader.sh_size = SHeader.sh_entsize;1787 1788 Flags.version = Section.Version;1789 Flags.isa_level = Section.ISALevel;1790 Flags.isa_rev = Section.ISARevision;1791 Flags.gpr_size = Section.GPRSize;1792 Flags.cpr1_size = Section.CPR1Size;1793 Flags.cpr2_size = Section.CPR2Size;1794 Flags.fp_abi = Section.FpABI;1795 Flags.isa_ext = Section.ISAExtension;1796 Flags.ases = Section.ASEs;1797 Flags.flags1 = Section.Flags1;1798 Flags.flags2 = Section.Flags2;1799 CBA.write((const char *)&Flags, sizeof(Flags));1800}1801 1802template <class ELFT>1803void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1804 const ELFYAML::DynamicSection &Section,1805 ContiguousBlobAccumulator &CBA) {1806 assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&1807 "Section type is not SHT_DYNAMIC");1808 1809 if (!Section.Entries)1810 return;1811 1812 for (const ELFYAML::DynamicEntry &DE : *Section.Entries) {1813 CBA.write<uintX_t>(DE.Tag, ELFT::Endianness);1814 CBA.write<uintX_t>(DE.Val, ELFT::Endianness);1815 }1816 SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size();1817}1818 1819template <class ELFT>1820void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1821 const ELFYAML::AddrsigSection &Section,1822 ContiguousBlobAccumulator &CBA) {1823 if (!Section.Symbols)1824 return;1825 1826 for (StringRef Sym : *Section.Symbols)1827 SHeader.sh_size +=1828 CBA.writeULEB128(toSymbolIndex(Sym, Section.Name, /*IsDynamic=*/false));1829}1830 1831template <class ELFT>1832void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1833 const ELFYAML::NoteSection &Section,1834 ContiguousBlobAccumulator &CBA) {1835 if (!Section.Notes || Section.Notes->empty())1836 return;1837 1838 unsigned Align;1839 switch (Section.AddressAlign) {1840 case 0:1841 case 4:1842 Align = 4;1843 break;1844 case 8:1845 Align = 8;1846 break;1847 default:1848 reportError(Section.Name + ": invalid alignment for a note section: 0x" +1849 Twine::utohexstr(Section.AddressAlign));1850 return;1851 }1852 1853 if (CBA.getOffset() != alignTo(CBA.getOffset(), Align)) {1854 reportError(Section.Name + ": invalid offset of a note section: 0x" +1855 Twine::utohexstr(CBA.getOffset()) + ", should be aligned to " +1856 Twine(Align));1857 return;1858 }1859 1860 uint64_t Offset = CBA.tell();1861 for (const ELFYAML::NoteEntry &NE : *Section.Notes) {1862 // Write name size.1863 if (NE.Name.empty())1864 CBA.write<uint32_t>(0, ELFT::Endianness);1865 else1866 CBA.write<uint32_t>(NE.Name.size() + 1, ELFT::Endianness);1867 1868 // Write description size.1869 if (NE.Desc.binary_size() == 0)1870 CBA.write<uint32_t>(0, ELFT::Endianness);1871 else1872 CBA.write<uint32_t>(NE.Desc.binary_size(), ELFT::Endianness);1873 1874 // Write type.1875 CBA.write<uint32_t>(NE.Type, ELFT::Endianness);1876 1877 // Write name, null terminator and padding.1878 if (!NE.Name.empty()) {1879 CBA.write(NE.Name.data(), NE.Name.size());1880 CBA.write('\0');1881 }1882 1883 // Write description and padding.1884 if (NE.Desc.binary_size() != 0) {1885 CBA.padToAlignment(Align);1886 CBA.writeAsBinary(NE.Desc);1887 }1888 1889 CBA.padToAlignment(Align);1890 }1891 1892 SHeader.sh_size = CBA.tell() - Offset;1893}1894 1895template <class ELFT>1896void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,1897 const ELFYAML::GnuHashSection &Section,1898 ContiguousBlobAccumulator &CBA) {1899 if (!Section.HashBuckets)1900 return;1901 1902 if (!Section.Header)1903 return;1904 1905 // We write the header first, starting with the hash buckets count. Normally1906 // it is the number of entries in HashBuckets, but the "NBuckets" property can1907 // be used to override this field, which is useful for producing broken1908 // objects.1909 if (Section.Header->NBuckets)1910 CBA.write<uint32_t>(*Section.Header->NBuckets, ELFT::Endianness);1911 else1912 CBA.write<uint32_t>(Section.HashBuckets->size(), ELFT::Endianness);1913 1914 // Write the index of the first symbol in the dynamic symbol table accessible1915 // via the hash table.1916 CBA.write<uint32_t>(Section.Header->SymNdx, ELFT::Endianness);1917 1918 // Write the number of words in the Bloom filter. As above, the "MaskWords"1919 // property can be used to set this field to any value.1920 if (Section.Header->MaskWords)1921 CBA.write<uint32_t>(*Section.Header->MaskWords, ELFT::Endianness);1922 else1923 CBA.write<uint32_t>(Section.BloomFilter->size(), ELFT::Endianness);1924 1925 // Write the shift constant used by the Bloom filter.1926 CBA.write<uint32_t>(Section.Header->Shift2, ELFT::Endianness);1927 1928 // We've finished writing the header. Now write the Bloom filter.1929 for (llvm::yaml::Hex64 Val : *Section.BloomFilter)1930 CBA.write<uintX_t>(Val, ELFT::Endianness);1931 1932 // Write an array of hash buckets.1933 for (llvm::yaml::Hex32 Val : *Section.HashBuckets)1934 CBA.write<uint32_t>(Val, ELFT::Endianness);1935 1936 // Write an array of hash values.1937 for (llvm::yaml::Hex32 Val : *Section.HashValues)1938 CBA.write<uint32_t>(Val, ELFT::Endianness);1939 1940 SHeader.sh_size = 16 /*Header size*/ +1941 Section.BloomFilter->size() * sizeof(typename ELFT::uint) +1942 Section.HashBuckets->size() * 4 +1943 Section.HashValues->size() * 4;1944}1945 1946template <class ELFT>1947void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill,1948 ContiguousBlobAccumulator &CBA) {1949 size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0;1950 if (!PatternSize) {1951 CBA.writeZeros(Fill.Size);1952 return;1953 }1954 1955 // Fill the content with the specified pattern.1956 uint64_t Written = 0;1957 for (; Written + PatternSize <= Fill.Size; Written += PatternSize)1958 CBA.writeAsBinary(*Fill.Pattern);1959 CBA.writeAsBinary(*Fill.Pattern, Fill.Size - Written);1960}1961 1962template <class ELFT>1963DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() {1964 const ELFYAML::SectionHeaderTable &SectionHeaders =1965 Doc.getSectionHeaderTable();1966 if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders ||1967 SectionHeaders.isDefault())1968 return DenseMap<StringRef, size_t>();1969 1970 DenseMap<StringRef, size_t> Ret;1971 size_t SecNdx = 0;1972 StringSet<> Seen;1973 1974 auto AddSection = [&](const ELFYAML::SectionHeader &Hdr) {1975 if (!Ret.try_emplace(Hdr.Name, ++SecNdx).second)1976 reportError("repeated section name: '" + Hdr.Name +1977 "' in the section header description");1978 Seen.insert(Hdr.Name);1979 };1980 1981 if (SectionHeaders.Sections)1982 for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Sections)1983 AddSection(Hdr);1984 1985 if (SectionHeaders.Excluded)1986 for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)1987 AddSection(Hdr);1988 1989 for (const ELFYAML::Section *S : Doc.getSections()) {1990 // Ignore special first SHT_NULL section.1991 if (S == Doc.getSections().front())1992 continue;1993 if (!Seen.count(S->Name))1994 reportError("section '" + S->Name +1995 "' should be present in the 'Sections' or 'Excluded' lists");1996 Seen.erase(S->Name);1997 }1998 1999 for (const auto &It : Seen)2000 reportError("section header contains undefined section '" + It.getKey() +2001 "'");2002 return Ret;2003}2004 2005template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {2006 // A YAML description can have an explicit section header declaration that2007 // allows to change the order of section headers.2008 DenseMap<StringRef, size_t> ReorderMap = buildSectionHeaderReorderMap();2009 2010 if (HasError)2011 return;2012 2013 // Build excluded section headers map.2014 std::vector<ELFYAML::Section *> Sections = Doc.getSections();2015 const ELFYAML::SectionHeaderTable &SectionHeaders =2016 Doc.getSectionHeaderTable();2017 if (SectionHeaders.Excluded)2018 for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)2019 if (!ExcludedSectionHeaders.insert(Hdr.Name).second)2020 llvm_unreachable("buildSectionIndex() failed");2021 2022 if (SectionHeaders.NoHeaders.value_or(false))2023 for (const ELFYAML::Section *S : Sections)2024 if (!ExcludedSectionHeaders.insert(S->Name).second)2025 llvm_unreachable("buildSectionIndex() failed");2026 2027 size_t SecNdx = -1;2028 for (const ELFYAML::Section *S : Sections) {2029 ++SecNdx;2030 2031 size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(S->Name);2032 if (!SN2I.addName(S->Name, Index))2033 llvm_unreachable("buildSectionIndex() failed");2034 2035 if (!ExcludedSectionHeaders.count(S->Name))2036 ShStrtabStrings->add(ELFYAML::dropUniqueSuffix(S->Name));2037 }2038}2039 2040template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() {2041 auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) {2042 for (size_t I = 0, S = V.size(); I < S; ++I) {2043 const ELFYAML::Symbol &Sym = V[I];2044 if (!Sym.Name.empty() && !Map.addName(Sym.Name, I + 1))2045 reportError("repeated symbol name: '" + Sym.Name + "'");2046 }2047 };2048 2049 if (Doc.Symbols)2050 Build(*Doc.Symbols, SymN2I);2051 if (Doc.DynamicSymbols)2052 Build(*Doc.DynamicSymbols, DynSymN2I);2053}2054 2055template <class ELFT> void ELFState<ELFT>::finalizeStrings() {2056 // Add the regular symbol names to .strtab section.2057 if (Doc.Symbols)2058 for (const ELFYAML::Symbol &Sym : *Doc.Symbols)2059 DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name));2060 DotStrtab.finalize();2061 2062 // Add the dynamic symbol names to .dynstr section.2063 if (Doc.DynamicSymbols)2064 for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols)2065 DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name));2066 2067 // SHT_GNU_verdef and SHT_GNU_verneed sections might also2068 // add strings to .dynstr section.2069 for (const ELFYAML::Chunk *Sec : Doc.getSections()) {2070 if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec)) {2071 if (VerNeed->VerneedV) {2072 for (const ELFYAML::VerneedEntry &VE : *VerNeed->VerneedV) {2073 DotDynstr.add(VE.File);2074 for (const ELFYAML::VernauxEntry &Aux : VE.AuxV)2075 DotDynstr.add(Aux.Name);2076 }2077 }2078 } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec)) {2079 if (VerDef->Entries)2080 for (const ELFYAML::VerdefEntry &E : *VerDef->Entries)2081 for (StringRef Name : E.VerNames)2082 DotDynstr.add(Name);2083 }2084 }2085 2086 DotDynstr.finalize();2087 2088 // Don't finalize the section header string table a second time if it has2089 // already been finalized due to being one of the symbol string tables.2090 if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)2091 ShStrtabStrings->finalize();2092}2093 2094template <class ELFT>2095bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,2096 yaml::ErrorHandler EH, uint64_t MaxSize) {2097 ELFState<ELFT> State(Doc, EH);2098 if (State.HasError)2099 return false;2100 2101 // Build the section index, which adds sections to the section header string2102 // table first, so that we can finalize the section header string table.2103 State.buildSectionIndex();2104 State.buildSymbolIndexes();2105 2106 // Finalize section header string table and the .strtab and .dynstr sections.2107 // We do this early because we want to finalize the string table builders2108 // before writing the content of the sections that might want to use them.2109 State.finalizeStrings();2110 2111 if (State.HasError)2112 return false;2113 2114 std::vector<Elf_Phdr> PHeaders;2115 State.initProgramHeaders(PHeaders);2116 2117 // XXX: This offset is tightly coupled with the order that we write2118 // things to `OS`.2119 const size_t SectionContentBeginOffset =2120 sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();2121 // It is quite easy to accidentally create output with yaml2obj that is larger2122 // than intended, for example, due to an issue in the YAML description.2123 // We limit the maximum allowed output size, but also provide a command line2124 // option to change this limitation.2125 ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize);2126 2127 std::vector<Elf_Shdr> SHeaders;2128 State.initSectionHeaders(SHeaders, CBA);2129 2130 // Now we can decide segment offsets.2131 State.setProgramHeaderLayout(PHeaders, SHeaders);2132 2133 // Override section fields, if requested. This needs to happen after program2134 // header layout happens, because otherwise the layout will use the new2135 // values.2136 State.overrideSectionHeaders(SHeaders);2137 2138 bool ReachedLimit = CBA.getOffset() > MaxSize;2139 if (Error E = CBA.takeLimitError()) {2140 // We report a custom error message instead below.2141 consumeError(std::move(E));2142 ReachedLimit = true;2143 }2144 2145 if (ReachedLimit)2146 State.reportError(2147 "the desired output size is greater than permitted. Use the "2148 "--max-size option to change the limit");2149 2150 if (State.HasError)2151 return false;2152 2153 State.writeELFHeader(OS);2154 writeArrayData(OS, ArrayRef(PHeaders));2155 2156 const ELFYAML::SectionHeaderTable &SHT = Doc.getSectionHeaderTable();2157 if (!SHT.NoHeaders.value_or(false))2158 CBA.updateDataAt(*SHT.Offset, SHeaders.data(),2159 SHT.getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr));2160 2161 CBA.writeBlobToStream(OS);2162 return true;2163}2164 2165namespace llvm {2166namespace yaml {2167 2168bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH,2169 uint64_t MaxSize) {2170 bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);2171 bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);2172 if (Is64Bit) {2173 if (IsLE)2174 return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH, MaxSize);2175 return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH, MaxSize);2176 }2177 if (IsLE)2178 return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH, MaxSize);2179 return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH, MaxSize);2180}2181 2182} // namespace yaml2183} // namespace llvm2184