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/MemoryBuffer.h"
23 #include "llvm/Support/WithColor.h"
24 #include "llvm/Support/YAMLTraits.h"
25 #include "llvm/Support/raw_ostream.h"
29 // This class is used to build up a contiguous binary blob while keeping
30 // track of an offset in the output (which notionally begins at
33 class ContiguousBlobAccumulator
{
34 const uint64_t InitialOffset
;
35 SmallVector
<char, 128> Buf
;
36 raw_svector_ostream OS
;
38 /// \returns The new offset.
39 uint64_t padToAlignment(unsigned Align
) {
42 uint64_t CurrentOffset
= InitialOffset
+ OS
.tell();
43 uint64_t AlignedOffset
= alignTo(CurrentOffset
, Align
);
44 OS
.write_zeros(AlignedOffset
- CurrentOffset
);
45 return AlignedOffset
; // == CurrentOffset;
49 ContiguousBlobAccumulator(uint64_t InitialOffset_
)
50 : InitialOffset(InitialOffset_
), Buf(), OS(Buf
) {}
51 template <class Integer
>
52 raw_ostream
&getOSAndAlignedOffset(Integer
&Offset
, unsigned Align
) {
53 Offset
= padToAlignment(Align
);
56 void writeBlobToStream(raw_ostream
&Out
) { Out
<< OS
.str(); }
59 // Used to keep track of section and symbol names, so that in the YAML file
60 // sections and symbols can be referenced by name instead of by index.
62 StringMap
<unsigned> Map
;
65 /// \Returns false if name is already present in the map.
66 bool addName(StringRef Name
, unsigned Ndx
) {
67 return Map
.insert({Name
, Ndx
}).second
;
69 /// \Returns false if name is not present in the map.
70 bool lookup(StringRef Name
, unsigned &Idx
) const {
71 auto I
= Map
.find(Name
);
77 /// Asserts if name is not present in the map.
78 unsigned get(StringRef Name
) const {
80 if (lookup(Name
, Idx
))
82 assert(false && "Expected section not found in index");
85 unsigned size() const { return Map
.size(); }
88 /// "Single point of truth" for the ELF file construction.
89 /// TODO: This class still has a ways to go before it is truly a "single
91 template <class ELFT
> class ELFState
{
92 typedef typename
ELFT::Ehdr Elf_Ehdr
;
93 typedef typename
ELFT::Phdr Elf_Phdr
;
94 typedef typename
ELFT::Shdr Elf_Shdr
;
95 typedef typename
ELFT::Sym Elf_Sym
;
96 typedef typename
ELFT::Rel Elf_Rel
;
97 typedef typename
ELFT::Rela Elf_Rela
;
98 typedef typename
ELFT::Relr Elf_Relr
;
99 typedef typename
ELFT::Dyn Elf_Dyn
;
101 enum class SymtabType
{ Static
, Dynamic
};
103 /// The future ".strtab" section.
104 StringTableBuilder DotStrtab
{StringTableBuilder::ELF
};
106 /// The future ".shstrtab" section.
107 StringTableBuilder DotShStrtab
{StringTableBuilder::ELF
};
109 /// The future ".dynstr" section.
110 StringTableBuilder DotDynstr
{StringTableBuilder::ELF
};
114 NameToIdxMap DynSymN2I
;
115 ELFYAML::Object
&Doc
;
117 bool HasError
= false;
118 yaml::ErrorHandler ErrHandler
;
119 void reportError(const Twine
&Msg
);
121 std::vector
<Elf_Sym
> toELFSymbols(ArrayRef
<ELFYAML::Symbol
> Symbols
,
122 const StringTableBuilder
&Strtab
);
123 unsigned toSectionIndex(StringRef S
, StringRef LocSec
, StringRef LocSym
= "");
124 unsigned toSymbolIndex(StringRef S
, StringRef LocSec
, bool IsDynamic
);
126 void buildSectionIndex();
127 void buildSymbolIndexes();
128 void initProgramHeaders(std::vector
<Elf_Phdr
> &PHeaders
);
129 bool initImplicitHeader(ContiguousBlobAccumulator
&CBA
, Elf_Shdr
&Header
,
130 StringRef SecName
, ELFYAML::Section
*YAMLSec
);
131 void initSectionHeaders(std::vector
<Elf_Shdr
> &SHeaders
,
132 ContiguousBlobAccumulator
&CBA
);
133 void initSymtabSectionHeader(Elf_Shdr
&SHeader
, SymtabType STType
,
134 ContiguousBlobAccumulator
&CBA
,
135 ELFYAML::Section
*YAMLSec
);
136 void initStrtabSectionHeader(Elf_Shdr
&SHeader
, StringRef Name
,
137 StringTableBuilder
&STB
,
138 ContiguousBlobAccumulator
&CBA
,
139 ELFYAML::Section
*YAMLSec
);
140 void setProgramHeaderLayout(std::vector
<Elf_Phdr
> &PHeaders
,
141 std::vector
<Elf_Shdr
> &SHeaders
);
142 void finalizeStrings();
143 void writeELFHeader(ContiguousBlobAccumulator
&CBA
, raw_ostream
&OS
);
144 void writeSectionContent(Elf_Shdr
&SHeader
,
145 const ELFYAML::RawContentSection
&Section
,
146 ContiguousBlobAccumulator
&CBA
);
147 void writeSectionContent(Elf_Shdr
&SHeader
,
148 const ELFYAML::RelocationSection
&Section
,
149 ContiguousBlobAccumulator
&CBA
);
150 void writeSectionContent(Elf_Shdr
&SHeader
, const ELFYAML::Group
&Group
,
151 ContiguousBlobAccumulator
&CBA
);
152 void writeSectionContent(Elf_Shdr
&SHeader
,
153 const ELFYAML::SymtabShndxSection
&Shndx
,
154 ContiguousBlobAccumulator
&CBA
);
155 void writeSectionContent(Elf_Shdr
&SHeader
,
156 const ELFYAML::SymverSection
&Section
,
157 ContiguousBlobAccumulator
&CBA
);
158 void writeSectionContent(Elf_Shdr
&SHeader
,
159 const ELFYAML::VerneedSection
&Section
,
160 ContiguousBlobAccumulator
&CBA
);
161 void writeSectionContent(Elf_Shdr
&SHeader
,
162 const ELFYAML::VerdefSection
&Section
,
163 ContiguousBlobAccumulator
&CBA
);
164 void writeSectionContent(Elf_Shdr
&SHeader
,
165 const ELFYAML::MipsABIFlags
&Section
,
166 ContiguousBlobAccumulator
&CBA
);
167 void writeSectionContent(Elf_Shdr
&SHeader
,
168 const ELFYAML::DynamicSection
&Section
,
169 ContiguousBlobAccumulator
&CBA
);
170 ELFState(ELFYAML::Object
&D
, yaml::ErrorHandler EH
);
173 static bool writeELF(raw_ostream
&OS
, ELFYAML::Object
&Doc
,
174 yaml::ErrorHandler EH
);
176 } // end anonymous namespace
178 template <class T
> static size_t arrayDataSize(ArrayRef
<T
> A
) {
179 return A
.size() * sizeof(T
);
182 template <class T
> static void writeArrayData(raw_ostream
&OS
, ArrayRef
<T
> A
) {
183 OS
.write((const char *)A
.data(), arrayDataSize(A
));
186 template <class T
> static void zero(T
&Obj
) { memset(&Obj
, 0, sizeof(Obj
)); }
188 template <class ELFT
>
189 ELFState
<ELFT
>::ELFState(ELFYAML::Object
&D
, yaml::ErrorHandler EH
)
190 : Doc(D
), ErrHandler(EH
) {
191 StringSet
<> DocSections
;
192 for (std::unique_ptr
<ELFYAML::Section
> &D
: Doc
.Sections
)
193 if (!D
->Name
.empty())
194 DocSections
.insert(D
->Name
);
196 // Insert SHT_NULL section implicitly when it is not defined in YAML.
197 if (Doc
.Sections
.empty() || Doc
.Sections
.front()->Type
!= ELF::SHT_NULL
)
199 Doc
.Sections
.begin(),
200 std::make_unique
<ELFYAML::Section
>(
201 ELFYAML::Section::SectionKind::RawContent
, /*IsImplicit=*/true));
203 std::vector
<StringRef
> ImplicitSections
= {".symtab", ".strtab", ".shstrtab"};
204 if (!Doc
.DynamicSymbols
.empty())
205 ImplicitSections
.insert(ImplicitSections
.end(), {".dynsym", ".dynstr"});
207 // Insert placeholders for implicit sections that are not
208 // defined explicitly in YAML.
209 for (StringRef SecName
: ImplicitSections
) {
210 if (DocSections
.count(SecName
))
213 std::unique_ptr
<ELFYAML::Section
> Sec
= std::make_unique
<ELFYAML::Section
>(
214 ELFYAML::Section::SectionKind::RawContent
, true /*IsImplicit*/);
216 Doc
.Sections
.push_back(std::move(Sec
));
220 template <class ELFT
>
221 void ELFState
<ELFT
>::writeELFHeader(ContiguousBlobAccumulator
&CBA
, raw_ostream
&OS
) {
222 using namespace llvm::ELF
;
226 Header
.e_ident
[EI_MAG0
] = 0x7f;
227 Header
.e_ident
[EI_MAG1
] = 'E';
228 Header
.e_ident
[EI_MAG2
] = 'L';
229 Header
.e_ident
[EI_MAG3
] = 'F';
230 Header
.e_ident
[EI_CLASS
] = ELFT::Is64Bits
? ELFCLASS64
: ELFCLASS32
;
231 Header
.e_ident
[EI_DATA
] = Doc
.Header
.Data
;
232 Header
.e_ident
[EI_VERSION
] = EV_CURRENT
;
233 Header
.e_ident
[EI_OSABI
] = Doc
.Header
.OSABI
;
234 Header
.e_ident
[EI_ABIVERSION
] = Doc
.Header
.ABIVersion
;
235 Header
.e_type
= Doc
.Header
.Type
;
236 Header
.e_machine
= Doc
.Header
.Machine
;
237 Header
.e_version
= EV_CURRENT
;
238 Header
.e_entry
= Doc
.Header
.Entry
;
239 Header
.e_phoff
= Doc
.ProgramHeaders
.size() ? sizeof(Header
) : 0;
240 Header
.e_flags
= Doc
.Header
.Flags
;
241 Header
.e_ehsize
= sizeof(Elf_Ehdr
);
242 Header
.e_phentsize
= Doc
.ProgramHeaders
.size() ? sizeof(Elf_Phdr
) : 0;
243 Header
.e_phnum
= Doc
.ProgramHeaders
.size();
246 Doc
.Header
.SHEntSize
? (uint16_t)*Doc
.Header
.SHEntSize
: sizeof(Elf_Shdr
);
247 // Immediately following the ELF header and program headers.
248 // Align the start of the section header and write the ELF header.
250 CBA
.getOSAndAlignedOffset(SHOff
, sizeof(typename
ELFT::uint
));
252 Doc
.Header
.SHOff
? typename
ELFT::uint(*Doc
.Header
.SHOff
) : SHOff
;
254 Doc
.Header
.SHNum
? (uint16_t)*Doc
.Header
.SHNum
: Doc
.Sections
.size();
255 Header
.e_shstrndx
= Doc
.Header
.SHStrNdx
? (uint16_t)*Doc
.Header
.SHStrNdx
256 : SN2I
.get(".shstrtab");
258 OS
.write((const char *)&Header
, sizeof(Header
));
261 template <class ELFT
>
262 void ELFState
<ELFT
>::initProgramHeaders(std::vector
<Elf_Phdr
> &PHeaders
) {
263 for (const auto &YamlPhdr
: Doc
.ProgramHeaders
) {
265 Phdr
.p_type
= YamlPhdr
.Type
;
266 Phdr
.p_flags
= YamlPhdr
.Flags
;
267 Phdr
.p_vaddr
= YamlPhdr
.VAddr
;
268 Phdr
.p_paddr
= YamlPhdr
.PAddr
;
269 PHeaders
.push_back(Phdr
);
273 template <class ELFT
>
274 unsigned ELFState
<ELFT
>::toSectionIndex(StringRef S
, StringRef LocSec
,
277 if (SN2I
.lookup(S
, Index
) || to_integer(S
, Index
))
280 assert(LocSec
.empty() || LocSym
.empty());
282 reportError("unknown section referenced: '" + S
+ "' by YAML symbol '" +
285 reportError("unknown section referenced: '" + S
+ "' by YAML section '" +
290 template <class ELFT
>
291 unsigned ELFState
<ELFT
>::toSymbolIndex(StringRef S
, StringRef LocSec
,
293 const NameToIdxMap
&SymMap
= IsDynamic
? DynSymN2I
: SymN2I
;
295 // Here we try to look up S in the symbol table. If it is not there,
296 // treat its value as a symbol index.
297 if (!SymMap
.lookup(S
, Index
) && !to_integer(S
, Index
)) {
298 reportError("unknown symbol referenced: '" + S
+ "' by YAML section '" +
305 template <class ELFT
>
306 bool ELFState
<ELFT
>::initImplicitHeader(ContiguousBlobAccumulator
&CBA
,
307 Elf_Shdr
&Header
, StringRef SecName
,
308 ELFYAML::Section
*YAMLSec
) {
309 // Check if the header was already initialized.
310 if (Header
.sh_offset
)
313 if (SecName
== ".symtab")
314 initSymtabSectionHeader(Header
, SymtabType::Static
, CBA
, YAMLSec
);
315 else if (SecName
== ".strtab")
316 initStrtabSectionHeader(Header
, SecName
, DotStrtab
, CBA
, YAMLSec
);
317 else if (SecName
== ".shstrtab")
318 initStrtabSectionHeader(Header
, SecName
, DotShStrtab
, CBA
, YAMLSec
);
319 else if (SecName
== ".dynsym")
320 initSymtabSectionHeader(Header
, SymtabType::Dynamic
, CBA
, YAMLSec
);
321 else if (SecName
== ".dynstr")
322 initStrtabSectionHeader(Header
, SecName
, DotDynstr
, CBA
, YAMLSec
);
326 // Override the fields if requested.
329 Header
.sh_name
= *YAMLSec
->ShName
;
330 if (YAMLSec
->ShOffset
)
331 Header
.sh_offset
= *YAMLSec
->ShOffset
;
333 Header
.sh_size
= *YAMLSec
->ShSize
;
339 static StringRef
dropUniqueSuffix(StringRef S
) {
340 size_t SuffixPos
= S
.rfind(" [");
341 if (SuffixPos
== StringRef::npos
)
343 return S
.substr(0, SuffixPos
);
346 template <class ELFT
>
347 void ELFState
<ELFT
>::initSectionHeaders(std::vector
<Elf_Shdr
> &SHeaders
,
348 ContiguousBlobAccumulator
&CBA
) {
349 // Ensure SHN_UNDEF entry is present. An all-zero section header is a
350 // valid SHN_UNDEF entry since SHT_NULL == 0.
351 SHeaders
.resize(Doc
.Sections
.size());
353 for (size_t I
= 0; I
< Doc
.Sections
.size(); ++I
) {
354 ELFYAML::Section
*Sec
= Doc
.Sections
[I
].get();
355 if (I
== 0 && Sec
->IsImplicit
)
358 // We have a few sections like string or symbol tables that are usually
359 // added implicitly to the end. However, if they are explicitly specified
360 // in the YAML, we need to write them here. This ensures the file offset
362 Elf_Shdr
&SHeader
= SHeaders
[I
];
363 if (initImplicitHeader(CBA
, SHeader
, Sec
->Name
,
364 Sec
->IsImplicit
? nullptr : Sec
))
367 assert(Sec
&& "It can't be null unless it is an implicit section. But all "
368 "implicit sections should already have been handled above.");
370 SHeader
.sh_name
= DotShStrtab
.getOffset(dropUniqueSuffix(Sec
->Name
));
371 SHeader
.sh_type
= Sec
->Type
;
373 SHeader
.sh_flags
= *Sec
->Flags
;
374 SHeader
.sh_addr
= Sec
->Address
;
375 SHeader
.sh_addralign
= Sec
->AddressAlign
;
377 if (!Sec
->Link
.empty())
378 SHeader
.sh_link
= toSectionIndex(Sec
->Link
, Sec
->Name
);
381 if (auto RawSec
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
382 // We do not write any content for special SHN_UNDEF section.
384 SHeader
.sh_size
= *RawSec
->Size
;
386 SHeader
.sh_info
= *RawSec
->Info
;
389 SHeader
.sh_entsize
= *Sec
->EntSize
;
390 } else if (auto S
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
391 writeSectionContent(SHeader
, *S
, CBA
);
392 } else if (auto S
= dyn_cast
<ELFYAML::SymtabShndxSection
>(Sec
)) {
393 writeSectionContent(SHeader
, *S
, CBA
);
394 } else if (auto S
= dyn_cast
<ELFYAML::RelocationSection
>(Sec
)) {
395 writeSectionContent(SHeader
, *S
, CBA
);
396 } else if (auto S
= dyn_cast
<ELFYAML::Group
>(Sec
)) {
397 writeSectionContent(SHeader
, *S
, CBA
);
398 } else if (auto S
= dyn_cast
<ELFYAML::MipsABIFlags
>(Sec
)) {
399 writeSectionContent(SHeader
, *S
, CBA
);
400 } else if (auto S
= dyn_cast
<ELFYAML::NoBitsSection
>(Sec
)) {
401 SHeader
.sh_entsize
= 0;
402 SHeader
.sh_size
= S
->Size
;
403 // SHT_NOBITS section does not have content
404 // so just to setup the section offset.
405 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
406 } else if (auto S
= dyn_cast
<ELFYAML::DynamicSection
>(Sec
)) {
407 writeSectionContent(SHeader
, *S
, CBA
);
408 } else if (auto S
= dyn_cast
<ELFYAML::SymverSection
>(Sec
)) {
409 writeSectionContent(SHeader
, *S
, CBA
);
410 } else if (auto S
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
)) {
411 writeSectionContent(SHeader
, *S
, CBA
);
412 } else if (auto S
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
)) {
413 writeSectionContent(SHeader
, *S
, CBA
);
415 llvm_unreachable("Unknown section type");
418 // Override the fields if requested.
421 SHeader
.sh_name
= *Sec
->ShName
;
423 SHeader
.sh_offset
= *Sec
->ShOffset
;
425 SHeader
.sh_size
= *Sec
->ShSize
;
430 static size_t findFirstNonGlobal(ArrayRef
<ELFYAML::Symbol
> Symbols
) {
431 for (size_t I
= 0; I
< Symbols
.size(); ++I
)
432 if (Symbols
[I
].Binding
.value
!= ELF::STB_LOCAL
)
434 return Symbols
.size();
437 static uint64_t writeRawSectionData(raw_ostream
&OS
,
438 const ELFYAML::RawContentSection
&RawSec
) {
439 size_t ContentSize
= 0;
440 if (RawSec
.Content
) {
441 RawSec
.Content
->writeAsBinary(OS
);
442 ContentSize
= RawSec
.Content
->binary_size();
448 OS
.write_zeros(*RawSec
.Size
- ContentSize
);
452 template <class ELFT
>
453 std::vector
<typename
ELFT::Sym
>
454 ELFState
<ELFT
>::toELFSymbols(ArrayRef
<ELFYAML::Symbol
> Symbols
,
455 const StringTableBuilder
&Strtab
) {
456 std::vector
<Elf_Sym
> Ret
;
457 Ret
.resize(Symbols
.size() + 1);
460 for (const auto &Sym
: Symbols
) {
461 Elf_Sym
&Symbol
= Ret
[++I
];
463 // If NameIndex, which contains the name offset, is explicitly specified, we
464 // use it. This is useful for preparing broken objects. Otherwise, we add
465 // the specified Name to the string table builder to get its offset.
467 Symbol
.st_name
= *Sym
.NameIndex
;
468 else if (!Sym
.Name
.empty())
469 Symbol
.st_name
= Strtab
.getOffset(dropUniqueSuffix(Sym
.Name
));
471 Symbol
.setBindingAndType(Sym
.Binding
, Sym
.Type
);
472 if (!Sym
.Section
.empty())
473 Symbol
.st_shndx
= toSectionIndex(Sym
.Section
, "", Sym
.Name
);
475 Symbol
.st_shndx
= *Sym
.Index
;
477 Symbol
.st_value
= Sym
.Value
;
478 Symbol
.st_other
= Sym
.Other
? *Sym
.Other
: 0;
479 Symbol
.st_size
= Sym
.Size
;
485 template <class ELFT
>
486 void ELFState
<ELFT
>::initSymtabSectionHeader(Elf_Shdr
&SHeader
,
488 ContiguousBlobAccumulator
&CBA
,
489 ELFYAML::Section
*YAMLSec
) {
491 bool IsStatic
= STType
== SymtabType::Static
;
492 const auto &Symbols
= IsStatic
? Doc
.Symbols
: Doc
.DynamicSymbols
;
494 ELFYAML::RawContentSection
*RawSec
=
495 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
496 if (RawSec
&& !Symbols
.empty() && (RawSec
->Content
|| RawSec
->Size
)) {
498 reportError("cannot specify both `Content` and " +
499 (IsStatic
? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
500 " for symbol table section '" + RawSec
->Name
+ "'");
502 reportError("cannot specify both `Size` and " +
503 (IsStatic
? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
504 " for symbol table section '" + RawSec
->Name
+ "'");
509 SHeader
.sh_name
= DotShStrtab
.getOffset(IsStatic
? ".symtab" : ".dynsym");
512 SHeader
.sh_type
= YAMLSec
->Type
;
514 SHeader
.sh_type
= IsStatic
? ELF::SHT_SYMTAB
: ELF::SHT_DYNSYM
;
516 if (RawSec
&& !RawSec
->Link
.empty()) {
517 // If the Link field is explicitly defined in the document,
519 SHeader
.sh_link
= toSectionIndex(RawSec
->Link
, RawSec
->Name
);
521 // When we describe the .dynsym section in the document explicitly, it is
522 // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not
523 // added implicitly and we should be able to leave the Link zeroed if
524 // .dynstr is not defined.
527 Link
= SN2I
.get(".strtab");
529 SN2I
.lookup(".dynstr", Link
);
530 SHeader
.sh_link
= Link
;
533 if (YAMLSec
&& YAMLSec
->Flags
)
534 SHeader
.sh_flags
= *YAMLSec
->Flags
;
536 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
538 // If the symbol table section is explicitly described in the YAML
539 // then we should set the fields requested.
540 SHeader
.sh_info
= (RawSec
&& RawSec
->Info
) ? (unsigned)(*RawSec
->Info
)
541 : findFirstNonGlobal(Symbols
) + 1;
542 SHeader
.sh_entsize
= (YAMLSec
&& YAMLSec
->EntSize
)
543 ? (uint64_t)(*YAMLSec
->EntSize
)
545 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 8;
546 SHeader
.sh_addr
= YAMLSec
? (uint64_t)YAMLSec
->Address
: 0;
548 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
549 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
550 assert(Symbols
.empty());
551 SHeader
.sh_size
= writeRawSectionData(OS
, *RawSec
);
555 std::vector
<Elf_Sym
> Syms
=
556 toELFSymbols(Symbols
, IsStatic
? DotStrtab
: DotDynstr
);
557 writeArrayData(OS
, makeArrayRef(Syms
));
558 SHeader
.sh_size
= arrayDataSize(makeArrayRef(Syms
));
561 template <class ELFT
>
562 void ELFState
<ELFT
>::initStrtabSectionHeader(Elf_Shdr
&SHeader
, StringRef Name
,
563 StringTableBuilder
&STB
,
564 ContiguousBlobAccumulator
&CBA
,
565 ELFYAML::Section
*YAMLSec
) {
567 SHeader
.sh_name
= DotShStrtab
.getOffset(Name
);
568 SHeader
.sh_type
= YAMLSec
? YAMLSec
->Type
: ELF::SHT_STRTAB
;
569 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 1;
571 ELFYAML::RawContentSection
*RawSec
=
572 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
574 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
575 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
576 SHeader
.sh_size
= writeRawSectionData(OS
, *RawSec
);
579 SHeader
.sh_size
= STB
.getSize();
582 if (YAMLSec
&& YAMLSec
->EntSize
)
583 SHeader
.sh_entsize
= *YAMLSec
->EntSize
;
585 if (RawSec
&& RawSec
->Info
)
586 SHeader
.sh_info
= *RawSec
->Info
;
588 if (YAMLSec
&& YAMLSec
->Flags
)
589 SHeader
.sh_flags
= *YAMLSec
->Flags
;
590 else if (Name
== ".dynstr")
591 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
593 // If the section is explicitly described in the YAML
594 // then we want to use its section address.
596 SHeader
.sh_addr
= YAMLSec
->Address
;
599 template <class ELFT
> void ELFState
<ELFT
>::reportError(const Twine
&Msg
) {
604 template <class ELFT
>
605 void ELFState
<ELFT
>::setProgramHeaderLayout(std::vector
<Elf_Phdr
> &PHeaders
,
606 std::vector
<Elf_Shdr
> &SHeaders
) {
607 uint32_t PhdrIdx
= 0;
608 for (auto &YamlPhdr
: Doc
.ProgramHeaders
) {
609 Elf_Phdr
&PHeader
= PHeaders
[PhdrIdx
++];
611 std::vector
<Elf_Shdr
*> Sections
;
612 for (const ELFYAML::SectionName
&SecName
: YamlPhdr
.Sections
) {
614 if (!SN2I
.lookup(SecName
.Section
, Index
)) {
615 reportError("unknown section referenced: '" + SecName
.Section
+
616 "' by program header");
619 Sections
.push_back(&SHeaders
[Index
]);
622 if (YamlPhdr
.Offset
) {
623 PHeader
.p_offset
= *YamlPhdr
.Offset
;
625 if (YamlPhdr
.Sections
.size())
626 PHeader
.p_offset
= UINT32_MAX
;
628 PHeader
.p_offset
= 0;
630 // Find the minimum offset for the program header.
631 for (Elf_Shdr
*SHeader
: Sections
)
632 PHeader
.p_offset
= std::min(PHeader
.p_offset
, SHeader
->sh_offset
);
635 // Find the maximum offset of the end of a section in order to set p_filesz
636 // and p_memsz. When setting p_filesz, trailing SHT_NOBITS sections are not
638 uint64_t FileOffset
= PHeader
.p_offset
, MemOffset
= PHeader
.p_offset
;
639 for (Elf_Shdr
*SHeader
: Sections
) {
640 uint64_t End
= SHeader
->sh_offset
+ SHeader
->sh_size
;
641 MemOffset
= std::max(MemOffset
, End
);
643 if (SHeader
->sh_type
!= llvm::ELF::SHT_NOBITS
)
644 FileOffset
= std::max(FileOffset
, End
);
647 // Set the file size and the memory size if not set explicitly.
648 PHeader
.p_filesz
= YamlPhdr
.FileSize
? uint64_t(*YamlPhdr
.FileSize
)
649 : FileOffset
- PHeader
.p_offset
;
650 PHeader
.p_memsz
= YamlPhdr
.MemSize
? uint64_t(*YamlPhdr
.MemSize
)
651 : MemOffset
- PHeader
.p_offset
;
653 if (YamlPhdr
.Align
) {
654 PHeader
.p_align
= *YamlPhdr
.Align
;
656 // Set the alignment of the segment to be the maximum alignment of the
657 // sections so that by default the segment has a valid and sensible
660 for (Elf_Shdr
*SHeader
: Sections
)
661 PHeader
.p_align
= std::max(PHeader
.p_align
, SHeader
->sh_addralign
);
666 template <class ELFT
>
667 void ELFState
<ELFT
>::writeSectionContent(
668 Elf_Shdr
&SHeader
, const ELFYAML::RawContentSection
&Section
,
669 ContiguousBlobAccumulator
&CBA
) {
671 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
672 SHeader
.sh_size
= writeRawSectionData(OS
, Section
);
675 SHeader
.sh_entsize
= *Section
.EntSize
;
676 else if (Section
.Type
== llvm::ELF::SHT_RELR
)
677 SHeader
.sh_entsize
= sizeof(Elf_Relr
);
679 SHeader
.sh_entsize
= 0;
682 SHeader
.sh_info
= *Section
.Info
;
685 static bool isMips64EL(const ELFYAML::Object
&Doc
) {
686 return Doc
.Header
.Machine
== ELFYAML::ELF_EM(llvm::ELF::EM_MIPS
) &&
687 Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
) &&
688 Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
691 template <class ELFT
>
692 void ELFState
<ELFT
>::writeSectionContent(
693 Elf_Shdr
&SHeader
, const ELFYAML::RelocationSection
&Section
,
694 ContiguousBlobAccumulator
&CBA
) {
695 assert((Section
.Type
== llvm::ELF::SHT_REL
||
696 Section
.Type
== llvm::ELF::SHT_RELA
) &&
697 "Section type is not SHT_REL nor SHT_RELA");
699 bool IsRela
= Section
.Type
== llvm::ELF::SHT_RELA
;
700 SHeader
.sh_entsize
= IsRela
? sizeof(Elf_Rela
) : sizeof(Elf_Rel
);
701 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Relocations
.size();
703 // For relocation section set link to .symtab by default.
704 if (Section
.Link
.empty())
705 SHeader
.sh_link
= SN2I
.get(".symtab");
707 if (!Section
.RelocatableSec
.empty())
708 SHeader
.sh_info
= toSectionIndex(Section
.RelocatableSec
, Section
.Name
);
710 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
711 for (const auto &Rel
: Section
.Relocations
) {
712 unsigned SymIdx
= Rel
.Symbol
? toSymbolIndex(*Rel
.Symbol
, Section
.Name
,
713 Section
.Link
== ".dynsym")
718 REntry
.r_offset
= Rel
.Offset
;
719 REntry
.r_addend
= Rel
.Addend
;
720 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
721 OS
.write((const char *)&REntry
, sizeof(REntry
));
725 REntry
.r_offset
= Rel
.Offset
;
726 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
727 OS
.write((const char *)&REntry
, sizeof(REntry
));
732 template <class ELFT
>
733 void ELFState
<ELFT
>::writeSectionContent(
734 Elf_Shdr
&SHeader
, const ELFYAML::SymtabShndxSection
&Shndx
,
735 ContiguousBlobAccumulator
&CBA
) {
737 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
739 for (uint32_t E
: Shndx
.Entries
)
740 support::endian::write
<uint32_t>(OS
, E
, ELFT::TargetEndianness
);
742 SHeader
.sh_entsize
= Shndx
.EntSize
? (uint64_t)*Shndx
.EntSize
: 4;
743 SHeader
.sh_size
= Shndx
.Entries
.size() * SHeader
.sh_entsize
;
746 template <class ELFT
>
747 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
748 const ELFYAML::Group
&Section
,
749 ContiguousBlobAccumulator
&CBA
) {
750 assert(Section
.Type
== llvm::ELF::SHT_GROUP
&&
751 "Section type is not SHT_GROUP");
753 SHeader
.sh_entsize
= 4;
754 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Members
.size();
756 toSymbolIndex(Section
.Signature
, Section
.Name
, /*IsDynamic=*/false);
759 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
761 for (const ELFYAML::SectionOrType
&Member
: Section
.Members
) {
762 unsigned int SectionIndex
= 0;
763 if (Member
.sectionNameOrType
== "GRP_COMDAT")
764 SectionIndex
= llvm::ELF::GRP_COMDAT
;
766 SectionIndex
= toSectionIndex(Member
.sectionNameOrType
, Section
.Name
);
767 support::endian::write
<uint32_t>(OS
, SectionIndex
, ELFT::TargetEndianness
);
771 template <class ELFT
>
772 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
773 const ELFYAML::SymverSection
&Section
,
774 ContiguousBlobAccumulator
&CBA
) {
776 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
777 for (uint16_t Version
: Section
.Entries
)
778 support::endian::write
<uint16_t>(OS
, Version
, ELFT::TargetEndianness
);
780 SHeader
.sh_entsize
= Section
.EntSize
? (uint64_t)*Section
.EntSize
: 2;
781 SHeader
.sh_size
= Section
.Entries
.size() * SHeader
.sh_entsize
;
784 template <class ELFT
>
785 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
786 const ELFYAML::VerdefSection
&Section
,
787 ContiguousBlobAccumulator
&CBA
) {
788 typedef typename
ELFT::Verdef Elf_Verdef
;
789 typedef typename
ELFT::Verdaux Elf_Verdaux
;
791 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
794 for (size_t I
= 0; I
< Section
.Entries
.size(); ++I
) {
795 const ELFYAML::VerdefEntry
&E
= Section
.Entries
[I
];
798 VerDef
.vd_version
= E
.Version
;
799 VerDef
.vd_flags
= E
.Flags
;
800 VerDef
.vd_ndx
= E
.VersionNdx
;
801 VerDef
.vd_hash
= E
.Hash
;
802 VerDef
.vd_aux
= sizeof(Elf_Verdef
);
803 VerDef
.vd_cnt
= E
.VerNames
.size();
804 if (I
== Section
.Entries
.size() - 1)
808 sizeof(Elf_Verdef
) + E
.VerNames
.size() * sizeof(Elf_Verdaux
);
809 OS
.write((const char *)&VerDef
, sizeof(Elf_Verdef
));
811 for (size_t J
= 0; J
< E
.VerNames
.size(); ++J
, ++AuxCnt
) {
813 VernAux
.vda_name
= DotDynstr
.getOffset(E
.VerNames
[J
]);
814 if (J
== E
.VerNames
.size() - 1)
815 VernAux
.vda_next
= 0;
817 VernAux
.vda_next
= sizeof(Elf_Verdaux
);
818 OS
.write((const char *)&VernAux
, sizeof(Elf_Verdaux
));
822 SHeader
.sh_size
= Section
.Entries
.size() * sizeof(Elf_Verdef
) +
823 AuxCnt
* sizeof(Elf_Verdaux
);
824 SHeader
.sh_info
= Section
.Info
;
827 template <class ELFT
>
828 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
829 const ELFYAML::VerneedSection
&Section
,
830 ContiguousBlobAccumulator
&CBA
) {
831 typedef typename
ELFT::Verneed Elf_Verneed
;
832 typedef typename
ELFT::Vernaux Elf_Vernaux
;
834 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
837 for (size_t I
= 0; I
< Section
.VerneedV
.size(); ++I
) {
838 const ELFYAML::VerneedEntry
&VE
= Section
.VerneedV
[I
];
841 VerNeed
.vn_version
= VE
.Version
;
842 VerNeed
.vn_file
= DotDynstr
.getOffset(VE
.File
);
843 if (I
== Section
.VerneedV
.size() - 1)
847 sizeof(Elf_Verneed
) + VE
.AuxV
.size() * sizeof(Elf_Vernaux
);
848 VerNeed
.vn_cnt
= VE
.AuxV
.size();
849 VerNeed
.vn_aux
= sizeof(Elf_Verneed
);
850 OS
.write((const char *)&VerNeed
, sizeof(Elf_Verneed
));
852 for (size_t J
= 0; J
< VE
.AuxV
.size(); ++J
, ++AuxCnt
) {
853 const ELFYAML::VernauxEntry
&VAuxE
= VE
.AuxV
[J
];
856 VernAux
.vna_hash
= VAuxE
.Hash
;
857 VernAux
.vna_flags
= VAuxE
.Flags
;
858 VernAux
.vna_other
= VAuxE
.Other
;
859 VernAux
.vna_name
= DotDynstr
.getOffset(VAuxE
.Name
);
860 if (J
== VE
.AuxV
.size() - 1)
861 VernAux
.vna_next
= 0;
863 VernAux
.vna_next
= sizeof(Elf_Vernaux
);
864 OS
.write((const char *)&VernAux
, sizeof(Elf_Vernaux
));
868 SHeader
.sh_size
= Section
.VerneedV
.size() * sizeof(Elf_Verneed
) +
869 AuxCnt
* sizeof(Elf_Vernaux
);
870 SHeader
.sh_info
= Section
.Info
;
873 template <class ELFT
>
874 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
875 const ELFYAML::MipsABIFlags
&Section
,
876 ContiguousBlobAccumulator
&CBA
) {
877 assert(Section
.Type
== llvm::ELF::SHT_MIPS_ABIFLAGS
&&
878 "Section type is not SHT_MIPS_ABIFLAGS");
880 object::Elf_Mips_ABIFlags
<ELFT
> Flags
;
882 SHeader
.sh_entsize
= sizeof(Flags
);
883 SHeader
.sh_size
= SHeader
.sh_entsize
;
885 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
886 Flags
.version
= Section
.Version
;
887 Flags
.isa_level
= Section
.ISALevel
;
888 Flags
.isa_rev
= Section
.ISARevision
;
889 Flags
.gpr_size
= Section
.GPRSize
;
890 Flags
.cpr1_size
= Section
.CPR1Size
;
891 Flags
.cpr2_size
= Section
.CPR2Size
;
892 Flags
.fp_abi
= Section
.FpABI
;
893 Flags
.isa_ext
= Section
.ISAExtension
;
894 Flags
.ases
= Section
.ASEs
;
895 Flags
.flags1
= Section
.Flags1
;
896 Flags
.flags2
= Section
.Flags2
;
897 OS
.write((const char *)&Flags
, sizeof(Flags
));
900 template <class ELFT
>
901 void ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
902 const ELFYAML::DynamicSection
&Section
,
903 ContiguousBlobAccumulator
&CBA
) {
904 typedef typename
ELFT::uint uintX_t
;
906 assert(Section
.Type
== llvm::ELF::SHT_DYNAMIC
&&
907 "Section type is not SHT_DYNAMIC");
909 if (!Section
.Entries
.empty() && Section
.Content
)
910 reportError("cannot specify both raw content and explicit entries "
911 "for dynamic section '" +
915 SHeader
.sh_size
= Section
.Content
->binary_size();
917 SHeader
.sh_size
= 2 * sizeof(uintX_t
) * Section
.Entries
.size();
919 SHeader
.sh_entsize
= *Section
.EntSize
;
921 SHeader
.sh_entsize
= sizeof(Elf_Dyn
);
924 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
925 for (const ELFYAML::DynamicEntry
&DE
: Section
.Entries
) {
926 support::endian::write
<uintX_t
>(OS
, DE
.Tag
, ELFT::TargetEndianness
);
927 support::endian::write
<uintX_t
>(OS
, DE
.Val
, ELFT::TargetEndianness
);
930 Section
.Content
->writeAsBinary(OS
);
933 template <class ELFT
> void ELFState
<ELFT
>::buildSectionIndex() {
934 for (unsigned I
= 0, E
= Doc
.Sections
.size(); I
!= E
; ++I
) {
935 StringRef Name
= Doc
.Sections
[I
]->Name
;
939 DotShStrtab
.add(dropUniqueSuffix(Name
));
940 if (!SN2I
.addName(Name
, I
))
941 reportError("repeated section name: '" + Name
+
942 "' at YAML section number " + Twine(I
));
945 DotShStrtab
.finalize();
948 template <class ELFT
> void ELFState
<ELFT
>::buildSymbolIndexes() {
949 auto Build
= [this](ArrayRef
<ELFYAML::Symbol
> V
, NameToIdxMap
&Map
) {
950 for (size_t I
= 0, S
= V
.size(); I
< S
; ++I
) {
951 const ELFYAML::Symbol
&Sym
= V
[I
];
952 if (!Sym
.Name
.empty() && !Map
.addName(Sym
.Name
, I
+ 1))
953 reportError("repeated symbol name: '" + Sym
.Name
+ "'");
957 Build(Doc
.Symbols
, SymN2I
);
958 Build(Doc
.DynamicSymbols
, DynSymN2I
);
961 template <class ELFT
> void ELFState
<ELFT
>::finalizeStrings() {
962 // Add the regular symbol names to .strtab section.
963 for (const ELFYAML::Symbol
&Sym
: Doc
.Symbols
)
964 DotStrtab
.add(dropUniqueSuffix(Sym
.Name
));
965 DotStrtab
.finalize();
967 // Add the dynamic symbol names to .dynstr section.
968 for (const ELFYAML::Symbol
&Sym
: Doc
.DynamicSymbols
)
969 DotDynstr
.add(dropUniqueSuffix(Sym
.Name
));
971 // SHT_GNU_verdef and SHT_GNU_verneed sections might also
972 // add strings to .dynstr section.
973 for (const std::unique_ptr
<ELFYAML::Section
> &Sec
: Doc
.Sections
) {
974 if (auto VerNeed
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
.get())) {
975 for (const ELFYAML::VerneedEntry
&VE
: VerNeed
->VerneedV
) {
976 DotDynstr
.add(VE
.File
);
977 for (const ELFYAML::VernauxEntry
&Aux
: VE
.AuxV
)
978 DotDynstr
.add(Aux
.Name
);
980 } else if (auto VerDef
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
.get())) {
981 for (const ELFYAML::VerdefEntry
&E
: VerDef
->Entries
)
982 for (StringRef Name
: E
.VerNames
)
987 DotDynstr
.finalize();
990 template <class ELFT
>
991 bool ELFState
<ELFT
>::writeELF(raw_ostream
&OS
, ELFYAML::Object
&Doc
,
992 yaml::ErrorHandler EH
) {
993 ELFState
<ELFT
> State(Doc
, EH
);
995 // Finalize .strtab and .dynstr sections. We do that early because want to
996 // finalize the string table builders before writing the content of the
997 // sections that might want to use them.
998 State
.finalizeStrings();
1000 State
.buildSectionIndex();
1001 State
.buildSymbolIndexes();
1003 std::vector
<Elf_Phdr
> PHeaders
;
1004 State
.initProgramHeaders(PHeaders
);
1006 // XXX: This offset is tightly coupled with the order that we write
1008 const size_t SectionContentBeginOffset
=
1009 sizeof(Elf_Ehdr
) + sizeof(Elf_Phdr
) * Doc
.ProgramHeaders
.size();
1010 ContiguousBlobAccumulator
CBA(SectionContentBeginOffset
);
1012 std::vector
<Elf_Shdr
> SHeaders
;
1013 State
.initSectionHeaders(SHeaders
, CBA
);
1015 // Now we can decide segment offsets
1016 State
.setProgramHeaderLayout(PHeaders
, SHeaders
);
1021 State
.writeELFHeader(CBA
, OS
);
1022 writeArrayData(OS
, makeArrayRef(PHeaders
));
1023 CBA
.writeBlobToStream(OS
);
1024 writeArrayData(OS
, makeArrayRef(SHeaders
));
1031 bool yaml2elf(llvm::ELFYAML::Object
&Doc
, raw_ostream
&Out
, ErrorHandler EH
) {
1032 bool IsLE
= Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
1033 bool Is64Bit
= Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
);
1036 return ELFState
<object::ELF64LE
>::writeELF(Out
, Doc
, EH
);
1037 return ELFState
<object::ELF64BE
>::writeELF(Out
, Doc
, EH
);
1040 return ELFState
<object::ELF32LE
>::writeELF(Out
, Doc
, EH
);
1041 return ELFState
<object::ELF32BE
>::writeELF(Out
, Doc
, EH
);