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