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 buildSectionIndex();
118 bool buildSymbolIndexes();
119 void initProgramHeaders(std::vector
<Elf_Phdr
> &PHeaders
);
120 bool initImplicitHeader(ContiguousBlobAccumulator
&CBA
, Elf_Shdr
&Header
,
121 StringRef SecName
, ELFYAML::Section
*YAMLSec
);
122 bool initSectionHeaders(std::vector
<Elf_Shdr
> &SHeaders
,
123 ContiguousBlobAccumulator
&CBA
);
124 void initSymtabSectionHeader(Elf_Shdr
&SHeader
, SymtabType STType
,
125 ContiguousBlobAccumulator
&CBA
,
126 ELFYAML::Section
*YAMLSec
);
127 void initStrtabSectionHeader(Elf_Shdr
&SHeader
, StringRef Name
,
128 StringTableBuilder
&STB
,
129 ContiguousBlobAccumulator
&CBA
,
130 ELFYAML::Section
*YAMLSec
);
131 void setProgramHeaderLayout(std::vector
<Elf_Phdr
> &PHeaders
,
132 std::vector
<Elf_Shdr
> &SHeaders
);
133 void finalizeStrings();
134 void writeELFHeader(ContiguousBlobAccumulator
&CBA
, raw_ostream
&OS
);
135 bool writeSectionContent(Elf_Shdr
&SHeader
,
136 const ELFYAML::RawContentSection
&Section
,
137 ContiguousBlobAccumulator
&CBA
);
138 bool writeSectionContent(Elf_Shdr
&SHeader
,
139 const ELFYAML::RelocationSection
&Section
,
140 ContiguousBlobAccumulator
&CBA
);
141 bool writeSectionContent(Elf_Shdr
&SHeader
, const ELFYAML::Group
&Group
,
142 ContiguousBlobAccumulator
&CBA
);
143 bool writeSectionContent(Elf_Shdr
&SHeader
,
144 const ELFYAML::SymtabShndxSection
&Shndx
,
145 ContiguousBlobAccumulator
&CBA
);
146 bool writeSectionContent(Elf_Shdr
&SHeader
,
147 const ELFYAML::SymverSection
&Section
,
148 ContiguousBlobAccumulator
&CBA
);
149 bool writeSectionContent(Elf_Shdr
&SHeader
,
150 const ELFYAML::VerneedSection
&Section
,
151 ContiguousBlobAccumulator
&CBA
);
152 bool writeSectionContent(Elf_Shdr
&SHeader
,
153 const ELFYAML::VerdefSection
&Section
,
154 ContiguousBlobAccumulator
&CBA
);
155 bool writeSectionContent(Elf_Shdr
&SHeader
,
156 const ELFYAML::MipsABIFlags
&Section
,
157 ContiguousBlobAccumulator
&CBA
);
158 bool writeSectionContent(Elf_Shdr
&SHeader
,
159 const ELFYAML::DynamicSection
&Section
,
160 ContiguousBlobAccumulator
&CBA
);
161 ELFState(ELFYAML::Object
&D
);
164 static int writeELF(raw_ostream
&OS
, ELFYAML::Object
&Doc
);
166 } // end anonymous namespace
168 template <class T
> static size_t arrayDataSize(ArrayRef
<T
> A
) {
169 return A
.size() * sizeof(T
);
172 template <class T
> static void writeArrayData(raw_ostream
&OS
, ArrayRef
<T
> A
) {
173 OS
.write((const char *)A
.data(), arrayDataSize(A
));
176 template <class T
> static void zero(T
&Obj
) { memset(&Obj
, 0, sizeof(Obj
)); }
178 template <class ELFT
> ELFState
<ELFT
>::ELFState(ELFYAML::Object
&D
) : Doc(D
) {
179 StringSet
<> DocSections
;
180 for (std::unique_ptr
<ELFYAML::Section
> &D
: Doc
.Sections
)
181 if (!D
->Name
.empty())
182 DocSections
.insert(D
->Name
);
184 // Insert SHT_NULL section implicitly when it is not defined in YAML.
185 if (Doc
.Sections
.empty() || Doc
.Sections
.front()->Type
!= ELF::SHT_NULL
)
187 Doc
.Sections
.begin(),
188 std::make_unique
<ELFYAML::Section
>(
189 ELFYAML::Section::SectionKind::RawContent
, /*IsImplicit=*/true));
191 std::vector
<StringRef
> ImplicitSections
= {".symtab", ".strtab", ".shstrtab"};
192 if (!Doc
.DynamicSymbols
.empty())
193 ImplicitSections
.insert(ImplicitSections
.end(), {".dynsym", ".dynstr"});
195 // Insert placeholders for implicit sections that are not
196 // defined explicitly in YAML.
197 for (StringRef SecName
: ImplicitSections
) {
198 if (DocSections
.count(SecName
))
201 std::unique_ptr
<ELFYAML::Section
> Sec
= std::make_unique
<ELFYAML::Section
>(
202 ELFYAML::Section::SectionKind::RawContent
, true /*IsImplicit*/);
204 Doc
.Sections
.push_back(std::move(Sec
));
208 template <class ELFT
>
209 void ELFState
<ELFT
>::writeELFHeader(ContiguousBlobAccumulator
&CBA
, raw_ostream
&OS
) {
210 using namespace llvm::ELF
;
214 Header
.e_ident
[EI_MAG0
] = 0x7f;
215 Header
.e_ident
[EI_MAG1
] = 'E';
216 Header
.e_ident
[EI_MAG2
] = 'L';
217 Header
.e_ident
[EI_MAG3
] = 'F';
218 Header
.e_ident
[EI_CLASS
] = ELFT::Is64Bits
? ELFCLASS64
: ELFCLASS32
;
219 Header
.e_ident
[EI_DATA
] = Doc
.Header
.Data
;
220 Header
.e_ident
[EI_VERSION
] = EV_CURRENT
;
221 Header
.e_ident
[EI_OSABI
] = Doc
.Header
.OSABI
;
222 Header
.e_ident
[EI_ABIVERSION
] = Doc
.Header
.ABIVersion
;
223 Header
.e_type
= Doc
.Header
.Type
;
224 Header
.e_machine
= Doc
.Header
.Machine
;
225 Header
.e_version
= EV_CURRENT
;
226 Header
.e_entry
= Doc
.Header
.Entry
;
227 Header
.e_phoff
= Doc
.ProgramHeaders
.size() ? sizeof(Header
) : 0;
228 Header
.e_flags
= Doc
.Header
.Flags
;
229 Header
.e_ehsize
= sizeof(Elf_Ehdr
);
230 Header
.e_phentsize
= Doc
.ProgramHeaders
.size() ? sizeof(Elf_Phdr
) : 0;
231 Header
.e_phnum
= Doc
.ProgramHeaders
.size();
234 Doc
.Header
.SHEntSize
? (uint16_t)*Doc
.Header
.SHEntSize
: sizeof(Elf_Shdr
);
235 // Immediately following the ELF header and program headers.
236 // Align the start of the section header and write the ELF header.
238 CBA
.getOSAndAlignedOffset(SHOff
, sizeof(typename
ELFT::uint
));
240 Doc
.Header
.SHOff
? typename
ELFT::uint(*Doc
.Header
.SHOff
) : SHOff
;
242 Doc
.Header
.SHNum
? (uint16_t)*Doc
.Header
.SHNum
: Doc
.Sections
.size();
243 Header
.e_shstrndx
= Doc
.Header
.SHStrNdx
? (uint16_t)*Doc
.Header
.SHStrNdx
244 : SN2I
.get(".shstrtab");
246 OS
.write((const char *)&Header
, sizeof(Header
));
249 template <class ELFT
>
250 void ELFState
<ELFT
>::initProgramHeaders(std::vector
<Elf_Phdr
> &PHeaders
) {
251 for (const auto &YamlPhdr
: Doc
.ProgramHeaders
) {
253 Phdr
.p_type
= YamlPhdr
.Type
;
254 Phdr
.p_flags
= YamlPhdr
.Flags
;
255 Phdr
.p_vaddr
= YamlPhdr
.VAddr
;
256 Phdr
.p_paddr
= YamlPhdr
.PAddr
;
257 PHeaders
.push_back(Phdr
);
261 static bool convertSectionIndex(NameToIdxMap
&SN2I
, StringRef SecName
,
262 StringRef IndexSrc
, unsigned &IndexDest
) {
263 if (!SN2I
.lookup(IndexSrc
, IndexDest
) && !to_integer(IndexSrc
, IndexDest
)) {
264 WithColor::error() << "Unknown section referenced: '" << IndexSrc
265 << "' at YAML section '" << SecName
<< "'.\n";
271 template <class ELFT
>
272 bool ELFState
<ELFT
>::initImplicitHeader(ContiguousBlobAccumulator
&CBA
,
273 Elf_Shdr
&Header
, StringRef SecName
,
274 ELFYAML::Section
*YAMLSec
) {
275 // Check if the header was already initialized.
276 if (Header
.sh_offset
)
279 if (SecName
== ".symtab")
280 initSymtabSectionHeader(Header
, SymtabType::Static
, CBA
, YAMLSec
);
281 else if (SecName
== ".strtab")
282 initStrtabSectionHeader(Header
, SecName
, DotStrtab
, CBA
, YAMLSec
);
283 else if (SecName
== ".shstrtab")
284 initStrtabSectionHeader(Header
, SecName
, DotShStrtab
, CBA
, YAMLSec
);
285 else if (SecName
== ".dynsym")
286 initSymtabSectionHeader(Header
, SymtabType::Dynamic
, CBA
, YAMLSec
);
287 else if (SecName
== ".dynstr")
288 initStrtabSectionHeader(Header
, SecName
, DotDynstr
, CBA
, YAMLSec
);
292 // Override the fields if requested.
295 Header
.sh_name
= *YAMLSec
->ShName
;
296 if (YAMLSec
->ShOffset
)
297 Header
.sh_offset
= *YAMLSec
->ShOffset
;
299 Header
.sh_size
= *YAMLSec
->ShSize
;
305 static StringRef
dropUniqueSuffix(StringRef S
) {
306 size_t SuffixPos
= S
.rfind(" [");
307 if (SuffixPos
== StringRef::npos
)
309 return S
.substr(0, SuffixPos
);
312 template <class ELFT
>
313 bool ELFState
<ELFT
>::initSectionHeaders(std::vector
<Elf_Shdr
> &SHeaders
,
314 ContiguousBlobAccumulator
&CBA
) {
315 // Ensure SHN_UNDEF entry is present. An all-zero section header is a
316 // valid SHN_UNDEF entry since SHT_NULL == 0.
317 SHeaders
.resize(Doc
.Sections
.size());
319 for (size_t I
= 0; I
< Doc
.Sections
.size(); ++I
) {
320 ELFYAML::Section
*Sec
= Doc
.Sections
[I
].get();
321 if (I
== 0 && Sec
->IsImplicit
)
324 // We have a few sections like string or symbol tables that are usually
325 // added implicitly to the end. However, if they are explicitly specified
326 // in the YAML, we need to write them here. This ensures the file offset
328 Elf_Shdr
&SHeader
= SHeaders
[I
];
329 if (initImplicitHeader(CBA
, SHeader
, Sec
->Name
,
330 Sec
->IsImplicit
? nullptr : Sec
))
333 assert(Sec
&& "It can't be null unless it is an implicit section. But all "
334 "implicit sections should already have been handled above.");
336 SHeader
.sh_name
= DotShStrtab
.getOffset(dropUniqueSuffix(Sec
->Name
));
337 SHeader
.sh_type
= Sec
->Type
;
339 SHeader
.sh_flags
= *Sec
->Flags
;
340 SHeader
.sh_addr
= Sec
->Address
;
341 SHeader
.sh_addralign
= Sec
->AddressAlign
;
343 if (!Sec
->Link
.empty()) {
345 if (!convertSectionIndex(SN2I
, Sec
->Name
, Sec
->Link
, Index
))
347 SHeader
.sh_link
= Index
;
351 if (auto RawSec
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
352 // We do not write any content for special SHN_UNDEF section.
354 SHeader
.sh_size
= *RawSec
->Size
;
356 SHeader
.sh_info
= *RawSec
->Info
;
359 SHeader
.sh_entsize
= *Sec
->EntSize
;
360 } else if (auto S
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
)) {
361 if (!writeSectionContent(SHeader
, *S
, CBA
))
363 } else if (auto S
= dyn_cast
<ELFYAML::SymtabShndxSection
>(Sec
)) {
364 if (!writeSectionContent(SHeader
, *S
, CBA
))
366 } else if (auto S
= dyn_cast
<ELFYAML::RelocationSection
>(Sec
)) {
367 if (!writeSectionContent(SHeader
, *S
, CBA
))
369 } else if (auto S
= dyn_cast
<ELFYAML::Group
>(Sec
)) {
370 if (!writeSectionContent(SHeader
, *S
, CBA
))
372 } else if (auto S
= dyn_cast
<ELFYAML::MipsABIFlags
>(Sec
)) {
373 if (!writeSectionContent(SHeader
, *S
, CBA
))
375 } else if (auto S
= dyn_cast
<ELFYAML::NoBitsSection
>(Sec
)) {
376 SHeader
.sh_entsize
= 0;
377 SHeader
.sh_size
= S
->Size
;
378 // SHT_NOBITS section does not have content
379 // so just to setup the section offset.
380 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
381 } else if (auto S
= dyn_cast
<ELFYAML::DynamicSection
>(Sec
)) {
382 if (!writeSectionContent(SHeader
, *S
, CBA
))
384 } else if (auto S
= dyn_cast
<ELFYAML::SymverSection
>(Sec
)) {
385 if (!writeSectionContent(SHeader
, *S
, CBA
))
387 } else if (auto S
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
)) {
388 if (!writeSectionContent(SHeader
, *S
, CBA
))
390 } else if (auto S
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
)) {
391 if (!writeSectionContent(SHeader
, *S
, CBA
))
394 llvm_unreachable("Unknown section type");
396 // Override the fields if requested.
399 SHeader
.sh_name
= *Sec
->ShName
;
401 SHeader
.sh_offset
= *Sec
->ShOffset
;
403 SHeader
.sh_size
= *Sec
->ShSize
;
410 static size_t findFirstNonGlobal(ArrayRef
<ELFYAML::Symbol
> Symbols
) {
411 for (size_t I
= 0; I
< Symbols
.size(); ++I
)
412 if (Symbols
[I
].Binding
.value
!= ELF::STB_LOCAL
)
414 return Symbols
.size();
417 static uint64_t writeRawSectionData(raw_ostream
&OS
,
418 const ELFYAML::RawContentSection
&RawSec
) {
419 size_t ContentSize
= 0;
420 if (RawSec
.Content
) {
421 RawSec
.Content
->writeAsBinary(OS
);
422 ContentSize
= RawSec
.Content
->binary_size();
428 OS
.write_zeros(*RawSec
.Size
- ContentSize
);
432 template <class ELFT
>
433 static std::vector
<typename
ELFT::Sym
>
434 toELFSymbols(NameToIdxMap
&SN2I
, ArrayRef
<ELFYAML::Symbol
> Symbols
,
435 const StringTableBuilder
&Strtab
) {
436 using Elf_Sym
= typename
ELFT::Sym
;
438 std::vector
<Elf_Sym
> Ret
;
439 Ret
.resize(Symbols
.size() + 1);
442 for (const auto &Sym
: Symbols
) {
443 Elf_Sym
&Symbol
= Ret
[++I
];
445 // If NameIndex, which contains the name offset, is explicitly specified, we
446 // use it. This is useful for preparing broken objects. Otherwise, we add
447 // the specified Name to the string table builder to get its offset.
449 Symbol
.st_name
= *Sym
.NameIndex
;
450 else if (!Sym
.Name
.empty())
451 Symbol
.st_name
= Strtab
.getOffset(dropUniqueSuffix(Sym
.Name
));
453 Symbol
.setBindingAndType(Sym
.Binding
, Sym
.Type
);
454 if (!Sym
.Section
.empty()) {
456 if (!SN2I
.lookup(Sym
.Section
, Index
)) {
457 WithColor::error() << "Unknown section referenced: '" << Sym
.Section
458 << "' by YAML symbol " << Sym
.Name
<< ".\n";
461 Symbol
.st_shndx
= Index
;
462 } else if (Sym
.Index
) {
463 Symbol
.st_shndx
= *Sym
.Index
;
465 // else Symbol.st_shndex == SHN_UNDEF (== 0), since it was zero'd earlier.
466 Symbol
.st_value
= Sym
.Value
;
467 Symbol
.st_other
= Sym
.Other
? *Sym
.Other
: 0;
468 Symbol
.st_size
= Sym
.Size
;
474 template <class ELFT
>
475 void ELFState
<ELFT
>::initSymtabSectionHeader(Elf_Shdr
&SHeader
,
477 ContiguousBlobAccumulator
&CBA
,
478 ELFYAML::Section
*YAMLSec
) {
480 bool IsStatic
= STType
== SymtabType::Static
;
481 const auto &Symbols
= IsStatic
? Doc
.Symbols
: Doc
.DynamicSymbols
;
483 ELFYAML::RawContentSection
*RawSec
=
484 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
485 if (RawSec
&& !Symbols
.empty() && (RawSec
->Content
|| RawSec
->Size
)) {
487 WithColor::error() << "Cannot specify both `Content` and " +
488 (IsStatic
? Twine("`Symbols`")
489 : Twine("`DynamicSymbols`")) +
490 " for symbol table section '"
491 << RawSec
->Name
<< "'.\n";
493 WithColor::error() << "Cannot specify both `Size` and " +
494 (IsStatic
? Twine("`Symbols`")
495 : Twine("`DynamicSymbols`")) +
496 " for symbol table section '"
497 << RawSec
->Name
<< "'.\n";
502 SHeader
.sh_name
= DotShStrtab
.getOffset(IsStatic
? ".symtab" : ".dynsym");
505 SHeader
.sh_type
= YAMLSec
->Type
;
507 SHeader
.sh_type
= IsStatic
? ELF::SHT_SYMTAB
: ELF::SHT_DYNSYM
;
509 if (RawSec
&& !RawSec
->Link
.empty()) {
510 // If the Link field is explicitly defined in the document,
513 if (!convertSectionIndex(SN2I
, RawSec
->Name
, RawSec
->Link
, Index
))
515 SHeader
.sh_link
= Index
;
517 // When we describe the .dynsym section in the document explicitly, it is
518 // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not
519 // added implicitly and we should be able to leave the Link zeroed if
520 // .dynstr is not defined.
523 Link
= SN2I
.get(".strtab");
525 SN2I
.lookup(".dynstr", Link
);
526 SHeader
.sh_link
= Link
;
529 if (YAMLSec
&& YAMLSec
->Flags
)
530 SHeader
.sh_flags
= *YAMLSec
->Flags
;
532 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
534 // If the symbol table section is explicitly described in the YAML
535 // then we should set the fields requested.
536 SHeader
.sh_info
= (RawSec
&& RawSec
->Info
) ? (unsigned)(*RawSec
->Info
)
537 : findFirstNonGlobal(Symbols
) + 1;
538 SHeader
.sh_entsize
= (YAMLSec
&& YAMLSec
->EntSize
)
539 ? (uint64_t)(*YAMLSec
->EntSize
)
541 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 8;
542 SHeader
.sh_addr
= YAMLSec
? (uint64_t)YAMLSec
->Address
: 0;
544 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
545 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
546 assert(Symbols
.empty());
547 SHeader
.sh_size
= writeRawSectionData(OS
, *RawSec
);
551 std::vector
<Elf_Sym
> Syms
=
552 toELFSymbols
<ELFT
>(SN2I
, Symbols
, IsStatic
? DotStrtab
: DotDynstr
);
553 writeArrayData(OS
, makeArrayRef(Syms
));
554 SHeader
.sh_size
= arrayDataSize(makeArrayRef(Syms
));
557 template <class ELFT
>
558 void ELFState
<ELFT
>::initStrtabSectionHeader(Elf_Shdr
&SHeader
, StringRef Name
,
559 StringTableBuilder
&STB
,
560 ContiguousBlobAccumulator
&CBA
,
561 ELFYAML::Section
*YAMLSec
) {
563 SHeader
.sh_name
= DotShStrtab
.getOffset(Name
);
564 SHeader
.sh_type
= YAMLSec
? YAMLSec
->Type
: ELF::SHT_STRTAB
;
565 SHeader
.sh_addralign
= YAMLSec
? (uint64_t)YAMLSec
->AddressAlign
: 1;
567 ELFYAML::RawContentSection
*RawSec
=
568 dyn_cast_or_null
<ELFYAML::RawContentSection
>(YAMLSec
);
570 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
571 if (RawSec
&& (RawSec
->Content
|| RawSec
->Size
)) {
572 SHeader
.sh_size
= writeRawSectionData(OS
, *RawSec
);
575 SHeader
.sh_size
= STB
.getSize();
578 if (YAMLSec
&& YAMLSec
->EntSize
)
579 SHeader
.sh_entsize
= *YAMLSec
->EntSize
;
581 if (RawSec
&& RawSec
->Info
)
582 SHeader
.sh_info
= *RawSec
->Info
;
584 if (YAMLSec
&& YAMLSec
->Flags
)
585 SHeader
.sh_flags
= *YAMLSec
->Flags
;
586 else if (Name
== ".dynstr")
587 SHeader
.sh_flags
= ELF::SHF_ALLOC
;
589 // If the section is explicitly described in the YAML
590 // then we want to use its section address.
592 SHeader
.sh_addr
= YAMLSec
->Address
;
595 template <class ELFT
>
596 void ELFState
<ELFT
>::setProgramHeaderLayout(std::vector
<Elf_Phdr
> &PHeaders
,
597 std::vector
<Elf_Shdr
> &SHeaders
) {
598 uint32_t PhdrIdx
= 0;
599 for (auto &YamlPhdr
: Doc
.ProgramHeaders
) {
600 Elf_Phdr
&PHeader
= PHeaders
[PhdrIdx
++];
602 std::vector
<Elf_Shdr
*> Sections
;
603 for (const ELFYAML::SectionName
&SecName
: YamlPhdr
.Sections
) {
605 if (!SN2I
.lookup(SecName
.Section
, Index
)) {
606 WithColor::error() << "Unknown section referenced: '" << SecName
.Section
607 << "' by program header.\n";
610 Sections
.push_back(&SHeaders
[Index
]);
613 if (YamlPhdr
.Offset
) {
614 PHeader
.p_offset
= *YamlPhdr
.Offset
;
616 if (YamlPhdr
.Sections
.size())
617 PHeader
.p_offset
= UINT32_MAX
;
619 PHeader
.p_offset
= 0;
621 // Find the minimum offset for the program header.
622 for (Elf_Shdr
*SHeader
: Sections
)
623 PHeader
.p_offset
= std::min(PHeader
.p_offset
, SHeader
->sh_offset
);
626 // Find the maximum offset of the end of a section in order to set p_filesz,
627 // if not set explicitly.
628 if (YamlPhdr
.FileSize
) {
629 PHeader
.p_filesz
= *YamlPhdr
.FileSize
;
631 PHeader
.p_filesz
= 0;
632 for (Elf_Shdr
*SHeader
: Sections
) {
633 uint64_t EndOfSection
;
634 if (SHeader
->sh_type
== llvm::ELF::SHT_NOBITS
)
635 EndOfSection
= SHeader
->sh_offset
;
637 EndOfSection
= SHeader
->sh_offset
+ SHeader
->sh_size
;
638 uint64_t EndOfSegment
= PHeader
.p_offset
+ PHeader
.p_filesz
;
639 EndOfSegment
= std::max(EndOfSegment
, EndOfSection
);
640 PHeader
.p_filesz
= EndOfSegment
- PHeader
.p_offset
;
644 // If not set explicitly, find the memory size by adding the size of
645 // sections at the end of the segment. These should be empty (size of zero)
646 // and NOBITS sections.
647 if (YamlPhdr
.MemSize
) {
648 PHeader
.p_memsz
= *YamlPhdr
.MemSize
;
650 PHeader
.p_memsz
= PHeader
.p_filesz
;
651 for (Elf_Shdr
*SHeader
: Sections
)
652 if (SHeader
->sh_offset
== PHeader
.p_offset
+ PHeader
.p_filesz
)
653 PHeader
.p_memsz
+= SHeader
->sh_size
;
656 // Set the alignment of the segment to be the same as the maximum alignment
657 // of the sections with the same offset so that by default the segment
658 // has a valid and sensible alignment.
659 if (YamlPhdr
.Align
) {
660 PHeader
.p_align
= *YamlPhdr
.Align
;
663 for (Elf_Shdr
*SHeader
: Sections
)
664 if (SHeader
->sh_offset
== PHeader
.p_offset
)
665 PHeader
.p_align
= std::max(PHeader
.p_align
, SHeader
->sh_addralign
);
670 template <class ELFT
>
671 bool ELFState
<ELFT
>::writeSectionContent(
672 Elf_Shdr
&SHeader
, const ELFYAML::RawContentSection
&Section
,
673 ContiguousBlobAccumulator
&CBA
) {
675 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
676 SHeader
.sh_size
= writeRawSectionData(OS
, Section
);
679 SHeader
.sh_entsize
= *Section
.EntSize
;
680 else if (Section
.Type
== llvm::ELF::SHT_RELR
)
681 SHeader
.sh_entsize
= sizeof(Elf_Relr
);
683 SHeader
.sh_entsize
= 0;
686 SHeader
.sh_info
= *Section
.Info
;
691 static bool isMips64EL(const ELFYAML::Object
&Doc
) {
692 return Doc
.Header
.Machine
== ELFYAML::ELF_EM(llvm::ELF::EM_MIPS
) &&
693 Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
) &&
694 Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
697 template <class ELFT
>
698 bool ELFState
<ELFT
>::writeSectionContent(
699 Elf_Shdr
&SHeader
, const ELFYAML::RelocationSection
&Section
,
700 ContiguousBlobAccumulator
&CBA
) {
701 assert((Section
.Type
== llvm::ELF::SHT_REL
||
702 Section
.Type
== llvm::ELF::SHT_RELA
) &&
703 "Section type is not SHT_REL nor SHT_RELA");
705 bool IsRela
= Section
.Type
== llvm::ELF::SHT_RELA
;
706 SHeader
.sh_entsize
= IsRela
? sizeof(Elf_Rela
) : sizeof(Elf_Rel
);
707 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Relocations
.size();
709 // For relocation section set link to .symtab by default.
710 if (Section
.Link
.empty())
711 SHeader
.sh_link
= SN2I
.get(".symtab");
714 if (!Section
.RelocatableSec
.empty() &&
715 !convertSectionIndex(SN2I
, Section
.Name
, Section
.RelocatableSec
, Index
))
717 SHeader
.sh_info
= Index
;
719 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
721 const NameToIdxMap
&SymMap
= Section
.Link
== ".dynsym" ? DynSymN2I
: SymN2I
;
722 for (const auto &Rel
: Section
.Relocations
) {
724 // If a relocation references a symbol, try to look one up in the symbol
725 // table. If it is not there, treat the value as a symbol index.
726 if (Rel
.Symbol
&& !SymMap
.lookup(*Rel
.Symbol
, SymIdx
) &&
727 !to_integer(*Rel
.Symbol
, SymIdx
)) {
728 WithColor::error() << "Unknown symbol referenced: '" << *Rel
.Symbol
729 << "' at YAML section '" << Section
.Name
<< "'.\n";
736 REntry
.r_offset
= Rel
.Offset
;
737 REntry
.r_addend
= Rel
.Addend
;
738 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
739 OS
.write((const char *)&REntry
, sizeof(REntry
));
743 REntry
.r_offset
= Rel
.Offset
;
744 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
745 OS
.write((const char *)&REntry
, sizeof(REntry
));
751 template <class ELFT
>
752 bool 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
;
766 template <class ELFT
>
767 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
768 const ELFYAML::Group
&Section
,
769 ContiguousBlobAccumulator
&CBA
) {
770 assert(Section
.Type
== llvm::ELF::SHT_GROUP
&&
771 "Section type is not SHT_GROUP");
773 SHeader
.sh_entsize
= 4;
774 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Members
.size();
777 if (!SymN2I
.lookup(Section
.Signature
, SymIdx
) &&
778 !to_integer(Section
.Signature
, SymIdx
)) {
779 WithColor::error() << "Unknown symbol referenced: '" << Section
.Signature
780 << "' at YAML section '" << Section
.Name
<< "'.\n";
783 SHeader
.sh_info
= SymIdx
;
786 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
788 for (const ELFYAML::SectionOrType
&Member
: Section
.Members
) {
789 unsigned int SectionIndex
= 0;
790 if (Member
.sectionNameOrType
== "GRP_COMDAT")
791 SectionIndex
= llvm::ELF::GRP_COMDAT
;
792 else if (!convertSectionIndex(SN2I
, Section
.Name
, Member
.sectionNameOrType
,
795 support::endian::write
<uint32_t>(OS
, SectionIndex
, ELFT::TargetEndianness
);
800 template <class ELFT
>
801 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
802 const ELFYAML::SymverSection
&Section
,
803 ContiguousBlobAccumulator
&CBA
) {
805 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
806 for (uint16_t Version
: Section
.Entries
)
807 support::endian::write
<uint16_t>(OS
, Version
, ELFT::TargetEndianness
);
809 SHeader
.sh_entsize
= Section
.EntSize
? (uint64_t)*Section
.EntSize
: 2;
810 SHeader
.sh_size
= Section
.Entries
.size() * SHeader
.sh_entsize
;
814 template <class ELFT
>
815 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
816 const ELFYAML::VerdefSection
&Section
,
817 ContiguousBlobAccumulator
&CBA
) {
818 typedef typename
ELFT::Verdef Elf_Verdef
;
819 typedef typename
ELFT::Verdaux Elf_Verdaux
;
821 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
824 for (size_t I
= 0; I
< Section
.Entries
.size(); ++I
) {
825 const ELFYAML::VerdefEntry
&E
= Section
.Entries
[I
];
828 VerDef
.vd_version
= E
.Version
;
829 VerDef
.vd_flags
= E
.Flags
;
830 VerDef
.vd_ndx
= E
.VersionNdx
;
831 VerDef
.vd_hash
= E
.Hash
;
832 VerDef
.vd_aux
= sizeof(Elf_Verdef
);
833 VerDef
.vd_cnt
= E
.VerNames
.size();
834 if (I
== Section
.Entries
.size() - 1)
838 sizeof(Elf_Verdef
) + E
.VerNames
.size() * sizeof(Elf_Verdaux
);
839 OS
.write((const char *)&VerDef
, sizeof(Elf_Verdef
));
841 for (size_t J
= 0; J
< E
.VerNames
.size(); ++J
, ++AuxCnt
) {
843 VernAux
.vda_name
= DotDynstr
.getOffset(E
.VerNames
[J
]);
844 if (J
== E
.VerNames
.size() - 1)
845 VernAux
.vda_next
= 0;
847 VernAux
.vda_next
= sizeof(Elf_Verdaux
);
848 OS
.write((const char *)&VernAux
, sizeof(Elf_Verdaux
));
852 SHeader
.sh_size
= Section
.Entries
.size() * sizeof(Elf_Verdef
) +
853 AuxCnt
* sizeof(Elf_Verdaux
);
854 SHeader
.sh_info
= Section
.Info
;
859 template <class ELFT
>
860 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
861 const ELFYAML::VerneedSection
&Section
,
862 ContiguousBlobAccumulator
&CBA
) {
863 typedef typename
ELFT::Verneed Elf_Verneed
;
864 typedef typename
ELFT::Vernaux Elf_Vernaux
;
866 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
869 for (size_t I
= 0; I
< Section
.VerneedV
.size(); ++I
) {
870 const ELFYAML::VerneedEntry
&VE
= Section
.VerneedV
[I
];
873 VerNeed
.vn_version
= VE
.Version
;
874 VerNeed
.vn_file
= DotDynstr
.getOffset(VE
.File
);
875 if (I
== Section
.VerneedV
.size() - 1)
879 sizeof(Elf_Verneed
) + VE
.AuxV
.size() * sizeof(Elf_Vernaux
);
880 VerNeed
.vn_cnt
= VE
.AuxV
.size();
881 VerNeed
.vn_aux
= sizeof(Elf_Verneed
);
882 OS
.write((const char *)&VerNeed
, sizeof(Elf_Verneed
));
884 for (size_t J
= 0; J
< VE
.AuxV
.size(); ++J
, ++AuxCnt
) {
885 const ELFYAML::VernauxEntry
&VAuxE
= VE
.AuxV
[J
];
888 VernAux
.vna_hash
= VAuxE
.Hash
;
889 VernAux
.vna_flags
= VAuxE
.Flags
;
890 VernAux
.vna_other
= VAuxE
.Other
;
891 VernAux
.vna_name
= DotDynstr
.getOffset(VAuxE
.Name
);
892 if (J
== VE
.AuxV
.size() - 1)
893 VernAux
.vna_next
= 0;
895 VernAux
.vna_next
= sizeof(Elf_Vernaux
);
896 OS
.write((const char *)&VernAux
, sizeof(Elf_Vernaux
));
900 SHeader
.sh_size
= Section
.VerneedV
.size() * sizeof(Elf_Verneed
) +
901 AuxCnt
* sizeof(Elf_Vernaux
);
902 SHeader
.sh_info
= Section
.Info
;
907 template <class ELFT
>
908 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
909 const ELFYAML::MipsABIFlags
&Section
,
910 ContiguousBlobAccumulator
&CBA
) {
911 assert(Section
.Type
== llvm::ELF::SHT_MIPS_ABIFLAGS
&&
912 "Section type is not SHT_MIPS_ABIFLAGS");
914 object::Elf_Mips_ABIFlags
<ELFT
> Flags
;
916 SHeader
.sh_entsize
= sizeof(Flags
);
917 SHeader
.sh_size
= SHeader
.sh_entsize
;
919 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
920 Flags
.version
= Section
.Version
;
921 Flags
.isa_level
= Section
.ISALevel
;
922 Flags
.isa_rev
= Section
.ISARevision
;
923 Flags
.gpr_size
= Section
.GPRSize
;
924 Flags
.cpr1_size
= Section
.CPR1Size
;
925 Flags
.cpr2_size
= Section
.CPR2Size
;
926 Flags
.fp_abi
= Section
.FpABI
;
927 Flags
.isa_ext
= Section
.ISAExtension
;
928 Flags
.ases
= Section
.ASEs
;
929 Flags
.flags1
= Section
.Flags1
;
930 Flags
.flags2
= Section
.Flags2
;
931 OS
.write((const char *)&Flags
, sizeof(Flags
));
936 template <class ELFT
>
937 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
938 const ELFYAML::DynamicSection
&Section
,
939 ContiguousBlobAccumulator
&CBA
) {
940 typedef typename
ELFT::uint uintX_t
;
942 assert(Section
.Type
== llvm::ELF::SHT_DYNAMIC
&&
943 "Section type is not SHT_DYNAMIC");
945 if (!Section
.Entries
.empty() && Section
.Content
) {
947 << "Cannot specify both raw content and explicit entries "
948 "for dynamic section '"
949 << Section
.Name
<< "'.\n";
954 SHeader
.sh_size
= Section
.Content
->binary_size();
956 SHeader
.sh_size
= 2 * sizeof(uintX_t
) * Section
.Entries
.size();
958 SHeader
.sh_entsize
= *Section
.EntSize
;
960 SHeader
.sh_entsize
= sizeof(Elf_Dyn
);
963 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
964 for (const ELFYAML::DynamicEntry
&DE
: Section
.Entries
) {
965 support::endian::write
<uintX_t
>(OS
, DE
.Tag
, ELFT::TargetEndianness
);
966 support::endian::write
<uintX_t
>(OS
, DE
.Val
, ELFT::TargetEndianness
);
969 Section
.Content
->writeAsBinary(OS
);
974 template <class ELFT
> bool ELFState
<ELFT
>::buildSectionIndex() {
975 for (unsigned I
= 0, E
= Doc
.Sections
.size(); I
!= E
; ++I
) {
976 StringRef Name
= Doc
.Sections
[I
]->Name
;
980 DotShStrtab
.add(dropUniqueSuffix(Name
));
981 if (!SN2I
.addName(Name
, I
)) {
982 WithColor::error() << "Repeated section name: '" << Name
983 << "' at YAML section number " << I
<< ".\n";
988 DotShStrtab
.finalize();
992 static bool buildSymbolsMap(ArrayRef
<ELFYAML::Symbol
> V
, NameToIdxMap
&Map
) {
993 for (size_t I
= 0, S
= V
.size(); I
< S
; ++I
) {
994 const ELFYAML::Symbol
&Sym
= V
[I
];
995 if (Sym
.Name
.empty() || Map
.addName(Sym
.Name
, I
+ 1))
997 WithColor::error() << "Repeated symbol name: '" << Sym
.Name
<< "'.\n";
1003 template <class ELFT
> bool ELFState
<ELFT
>::buildSymbolIndexes() {
1004 return buildSymbolsMap(Doc
.Symbols
, SymN2I
) &&
1005 buildSymbolsMap(Doc
.DynamicSymbols
, DynSymN2I
);
1008 template <class ELFT
> void ELFState
<ELFT
>::finalizeStrings() {
1009 // Add the regular symbol names to .strtab section.
1010 for (const ELFYAML::Symbol
&Sym
: Doc
.Symbols
)
1011 DotStrtab
.add(dropUniqueSuffix(Sym
.Name
));
1012 DotStrtab
.finalize();
1014 // Add the dynamic symbol names to .dynstr section.
1015 for (const ELFYAML::Symbol
&Sym
: Doc
.DynamicSymbols
)
1016 DotDynstr
.add(dropUniqueSuffix(Sym
.Name
));
1018 // SHT_GNU_verdef and SHT_GNU_verneed sections might also
1019 // add strings to .dynstr section.
1020 for (const std::unique_ptr
<ELFYAML::Section
> &Sec
: Doc
.Sections
) {
1021 if (auto VerNeed
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
.get())) {
1022 for (const ELFYAML::VerneedEntry
&VE
: VerNeed
->VerneedV
) {
1023 DotDynstr
.add(VE
.File
);
1024 for (const ELFYAML::VernauxEntry
&Aux
: VE
.AuxV
)
1025 DotDynstr
.add(Aux
.Name
);
1027 } else if (auto VerDef
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
.get())) {
1028 for (const ELFYAML::VerdefEntry
&E
: VerDef
->Entries
)
1029 for (StringRef Name
: E
.VerNames
)
1030 DotDynstr
.add(Name
);
1034 DotDynstr
.finalize();
1037 template <class ELFT
>
1038 int ELFState
<ELFT
>::writeELF(raw_ostream
&OS
, ELFYAML::Object
&Doc
) {
1039 ELFState
<ELFT
> State(Doc
);
1041 // Finalize .strtab and .dynstr sections. We do that early because want to
1042 // finalize the string table builders before writing the content of the
1043 // sections that might want to use them.
1044 State
.finalizeStrings();
1046 if (!State
.buildSectionIndex() || !State
.buildSymbolIndexes())
1049 std::vector
<Elf_Phdr
> PHeaders
;
1050 State
.initProgramHeaders(PHeaders
);
1052 // XXX: This offset is tightly coupled with the order that we write
1054 const size_t SectionContentBeginOffset
=
1055 sizeof(Elf_Ehdr
) + sizeof(Elf_Phdr
) * Doc
.ProgramHeaders
.size();
1056 ContiguousBlobAccumulator
CBA(SectionContentBeginOffset
);
1058 std::vector
<Elf_Shdr
> SHeaders
;
1059 if (!State
.initSectionHeaders(SHeaders
, CBA
))
1062 // Now we can decide segment offsets
1063 State
.setProgramHeaderLayout(PHeaders
, SHeaders
);
1065 State
.writeELFHeader(CBA
, OS
);
1066 writeArrayData(OS
, makeArrayRef(PHeaders
));
1067 CBA
.writeBlobToStream(OS
);
1068 writeArrayData(OS
, makeArrayRef(SHeaders
));
1075 int yaml2elf(llvm::ELFYAML::Object
&Doc
, raw_ostream
&Out
) {
1076 bool IsLE
= Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
1077 bool Is64Bit
= Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
);
1080 return ELFState
<object::ELF64LE
>::writeELF(Out
, Doc
);
1081 return ELFState
<object::ELF64BE
>::writeELF(Out
, Doc
);
1084 return ELFState
<object::ELF32LE
>::writeELF(Out
, Doc
);
1085 return ELFState
<object::ELF32BE
>::writeELF(Out
, Doc
);