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 // Some sections wants to link to .symtab by default.
208 // That means we want to create the symbol table for them.
209 if (D
->Type
== llvm::ELF::SHT_REL
|| D
->Type
== llvm::ELF::SHT_RELA
)
210 if (!Doc
.Symbols
&& D
->Link
.empty())
211 Doc
.Symbols
.emplace();
214 // Insert SHT_NULL section implicitly when it is not defined in YAML.
215 if (Doc
.Sections
.empty() || Doc
.Sections
.front()->Type
!= ELF::SHT_NULL
)
217 Doc
.Sections
.begin(),
218 std::make_unique
<ELFYAML::Section
>(
219 ELFYAML::Section::SectionKind::RawContent
, /*IsImplicit=*/true));
221 std::vector
<StringRef
> ImplicitSections
;
223 ImplicitSections
.push_back(".symtab");
224 ImplicitSections
.insert(ImplicitSections
.end(), {".strtab", ".shstrtab"});
226 if (!Doc
.DynamicSymbols
.empty())
227 ImplicitSections
.insert(ImplicitSections
.end(), {".dynsym", ".dynstr"});
229 // Insert placeholders for implicit sections that are not
230 // defined explicitly in YAML.
231 for (StringRef SecName
: ImplicitSections
) {
232 if (DocSections
.count(SecName
))
235 std::unique_ptr
<ELFYAML::Section
> Sec
= std::make_unique
<ELFYAML::Section
>(
236 ELFYAML::Section::SectionKind::RawContent
, true /*IsImplicit*/);
238 Doc
.Sections
.push_back(std::move(Sec
));
242 template <class ELFT
>
243 void ELFState
<ELFT
>::writeELFHeader(ContiguousBlobAccumulator
&CBA
, raw_ostream
&OS
) {
244 using namespace llvm::ELF
;
248 Header
.e_ident
[EI_MAG0
] = 0x7f;
249 Header
.e_ident
[EI_MAG1
] = 'E';
250 Header
.e_ident
[EI_MAG2
] = 'L';
251 Header
.e_ident
[EI_MAG3
] = 'F';
252 Header
.e_ident
[EI_CLASS
] = ELFT::Is64Bits
? ELFCLASS64
: ELFCLASS32
;
253 Header
.e_ident
[EI_DATA
] = Doc
.Header
.Data
;
254 Header
.e_ident
[EI_VERSION
] = EV_CURRENT
;
255 Header
.e_ident
[EI_OSABI
] = Doc
.Header
.OSABI
;
256 Header
.e_ident
[EI_ABIVERSION
] = Doc
.Header
.ABIVersion
;
257 Header
.e_type
= Doc
.Header
.Type
;
258 Header
.e_machine
= Doc
.Header
.Machine
;
259 Header
.e_version
= EV_CURRENT
;
260 Header
.e_entry
= Doc
.Header
.Entry
;
261 Header
.e_phoff
= Doc
.ProgramHeaders
.size() ? sizeof(Header
) : 0;
262 Header
.e_flags
= Doc
.Header
.Flags
;
263 Header
.e_ehsize
= sizeof(Elf_Ehdr
);
264 Header
.e_phentsize
= Doc
.ProgramHeaders
.size() ? sizeof(Elf_Phdr
) : 0;
265 Header
.e_phnum
= Doc
.ProgramHeaders
.size();
268 Doc
.Header
.SHEntSize
? (uint16_t)*Doc
.Header
.SHEntSize
: sizeof(Elf_Shdr
);
269 // Immediately following the ELF header and program headers.
270 // Align the start of the section header and write the ELF header.
272 CBA
.getOSAndAlignedOffset(SHOff
, sizeof(typename
ELFT::uint
));
274 Doc
.Header
.SHOff
? typename
ELFT::uint(*Doc
.Header
.SHOff
) : SHOff
;
276 Doc
.Header
.SHNum
? (uint16_t)*Doc
.Header
.SHNum
: Doc
.Sections
.size();
277 Header
.e_shstrndx
= Doc
.Header
.SHStrNdx
? (uint16_t)*Doc
.Header
.SHStrNdx
278 : SN2I
.get(".shstrtab");
280 OS
.write((const char *)&Header
, sizeof(Header
));
283 template <class ELFT
>
284 void ELFState
<ELFT
>::initProgramHeaders(std::vector
<Elf_Phdr
> &PHeaders
) {
285 for (const auto &YamlPhdr
: Doc
.ProgramHeaders
) {
287 Phdr
.p_type
= YamlPhdr
.Type
;
288 Phdr
.p_flags
= YamlPhdr
.Flags
;
289 Phdr
.p_vaddr
= YamlPhdr
.VAddr
;
290 Phdr
.p_paddr
= YamlPhdr
.PAddr
;
291 PHeaders
.push_back(Phdr
);
295 template <class ELFT
>
296 unsigned ELFState
<ELFT
>::toSectionIndex(StringRef S
, StringRef LocSec
,
299 if (SN2I
.lookup(S
, Index
) || to_integer(S
, Index
))
302 assert(LocSec
.empty() || LocSym
.empty());
304 reportError("unknown section referenced: '" + S
+ "' by YAML symbol '" +
307 reportError("unknown section referenced: '" + S
+ "' by YAML section '" +
312 template <class ELFT
>
313 unsigned ELFState
<ELFT
>::toSymbolIndex(StringRef S
, StringRef LocSec
,
315 const NameToIdxMap
&SymMap
= IsDynamic
? DynSymN2I
: SymN2I
;
317 // Here we try to look up S in the symbol table. If it is not there,
318 // treat its value as a symbol index.
319 if (!SymMap
.lookup(S
, Index
) && !to_integer(S
, Index
)) {
320 reportError("unknown symbol referenced: '" + S
+ "' by YAML section '" +
327 template <class ELFT
>
328 bool ELFState
<ELFT
>::initImplicitHeader(ContiguousBlobAccumulator
&CBA
,
329 Elf_Shdr
&Header
, StringRef SecName
,
330 ELFYAML::Section
*YAMLSec
) {
331 // Check if the header was already initialized.
332 if (Header
.sh_offset
)
335 if (SecName
== ".symtab")
336 initSymtabSectionHeader(Header
, SymtabType::Static
, CBA
, YAMLSec
);
337 else if (SecName
== ".strtab")
338 initStrtabSectionHeader(Header
, SecName
, DotStrtab
, CBA
, YAMLSec
);
339 else if (SecName
== ".shstrtab")
340 initStrtabSectionHeader(Header
, SecName
, DotShStrtab
, CBA
, YAMLSec
);
341 else if (SecName
== ".dynsym")
342 initSymtabSectionHeader(Header
, SymtabType::Dynamic
, CBA
, YAMLSec
);
343 else if (SecName
== ".dynstr")
344 initStrtabSectionHeader(Header
, SecName
, DotDynstr
, CBA
, YAMLSec
);
348 // Override the fields if requested.
351 Header
.sh_name
= *YAMLSec
->ShName
;
352 if (YAMLSec
->ShOffset
)
353 Header
.sh_offset
= *YAMLSec
->ShOffset
;
355 Header
.sh_size
= *YAMLSec
->ShSize
;
361 StringRef
llvm::ELFYAML::dropUniqueSuffix(StringRef S
) {
362 size_t SuffixPos
= S
.rfind(" [");
363 if (SuffixPos
== StringRef::npos
)
365 return S
.substr(0, SuffixPos
);
368 template <class ELFT
>
369 void ELFState
<ELFT
>::initSectionHeaders(std::vector
<Elf_Shdr
> &SHeaders
,
370 ContiguousBlobAccumulator
&CBA
) {
371 // Ensure SHN_UNDEF entry is present. An all-zero section header is a
372 // valid SHN_UNDEF entry since SHT_NULL == 0.
373 SHeaders
.resize(Doc
.Sections
.size());
375 for (size_t I
= 0; I
< Doc
.Sections
.size(); ++I
) {
376 ELFYAML::Section
*Sec
= Doc
.Sections
[I
].get();
377 if (I
== 0 && Sec
->IsImplicit
)
380 // We have a few sections like string or symbol tables that are usually
381 // added implicitly to the end. However, if they are explicitly specified
382 // in the YAML, we need to write them here. This ensures the file offset
384 Elf_Shdr
&SHeader
= SHeaders
[I
];
385 if (initImplicitHeader(CBA
, SHeader
, Sec
->Name
,
386 Sec
->IsImplicit
? nullptr : Sec
))
389 assert(Sec
&& "It can't be null unless it is an implicit section. But all "
390 "implicit sections should already have been handled above.");
393 DotShStrtab
.getOffset(ELFYAML::dropUniqueSuffix(Sec
->Name
));
394 SHeader
.sh_type
= Sec
->Type
;
396 SHeader
.sh_flags
= *Sec
->Flags
;
397 SHeader
.sh_addr
= Sec
->Address
;
398 SHeader
.sh_addralign
= Sec
->AddressAlign
;
400 if (!Sec
->Link
.empty())
401 SHeader
.sh_link
= toSectionIndex(Sec
->Link
, Sec
->Name
);
404 if (auto RawSec
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
405 // We do not write any content for special SHN_UNDEF section.
407 SHeader
.sh_size
= *RawSec
->Size
;
409 SHeader
.sh_info
= *RawSec
->Info
;
412 SHeader
.sh_entsize
= *Sec
->EntSize
;
413 } else if (auto S
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
414 writeSectionContent(SHeader
, *S
, CBA
);
415 } else if (auto S
= dyn_cast
<ELFYAML::SymtabShndxSection
>(Sec
)) {
416 writeSectionContent(SHeader
, *S
, CBA
);
417 } else if (auto S
= dyn_cast
<ELFYAML::RelocationSection
>(Sec
)) {
418 writeSectionContent(SHeader
, *S
, CBA
);
419 } else if (auto S
= dyn_cast
<ELFYAML::Group
>(Sec
)) {
420 writeSectionContent(SHeader
, *S
, CBA
);
421 } else if (auto S
= dyn_cast
<ELFYAML::MipsABIFlags
>(Sec
)) {
422 writeSectionContent(SHeader
, *S
, CBA
);
423 } else if (auto S
= dyn_cast
<ELFYAML::NoBitsSection
>(Sec
)) {
424 SHeader
.sh_entsize
= 0;
425 SHeader
.sh_size
= S
->Size
;
426 // SHT_NOBITS section does not have content
427 // so just to setup the section offset.
428 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
429 } else if (auto S
= dyn_cast
<ELFYAML::DynamicSection
>(Sec
)) {
430 writeSectionContent(SHeader
, *S
, CBA
);
431 } else if (auto S
= dyn_cast
<ELFYAML::SymverSection
>(Sec
)) {
432 writeSectionContent(SHeader
, *S
, CBA
);
433 } else if (auto S
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
)) {
434 writeSectionContent(SHeader
, *S
, CBA
);
435 } else if (auto S
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
)) {
436 writeSectionContent(SHeader
, *S
, CBA
);
437 } else if (auto S
= dyn_cast
<ELFYAML::StackSizesSection
>(Sec
)) {
438 writeSectionContent(SHeader
, *S
, CBA
);
439 } else if (auto S
= dyn_cast
<ELFYAML::HashSection
>(Sec
)) {
440 writeSectionContent(SHeader
, *S
, CBA
);
441 } else if (auto S
= dyn_cast
<ELFYAML::AddrsigSection
>(Sec
)) {
442 writeSectionContent(SHeader
, *S
, CBA
);
444 llvm_unreachable("Unknown section type");
447 // Override the fields if requested.
450 SHeader
.sh_name
= *Sec
->ShName
;
452 SHeader
.sh_offset
= *Sec
->ShOffset
;
454 SHeader
.sh_size
= *Sec
->ShSize
;
459 static size_t findFirstNonGlobal(ArrayRef
<ELFYAML::Symbol
> Symbols
) {
460 for (size_t I
= 0; I
< Symbols
.size(); ++I
)
461 if (Symbols
[I
].Binding
.value
!= ELF::STB_LOCAL
)
463 return Symbols
.size();
466 static uint64_t writeContent(raw_ostream
&OS
,
467 const Optional
<yaml::BinaryRef
> &Content
,
468 const Optional
<llvm::yaml::Hex64
> &Size
) {
469 size_t ContentSize
= 0;
471 Content
->writeAsBinary(OS
);
472 ContentSize
= Content
->binary_size();
478 OS
.write_zeros(*Size
- ContentSize
);
482 template <class ELFT
>
483 std::vector
<typename
ELFT::Sym
>
484 ELFState
<ELFT
>::toELFSymbols(ArrayRef
<ELFYAML::Symbol
> Symbols
,
485 const StringTableBuilder
&Strtab
) {
486 std::vector
<Elf_Sym
> Ret
;
487 Ret
.resize(Symbols
.size() + 1);
490 for (const auto &Sym
: Symbols
) {
491 Elf_Sym
&Symbol
= Ret
[++I
];
493 // If NameIndex, which contains the name offset, is explicitly specified, we
494 // use it. This is useful for preparing broken objects. Otherwise, we add
495 // the specified Name to the string table builder to get its offset.
497 Symbol
.st_name
= *Sym
.NameIndex
;
498 else if (!Sym
.Name
.empty())
499 Symbol
.st_name
= Strtab
.getOffset(ELFYAML::dropUniqueSuffix(Sym
.Name
));
501 Symbol
.setBindingAndType(Sym
.Binding
, Sym
.Type
);
502 if (!Sym
.Section
.empty())
503 Symbol
.st_shndx
= toSectionIndex(Sym
.Section
, "", Sym
.Name
);
505 Symbol
.st_shndx
= *Sym
.Index
;
507 Symbol
.st_value
= Sym
.Value
;
508 Symbol
.st_other
= Sym
.Other
? *Sym
.Other
: 0;
509 Symbol
.st_size
= Sym
.Size
;
515 template <class ELFT
>
516 void ELFState
<ELFT
>::initSymtabSectionHeader(Elf_Shdr
&SHeader
,
518 ContiguousBlobAccumulator
&CBA
,
519 ELFYAML::Section
*YAMLSec
) {
521 bool IsStatic
= STType
== SymtabType::Static
;
522 ArrayRef
<ELFYAML::Symbol
> Symbols
;
523 if (IsStatic
&& Doc
.Symbols
)
524 Symbols
= *Doc
.Symbols
;
526 Symbols
= Doc
.DynamicSymbols
;
528 ELFYAML::RawContentSection
*RawSec
=
529 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
530 if (RawSec
&& !Symbols
.empty() && (RawSec
->Content
|| RawSec
->Size
)) {
532 reportError("cannot specify both `Content` and " +
533 (IsStatic
? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
534 " for symbol table section '" + RawSec
->Name
+ "'");
536 reportError("cannot specify both `Size` and " +
537 (IsStatic
? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
538 " for symbol table section '" + RawSec
->Name
+ "'");
543 SHeader
.sh_name
= DotShStrtab
.getOffset(IsStatic
? ".symtab" : ".dynsym");
546 SHeader
.sh_type
= YAMLSec
->Type
;
548 SHeader
.sh_type
= IsStatic
? ELF::SHT_SYMTAB
: ELF::SHT_DYNSYM
;
550 if (RawSec
&& !RawSec
->Link
.empty()) {
551 // If the Link field is explicitly defined in the document,
553 SHeader
.sh_link
= toSectionIndex(RawSec
->Link
, RawSec
->Name
);
555 // When we describe the .dynsym section in the document explicitly, it is
556 // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not
557 // added implicitly and we should be able to leave the Link zeroed if
558 // .dynstr is not defined.
561 Link
= SN2I
.get(".strtab");
563 SN2I
.lookup(".dynstr", Link
);
564 SHeader
.sh_link
= Link
;
567 if (YAMLSec
&& YAMLSec
->Flags
)
568 SHeader
.sh_flags
= *YAMLSec
->Flags
;
570 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
572 // If the symbol table section is explicitly described in the YAML
573 // then we should set the fields requested.
574 SHeader
.sh_info
= (RawSec
&& RawSec
->Info
) ? (unsigned)(*RawSec
->Info
)
575 : findFirstNonGlobal(Symbols
) + 1;
576 SHeader
.sh_entsize
= (YAMLSec
&& YAMLSec
->EntSize
)
577 ? (uint64_t)(*YAMLSec
->EntSize
)
579 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 8;
580 SHeader
.sh_addr
= YAMLSec
? (uint64_t)YAMLSec
->Address
: 0;
582 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
583 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
584 assert(Symbols
.empty());
585 SHeader
.sh_size
= writeContent(OS
, RawSec
->Content
, RawSec
->Size
);
589 std::vector
<Elf_Sym
> Syms
=
590 toELFSymbols(Symbols
, IsStatic
? DotStrtab
: DotDynstr
);
591 writeArrayData(OS
, makeArrayRef(Syms
));
592 SHeader
.sh_size
= arrayDataSize(makeArrayRef(Syms
));
595 template <class ELFT
>
596 void ELFState
<ELFT
>::initStrtabSectionHeader(Elf_Shdr
&SHeader
, StringRef Name
,
597 StringTableBuilder
&STB
,
598 ContiguousBlobAccumulator
&CBA
,
599 ELFYAML::Section
*YAMLSec
) {
601 SHeader
.sh_name
= DotShStrtab
.getOffset(Name
);
602 SHeader
.sh_type
= YAMLSec
? YAMLSec
->Type
: ELF::SHT_STRTAB
;
603 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 1;
605 ELFYAML::RawContentSection
*RawSec
=
606 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
608 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
609 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
610 SHeader
.sh_size
= writeContent(OS
, RawSec
->Content
, RawSec
->Size
);
613 SHeader
.sh_size
= STB
.getSize();
616 if (YAMLSec
&& YAMLSec
->EntSize
)
617 SHeader
.sh_entsize
= *YAMLSec
->EntSize
;
619 if (RawSec
&& RawSec
->Info
)
620 SHeader
.sh_info
= *RawSec
->Info
;
622 if (YAMLSec
&& YAMLSec
->Flags
)
623 SHeader
.sh_flags
= *YAMLSec
->Flags
;
624 else if (Name
== ".dynstr")
625 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
627 // If the section is explicitly described in the YAML
628 // then we want to use its section address.
630 SHeader
.sh_addr
= YAMLSec
->Address
;
633 template <class ELFT
> void ELFState
<ELFT
>::reportError(const Twine
&Msg
) {
638 template <class ELFT
>
639 void ELFState
<ELFT
>::setProgramHeaderLayout(std::vector
<Elf_Phdr
> &PHeaders
,
640 std::vector
<Elf_Shdr
> &SHeaders
) {
641 uint32_t PhdrIdx
= 0;
642 for (auto &YamlPhdr
: Doc
.ProgramHeaders
) {
643 Elf_Phdr
&PHeader
= PHeaders
[PhdrIdx
++];
645 std::vector
<Elf_Shdr
*> Sections
;
646 for (const ELFYAML::SectionName
&SecName
: YamlPhdr
.Sections
) {
648 if (!SN2I
.lookup(SecName
.Section
, Index
)) {
649 reportError("unknown section referenced: '" + SecName
.Section
+
650 "' by program header");
653 Sections
.push_back(&SHeaders
[Index
]);
656 if (YamlPhdr
.Offset
) {
657 PHeader
.p_offset
= *YamlPhdr
.Offset
;
659 if (YamlPhdr
.Sections
.size())
660 PHeader
.p_offset
= UINT32_MAX
;
662 PHeader
.p_offset
= 0;
664 // Find the minimum offset for the program header.
665 for (Elf_Shdr
*SHeader
: Sections
)
666 PHeader
.p_offset
= std::min(PHeader
.p_offset
, SHeader
->sh_offset
);
669 // Find the maximum offset of the end of a section in order to set p_filesz
670 // and p_memsz. When setting p_filesz, trailing SHT_NOBITS sections are not
672 uint64_t FileOffset
= PHeader
.p_offset
, MemOffset
= PHeader
.p_offset
;
673 for (Elf_Shdr
*SHeader
: Sections
) {
674 uint64_t End
= SHeader
->sh_offset
+ SHeader
->sh_size
;
675 MemOffset
= std::max(MemOffset
, End
);
677 if (SHeader
->sh_type
!= llvm::ELF::SHT_NOBITS
)
678 FileOffset
= std::max(FileOffset
, End
);
681 // Set the file size and the memory size if not set explicitly.
682 PHeader
.p_filesz
= YamlPhdr
.FileSize
? uint64_t(*YamlPhdr
.FileSize
)
683 : FileOffset
- PHeader
.p_offset
;
684 PHeader
.p_memsz
= YamlPhdr
.MemSize
? uint64_t(*YamlPhdr
.MemSize
)
685 : MemOffset
- PHeader
.p_offset
;
687 if (YamlPhdr
.Align
) {
688 PHeader
.p_align
= *YamlPhdr
.Align
;
690 // Set the alignment of the segment to be the maximum alignment of the
691 // sections so that by default the segment has a valid and sensible
694 for (Elf_Shdr
*SHeader
: Sections
)
695 PHeader
.p_align
= std::max(PHeader
.p_align
, SHeader
->sh_addralign
);
700 template <class ELFT
>
701 void ELFState
<ELFT
>::writeSectionContent(
702 Elf_Shdr
&SHeader
, const ELFYAML::RawContentSection
&Section
,
703 ContiguousBlobAccumulator
&CBA
) {
705 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
706 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
709 SHeader
.sh_entsize
= *Section
.EntSize
;
710 else if (Section
.Type
== llvm::ELF::SHT_RELR
)
711 SHeader
.sh_entsize
= sizeof(Elf_Relr
);
713 SHeader
.sh_entsize
= 0;
716 SHeader
.sh_info
= *Section
.Info
;
719 static bool isMips64EL(const ELFYAML::Object
&Doc
) {
720 return Doc
.Header
.Machine
== ELFYAML::ELF_EM(llvm::ELF::EM_MIPS
) &&
721 Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
) &&
722 Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
725 template <class ELFT
>
726 void ELFState
<ELFT
>::writeSectionContent(
727 Elf_Shdr
&SHeader
, const ELFYAML::RelocationSection
&Section
,
728 ContiguousBlobAccumulator
&CBA
) {
729 assert((Section
.Type
== llvm::ELF::SHT_REL
||
730 Section
.Type
== llvm::ELF::SHT_RELA
) &&
731 "Section type is not SHT_REL nor SHT_RELA");
733 bool IsRela
= Section
.Type
== llvm::ELF::SHT_RELA
;
734 SHeader
.sh_entsize
= IsRela
? sizeof(Elf_Rela
) : sizeof(Elf_Rel
);
735 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Relocations
.size();
737 // For relocation section set link to .symtab by default.
738 if (Section
.Link
.empty())
739 SHeader
.sh_link
= SN2I
.get(".symtab");
741 if (!Section
.RelocatableSec
.empty())
742 SHeader
.sh_info
= toSectionIndex(Section
.RelocatableSec
, Section
.Name
);
744 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
745 for (const auto &Rel
: Section
.Relocations
) {
746 unsigned SymIdx
= Rel
.Symbol
? toSymbolIndex(*Rel
.Symbol
, Section
.Name
,
747 Section
.Link
== ".dynsym")
752 REntry
.r_offset
= Rel
.Offset
;
753 REntry
.r_addend
= Rel
.Addend
;
754 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
755 OS
.write((const char *)&REntry
, sizeof(REntry
));
759 REntry
.r_offset
= Rel
.Offset
;
760 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
761 OS
.write((const char *)&REntry
, sizeof(REntry
));
766 template <class ELFT
>
767 void ELFState
<ELFT
>::writeSectionContent(
768 Elf_Shdr
&SHeader
, const ELFYAML::SymtabShndxSection
&Shndx
,
769 ContiguousBlobAccumulator
&CBA
) {
771 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
773 for (uint32_t E
: Shndx
.Entries
)
774 support::endian::write
<uint32_t>(OS
, E
, ELFT::TargetEndianness
);
776 SHeader
.sh_entsize
= Shndx
.EntSize
? (uint64_t)*Shndx
.EntSize
: 4;
777 SHeader
.sh_size
= Shndx
.Entries
.size() * SHeader
.sh_entsize
;
780 template <class ELFT
>
781 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
782 const ELFYAML::Group
&Section
,
783 ContiguousBlobAccumulator
&CBA
) {
784 assert(Section
.Type
== llvm::ELF::SHT_GROUP
&&
785 "Section type is not SHT_GROUP");
787 SHeader
.sh_entsize
= 4;
788 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Members
.size();
790 toSymbolIndex(Section
.Signature
, Section
.Name
, /*IsDynamic=*/false);
793 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
795 for (const ELFYAML::SectionOrType
&Member
: Section
.Members
) {
796 unsigned int SectionIndex
= 0;
797 if (Member
.sectionNameOrType
== "GRP_COMDAT")
798 SectionIndex
= llvm::ELF::GRP_COMDAT
;
800 SectionIndex
= toSectionIndex(Member
.sectionNameOrType
, Section
.Name
);
801 support::endian::write
<uint32_t>(OS
, SectionIndex
, ELFT::TargetEndianness
);
805 template <class ELFT
>
806 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
807 const ELFYAML::SymverSection
&Section
,
808 ContiguousBlobAccumulator
&CBA
) {
810 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
811 for (uint16_t Version
: Section
.Entries
)
812 support::endian::write
<uint16_t>(OS
, Version
, ELFT::TargetEndianness
);
814 SHeader
.sh_entsize
= Section
.EntSize
? (uint64_t)*Section
.EntSize
: 2;
815 SHeader
.sh_size
= Section
.Entries
.size() * SHeader
.sh_entsize
;
818 template <class ELFT
>
819 void ELFState
<ELFT
>::writeSectionContent(
820 Elf_Shdr
&SHeader
, const ELFYAML::StackSizesSection
&Section
,
821 ContiguousBlobAccumulator
&CBA
) {
822 using uintX_t
= typename
ELFT::uint
;
824 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
826 if (Section
.Content
|| Section
.Size
) {
827 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
831 for (const ELFYAML::StackSizeEntry
&E
: *Section
.Entries
) {
832 support::endian::write
<uintX_t
>(OS
, E
.Address
, ELFT::TargetEndianness
);
833 SHeader
.sh_size
+= sizeof(uintX_t
) + encodeULEB128(E
.Size
, OS
);
837 template <class ELFT
>
838 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
839 const ELFYAML::HashSection
&Section
,
840 ContiguousBlobAccumulator
&CBA
) {
842 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
845 if (Section
.Link
.empty() && SN2I
.lookup(".dynsym", Link
))
846 SHeader
.sh_link
= Link
;
848 if (Section
.Content
|| Section
.Size
) {
849 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
853 support::endian::write
<uint32_t>(OS
, Section
.Bucket
->size(),
854 ELFT::TargetEndianness
);
855 support::endian::write
<uint32_t>(OS
, Section
.Chain
->size(),
856 ELFT::TargetEndianness
);
857 for (uint32_t Val
: *Section
.Bucket
)
858 support::endian::write
<uint32_t>(OS
, Val
, ELFT::TargetEndianness
);
859 for (uint32_t Val
: *Section
.Chain
)
860 support::endian::write
<uint32_t>(OS
, Val
, ELFT::TargetEndianness
);
862 SHeader
.sh_size
= (2 + Section
.Bucket
->size() + Section
.Chain
->size()) * 4;
865 template <class ELFT
>
866 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
867 const ELFYAML::VerdefSection
&Section
,
868 ContiguousBlobAccumulator
&CBA
) {
869 typedef typename
ELFT::Verdef Elf_Verdef
;
870 typedef typename
ELFT::Verdaux Elf_Verdaux
;
872 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
875 for (size_t I
= 0; I
< Section
.Entries
.size(); ++I
) {
876 const ELFYAML::VerdefEntry
&E
= Section
.Entries
[I
];
879 VerDef
.vd_version
= E
.Version
;
880 VerDef
.vd_flags
= E
.Flags
;
881 VerDef
.vd_ndx
= E
.VersionNdx
;
882 VerDef
.vd_hash
= E
.Hash
;
883 VerDef
.vd_aux
= sizeof(Elf_Verdef
);
884 VerDef
.vd_cnt
= E
.VerNames
.size();
885 if (I
== Section
.Entries
.size() - 1)
889 sizeof(Elf_Verdef
) + E
.VerNames
.size() * sizeof(Elf_Verdaux
);
890 OS
.write((const char *)&VerDef
, sizeof(Elf_Verdef
));
892 for (size_t J
= 0; J
< E
.VerNames
.size(); ++J
, ++AuxCnt
) {
894 VernAux
.vda_name
= DotDynstr
.getOffset(E
.VerNames
[J
]);
895 if (J
== E
.VerNames
.size() - 1)
896 VernAux
.vda_next
= 0;
898 VernAux
.vda_next
= sizeof(Elf_Verdaux
);
899 OS
.write((const char *)&VernAux
, sizeof(Elf_Verdaux
));
903 SHeader
.sh_size
= Section
.Entries
.size() * sizeof(Elf_Verdef
) +
904 AuxCnt
* sizeof(Elf_Verdaux
);
905 SHeader
.sh_info
= Section
.Info
;
908 template <class ELFT
>
909 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
910 const ELFYAML::VerneedSection
&Section
,
911 ContiguousBlobAccumulator
&CBA
) {
912 typedef typename
ELFT::Verneed Elf_Verneed
;
913 typedef typename
ELFT::Vernaux Elf_Vernaux
;
915 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
918 for (size_t I
= 0; I
< Section
.VerneedV
.size(); ++I
) {
919 const ELFYAML::VerneedEntry
&VE
= Section
.VerneedV
[I
];
922 VerNeed
.vn_version
= VE
.Version
;
923 VerNeed
.vn_file
= DotDynstr
.getOffset(VE
.File
);
924 if (I
== Section
.VerneedV
.size() - 1)
928 sizeof(Elf_Verneed
) + VE
.AuxV
.size() * sizeof(Elf_Vernaux
);
929 VerNeed
.vn_cnt
= VE
.AuxV
.size();
930 VerNeed
.vn_aux
= sizeof(Elf_Verneed
);
931 OS
.write((const char *)&VerNeed
, sizeof(Elf_Verneed
));
933 for (size_t J
= 0; J
< VE
.AuxV
.size(); ++J
, ++AuxCnt
) {
934 const ELFYAML::VernauxEntry
&VAuxE
= VE
.AuxV
[J
];
937 VernAux
.vna_hash
= VAuxE
.Hash
;
938 VernAux
.vna_flags
= VAuxE
.Flags
;
939 VernAux
.vna_other
= VAuxE
.Other
;
940 VernAux
.vna_name
= DotDynstr
.getOffset(VAuxE
.Name
);
941 if (J
== VE
.AuxV
.size() - 1)
942 VernAux
.vna_next
= 0;
944 VernAux
.vna_next
= sizeof(Elf_Vernaux
);
945 OS
.write((const char *)&VernAux
, sizeof(Elf_Vernaux
));
949 SHeader
.sh_size
= Section
.VerneedV
.size() * sizeof(Elf_Verneed
) +
950 AuxCnt
* sizeof(Elf_Vernaux
);
951 SHeader
.sh_info
= Section
.Info
;
954 template <class ELFT
>
955 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
956 const ELFYAML::MipsABIFlags
&Section
,
957 ContiguousBlobAccumulator
&CBA
) {
958 assert(Section
.Type
== llvm::ELF::SHT_MIPS_ABIFLAGS
&&
959 "Section type is not SHT_MIPS_ABIFLAGS");
961 object::Elf_Mips_ABIFlags
<ELFT
> Flags
;
963 SHeader
.sh_entsize
= sizeof(Flags
);
964 SHeader
.sh_size
= SHeader
.sh_entsize
;
966 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
967 Flags
.version
= Section
.Version
;
968 Flags
.isa_level
= Section
.ISALevel
;
969 Flags
.isa_rev
= Section
.ISARevision
;
970 Flags
.gpr_size
= Section
.GPRSize
;
971 Flags
.cpr1_size
= Section
.CPR1Size
;
972 Flags
.cpr2_size
= Section
.CPR2Size
;
973 Flags
.fp_abi
= Section
.FpABI
;
974 Flags
.isa_ext
= Section
.ISAExtension
;
975 Flags
.ases
= Section
.ASEs
;
976 Flags
.flags1
= Section
.Flags1
;
977 Flags
.flags2
= Section
.Flags2
;
978 OS
.write((const char *)&Flags
, sizeof(Flags
));
981 template <class ELFT
>
982 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
983 const ELFYAML::DynamicSection
&Section
,
984 ContiguousBlobAccumulator
&CBA
) {
985 typedef typename
ELFT::uint uintX_t
;
987 assert(Section
.Type
== llvm::ELF::SHT_DYNAMIC
&&
988 "Section type is not SHT_DYNAMIC");
990 if (!Section
.Entries
.empty() && Section
.Content
)
991 reportError("cannot specify both raw content and explicit entries "
992 "for dynamic section '" +
996 SHeader
.sh_size
= Section
.Content
->binary_size();
998 SHeader
.sh_size
= 2 * sizeof(uintX_t
) * Section
.Entries
.size();
1000 SHeader
.sh_entsize
= *Section
.EntSize
;
1002 SHeader
.sh_entsize
= sizeof(Elf_Dyn
);
1005 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
1006 for (const ELFYAML::DynamicEntry
&DE
: Section
.Entries
) {
1007 support::endian::write
<uintX_t
>(OS
, DE
.Tag
, ELFT::TargetEndianness
);
1008 support::endian::write
<uintX_t
>(OS
, DE
.Val
, ELFT::TargetEndianness
);
1010 if (Section
.Content
)
1011 Section
.Content
->writeAsBinary(OS
);
1014 template <class ELFT
>
1015 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
1016 const ELFYAML::AddrsigSection
&Section
,
1017 ContiguousBlobAccumulator
&CBA
) {
1019 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
1022 if (Section
.Link
.empty() && SN2I
.lookup(".symtab", Link
))
1023 SHeader
.sh_link
= Link
;
1025 if (Section
.Content
|| Section
.Size
) {
1026 SHeader
.sh_size
= writeContent(OS
, Section
.Content
, Section
.Size
);
1030 for (const ELFYAML::AddrsigSymbol
&Sym
: *Section
.Symbols
) {
1032 Sym
.Name
? toSymbolIndex(*Sym
.Name
, Section
.Name
, /*IsDynamic=*/false)
1033 : (uint32_t)*Sym
.Index
;
1034 SHeader
.sh_size
+= encodeULEB128(Val
, OS
);
1038 template <class ELFT
> void ELFState
<ELFT
>::buildSectionIndex() {
1039 for (unsigned I
= 0, E
= Doc
.Sections
.size(); I
!= E
; ++I
) {
1040 StringRef Name
= Doc
.Sections
[I
]->Name
;
1044 DotShStrtab
.add(ELFYAML::dropUniqueSuffix(Name
));
1045 if (!SN2I
.addName(Name
, I
))
1046 reportError("repeated section name: '" + Name
+
1047 "' at YAML section number " + Twine(I
));
1050 DotShStrtab
.finalize();
1053 template <class ELFT
> void ELFState
<ELFT
>::buildSymbolIndexes() {
1054 auto Build
= [this](ArrayRef
<ELFYAML::Symbol
> V
, NameToIdxMap
&Map
) {
1055 for (size_t I
= 0, S
= V
.size(); I
< S
; ++I
) {
1056 const ELFYAML::Symbol
&Sym
= V
[I
];
1057 if (!Sym
.Name
.empty() && !Map
.addName(Sym
.Name
, I
+ 1))
1058 reportError("repeated symbol name: '" + Sym
.Name
+ "'");
1063 Build(*Doc
.Symbols
, SymN2I
);
1064 Build(Doc
.DynamicSymbols
, DynSymN2I
);
1067 template <class ELFT
> void ELFState
<ELFT
>::finalizeStrings() {
1068 // Add the regular symbol names to .strtab section.
1070 for (const ELFYAML::Symbol
&Sym
: *Doc
.Symbols
)
1071 DotStrtab
.add(ELFYAML::dropUniqueSuffix(Sym
.Name
));
1072 DotStrtab
.finalize();
1074 // Add the dynamic symbol names to .dynstr section.
1075 for (const ELFYAML::Symbol
&Sym
: Doc
.DynamicSymbols
)
1076 DotDynstr
.add(ELFYAML::dropUniqueSuffix(Sym
.Name
));
1078 // SHT_GNU_verdef and SHT_GNU_verneed sections might also
1079 // add strings to .dynstr section.
1080 for (const std::unique_ptr
<ELFYAML::Section
> &Sec
: Doc
.Sections
) {
1081 if (auto VerNeed
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
.get())) {
1082 for (const ELFYAML::VerneedEntry
&VE
: VerNeed
->VerneedV
) {
1083 DotDynstr
.add(VE
.File
);
1084 for (const ELFYAML::VernauxEntry
&Aux
: VE
.AuxV
)
1085 DotDynstr
.add(Aux
.Name
);
1087 } else if (auto VerDef
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
.get())) {
1088 for (const ELFYAML::VerdefEntry
&E
: VerDef
->Entries
)
1089 for (StringRef Name
: E
.VerNames
)
1090 DotDynstr
.add(Name
);
1094 DotDynstr
.finalize();
1097 template <class ELFT
>
1098 bool ELFState
<ELFT
>::writeELF(raw_ostream
&OS
, ELFYAML::Object
&Doc
,
1099 yaml::ErrorHandler EH
) {
1100 ELFState
<ELFT
> State(Doc
, EH
);
1102 // Finalize .strtab and .dynstr sections. We do that early because want to
1103 // finalize the string table builders before writing the content of the
1104 // sections that might want to use them.
1105 State
.finalizeStrings();
1107 State
.buildSectionIndex();
1108 State
.buildSymbolIndexes();
1110 std::vector
<Elf_Phdr
> PHeaders
;
1111 State
.initProgramHeaders(PHeaders
);
1113 // XXX: This offset is tightly coupled with the order that we write
1115 const size_t SectionContentBeginOffset
=
1116 sizeof(Elf_Ehdr
) + sizeof(Elf_Phdr
) * Doc
.ProgramHeaders
.size();
1117 ContiguousBlobAccumulator
CBA(SectionContentBeginOffset
);
1119 std::vector
<Elf_Shdr
> SHeaders
;
1120 State
.initSectionHeaders(SHeaders
, CBA
);
1122 // Now we can decide segment offsets
1123 State
.setProgramHeaderLayout(PHeaders
, SHeaders
);
1128 State
.writeELFHeader(CBA
, OS
);
1129 writeArrayData(OS
, makeArrayRef(PHeaders
));
1130 CBA
.writeBlobToStream(OS
);
1131 writeArrayData(OS
, makeArrayRef(SHeaders
));
1138 bool yaml2elf(llvm::ELFYAML::Object
&Doc
, raw_ostream
&Out
, ErrorHandler EH
) {
1139 bool IsLE
= Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
1140 bool Is64Bit
= Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
);
1143 return ELFState
<object::ELF64LE
>::writeELF(Out
, Doc
, EH
);
1144 return ELFState
<object::ELF64BE
>::writeELF(Out
, Doc
, EH
);
1147 return ELFState
<object::ELF32LE
>::writeELF(Out
, Doc
, EH
);
1148 return ELFState
<object::ELF32BE
>::writeELF(Out
, Doc
, EH
);