1 //===- yaml2elf - Convert YAML to a ELF object file -----------------------===//
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
7 //===----------------------------------------------------------------------===//
10 /// The ELF component of yaml2obj.
12 //===----------------------------------------------------------------------===//
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"
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
34 class ContiguousBlobAccumulator
{
35 const uint64_t InitialOffset
;
36 SmallVector
<char, 128> Buf
;
37 raw_svector_ostream OS
;
39 /// \returns The new offset.
40 uint64_t padToAlignment(unsigned Align
) {
43 uint64_t CurrentOffset
= InitialOffset
+ OS
.tell();
44 uint64_t AlignedOffset
= alignTo(CurrentOffset
, Align
);
45 OS
.write_zeros(AlignedOffset
- CurrentOffset
);
46 return AlignedOffset
; // == CurrentOffset;
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
);
57 void writeBlobToStream(raw_ostream
&Out
) { Out
<< OS
.str(); }
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.
63 StringMap
<unsigned> Map
;
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
;
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
);
78 /// Asserts if name is not present in the map.
79 unsigned get(StringRef Name
) const {
81 if (lookup(Name
, Idx
))
83 assert(false && "Expected section not found in index");
86 unsigned size() const { return Map
.size(); }
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
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
;
102 enum class SymtabType
{ Static
, Dynamic
};
104 /// The future ".strtab" section.
105 StringTableBuilder DotStrtab
{StringTableBuilder::ELF
};
107 /// The future ".shstrtab" section.
108 StringTableBuilder DotShStrtab
{StringTableBuilder::ELF
};
110 /// The future ".dynstr" section.
111 StringTableBuilder DotDynstr
{StringTableBuilder::ELF
};
115 NameToIdxMap DynSymN2I
;
116 ELFYAML::Object
&Doc
;
118 bool HasError
= false;
119 yaml::ErrorHandler ErrHandler
;
120 void reportError(const Twine
&Msg
);
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
);
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 void writeSectionContent(Elf_Shdr
&SHeader
,
175 const ELFYAML::HashSection
&Section
,
176 ContiguousBlobAccumulator
&CBA
);
177 ELFState(ELFYAML::Object
&D
, yaml::ErrorHandler EH
);
180 static bool writeELF(raw_ostream
&OS
, ELFYAML::Object
&Doc
,
181 yaml::ErrorHandler EH
);
183 } // end anonymous namespace
185 template <class T
> static size_t arrayDataSize(ArrayRef
<T
> A
) {
186 return A
.size() * sizeof(T
);
189 template <class T
> static void writeArrayData(raw_ostream
&OS
, ArrayRef
<T
> A
) {
190 OS
.write((const char *)A
.data(), arrayDataSize(A
));
193 template <class T
> static void zero(T
&Obj
) { memset(&Obj
, 0, sizeof(Obj
)); }
195 template <class ELFT
>
196 ELFState
<ELFT
>::ELFState(ELFYAML::Object
&D
, yaml::ErrorHandler EH
)
197 : Doc(D
), ErrHandler(EH
) {
198 StringSet
<> DocSections
;
199 for (std::unique_ptr
<ELFYAML::Section
> &D
: Doc
.Sections
)
200 if (!D
->Name
.empty())
201 DocSections
.insert(D
->Name
);
203 // Insert SHT_NULL section implicitly when it is not defined in YAML.
204 if (Doc
.Sections
.empty() || Doc
.Sections
.front()->Type
!= ELF::SHT_NULL
)
206 Doc
.Sections
.begin(),
207 std::make_unique
<ELFYAML::Section
>(
208 ELFYAML::Section::SectionKind::RawContent
, /*IsImplicit=*/true));
210 std::vector
<StringRef
> ImplicitSections
= {".symtab", ".strtab", ".shstrtab"};
211 if (!Doc
.DynamicSymbols
.empty())
212 ImplicitSections
.insert(ImplicitSections
.end(), {".dynsym", ".dynstr"});
214 // Insert placeholders for implicit sections that are not
215 // defined explicitly in YAML.
216 for (StringRef SecName
: ImplicitSections
) {
217 if (DocSections
.count(SecName
))
220 std::unique_ptr
<ELFYAML::Section
> Sec
= std::make_unique
<ELFYAML::Section
>(
221 ELFYAML::Section::SectionKind::RawContent
, true /*IsImplicit*/);
223 Doc
.Sections
.push_back(std::move(Sec
));
227 template <class ELFT
>
228 void ELFState
<ELFT
>::writeELFHeader(ContiguousBlobAccumulator
&CBA
, raw_ostream
&OS
) {
229 using namespace llvm::ELF
;
233 Header
.e_ident
[EI_MAG0
] = 0x7f;
234 Header
.e_ident
[EI_MAG1
] = 'E';
235 Header
.e_ident
[EI_MAG2
] = 'L';
236 Header
.e_ident
[EI_MAG3
] = 'F';
237 Header
.e_ident
[EI_CLASS
] = ELFT::Is64Bits
? ELFCLASS64
: ELFCLASS32
;
238 Header
.e_ident
[EI_DATA
] = Doc
.Header
.Data
;
239 Header
.e_ident
[EI_VERSION
] = EV_CURRENT
;
240 Header
.e_ident
[EI_OSABI
] = Doc
.Header
.OSABI
;
241 Header
.e_ident
[EI_ABIVERSION
] = Doc
.Header
.ABIVersion
;
242 Header
.e_type
= Doc
.Header
.Type
;
243 Header
.e_machine
= Doc
.Header
.Machine
;
244 Header
.e_version
= EV_CURRENT
;
245 Header
.e_entry
= Doc
.Header
.Entry
;
246 Header
.e_phoff
= Doc
.ProgramHeaders
.size() ? sizeof(Header
) : 0;
247 Header
.e_flags
= Doc
.Header
.Flags
;
248 Header
.e_ehsize
= sizeof(Elf_Ehdr
);
249 Header
.e_phentsize
= Doc
.ProgramHeaders
.size() ? sizeof(Elf_Phdr
) : 0;
250 Header
.e_phnum
= Doc
.ProgramHeaders
.size();
253 Doc
.Header
.SHEntSize
? (uint16_t)*Doc
.Header
.SHEntSize
: sizeof(Elf_Shdr
);
254 // Immediately following the ELF header and program headers.
255 // Align the start of the section header and write the ELF header.
257 CBA
.getOSAndAlignedOffset(SHOff
, sizeof(typename
ELFT::uint
));
259 Doc
.Header
.SHOff
? typename
ELFT::uint(*Doc
.Header
.SHOff
) : SHOff
;
261 Doc
.Header
.SHNum
? (uint16_t)*Doc
.Header
.SHNum
: Doc
.Sections
.size();
262 Header
.e_shstrndx
= Doc
.Header
.SHStrNdx
? (uint16_t)*Doc
.Header
.SHStrNdx
263 : SN2I
.get(".shstrtab");
265 OS
.write((const char *)&Header
, sizeof(Header
));
268 template <class ELFT
>
269 void ELFState
<ELFT
>::initProgramHeaders(std::vector
<Elf_Phdr
> &PHeaders
) {
270 for (const auto &YamlPhdr
: Doc
.ProgramHeaders
) {
272 Phdr
.p_type
= YamlPhdr
.Type
;
273 Phdr
.p_flags
= YamlPhdr
.Flags
;
274 Phdr
.p_vaddr
= YamlPhdr
.VAddr
;
275 Phdr
.p_paddr
= YamlPhdr
.PAddr
;
276 PHeaders
.push_back(Phdr
);
280 template <class ELFT
>
281 unsigned ELFState
<ELFT
>::toSectionIndex(StringRef S
, StringRef LocSec
,
284 if (SN2I
.lookup(S
, Index
) || to_integer(S
, Index
))
287 assert(LocSec
.empty() || LocSym
.empty());
289 reportError("unknown section referenced: '" + S
+ "' by YAML symbol '" +
292 reportError("unknown section referenced: '" + S
+ "' by YAML section '" +
297 template <class ELFT
>
298 unsigned ELFState
<ELFT
>::toSymbolIndex(StringRef S
, StringRef LocSec
,
300 const NameToIdxMap
&SymMap
= IsDynamic
? DynSymN2I
: SymN2I
;
302 // Here we try to look up S in the symbol table. If it is not there,
303 // treat its value as a symbol index.
304 if (!SymMap
.lookup(S
, Index
) && !to_integer(S
, Index
)) {
305 reportError("unknown symbol referenced: '" + S
+ "' by YAML section '" +
312 template <class ELFT
>
313 bool ELFState
<ELFT
>::initImplicitHeader(ContiguousBlobAccumulator
&CBA
,
314 Elf_Shdr
&Header
, StringRef SecName
,
315 ELFYAML::Section
*YAMLSec
) {
316 // Check if the header was already initialized.
317 if (Header
.sh_offset
)
320 if (SecName
== ".symtab")
321 initSymtabSectionHeader(Header
, SymtabType::Static
, CBA
, YAMLSec
);
322 else if (SecName
== ".strtab")
323 initStrtabSectionHeader(Header
, SecName
, DotStrtab
, CBA
, YAMLSec
);
324 else if (SecName
== ".shstrtab")
325 initStrtabSectionHeader(Header
, SecName
, DotShStrtab
, CBA
, YAMLSec
);
326 else if (SecName
== ".dynsym")
327 initSymtabSectionHeader(Header
, SymtabType::Dynamic
, CBA
, YAMLSec
);
328 else if (SecName
== ".dynstr")
329 initStrtabSectionHeader(Header
, SecName
, DotDynstr
, CBA
, YAMLSec
);
333 // Override the fields if requested.
336 Header
.sh_name
= *YAMLSec
->ShName
;
337 if (YAMLSec
->ShOffset
)
338 Header
.sh_offset
= *YAMLSec
->ShOffset
;
340 Header
.sh_size
= *YAMLSec
->ShSize
;
346 StringRef
llvm::ELFYAML::dropUniqueSuffix(StringRef S
) {
347 size_t SuffixPos
= S
.rfind(" [");
348 if (SuffixPos
== StringRef::npos
)
350 return S
.substr(0, SuffixPos
);
353 template <class ELFT
>
354 void ELFState
<ELFT
>::initSectionHeaders(std::vector
<Elf_Shdr
> &SHeaders
,
355 ContiguousBlobAccumulator
&CBA
) {
356 // Ensure SHN_UNDEF entry is present. An all-zero section header is a
357 // valid SHN_UNDEF entry since SHT_NULL == 0.
358 SHeaders
.resize(Doc
.Sections
.size());
360 for (size_t I
= 0; I
< Doc
.Sections
.size(); ++I
) {
361 ELFYAML::Section
*Sec
= Doc
.Sections
[I
].get();
362 if (I
== 0 && Sec
->IsImplicit
)
365 // We have a few sections like string or symbol tables that are usually
366 // added implicitly to the end. However, if they are explicitly specified
367 // in the YAML, we need to write them here. This ensures the file offset
369 Elf_Shdr
&SHeader
= SHeaders
[I
];
370 if (initImplicitHeader(CBA
, SHeader
, Sec
->Name
,
371 Sec
->IsImplicit
? nullptr : Sec
))
374 assert(Sec
&& "It can't be null unless it is an implicit section. But all "
375 "implicit sections should already have been handled above.");
378 DotShStrtab
.getOffset(ELFYAML::dropUniqueSuffix(Sec
->Name
));
379 SHeader
.sh_type
= Sec
->Type
;
381 SHeader
.sh_flags
= *Sec
->Flags
;
382 SHeader
.sh_addr
= Sec
->Address
;
383 SHeader
.sh_addralign
= Sec
->AddressAlign
;
385 if (!Sec
->Link
.empty())
386 SHeader
.sh_link
= toSectionIndex(Sec
->Link
, Sec
->Name
);
389 if (auto RawSec
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
390 // We do not write any content for special SHN_UNDEF section.
392 SHeader
.sh_size
= *RawSec
->Size
;
394 SHeader
.sh_info
= *RawSec
->Info
;
397 SHeader
.sh_entsize
= *Sec
->EntSize
;
398 } else if (auto S
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
399 writeSectionContent(SHeader
, *S
, CBA
);
400 } else if (auto S
= dyn_cast
<ELFYAML::SymtabShndxSection
>(Sec
)) {
401 writeSectionContent(SHeader
, *S
, CBA
);
402 } else if (auto S
= dyn_cast
<ELFYAML::RelocationSection
>(Sec
)) {
403 writeSectionContent(SHeader
, *S
, CBA
);
404 } else if (auto S
= dyn_cast
<ELFYAML::Group
>(Sec
)) {
405 writeSectionContent(SHeader
, *S
, CBA
);
406 } else if (auto S
= dyn_cast
<ELFYAML::MipsABIFlags
>(Sec
)) {
407 writeSectionContent(SHeader
, *S
, CBA
);
408 } else if (auto S
= dyn_cast
<ELFYAML::NoBitsSection
>(Sec
)) {
409 SHeader
.sh_entsize
= 0;
410 SHeader
.sh_size
= S
->Size
;
411 // SHT_NOBITS section does not have content
412 // so just to setup the section offset.
413 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
414 } else if (auto S
= dyn_cast
<ELFYAML::DynamicSection
>(Sec
)) {
415 writeSectionContent(SHeader
, *S
, CBA
);
416 } else if (auto S
= dyn_cast
<ELFYAML::SymverSection
>(Sec
)) {
417 writeSectionContent(SHeader
, *S
, CBA
);
418 } else if (auto S
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
)) {
419 writeSectionContent(SHeader
, *S
, CBA
);
420 } else if (auto S
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
)) {
421 writeSectionContent(SHeader
, *S
, CBA
);
422 } else if (auto S
= dyn_cast
<ELFYAML::StackSizesSection
>(Sec
)) {
423 writeSectionContent(SHeader
, *S
, CBA
);
424 } else if (auto S
= dyn_cast
<ELFYAML::HashSection
>(Sec
)) {
425 writeSectionContent(SHeader
, *S
, CBA
);
427 llvm_unreachable("Unknown section type");
430 // Override the fields if requested.
433 SHeader
.sh_name
= *Sec
->ShName
;
435 SHeader
.sh_offset
= *Sec
->ShOffset
;
437 SHeader
.sh_size
= *Sec
->ShSize
;
442 static size_t findFirstNonGlobal(ArrayRef
<ELFYAML::Symbol
> Symbols
) {
443 for (size_t I
= 0; I
< Symbols
.size(); ++I
)
444 if (Symbols
[I
].Binding
.value
!= ELF::STB_LOCAL
)
446 return Symbols
.size();
449 static uint64_t writeContent(raw_ostream
&OS
,
450 const Optional
<yaml::BinaryRef
> &Content
,
451 const Optional
<llvm::yaml::Hex64
> &Size
) {
452 size_t ContentSize
= 0;
454 Content
->writeAsBinary(OS
);
455 ContentSize
= Content
->binary_size();
461 OS
.write_zeros(*Size
- ContentSize
);
465 template <class ELFT
>
466 std::vector
<typename
ELFT::Sym
>
467 ELFState
<ELFT
>::toELFSymbols(ArrayRef
<ELFYAML::Symbol
> Symbols
,
468 const StringTableBuilder
&Strtab
) {
469 std::vector
<Elf_Sym
> Ret
;
470 Ret
.resize(Symbols
.size() + 1);
473 for (const auto &Sym
: Symbols
) {
474 Elf_Sym
&Symbol
= Ret
[++I
];
476 // If NameIndex, which contains the name offset, is explicitly specified, we
477 // use it. This is useful for preparing broken objects. Otherwise, we add
478 // the specified Name to the string table builder to get its offset.
480 Symbol
.st_name
= *Sym
.NameIndex
;
481 else if (!Sym
.Name
.empty())
482 Symbol
.st_name
= Strtab
.getOffset(ELFYAML::dropUniqueSuffix(Sym
.Name
));
484 Symbol
.setBindingAndType(Sym
.Binding
, Sym
.Type
);
485 if (!Sym
.Section
.empty())
486 Symbol
.st_shndx
= toSectionIndex(Sym
.Section
, "", Sym
.Name
);
488 Symbol
.st_shndx
= *Sym
.Index
;
490 Symbol
.st_value
= Sym
.Value
;
491 Symbol
.st_other
= Sym
.Other
? *Sym
.Other
: 0;
492 Symbol
.st_size
= Sym
.Size
;
498 template <class ELFT
>
499 void ELFState
<ELFT
>::initSymtabSectionHeader(Elf_Shdr
&SHeader
,
501 ContiguousBlobAccumulator
&CBA
,
502 ELFYAML::Section
*YAMLSec
) {
504 bool IsStatic
= STType
== SymtabType::Static
;
505 const auto &Symbols
= IsStatic
? Doc
.Symbols
: Doc
.DynamicSymbols
;
507 ELFYAML::RawContentSection
*RawSec
=
508 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
509 if (RawSec
&& !Symbols
.empty() && (RawSec
->Content
|| RawSec
->Size
)) {
511 reportError("cannot specify both `Content` and " +
512 (IsStatic
? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
513 " for symbol table section '" + RawSec
->Name
+ "'");
515 reportError("cannot specify both `Size` and " +
516 (IsStatic
? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
517 " for symbol table section '" + RawSec
->Name
+ "'");
522 SHeader
.sh_name
= DotShStrtab
.getOffset(IsStatic
? ".symtab" : ".dynsym");
525 SHeader
.sh_type
= YAMLSec
->Type
;
527 SHeader
.sh_type
= IsStatic
? ELF::SHT_SYMTAB
: ELF::SHT_DYNSYM
;
529 if (RawSec
&& !RawSec
->Link
.empty()) {
530 // If the Link field is explicitly defined in the document,
532 SHeader
.sh_link
= toSectionIndex(RawSec
->Link
, RawSec
->Name
);
534 // When we describe the .dynsym section in the document explicitly, it is
535 // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not
536 // added implicitly and we should be able to leave the Link zeroed if
537 // .dynstr is not defined.
540 Link
= SN2I
.get(".strtab");
542 SN2I
.lookup(".dynstr", Link
);
543 SHeader
.sh_link
= Link
;
546 if (YAMLSec
&& YAMLSec
->Flags
)
547 SHeader
.sh_flags
= *YAMLSec
->Flags
;
549 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
551 // If the symbol table section is explicitly described in the YAML
552 // then we should set the fields requested.
553 SHeader
.sh_info
= (RawSec
&& RawSec
->Info
) ? (unsigned)(*RawSec
->Info
)
554 : findFirstNonGlobal(Symbols
) + 1;
555 SHeader
.sh_entsize
= (YAMLSec
&& YAMLSec
->EntSize
)
556 ? (uint64_t)(*YAMLSec
->EntSize
)
558 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 8;
559 SHeader
.sh_addr
= YAMLSec
? (uint64_t)YAMLSec
->Address
: 0;
561 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
562 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
563 assert(Symbols
.empty());
564 SHeader
.sh_size
= writeContent(OS
, RawSec
->Content
, RawSec
->Size
);
568 std::vector
<Elf_Sym
> Syms
=
569 toELFSymbols(Symbols
, IsStatic
? DotStrtab
: DotDynstr
);
570 writeArrayData(OS
, makeArrayRef(Syms
));
571 SHeader
.sh_size
= arrayDataSize(makeArrayRef(Syms
));
574 template <class ELFT
>
575 void ELFState
<ELFT
>::initStrtabSectionHeader(Elf_Shdr
&SHeader
, StringRef Name
,
576 StringTableBuilder
&STB
,
577 ContiguousBlobAccumulator
&CBA
,
578 ELFYAML::Section
*YAMLSec
) {
580 SHeader
.sh_name
= DotShStrtab
.getOffset(Name
);
581 SHeader
.sh_type
= YAMLSec
? YAMLSec
->Type
: ELF::SHT_STRTAB
;
582 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 1;
584 ELFYAML::RawContentSection
*RawSec
=
585 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
587 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
588 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
589 SHeader
.sh_size
= writeContent(OS
, RawSec
->Content
, RawSec
->Size
);
592 SHeader
.sh_size
= STB
.getSize();
595 if (YAMLSec
&& YAMLSec
->EntSize
)
596 SHeader
.sh_entsize
= *YAMLSec
->EntSize
;
598 if (RawSec
&& RawSec
->Info
)
599 SHeader
.sh_info
= *RawSec
->Info
;
601 if (YAMLSec
&& YAMLSec
->Flags
)
602 SHeader
.sh_flags
= *YAMLSec
->Flags
;
603 else if (Name
== ".dynstr")
604 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
606 // If the section is explicitly described in the YAML
607 // then we want to use its section address.
609 SHeader
.sh_addr
= YAMLSec
->Address
;
612 template <class ELFT
> void ELFState
<ELFT
>::reportError(const Twine
&Msg
) {
617 template <class ELFT
>
618 void ELFState
<ELFT
>::setProgramHeaderLayout(std::vector
<Elf_Phdr
> &PHeaders
,
619 std::vector
<Elf_Shdr
> &SHeaders
) {
620 uint32_t PhdrIdx
= 0;
621 for (auto &YamlPhdr
: Doc
.ProgramHeaders
) {
622 Elf_Phdr
&PHeader
= PHeaders
[PhdrIdx
++];
624 std::vector
<Elf_Shdr
*> Sections
;
625 for (const ELFYAML::SectionName
&SecName
: YamlPhdr
.Sections
) {
627 if (!SN2I
.lookup(SecName
.Section
, Index
)) {
628 reportError("unknown section referenced: '" + SecName
.Section
+
629 "' by program header");
632 Sections
.push_back(&SHeaders
[Index
]);
635 if (YamlPhdr
.Offset
) {
636 PHeader
.p_offset
= *YamlPhdr
.Offset
;
638 if (YamlPhdr
.Sections
.size())
639 PHeader
.p_offset
= UINT32_MAX
;
641 PHeader
.p_offset
= 0;
643 // Find the minimum offset for the program header.
644 for (Elf_Shdr
*SHeader
: Sections
)
645 PHeader
.p_offset
= std::min(PHeader
.p_offset
, SHeader
->sh_offset
);
648 // Find the maximum offset of the end of a section in order to set p_filesz
649 // and p_memsz. When setting p_filesz, trailing SHT_NOBITS sections are not
651 uint64_t FileOffset
= PHeader
.p_offset
, MemOffset
= PHeader
.p_offset
;
652 for (Elf_Shdr
*SHeader
: Sections
) {
653 uint64_t End
= SHeader
->sh_offset
+ SHeader
->sh_size
;
654 MemOffset
= std::max(MemOffset
, End
);
656 if (SHeader
->sh_type
!= llvm::ELF::SHT_NOBITS
)
657 FileOffset
= std::max(FileOffset
, End
);
660 // Set the file size and the memory size if not set explicitly.
661 PHeader
.p_filesz
= YamlPhdr
.FileSize
? uint64_t(*YamlPhdr
.FileSize
)
662 : FileOffset
- PHeader
.p_offset
;
663 PHeader
.p_memsz
= YamlPhdr
.MemSize
? uint64_t(*YamlPhdr
.MemSize
)
664 : MemOffset
- PHeader
.p_offset
;
666 if (YamlPhdr
.Align
) {
667 PHeader
.p_align
= *YamlPhdr
.Align
;
669 // Set the alignment of the segment to be the maximum alignment of the
670 // sections so that by default the segment has a valid and sensible
673 for (Elf_Shdr
*SHeader
: Sections
)
674 PHeader
.p_align
= std::max(PHeader
.p_align
, SHeader
->sh_addralign
);
679 template <class ELFT
>
680 void ELFState
<ELFT
>::writeSectionContent(
681 Elf_Shdr
&SHeader
, const ELFYAML::RawContentSection
&Section
,
682 ContiguousBlobAccumulator
&CBA
) {
684 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
685 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
688 SHeader
.sh_entsize
= *Section
.EntSize
;
689 else if (Section
.Type
== llvm::ELF::SHT_RELR
)
690 SHeader
.sh_entsize
= sizeof(Elf_Relr
);
692 SHeader
.sh_entsize
= 0;
695 SHeader
.sh_info
= *Section
.Info
;
698 static bool isMips64EL(const ELFYAML::Object
&Doc
) {
699 return Doc
.Header
.Machine
== ELFYAML::ELF_EM(llvm::ELF::EM_MIPS
) &&
700 Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
) &&
701 Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
704 template <class ELFT
>
705 void ELFState
<ELFT
>::writeSectionContent(
706 Elf_Shdr
&SHeader
, const ELFYAML::RelocationSection
&Section
,
707 ContiguousBlobAccumulator
&CBA
) {
708 assert((Section
.Type
== llvm::ELF::SHT_REL
||
709 Section
.Type
== llvm::ELF::SHT_RELA
) &&
710 "Section type is not SHT_REL nor SHT_RELA");
712 bool IsRela
= Section
.Type
== llvm::ELF::SHT_RELA
;
713 SHeader
.sh_entsize
= IsRela
? sizeof(Elf_Rela
) : sizeof(Elf_Rel
);
714 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Relocations
.size();
716 // For relocation section set link to .symtab by default.
717 if (Section
.Link
.empty())
718 SHeader
.sh_link
= SN2I
.get(".symtab");
720 if (!Section
.RelocatableSec
.empty())
721 SHeader
.sh_info
= toSectionIndex(Section
.RelocatableSec
, Section
.Name
);
723 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
724 for (const auto &Rel
: Section
.Relocations
) {
725 unsigned SymIdx
= Rel
.Symbol
? toSymbolIndex(*Rel
.Symbol
, Section
.Name
,
726 Section
.Link
== ".dynsym")
731 REntry
.r_offset
= Rel
.Offset
;
732 REntry
.r_addend
= Rel
.Addend
;
733 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
734 OS
.write((const char *)&REntry
, sizeof(REntry
));
738 REntry
.r_offset
= Rel
.Offset
;
739 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
740 OS
.write((const char *)&REntry
, sizeof(REntry
));
745 template <class ELFT
>
746 void ELFState
<ELFT
>::writeSectionContent(
747 Elf_Shdr
&SHeader
, const ELFYAML::SymtabShndxSection
&Shndx
,
748 ContiguousBlobAccumulator
&CBA
) {
750 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
752 for (uint32_t E
: Shndx
.Entries
)
753 support::endian::write
<uint32_t>(OS
, E
, ELFT::TargetEndianness
);
755 SHeader
.sh_entsize
= Shndx
.EntSize
? (uint64_t)*Shndx
.EntSize
: 4;
756 SHeader
.sh_size
= Shndx
.Entries
.size() * SHeader
.sh_entsize
;
759 template <class ELFT
>
760 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
761 const ELFYAML::Group
&Section
,
762 ContiguousBlobAccumulator
&CBA
) {
763 assert(Section
.Type
== llvm::ELF::SHT_GROUP
&&
764 "Section type is not SHT_GROUP");
766 SHeader
.sh_entsize
= 4;
767 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Members
.size();
769 toSymbolIndex(Section
.Signature
, Section
.Name
, /*IsDynamic=*/false);
772 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
774 for (const ELFYAML::SectionOrType
&Member
: Section
.Members
) {
775 unsigned int SectionIndex
= 0;
776 if (Member
.sectionNameOrType
== "GRP_COMDAT")
777 SectionIndex
= llvm::ELF::GRP_COMDAT
;
779 SectionIndex
= toSectionIndex(Member
.sectionNameOrType
, Section
.Name
);
780 support::endian::write
<uint32_t>(OS
, SectionIndex
, ELFT::TargetEndianness
);
784 template <class ELFT
>
785 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
786 const ELFYAML::SymverSection
&Section
,
787 ContiguousBlobAccumulator
&CBA
) {
789 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
790 for (uint16_t Version
: Section
.Entries
)
791 support::endian::write
<uint16_t>(OS
, Version
, ELFT::TargetEndianness
);
793 SHeader
.sh_entsize
= Section
.EntSize
? (uint64_t)*Section
.EntSize
: 2;
794 SHeader
.sh_size
= Section
.Entries
.size() * SHeader
.sh_entsize
;
797 template <class ELFT
>
798 void ELFState
<ELFT
>::writeSectionContent(
799 Elf_Shdr
&SHeader
, const ELFYAML::StackSizesSection
&Section
,
800 ContiguousBlobAccumulator
&CBA
) {
801 using uintX_t
= typename
ELFT::uint
;
803 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
805 if (Section
.Content
|| Section
.Size
) {
806 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
810 for (const ELFYAML::StackSizeEntry
&E
: *Section
.Entries
) {
811 support::endian::write
<uintX_t
>(OS
, E
.Address
, ELFT::TargetEndianness
);
812 SHeader
.sh_size
+= sizeof(uintX_t
) + encodeULEB128(E
.Size
, OS
);
816 template <class ELFT
>
817 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
818 const ELFYAML::HashSection
&Section
,
819 ContiguousBlobAccumulator
&CBA
) {
821 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
824 if (Section
.Link
.empty() && SN2I
.lookup(".dynsym", Link
))
825 SHeader
.sh_link
= Link
;
827 if (Section
.Content
|| Section
.Size
) {
828 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
832 support::endian::write
<uint32_t>(OS
, Section
.Bucket
->size(),
833 ELFT::TargetEndianness
);
834 support::endian::write
<uint32_t>(OS
, Section
.Chain
->size(),
835 ELFT::TargetEndianness
);
836 for (uint32_t Val
: *Section
.Bucket
)
837 support::endian::write
<uint32_t>(OS
, Val
, ELFT::TargetEndianness
);
838 for (uint32_t Val
: *Section
.Chain
)
839 support::endian::write
<uint32_t>(OS
, Val
, ELFT::TargetEndianness
);
841 SHeader
.sh_size
= (2 + Section
.Bucket
->size() + Section
.Chain
->size()) * 4;
844 template <class ELFT
>
845 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
846 const ELFYAML::VerdefSection
&Section
,
847 ContiguousBlobAccumulator
&CBA
) {
848 typedef typename
ELFT::Verdef Elf_Verdef
;
849 typedef typename
ELFT::Verdaux Elf_Verdaux
;
851 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
854 for (size_t I
= 0; I
< Section
.Entries
.size(); ++I
) {
855 const ELFYAML::VerdefEntry
&E
= Section
.Entries
[I
];
858 VerDef
.vd_version
= E
.Version
;
859 VerDef
.vd_flags
= E
.Flags
;
860 VerDef
.vd_ndx
= E
.VersionNdx
;
861 VerDef
.vd_hash
= E
.Hash
;
862 VerDef
.vd_aux
= sizeof(Elf_Verdef
);
863 VerDef
.vd_cnt
= E
.VerNames
.size();
864 if (I
== Section
.Entries
.size() - 1)
868 sizeof(Elf_Verdef
) + E
.VerNames
.size() * sizeof(Elf_Verdaux
);
869 OS
.write((const char *)&VerDef
, sizeof(Elf_Verdef
));
871 for (size_t J
= 0; J
< E
.VerNames
.size(); ++J
, ++AuxCnt
) {
873 VernAux
.vda_name
= DotDynstr
.getOffset(E
.VerNames
[J
]);
874 if (J
== E
.VerNames
.size() - 1)
875 VernAux
.vda_next
= 0;
877 VernAux
.vda_next
= sizeof(Elf_Verdaux
);
878 OS
.write((const char *)&VernAux
, sizeof(Elf_Verdaux
));
882 SHeader
.sh_size
= Section
.Entries
.size() * sizeof(Elf_Verdef
) +
883 AuxCnt
* sizeof(Elf_Verdaux
);
884 SHeader
.sh_info
= Section
.Info
;
887 template <class ELFT
>
888 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
889 const ELFYAML::VerneedSection
&Section
,
890 ContiguousBlobAccumulator
&CBA
) {
891 typedef typename
ELFT::Verneed Elf_Verneed
;
892 typedef typename
ELFT::Vernaux Elf_Vernaux
;
894 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
897 for (size_t I
= 0; I
< Section
.VerneedV
.size(); ++I
) {
898 const ELFYAML::VerneedEntry
&VE
= Section
.VerneedV
[I
];
901 VerNeed
.vn_version
= VE
.Version
;
902 VerNeed
.vn_file
= DotDynstr
.getOffset(VE
.File
);
903 if (I
== Section
.VerneedV
.size() - 1)
907 sizeof(Elf_Verneed
) + VE
.AuxV
.size() * sizeof(Elf_Vernaux
);
908 VerNeed
.vn_cnt
= VE
.AuxV
.size();
909 VerNeed
.vn_aux
= sizeof(Elf_Verneed
);
910 OS
.write((const char *)&VerNeed
, sizeof(Elf_Verneed
));
912 for (size_t J
= 0; J
< VE
.AuxV
.size(); ++J
, ++AuxCnt
) {
913 const ELFYAML::VernauxEntry
&VAuxE
= VE
.AuxV
[J
];
916 VernAux
.vna_hash
= VAuxE
.Hash
;
917 VernAux
.vna_flags
= VAuxE
.Flags
;
918 VernAux
.vna_other
= VAuxE
.Other
;
919 VernAux
.vna_name
= DotDynstr
.getOffset(VAuxE
.Name
);
920 if (J
== VE
.AuxV
.size() - 1)
921 VernAux
.vna_next
= 0;
923 VernAux
.vna_next
= sizeof(Elf_Vernaux
);
924 OS
.write((const char *)&VernAux
, sizeof(Elf_Vernaux
));
928 SHeader
.sh_size
= Section
.VerneedV
.size() * sizeof(Elf_Verneed
) +
929 AuxCnt
* sizeof(Elf_Vernaux
);
930 SHeader
.sh_info
= Section
.Info
;
933 template <class ELFT
>
934 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
935 const ELFYAML::MipsABIFlags
&Section
,
936 ContiguousBlobAccumulator
&CBA
) {
937 assert(Section
.Type
== llvm::ELF::SHT_MIPS_ABIFLAGS
&&
938 "Section type is not SHT_MIPS_ABIFLAGS");
940 object::Elf_Mips_ABIFlags
<ELFT
> Flags
;
942 SHeader
.sh_entsize
= sizeof(Flags
);
943 SHeader
.sh_size
= SHeader
.sh_entsize
;
945 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
946 Flags
.version
= Section
.Version
;
947 Flags
.isa_level
= Section
.ISALevel
;
948 Flags
.isa_rev
= Section
.ISARevision
;
949 Flags
.gpr_size
= Section
.GPRSize
;
950 Flags
.cpr1_size
= Section
.CPR1Size
;
951 Flags
.cpr2_size
= Section
.CPR2Size
;
952 Flags
.fp_abi
= Section
.FpABI
;
953 Flags
.isa_ext
= Section
.ISAExtension
;
954 Flags
.ases
= Section
.ASEs
;
955 Flags
.flags1
= Section
.Flags1
;
956 Flags
.flags2
= Section
.Flags2
;
957 OS
.write((const char *)&Flags
, sizeof(Flags
));
960 template <class ELFT
>
961 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
962 const ELFYAML::DynamicSection
&Section
,
963 ContiguousBlobAccumulator
&CBA
) {
964 typedef typename
ELFT::uint uintX_t
;
966 assert(Section
.Type
== llvm::ELF::SHT_DYNAMIC
&&
967 "Section type is not SHT_DYNAMIC");
969 if (!Section
.Entries
.empty() && Section
.Content
)
970 reportError("cannot specify both raw content and explicit entries "
971 "for dynamic section '" +
975 SHeader
.sh_size
= Section
.Content
->binary_size();
977 SHeader
.sh_size
= 2 * sizeof(uintX_t
) * Section
.Entries
.size();
979 SHeader
.sh_entsize
= *Section
.EntSize
;
981 SHeader
.sh_entsize
= sizeof(Elf_Dyn
);
984 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
985 for (const ELFYAML::DynamicEntry
&DE
: Section
.Entries
) {
986 support::endian::write
<uintX_t
>(OS
, DE
.Tag
, ELFT::TargetEndianness
);
987 support::endian::write
<uintX_t
>(OS
, DE
.Val
, ELFT::TargetEndianness
);
990 Section
.Content
->writeAsBinary(OS
);
993 template <class ELFT
> void ELFState
<ELFT
>::buildSectionIndex() {
994 for (unsigned I
= 0, E
= Doc
.Sections
.size(); I
!= E
; ++I
) {
995 StringRef Name
= Doc
.Sections
[I
]->Name
;
999 DotShStrtab
.add(ELFYAML::dropUniqueSuffix(Name
));
1000 if (!SN2I
.addName(Name
, I
))
1001 reportError("repeated section name: '" + Name
+
1002 "' at YAML section number " + Twine(I
));
1005 DotShStrtab
.finalize();
1008 template <class ELFT
> void ELFState
<ELFT
>::buildSymbolIndexes() {
1009 auto Build
= [this](ArrayRef
<ELFYAML::Symbol
> V
, NameToIdxMap
&Map
) {
1010 for (size_t I
= 0, S
= V
.size(); I
< S
; ++I
) {
1011 const ELFYAML::Symbol
&Sym
= V
[I
];
1012 if (!Sym
.Name
.empty() && !Map
.addName(Sym
.Name
, I
+ 1))
1013 reportError("repeated symbol name: '" + Sym
.Name
+ "'");
1017 Build(Doc
.Symbols
, SymN2I
);
1018 Build(Doc
.DynamicSymbols
, DynSymN2I
);
1021 template <class ELFT
> void ELFState
<ELFT
>::finalizeStrings() {
1022 // Add the regular symbol names to .strtab section.
1023 for (const ELFYAML::Symbol
&Sym
: Doc
.Symbols
)
1024 DotStrtab
.add(ELFYAML::dropUniqueSuffix(Sym
.Name
));
1025 DotStrtab
.finalize();
1027 // Add the dynamic symbol names to .dynstr section.
1028 for (const ELFYAML::Symbol
&Sym
: Doc
.DynamicSymbols
)
1029 DotDynstr
.add(ELFYAML::dropUniqueSuffix(Sym
.Name
));
1031 // SHT_GNU_verdef and SHT_GNU_verneed sections might also
1032 // add strings to .dynstr section.
1033 for (const std::unique_ptr
<ELFYAML::Section
> &Sec
: Doc
.Sections
) {
1034 if (auto VerNeed
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
.get())) {
1035 for (const ELFYAML::VerneedEntry
&VE
: VerNeed
->VerneedV
) {
1036 DotDynstr
.add(VE
.File
);
1037 for (const ELFYAML::VernauxEntry
&Aux
: VE
.AuxV
)
1038 DotDynstr
.add(Aux
.Name
);
1040 } else if (auto VerDef
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
.get())) {
1041 for (const ELFYAML::VerdefEntry
&E
: VerDef
->Entries
)
1042 for (StringRef Name
: E
.VerNames
)
1043 DotDynstr
.add(Name
);
1047 DotDynstr
.finalize();
1050 template <class ELFT
>
1051 bool ELFState
<ELFT
>::writeELF(raw_ostream
&OS
, ELFYAML::Object
&Doc
,
1052 yaml::ErrorHandler EH
) {
1053 ELFState
<ELFT
> State(Doc
, EH
);
1055 // Finalize .strtab and .dynstr sections. We do that early because want to
1056 // finalize the string table builders before writing the content of the
1057 // sections that might want to use them.
1058 State
.finalizeStrings();
1060 State
.buildSectionIndex();
1061 State
.buildSymbolIndexes();
1063 std::vector
<Elf_Phdr
> PHeaders
;
1064 State
.initProgramHeaders(PHeaders
);
1066 // XXX: This offset is tightly coupled with the order that we write
1068 const size_t SectionContentBeginOffset
=
1069 sizeof(Elf_Ehdr
) + sizeof(Elf_Phdr
) * Doc
.ProgramHeaders
.size();
1070 ContiguousBlobAccumulator
CBA(SectionContentBeginOffset
);
1072 std::vector
<Elf_Shdr
> SHeaders
;
1073 State
.initSectionHeaders(SHeaders
, CBA
);
1075 // Now we can decide segment offsets
1076 State
.setProgramHeaderLayout(PHeaders
, SHeaders
);
1081 State
.writeELFHeader(CBA
, OS
);
1082 writeArrayData(OS
, makeArrayRef(PHeaders
));
1083 CBA
.writeBlobToStream(OS
);
1084 writeArrayData(OS
, makeArrayRef(SHeaders
));
1091 bool yaml2elf(llvm::ELFYAML::Object
&Doc
, raw_ostream
&Out
, ErrorHandler EH
) {
1092 bool IsLE
= Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
1093 bool Is64Bit
= Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
);
1096 return ELFState
<object::ELF64LE
>::writeELF(Out
, Doc
, EH
);
1097 return ELFState
<object::ELF64BE
>::writeELF(Out
, Doc
, EH
);
1100 return ELFState
<object::ELF32LE
>::writeELF(Out
, Doc
, EH
);
1101 return ELFState
<object::ELF32BE
>::writeELF(Out
, Doc
, EH
);