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 void writeSectionContent(Elf_Shdr
&SHeader
,
178 const ELFYAML::AddrsigSection
&Section
,
179 ContiguousBlobAccumulator
&CBA
);
181 ELFState(ELFYAML::Object
&D
, yaml::ErrorHandler EH
);
184 static bool writeELF(raw_ostream
&OS
, ELFYAML::Object
&Doc
,
185 yaml::ErrorHandler EH
);
187 } // end anonymous namespace
189 template <class T
> static size_t arrayDataSize(ArrayRef
<T
> A
) {
190 return A
.size() * sizeof(T
);
193 template <class T
> static void writeArrayData(raw_ostream
&OS
, ArrayRef
<T
> A
) {
194 OS
.write((const char *)A
.data(), arrayDataSize(A
));
197 template <class T
> static void zero(T
&Obj
) { memset(&Obj
, 0, sizeof(Obj
)); }
199 template <class ELFT
>
200 ELFState
<ELFT
>::ELFState(ELFYAML::Object
&D
, yaml::ErrorHandler EH
)
201 : Doc(D
), ErrHandler(EH
) {
202 StringSet
<> DocSections
;
203 for (std::unique_ptr
<ELFYAML::Section
> &D
: Doc
.Sections
)
204 if (!D
->Name
.empty())
205 DocSections
.insert(D
->Name
);
207 // Insert SHT_NULL section implicitly when it is not defined in YAML.
208 if (Doc
.Sections
.empty() || Doc
.Sections
.front()->Type
!= ELF::SHT_NULL
)
210 Doc
.Sections
.begin(),
211 std::make_unique
<ELFYAML::Section
>(
212 ELFYAML::Section::SectionKind::RawContent
, /*IsImplicit=*/true));
214 std::vector
<StringRef
> ImplicitSections
= {".symtab", ".strtab", ".shstrtab"};
215 if (!Doc
.DynamicSymbols
.empty())
216 ImplicitSections
.insert(ImplicitSections
.end(), {".dynsym", ".dynstr"});
218 // Insert placeholders for implicit sections that are not
219 // defined explicitly in YAML.
220 for (StringRef SecName
: ImplicitSections
) {
221 if (DocSections
.count(SecName
))
224 std::unique_ptr
<ELFYAML::Section
> Sec
= std::make_unique
<ELFYAML::Section
>(
225 ELFYAML::Section::SectionKind::RawContent
, true /*IsImplicit*/);
227 Doc
.Sections
.push_back(std::move(Sec
));
231 template <class ELFT
>
232 void ELFState
<ELFT
>::writeELFHeader(ContiguousBlobAccumulator
&CBA
, raw_ostream
&OS
) {
233 using namespace llvm::ELF
;
237 Header
.e_ident
[EI_MAG0
] = 0x7f;
238 Header
.e_ident
[EI_MAG1
] = 'E';
239 Header
.e_ident
[EI_MAG2
] = 'L';
240 Header
.e_ident
[EI_MAG3
] = 'F';
241 Header
.e_ident
[EI_CLASS
] = ELFT::Is64Bits
? ELFCLASS64
: ELFCLASS32
;
242 Header
.e_ident
[EI_DATA
] = Doc
.Header
.Data
;
243 Header
.e_ident
[EI_VERSION
] = EV_CURRENT
;
244 Header
.e_ident
[EI_OSABI
] = Doc
.Header
.OSABI
;
245 Header
.e_ident
[EI_ABIVERSION
] = Doc
.Header
.ABIVersion
;
246 Header
.e_type
= Doc
.Header
.Type
;
247 Header
.e_machine
= Doc
.Header
.Machine
;
248 Header
.e_version
= EV_CURRENT
;
249 Header
.e_entry
= Doc
.Header
.Entry
;
250 Header
.e_phoff
= Doc
.ProgramHeaders
.size() ? sizeof(Header
) : 0;
251 Header
.e_flags
= Doc
.Header
.Flags
;
252 Header
.e_ehsize
= sizeof(Elf_Ehdr
);
253 Header
.e_phentsize
= Doc
.ProgramHeaders
.size() ? sizeof(Elf_Phdr
) : 0;
254 Header
.e_phnum
= Doc
.ProgramHeaders
.size();
257 Doc
.Header
.SHEntSize
? (uint16_t)*Doc
.Header
.SHEntSize
: sizeof(Elf_Shdr
);
258 // Immediately following the ELF header and program headers.
259 // Align the start of the section header and write the ELF header.
261 CBA
.getOSAndAlignedOffset(SHOff
, sizeof(typename
ELFT::uint
));
263 Doc
.Header
.SHOff
? typename
ELFT::uint(*Doc
.Header
.SHOff
) : SHOff
;
265 Doc
.Header
.SHNum
? (uint16_t)*Doc
.Header
.SHNum
: Doc
.Sections
.size();
266 Header
.e_shstrndx
= Doc
.Header
.SHStrNdx
? (uint16_t)*Doc
.Header
.SHStrNdx
267 : SN2I
.get(".shstrtab");
269 OS
.write((const char *)&Header
, sizeof(Header
));
272 template <class ELFT
>
273 void ELFState
<ELFT
>::initProgramHeaders(std::vector
<Elf_Phdr
> &PHeaders
) {
274 for (const auto &YamlPhdr
: Doc
.ProgramHeaders
) {
276 Phdr
.p_type
= YamlPhdr
.Type
;
277 Phdr
.p_flags
= YamlPhdr
.Flags
;
278 Phdr
.p_vaddr
= YamlPhdr
.VAddr
;
279 Phdr
.p_paddr
= YamlPhdr
.PAddr
;
280 PHeaders
.push_back(Phdr
);
284 template <class ELFT
>
285 unsigned ELFState
<ELFT
>::toSectionIndex(StringRef S
, StringRef LocSec
,
288 if (SN2I
.lookup(S
, Index
) || to_integer(S
, Index
))
291 assert(LocSec
.empty() || LocSym
.empty());
293 reportError("unknown section referenced: '" + S
+ "' by YAML symbol '" +
296 reportError("unknown section referenced: '" + S
+ "' by YAML section '" +
301 template <class ELFT
>
302 unsigned ELFState
<ELFT
>::toSymbolIndex(StringRef S
, StringRef LocSec
,
304 const NameToIdxMap
&SymMap
= IsDynamic
? DynSymN2I
: SymN2I
;
306 // Here we try to look up S in the symbol table. If it is not there,
307 // treat its value as a symbol index.
308 if (!SymMap
.lookup(S
, Index
) && !to_integer(S
, Index
)) {
309 reportError("unknown symbol referenced: '" + S
+ "' by YAML section '" +
316 template <class ELFT
>
317 bool ELFState
<ELFT
>::initImplicitHeader(ContiguousBlobAccumulator
&CBA
,
318 Elf_Shdr
&Header
, StringRef SecName
,
319 ELFYAML::Section
*YAMLSec
) {
320 // Check if the header was already initialized.
321 if (Header
.sh_offset
)
324 if (SecName
== ".symtab")
325 initSymtabSectionHeader(Header
, SymtabType::Static
, CBA
, YAMLSec
);
326 else if (SecName
== ".strtab")
327 initStrtabSectionHeader(Header
, SecName
, DotStrtab
, CBA
, YAMLSec
);
328 else if (SecName
== ".shstrtab")
329 initStrtabSectionHeader(Header
, SecName
, DotShStrtab
, CBA
, YAMLSec
);
330 else if (SecName
== ".dynsym")
331 initSymtabSectionHeader(Header
, SymtabType::Dynamic
, CBA
, YAMLSec
);
332 else if (SecName
== ".dynstr")
333 initStrtabSectionHeader(Header
, SecName
, DotDynstr
, CBA
, YAMLSec
);
337 // Override the fields if requested.
340 Header
.sh_name
= *YAMLSec
->ShName
;
341 if (YAMLSec
->ShOffset
)
342 Header
.sh_offset
= *YAMLSec
->ShOffset
;
344 Header
.sh_size
= *YAMLSec
->ShSize
;
350 StringRef
llvm::ELFYAML::dropUniqueSuffix(StringRef S
) {
351 size_t SuffixPos
= S
.rfind(" [");
352 if (SuffixPos
== StringRef::npos
)
354 return S
.substr(0, SuffixPos
);
357 template <class ELFT
>
358 void ELFState
<ELFT
>::initSectionHeaders(std::vector
<Elf_Shdr
> &SHeaders
,
359 ContiguousBlobAccumulator
&CBA
) {
360 // Ensure SHN_UNDEF entry is present. An all-zero section header is a
361 // valid SHN_UNDEF entry since SHT_NULL == 0.
362 SHeaders
.resize(Doc
.Sections
.size());
364 for (size_t I
= 0; I
< Doc
.Sections
.size(); ++I
) {
365 ELFYAML::Section
*Sec
= Doc
.Sections
[I
].get();
366 if (I
== 0 && Sec
->IsImplicit
)
369 // We have a few sections like string or symbol tables that are usually
370 // added implicitly to the end. However, if they are explicitly specified
371 // in the YAML, we need to write them here. This ensures the file offset
373 Elf_Shdr
&SHeader
= SHeaders
[I
];
374 if (initImplicitHeader(CBA
, SHeader
, Sec
->Name
,
375 Sec
->IsImplicit
? nullptr : Sec
))
378 assert(Sec
&& "It can't be null unless it is an implicit section. But all "
379 "implicit sections should already have been handled above.");
382 DotShStrtab
.getOffset(ELFYAML::dropUniqueSuffix(Sec
->Name
));
383 SHeader
.sh_type
= Sec
->Type
;
385 SHeader
.sh_flags
= *Sec
->Flags
;
386 SHeader
.sh_addr
= Sec
->Address
;
387 SHeader
.sh_addralign
= Sec
->AddressAlign
;
389 if (!Sec
->Link
.empty())
390 SHeader
.sh_link
= toSectionIndex(Sec
->Link
, Sec
->Name
);
393 if (auto RawSec
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
394 // We do not write any content for special SHN_UNDEF section.
396 SHeader
.sh_size
= *RawSec
->Size
;
398 SHeader
.sh_info
= *RawSec
->Info
;
401 SHeader
.sh_entsize
= *Sec
->EntSize
;
402 } else if (auto S
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
403 writeSectionContent(SHeader
, *S
, CBA
);
404 } else if (auto S
= dyn_cast
<ELFYAML::SymtabShndxSection
>(Sec
)) {
405 writeSectionContent(SHeader
, *S
, CBA
);
406 } else if (auto S
= dyn_cast
<ELFYAML::RelocationSection
>(Sec
)) {
407 writeSectionContent(SHeader
, *S
, CBA
);
408 } else if (auto S
= dyn_cast
<ELFYAML::Group
>(Sec
)) {
409 writeSectionContent(SHeader
, *S
, CBA
);
410 } else if (auto S
= dyn_cast
<ELFYAML::MipsABIFlags
>(Sec
)) {
411 writeSectionContent(SHeader
, *S
, CBA
);
412 } else if (auto S
= dyn_cast
<ELFYAML::NoBitsSection
>(Sec
)) {
413 SHeader
.sh_entsize
= 0;
414 SHeader
.sh_size
= S
->Size
;
415 // SHT_NOBITS section does not have content
416 // so just to setup the section offset.
417 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
418 } else if (auto S
= dyn_cast
<ELFYAML::DynamicSection
>(Sec
)) {
419 writeSectionContent(SHeader
, *S
, CBA
);
420 } else if (auto S
= dyn_cast
<ELFYAML::SymverSection
>(Sec
)) {
421 writeSectionContent(SHeader
, *S
, CBA
);
422 } else if (auto S
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
)) {
423 writeSectionContent(SHeader
, *S
, CBA
);
424 } else if (auto S
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
)) {
425 writeSectionContent(SHeader
, *S
, CBA
);
426 } else if (auto S
= dyn_cast
<ELFYAML::StackSizesSection
>(Sec
)) {
427 writeSectionContent(SHeader
, *S
, CBA
);
428 } else if (auto S
= dyn_cast
<ELFYAML::HashSection
>(Sec
)) {
429 writeSectionContent(SHeader
, *S
, CBA
);
430 } else if (auto S
= dyn_cast
<ELFYAML::AddrsigSection
>(Sec
)) {
431 writeSectionContent(SHeader
, *S
, CBA
);
433 llvm_unreachable("Unknown section type");
436 // Override the fields if requested.
439 SHeader
.sh_name
= *Sec
->ShName
;
441 SHeader
.sh_offset
= *Sec
->ShOffset
;
443 SHeader
.sh_size
= *Sec
->ShSize
;
448 static size_t findFirstNonGlobal(ArrayRef
<ELFYAML::Symbol
> Symbols
) {
449 for (size_t I
= 0; I
< Symbols
.size(); ++I
)
450 if (Symbols
[I
].Binding
.value
!= ELF::STB_LOCAL
)
452 return Symbols
.size();
455 static uint64_t writeContent(raw_ostream
&OS
,
456 const Optional
<yaml::BinaryRef
> &Content
,
457 const Optional
<llvm::yaml::Hex64
> &Size
) {
458 size_t ContentSize
= 0;
460 Content
->writeAsBinary(OS
);
461 ContentSize
= Content
->binary_size();
467 OS
.write_zeros(*Size
- ContentSize
);
471 template <class ELFT
>
472 std::vector
<typename
ELFT::Sym
>
473 ELFState
<ELFT
>::toELFSymbols(ArrayRef
<ELFYAML::Symbol
> Symbols
,
474 const StringTableBuilder
&Strtab
) {
475 std::vector
<Elf_Sym
> Ret
;
476 Ret
.resize(Symbols
.size() + 1);
479 for (const auto &Sym
: Symbols
) {
480 Elf_Sym
&Symbol
= Ret
[++I
];
482 // If NameIndex, which contains the name offset, is explicitly specified, we
483 // use it. This is useful for preparing broken objects. Otherwise, we add
484 // the specified Name to the string table builder to get its offset.
486 Symbol
.st_name
= *Sym
.NameIndex
;
487 else if (!Sym
.Name
.empty())
488 Symbol
.st_name
= Strtab
.getOffset(ELFYAML::dropUniqueSuffix(Sym
.Name
));
490 Symbol
.setBindingAndType(Sym
.Binding
, Sym
.Type
);
491 if (!Sym
.Section
.empty())
492 Symbol
.st_shndx
= toSectionIndex(Sym
.Section
, "", Sym
.Name
);
494 Symbol
.st_shndx
= *Sym
.Index
;
496 Symbol
.st_value
= Sym
.Value
;
497 Symbol
.st_other
= Sym
.Other
? *Sym
.Other
: 0;
498 Symbol
.st_size
= Sym
.Size
;
504 template <class ELFT
>
505 void ELFState
<ELFT
>::initSymtabSectionHeader(Elf_Shdr
&SHeader
,
507 ContiguousBlobAccumulator
&CBA
,
508 ELFYAML::Section
*YAMLSec
) {
510 bool IsStatic
= STType
== SymtabType::Static
;
511 const auto &Symbols
= IsStatic
? Doc
.Symbols
: Doc
.DynamicSymbols
;
513 ELFYAML::RawContentSection
*RawSec
=
514 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
515 if (RawSec
&& !Symbols
.empty() && (RawSec
->Content
|| RawSec
->Size
)) {
517 reportError("cannot specify both `Content` and " +
518 (IsStatic
? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
519 " for symbol table section '" + RawSec
->Name
+ "'");
521 reportError("cannot specify both `Size` and " +
522 (IsStatic
? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
523 " for symbol table section '" + RawSec
->Name
+ "'");
528 SHeader
.sh_name
= DotShStrtab
.getOffset(IsStatic
? ".symtab" : ".dynsym");
531 SHeader
.sh_type
= YAMLSec
->Type
;
533 SHeader
.sh_type
= IsStatic
? ELF::SHT_SYMTAB
: ELF::SHT_DYNSYM
;
535 if (RawSec
&& !RawSec
->Link
.empty()) {
536 // If the Link field is explicitly defined in the document,
538 SHeader
.sh_link
= toSectionIndex(RawSec
->Link
, RawSec
->Name
);
540 // When we describe the .dynsym section in the document explicitly, it is
541 // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not
542 // added implicitly and we should be able to leave the Link zeroed if
543 // .dynstr is not defined.
546 Link
= SN2I
.get(".strtab");
548 SN2I
.lookup(".dynstr", Link
);
549 SHeader
.sh_link
= Link
;
552 if (YAMLSec
&& YAMLSec
->Flags
)
553 SHeader
.sh_flags
= *YAMLSec
->Flags
;
555 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
557 // If the symbol table section is explicitly described in the YAML
558 // then we should set the fields requested.
559 SHeader
.sh_info
= (RawSec
&& RawSec
->Info
) ? (unsigned)(*RawSec
->Info
)
560 : findFirstNonGlobal(Symbols
) + 1;
561 SHeader
.sh_entsize
= (YAMLSec
&& YAMLSec
->EntSize
)
562 ? (uint64_t)(*YAMLSec
->EntSize
)
564 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 8;
565 SHeader
.sh_addr
= YAMLSec
? (uint64_t)YAMLSec
->Address
: 0;
567 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
568 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
569 assert(Symbols
.empty());
570 SHeader
.sh_size
= writeContent(OS
, RawSec
->Content
, RawSec
->Size
);
574 std::vector
<Elf_Sym
> Syms
=
575 toELFSymbols(Symbols
, IsStatic
? DotStrtab
: DotDynstr
);
576 writeArrayData(OS
, makeArrayRef(Syms
));
577 SHeader
.sh_size
= arrayDataSize(makeArrayRef(Syms
));
580 template <class ELFT
>
581 void ELFState
<ELFT
>::initStrtabSectionHeader(Elf_Shdr
&SHeader
, StringRef Name
,
582 StringTableBuilder
&STB
,
583 ContiguousBlobAccumulator
&CBA
,
584 ELFYAML::Section
*YAMLSec
) {
586 SHeader
.sh_name
= DotShStrtab
.getOffset(Name
);
587 SHeader
.sh_type
= YAMLSec
? YAMLSec
->Type
: ELF::SHT_STRTAB
;
588 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 1;
590 ELFYAML::RawContentSection
*RawSec
=
591 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
593 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
594 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
595 SHeader
.sh_size
= writeContent(OS
, RawSec
->Content
, RawSec
->Size
);
598 SHeader
.sh_size
= STB
.getSize();
601 if (YAMLSec
&& YAMLSec
->EntSize
)
602 SHeader
.sh_entsize
= *YAMLSec
->EntSize
;
604 if (RawSec
&& RawSec
->Info
)
605 SHeader
.sh_info
= *RawSec
->Info
;
607 if (YAMLSec
&& YAMLSec
->Flags
)
608 SHeader
.sh_flags
= *YAMLSec
->Flags
;
609 else if (Name
== ".dynstr")
610 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
612 // If the section is explicitly described in the YAML
613 // then we want to use its section address.
615 SHeader
.sh_addr
= YAMLSec
->Address
;
618 template <class ELFT
> void ELFState
<ELFT
>::reportError(const Twine
&Msg
) {
623 template <class ELFT
>
624 void ELFState
<ELFT
>::setProgramHeaderLayout(std::vector
<Elf_Phdr
> &PHeaders
,
625 std::vector
<Elf_Shdr
> &SHeaders
) {
626 uint32_t PhdrIdx
= 0;
627 for (auto &YamlPhdr
: Doc
.ProgramHeaders
) {
628 Elf_Phdr
&PHeader
= PHeaders
[PhdrIdx
++];
630 std::vector
<Elf_Shdr
*> Sections
;
631 for (const ELFYAML::SectionName
&SecName
: YamlPhdr
.Sections
) {
633 if (!SN2I
.lookup(SecName
.Section
, Index
)) {
634 reportError("unknown section referenced: '" + SecName
.Section
+
635 "' by program header");
638 Sections
.push_back(&SHeaders
[Index
]);
641 if (YamlPhdr
.Offset
) {
642 PHeader
.p_offset
= *YamlPhdr
.Offset
;
644 if (YamlPhdr
.Sections
.size())
645 PHeader
.p_offset
= UINT32_MAX
;
647 PHeader
.p_offset
= 0;
649 // Find the minimum offset for the program header.
650 for (Elf_Shdr
*SHeader
: Sections
)
651 PHeader
.p_offset
= std::min(PHeader
.p_offset
, SHeader
->sh_offset
);
654 // Find the maximum offset of the end of a section in order to set p_filesz
655 // and p_memsz. When setting p_filesz, trailing SHT_NOBITS sections are not
657 uint64_t FileOffset
= PHeader
.p_offset
, MemOffset
= PHeader
.p_offset
;
658 for (Elf_Shdr
*SHeader
: Sections
) {
659 uint64_t End
= SHeader
->sh_offset
+ SHeader
->sh_size
;
660 MemOffset
= std::max(MemOffset
, End
);
662 if (SHeader
->sh_type
!= llvm::ELF::SHT_NOBITS
)
663 FileOffset
= std::max(FileOffset
, End
);
666 // Set the file size and the memory size if not set explicitly.
667 PHeader
.p_filesz
= YamlPhdr
.FileSize
? uint64_t(*YamlPhdr
.FileSize
)
668 : FileOffset
- PHeader
.p_offset
;
669 PHeader
.p_memsz
= YamlPhdr
.MemSize
? uint64_t(*YamlPhdr
.MemSize
)
670 : MemOffset
- PHeader
.p_offset
;
672 if (YamlPhdr
.Align
) {
673 PHeader
.p_align
= *YamlPhdr
.Align
;
675 // Set the alignment of the segment to be the maximum alignment of the
676 // sections so that by default the segment has a valid and sensible
679 for (Elf_Shdr
*SHeader
: Sections
)
680 PHeader
.p_align
= std::max(PHeader
.p_align
, SHeader
->sh_addralign
);
685 template <class ELFT
>
686 void ELFState
<ELFT
>::writeSectionContent(
687 Elf_Shdr
&SHeader
, const ELFYAML::RawContentSection
&Section
,
688 ContiguousBlobAccumulator
&CBA
) {
690 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
691 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
694 SHeader
.sh_entsize
= *Section
.EntSize
;
695 else if (Section
.Type
== llvm::ELF::SHT_RELR
)
696 SHeader
.sh_entsize
= sizeof(Elf_Relr
);
698 SHeader
.sh_entsize
= 0;
701 SHeader
.sh_info
= *Section
.Info
;
704 static bool isMips64EL(const ELFYAML::Object
&Doc
) {
705 return Doc
.Header
.Machine
== ELFYAML::ELF_EM(llvm::ELF::EM_MIPS
) &&
706 Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
) &&
707 Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
710 template <class ELFT
>
711 void ELFState
<ELFT
>::writeSectionContent(
712 Elf_Shdr
&SHeader
, const ELFYAML::RelocationSection
&Section
,
713 ContiguousBlobAccumulator
&CBA
) {
714 assert((Section
.Type
== llvm::ELF::SHT_REL
||
715 Section
.Type
== llvm::ELF::SHT_RELA
) &&
716 "Section type is not SHT_REL nor SHT_RELA");
718 bool IsRela
= Section
.Type
== llvm::ELF::SHT_RELA
;
719 SHeader
.sh_entsize
= IsRela
? sizeof(Elf_Rela
) : sizeof(Elf_Rel
);
720 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Relocations
.size();
722 // For relocation section set link to .symtab by default.
723 if (Section
.Link
.empty())
724 SHeader
.sh_link
= SN2I
.get(".symtab");
726 if (!Section
.RelocatableSec
.empty())
727 SHeader
.sh_info
= toSectionIndex(Section
.RelocatableSec
, Section
.Name
);
729 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
730 for (const auto &Rel
: Section
.Relocations
) {
731 unsigned SymIdx
= Rel
.Symbol
? toSymbolIndex(*Rel
.Symbol
, Section
.Name
,
732 Section
.Link
== ".dynsym")
737 REntry
.r_offset
= Rel
.Offset
;
738 REntry
.r_addend
= Rel
.Addend
;
739 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
740 OS
.write((const char *)&REntry
, sizeof(REntry
));
744 REntry
.r_offset
= Rel
.Offset
;
745 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
746 OS
.write((const char *)&REntry
, sizeof(REntry
));
751 template <class ELFT
>
752 void ELFState
<ELFT
>::writeSectionContent(
753 Elf_Shdr
&SHeader
, const ELFYAML::SymtabShndxSection
&Shndx
,
754 ContiguousBlobAccumulator
&CBA
) {
756 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
758 for (uint32_t E
: Shndx
.Entries
)
759 support::endian::write
<uint32_t>(OS
, E
, ELFT::TargetEndianness
);
761 SHeader
.sh_entsize
= Shndx
.EntSize
? (uint64_t)*Shndx
.EntSize
: 4;
762 SHeader
.sh_size
= Shndx
.Entries
.size() * SHeader
.sh_entsize
;
765 template <class ELFT
>
766 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
767 const ELFYAML::Group
&Section
,
768 ContiguousBlobAccumulator
&CBA
) {
769 assert(Section
.Type
== llvm::ELF::SHT_GROUP
&&
770 "Section type is not SHT_GROUP");
772 SHeader
.sh_entsize
= 4;
773 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Members
.size();
775 toSymbolIndex(Section
.Signature
, Section
.Name
, /*IsDynamic=*/false);
778 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
780 for (const ELFYAML::SectionOrType
&Member
: Section
.Members
) {
781 unsigned int SectionIndex
= 0;
782 if (Member
.sectionNameOrType
== "GRP_COMDAT")
783 SectionIndex
= llvm::ELF::GRP_COMDAT
;
785 SectionIndex
= toSectionIndex(Member
.sectionNameOrType
, Section
.Name
);
786 support::endian::write
<uint32_t>(OS
, SectionIndex
, ELFT::TargetEndianness
);
790 template <class ELFT
>
791 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
792 const ELFYAML::SymverSection
&Section
,
793 ContiguousBlobAccumulator
&CBA
) {
795 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
796 for (uint16_t Version
: Section
.Entries
)
797 support::endian::write
<uint16_t>(OS
, Version
, ELFT::TargetEndianness
);
799 SHeader
.sh_entsize
= Section
.EntSize
? (uint64_t)*Section
.EntSize
: 2;
800 SHeader
.sh_size
= Section
.Entries
.size() * SHeader
.sh_entsize
;
803 template <class ELFT
>
804 void ELFState
<ELFT
>::writeSectionContent(
805 Elf_Shdr
&SHeader
, const ELFYAML::StackSizesSection
&Section
,
806 ContiguousBlobAccumulator
&CBA
) {
807 using uintX_t
= typename
ELFT::uint
;
809 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
811 if (Section
.Content
|| Section
.Size
) {
812 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
816 for (const ELFYAML::StackSizeEntry
&E
: *Section
.Entries
) {
817 support::endian::write
<uintX_t
>(OS
, E
.Address
, ELFT::TargetEndianness
);
818 SHeader
.sh_size
+= sizeof(uintX_t
) + encodeULEB128(E
.Size
, OS
);
822 template <class ELFT
>
823 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
824 const ELFYAML::HashSection
&Section
,
825 ContiguousBlobAccumulator
&CBA
) {
827 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
830 if (Section
.Link
.empty() && SN2I
.lookup(".dynsym", Link
))
831 SHeader
.sh_link
= Link
;
833 if (Section
.Content
|| Section
.Size
) {
834 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
838 support::endian::write
<uint32_t>(OS
, Section
.Bucket
->size(),
839 ELFT::TargetEndianness
);
840 support::endian::write
<uint32_t>(OS
, Section
.Chain
->size(),
841 ELFT::TargetEndianness
);
842 for (uint32_t Val
: *Section
.Bucket
)
843 support::endian::write
<uint32_t>(OS
, Val
, ELFT::TargetEndianness
);
844 for (uint32_t Val
: *Section
.Chain
)
845 support::endian::write
<uint32_t>(OS
, Val
, ELFT::TargetEndianness
);
847 SHeader
.sh_size
= (2 + Section
.Bucket
->size() + Section
.Chain
->size()) * 4;
850 template <class ELFT
>
851 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
852 const ELFYAML::VerdefSection
&Section
,
853 ContiguousBlobAccumulator
&CBA
) {
854 typedef typename
ELFT::Verdef Elf_Verdef
;
855 typedef typename
ELFT::Verdaux Elf_Verdaux
;
857 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
860 for (size_t I
= 0; I
< Section
.Entries
.size(); ++I
) {
861 const ELFYAML::VerdefEntry
&E
= Section
.Entries
[I
];
864 VerDef
.vd_version
= E
.Version
;
865 VerDef
.vd_flags
= E
.Flags
;
866 VerDef
.vd_ndx
= E
.VersionNdx
;
867 VerDef
.vd_hash
= E
.Hash
;
868 VerDef
.vd_aux
= sizeof(Elf_Verdef
);
869 VerDef
.vd_cnt
= E
.VerNames
.size();
870 if (I
== Section
.Entries
.size() - 1)
874 sizeof(Elf_Verdef
) + E
.VerNames
.size() * sizeof(Elf_Verdaux
);
875 OS
.write((const char *)&VerDef
, sizeof(Elf_Verdef
));
877 for (size_t J
= 0; J
< E
.VerNames
.size(); ++J
, ++AuxCnt
) {
879 VernAux
.vda_name
= DotDynstr
.getOffset(E
.VerNames
[J
]);
880 if (J
== E
.VerNames
.size() - 1)
881 VernAux
.vda_next
= 0;
883 VernAux
.vda_next
= sizeof(Elf_Verdaux
);
884 OS
.write((const char *)&VernAux
, sizeof(Elf_Verdaux
));
888 SHeader
.sh_size
= Section
.Entries
.size() * sizeof(Elf_Verdef
) +
889 AuxCnt
* sizeof(Elf_Verdaux
);
890 SHeader
.sh_info
= Section
.Info
;
893 template <class ELFT
>
894 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
895 const ELFYAML::VerneedSection
&Section
,
896 ContiguousBlobAccumulator
&CBA
) {
897 typedef typename
ELFT::Verneed Elf_Verneed
;
898 typedef typename
ELFT::Vernaux Elf_Vernaux
;
900 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
903 for (size_t I
= 0; I
< Section
.VerneedV
.size(); ++I
) {
904 const ELFYAML::VerneedEntry
&VE
= Section
.VerneedV
[I
];
907 VerNeed
.vn_version
= VE
.Version
;
908 VerNeed
.vn_file
= DotDynstr
.getOffset(VE
.File
);
909 if (I
== Section
.VerneedV
.size() - 1)
913 sizeof(Elf_Verneed
) + VE
.AuxV
.size() * sizeof(Elf_Vernaux
);
914 VerNeed
.vn_cnt
= VE
.AuxV
.size();
915 VerNeed
.vn_aux
= sizeof(Elf_Verneed
);
916 OS
.write((const char *)&VerNeed
, sizeof(Elf_Verneed
));
918 for (size_t J
= 0; J
< VE
.AuxV
.size(); ++J
, ++AuxCnt
) {
919 const ELFYAML::VernauxEntry
&VAuxE
= VE
.AuxV
[J
];
922 VernAux
.vna_hash
= VAuxE
.Hash
;
923 VernAux
.vna_flags
= VAuxE
.Flags
;
924 VernAux
.vna_other
= VAuxE
.Other
;
925 VernAux
.vna_name
= DotDynstr
.getOffset(VAuxE
.Name
);
926 if (J
== VE
.AuxV
.size() - 1)
927 VernAux
.vna_next
= 0;
929 VernAux
.vna_next
= sizeof(Elf_Vernaux
);
930 OS
.write((const char *)&VernAux
, sizeof(Elf_Vernaux
));
934 SHeader
.sh_size
= Section
.VerneedV
.size() * sizeof(Elf_Verneed
) +
935 AuxCnt
* sizeof(Elf_Vernaux
);
936 SHeader
.sh_info
= Section
.Info
;
939 template <class ELFT
>
940 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
941 const ELFYAML::MipsABIFlags
&Section
,
942 ContiguousBlobAccumulator
&CBA
) {
943 assert(Section
.Type
== llvm::ELF::SHT_MIPS_ABIFLAGS
&&
944 "Section type is not SHT_MIPS_ABIFLAGS");
946 object::Elf_Mips_ABIFlags
<ELFT
> Flags
;
948 SHeader
.sh_entsize
= sizeof(Flags
);
949 SHeader
.sh_size
= SHeader
.sh_entsize
;
951 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
952 Flags
.version
= Section
.Version
;
953 Flags
.isa_level
= Section
.ISALevel
;
954 Flags
.isa_rev
= Section
.ISARevision
;
955 Flags
.gpr_size
= Section
.GPRSize
;
956 Flags
.cpr1_size
= Section
.CPR1Size
;
957 Flags
.cpr2_size
= Section
.CPR2Size
;
958 Flags
.fp_abi
= Section
.FpABI
;
959 Flags
.isa_ext
= Section
.ISAExtension
;
960 Flags
.ases
= Section
.ASEs
;
961 Flags
.flags1
= Section
.Flags1
;
962 Flags
.flags2
= Section
.Flags2
;
963 OS
.write((const char *)&Flags
, sizeof(Flags
));
966 template <class ELFT
>
967 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
968 const ELFYAML::DynamicSection
&Section
,
969 ContiguousBlobAccumulator
&CBA
) {
970 typedef typename
ELFT::uint uintX_t
;
972 assert(Section
.Type
== llvm::ELF::SHT_DYNAMIC
&&
973 "Section type is not SHT_DYNAMIC");
975 if (!Section
.Entries
.empty() && Section
.Content
)
976 reportError("cannot specify both raw content and explicit entries "
977 "for dynamic section '" +
981 SHeader
.sh_size
= Section
.Content
->binary_size();
983 SHeader
.sh_size
= 2 * sizeof(uintX_t
) * Section
.Entries
.size();
985 SHeader
.sh_entsize
= *Section
.EntSize
;
987 SHeader
.sh_entsize
= sizeof(Elf_Dyn
);
990 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
991 for (const ELFYAML::DynamicEntry
&DE
: Section
.Entries
) {
992 support::endian::write
<uintX_t
>(OS
, DE
.Tag
, ELFT::TargetEndianness
);
993 support::endian::write
<uintX_t
>(OS
, DE
.Val
, ELFT::TargetEndianness
);
996 Section
.Content
->writeAsBinary(OS
);
999 template <class ELFT
>
1000 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
1001 const ELFYAML::AddrsigSection
&Section
,
1002 ContiguousBlobAccumulator
&CBA
) {
1004 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
1007 if (Section
.Link
.empty() && SN2I
.lookup(".symtab", Link
))
1008 SHeader
.sh_link
= Link
;
1010 if (Section
.Content
) {
1011 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, None
);
1015 for (const ELFYAML::AddrsigSymbol
&Sym
: *Section
.Symbols
) {
1017 Sym
.Name
? toSymbolIndex(*Sym
.Name
, Section
.Name
, /*IsDynamic=*/false)
1018 : (uint32_t)*Sym
.Index
;
1019 SHeader
.sh_size
+= encodeULEB128(Val
, OS
);
1023 template <class ELFT
> void ELFState
<ELFT
>::buildSectionIndex() {
1024 for (unsigned I
= 0, E
= Doc
.Sections
.size(); I
!= E
; ++I
) {
1025 StringRef Name
= Doc
.Sections
[I
]->Name
;
1029 DotShStrtab
.add(ELFYAML::dropUniqueSuffix(Name
));
1030 if (!SN2I
.addName(Name
, I
))
1031 reportError("repeated section name: '" + Name
+
1032 "' at YAML section number " + Twine(I
));
1035 DotShStrtab
.finalize();
1038 template <class ELFT
> void ELFState
<ELFT
>::buildSymbolIndexes() {
1039 auto Build
= [this](ArrayRef
<ELFYAML::Symbol
> V
, NameToIdxMap
&Map
) {
1040 for (size_t I
= 0, S
= V
.size(); I
< S
; ++I
) {
1041 const ELFYAML::Symbol
&Sym
= V
[I
];
1042 if (!Sym
.Name
.empty() && !Map
.addName(Sym
.Name
, I
+ 1))
1043 reportError("repeated symbol name: '" + Sym
.Name
+ "'");
1047 Build(Doc
.Symbols
, SymN2I
);
1048 Build(Doc
.DynamicSymbols
, DynSymN2I
);
1051 template <class ELFT
> void ELFState
<ELFT
>::finalizeStrings() {
1052 // Add the regular symbol names to .strtab section.
1053 for (const ELFYAML::Symbol
&Sym
: Doc
.Symbols
)
1054 DotStrtab
.add(ELFYAML::dropUniqueSuffix(Sym
.Name
));
1055 DotStrtab
.finalize();
1057 // Add the dynamic symbol names to .dynstr section.
1058 for (const ELFYAML::Symbol
&Sym
: Doc
.DynamicSymbols
)
1059 DotDynstr
.add(ELFYAML::dropUniqueSuffix(Sym
.Name
));
1061 // SHT_GNU_verdef and SHT_GNU_verneed sections might also
1062 // add strings to .dynstr section.
1063 for (const std::unique_ptr
<ELFYAML::Section
> &Sec
: Doc
.Sections
) {
1064 if (auto VerNeed
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
.get())) {
1065 for (const ELFYAML::VerneedEntry
&VE
: VerNeed
->VerneedV
) {
1066 DotDynstr
.add(VE
.File
);
1067 for (const ELFYAML::VernauxEntry
&Aux
: VE
.AuxV
)
1068 DotDynstr
.add(Aux
.Name
);
1070 } else if (auto VerDef
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
.get())) {
1071 for (const ELFYAML::VerdefEntry
&E
: VerDef
->Entries
)
1072 for (StringRef Name
: E
.VerNames
)
1073 DotDynstr
.add(Name
);
1077 DotDynstr
.finalize();
1080 template <class ELFT
>
1081 bool ELFState
<ELFT
>::writeELF(raw_ostream
&OS
, ELFYAML::Object
&Doc
,
1082 yaml::ErrorHandler EH
) {
1083 ELFState
<ELFT
> State(Doc
, EH
);
1085 // Finalize .strtab and .dynstr sections. We do that early because want to
1086 // finalize the string table builders before writing the content of the
1087 // sections that might want to use them.
1088 State
.finalizeStrings();
1090 State
.buildSectionIndex();
1091 State
.buildSymbolIndexes();
1093 std::vector
<Elf_Phdr
> PHeaders
;
1094 State
.initProgramHeaders(PHeaders
);
1096 // XXX: This offset is tightly coupled with the order that we write
1098 const size_t SectionContentBeginOffset
=
1099 sizeof(Elf_Ehdr
) + sizeof(Elf_Phdr
) * Doc
.ProgramHeaders
.size();
1100 ContiguousBlobAccumulator
CBA(SectionContentBeginOffset
);
1102 std::vector
<Elf_Shdr
> SHeaders
;
1103 State
.initSectionHeaders(SHeaders
, CBA
);
1105 // Now we can decide segment offsets
1106 State
.setProgramHeaderLayout(PHeaders
, SHeaders
);
1111 State
.writeELFHeader(CBA
, OS
);
1112 writeArrayData(OS
, makeArrayRef(PHeaders
));
1113 CBA
.writeBlobToStream(OS
);
1114 writeArrayData(OS
, makeArrayRef(SHeaders
));
1121 bool yaml2elf(llvm::ELFYAML::Object
&Doc
, raw_ostream
&Out
, ErrorHandler EH
) {
1122 bool IsLE
= Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
1123 bool Is64Bit
= Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
);
1126 return ELFState
<object::ELF64LE
>::writeELF(Out
, Doc
, EH
);
1127 return ELFState
<object::ELF64BE
>::writeELF(Out
, Doc
, EH
);
1130 return ELFState
<object::ELF32LE
>::writeELF(Out
, Doc
, EH
);
1131 return ELFState
<object::ELF32BE
>::writeELF(Out
, Doc
, EH
);