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 //===----------------------------------------------------------------------===//
15 #include "llvm/ADT/ArrayRef.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/Support/EndianStream.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include "llvm/Support/WithColor.h"
23 #include "llvm/Support/YAMLTraits.h"
24 #include "llvm/Support/raw_ostream.h"
28 // This class is used to build up a contiguous binary blob while keeping
29 // track of an offset in the output (which notionally begins at
32 class ContiguousBlobAccumulator
{
33 const uint64_t InitialOffset
;
34 SmallVector
<char, 128> Buf
;
35 raw_svector_ostream OS
;
37 /// \returns The new offset.
38 uint64_t padToAlignment(unsigned Align
) {
41 uint64_t CurrentOffset
= InitialOffset
+ OS
.tell();
42 uint64_t AlignedOffset
= alignTo(CurrentOffset
, Align
);
43 OS
.write_zeros(AlignedOffset
- CurrentOffset
);
44 return AlignedOffset
; // == CurrentOffset;
48 ContiguousBlobAccumulator(uint64_t InitialOffset_
)
49 : InitialOffset(InitialOffset_
), Buf(), OS(Buf
) {}
50 template <class Integer
>
51 raw_ostream
&getOSAndAlignedOffset(Integer
&Offset
, unsigned Align
) {
52 Offset
= padToAlignment(Align
);
55 void writeBlobToStream(raw_ostream
&Out
) { Out
<< OS
.str(); }
57 } // end anonymous namespace
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.
65 /// \returns true if name is already present in the map.
66 bool addName(StringRef Name
, unsigned i
) {
67 return !Map
.insert(std::make_pair(Name
, (int)i
)).second
;
69 /// \returns true if name is not present in the map
70 bool lookup(StringRef Name
, unsigned &Idx
) const {
71 StringMap
<int>::const_iterator I
= Map
.find(Name
);
77 /// asserts if name is not present in the map
78 unsigned get(StringRef Name
) const {
80 auto missing
= lookup(Name
, Idx
);
82 assert(!missing
&& "Expected section not found in index");
85 unsigned size() const { return Map
.size(); }
87 } // end anonymous namespace
90 static size_t arrayDataSize(ArrayRef
<T
> A
) {
91 return A
.size() * sizeof(T
);
95 static void writeArrayData(raw_ostream
&OS
, ArrayRef
<T
> A
) {
96 OS
.write((const char *)A
.data(), arrayDataSize(A
));
100 static void zero(T
&Obj
) {
101 memset(&Obj
, 0, sizeof(Obj
));
105 /// "Single point of truth" for the ELF file construction.
106 /// TODO: This class still has a ways to go before it is truly a "single
108 template <class ELFT
>
110 typedef typename
ELFT::Ehdr Elf_Ehdr
;
111 typedef typename
ELFT::Phdr Elf_Phdr
;
112 typedef typename
ELFT::Shdr Elf_Shdr
;
113 typedef typename
ELFT::Sym Elf_Sym
;
114 typedef typename
ELFT::Rel Elf_Rel
;
115 typedef typename
ELFT::Rela Elf_Rela
;
116 typedef typename
ELFT::Relr Elf_Relr
;
117 typedef typename
ELFT::Dyn Elf_Dyn
;
119 enum class SymtabType
{ Static
, Dynamic
};
121 /// The future ".strtab" section.
122 StringTableBuilder DotStrtab
{StringTableBuilder::ELF
};
124 /// The future ".shstrtab" section.
125 StringTableBuilder DotShStrtab
{StringTableBuilder::ELF
};
127 /// The future ".dynstr" section.
128 StringTableBuilder DotDynstr
{StringTableBuilder::ELF
};
132 const ELFYAML::Object
&Doc
;
134 bool buildSectionIndex();
135 bool buildSymbolIndex(ArrayRef
<ELFYAML::Symbol
> Symbols
);
136 void initELFHeader(Elf_Ehdr
&Header
);
137 void initProgramHeaders(std::vector
<Elf_Phdr
> &PHeaders
);
138 bool initSectionHeaders(std::vector
<Elf_Shdr
> &SHeaders
,
139 ContiguousBlobAccumulator
&CBA
);
140 void initSymtabSectionHeader(Elf_Shdr
&SHeader
, SymtabType STType
,
141 ContiguousBlobAccumulator
&CBA
);
142 void initStrtabSectionHeader(Elf_Shdr
&SHeader
, StringRef Name
,
143 StringTableBuilder
&STB
,
144 ContiguousBlobAccumulator
&CBA
);
145 void setProgramHeaderLayout(std::vector
<Elf_Phdr
> &PHeaders
,
146 std::vector
<Elf_Shdr
> &SHeaders
);
147 void addSymbols(ArrayRef
<ELFYAML::Symbol
> Symbols
, std::vector
<Elf_Sym
> &Syms
,
148 const StringTableBuilder
&Strtab
);
149 bool writeSectionContent(Elf_Shdr
&SHeader
,
150 const ELFYAML::RawContentSection
&Section
,
151 ContiguousBlobAccumulator
&CBA
);
152 bool writeSectionContent(Elf_Shdr
&SHeader
,
153 const ELFYAML::RelocationSection
&Section
,
154 ContiguousBlobAccumulator
&CBA
);
155 bool writeSectionContent(Elf_Shdr
&SHeader
, const ELFYAML::Group
&Group
,
156 ContiguousBlobAccumulator
&CBA
);
157 bool writeSectionContent(Elf_Shdr
&SHeader
,
158 const ELFYAML::SymverSection
&Section
,
159 ContiguousBlobAccumulator
&CBA
);
160 bool writeSectionContent(Elf_Shdr
&SHeader
,
161 const ELFYAML::VerneedSection
&Section
,
162 ContiguousBlobAccumulator
&CBA
);
163 bool writeSectionContent(Elf_Shdr
&SHeader
,
164 const ELFYAML::VerdefSection
&Section
,
165 ContiguousBlobAccumulator
&CBA
);
166 bool writeSectionContent(Elf_Shdr
&SHeader
,
167 const ELFYAML::MipsABIFlags
&Section
,
168 ContiguousBlobAccumulator
&CBA
);
169 bool writeSectionContent(Elf_Shdr
&SHeader
,
170 const ELFYAML::DynamicSection
&Section
,
171 ContiguousBlobAccumulator
&CBA
);
172 std::vector
<StringRef
> implicitSectionNames() const;
174 // - SHT_NULL entry (placed first, i.e. 0'th entry)
175 // - symbol table (.symtab) (defaults to after last yaml section)
176 // - string table (.strtab) (defaults to after .symtab)
177 // - section header string table (.shstrtab) (defaults to after .strtab)
178 // - dynamic symbol table (.dynsym) (defaults to after .shstrtab)
179 // - dynamic string table (.dynstr) (defaults to after .dynsym)
180 unsigned getDotSymTabSecNo() const { return SN2I
.get(".symtab"); }
181 unsigned getDotStrTabSecNo() const { return SN2I
.get(".strtab"); }
182 unsigned getDotShStrTabSecNo() const { return SN2I
.get(".shstrtab"); }
183 unsigned getDotDynSymSecNo() const { return SN2I
.get(".dynsym"); }
184 unsigned getDotDynStrSecNo() const { return SN2I
.get(".dynstr"); }
185 unsigned getSectionCount() const { return SN2I
.size() + 1; }
187 ELFState(const ELFYAML::Object
&D
) : Doc(D
) {}
190 static int writeELF(raw_ostream
&OS
, const ELFYAML::Object
&Doc
);
193 void finalizeStrings();
195 } // end anonymous namespace
197 template <class ELFT
>
198 void ELFState
<ELFT
>::initELFHeader(Elf_Ehdr
&Header
) {
199 using namespace llvm::ELF
;
201 Header
.e_ident
[EI_MAG0
] = 0x7f;
202 Header
.e_ident
[EI_MAG1
] = 'E';
203 Header
.e_ident
[EI_MAG2
] = 'L';
204 Header
.e_ident
[EI_MAG3
] = 'F';
205 Header
.e_ident
[EI_CLASS
] = ELFT::Is64Bits
? ELFCLASS64
: ELFCLASS32
;
206 Header
.e_ident
[EI_DATA
] = Doc
.Header
.Data
;
207 Header
.e_ident
[EI_VERSION
] = EV_CURRENT
;
208 Header
.e_ident
[EI_OSABI
] = Doc
.Header
.OSABI
;
209 Header
.e_ident
[EI_ABIVERSION
] = Doc
.Header
.ABIVersion
;
210 Header
.e_type
= Doc
.Header
.Type
;
211 Header
.e_machine
= Doc
.Header
.Machine
;
212 Header
.e_version
= EV_CURRENT
;
213 Header
.e_entry
= Doc
.Header
.Entry
;
214 Header
.e_phoff
= sizeof(Header
);
215 Header
.e_flags
= Doc
.Header
.Flags
;
216 Header
.e_ehsize
= sizeof(Elf_Ehdr
);
217 Header
.e_phentsize
= sizeof(Elf_Phdr
);
218 Header
.e_phnum
= Doc
.ProgramHeaders
.size();
219 Header
.e_shentsize
= sizeof(Elf_Shdr
);
220 // Immediately following the ELF header and program headers.
222 sizeof(Header
) + sizeof(Elf_Phdr
) * Doc
.ProgramHeaders
.size();
223 Header
.e_shnum
= getSectionCount();
224 Header
.e_shstrndx
= getDotShStrTabSecNo();
227 template <class ELFT
>
228 void ELFState
<ELFT
>::initProgramHeaders(std::vector
<Elf_Phdr
> &PHeaders
) {
229 for (const auto &YamlPhdr
: Doc
.ProgramHeaders
) {
231 Phdr
.p_type
= YamlPhdr
.Type
;
232 Phdr
.p_flags
= YamlPhdr
.Flags
;
233 Phdr
.p_vaddr
= YamlPhdr
.VAddr
;
234 Phdr
.p_paddr
= YamlPhdr
.PAddr
;
235 PHeaders
.push_back(Phdr
);
239 static bool convertSectionIndex(NameToIdxMap
&SN2I
, StringRef SecName
,
240 StringRef IndexSrc
, unsigned &IndexDest
) {
241 if (SN2I
.lookup(IndexSrc
, IndexDest
) && !to_integer(IndexSrc
, IndexDest
)) {
242 WithColor::error() << "Unknown section referenced: '" << IndexSrc
243 << "' at YAML section '" << SecName
<< "'.\n";
249 template <class ELFT
>
250 bool ELFState
<ELFT
>::initSectionHeaders(std::vector
<Elf_Shdr
> &SHeaders
,
251 ContiguousBlobAccumulator
&CBA
) {
252 // Ensure SHN_UNDEF entry is present. An all-zero section header is a
253 // valid SHN_UNDEF entry since SHT_NULL == 0.
256 SHeaders
.push_back(SHeader
);
258 for (const auto &Sec
: Doc
.Sections
) {
260 SHeader
.sh_name
= DotShStrtab
.getOffset(Sec
->Name
);
261 SHeader
.sh_type
= Sec
->Type
;
262 SHeader
.sh_flags
= Sec
->Flags
;
263 SHeader
.sh_addr
= Sec
->Address
;
264 SHeader
.sh_addralign
= Sec
->AddressAlign
;
266 if (!Sec
->Link
.empty()) {
268 if (!convertSectionIndex(SN2I
, Sec
->Name
, Sec
->Link
, Index
))
270 SHeader
.sh_link
= Index
;
273 if (auto S
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
.get())) {
274 if (!writeSectionContent(SHeader
, *S
, CBA
))
276 } else if (auto S
= dyn_cast
<ELFYAML::RelocationSection
>(Sec
.get())) {
277 if (!writeSectionContent(SHeader
, *S
, CBA
))
279 } else if (auto S
= dyn_cast
<ELFYAML::Group
>(Sec
.get())) {
280 if (!writeSectionContent(SHeader
, *S
, CBA
))
282 } else if (auto S
= dyn_cast
<ELFYAML::MipsABIFlags
>(Sec
.get())) {
283 if (!writeSectionContent(SHeader
, *S
, CBA
))
285 } else if (auto S
= dyn_cast
<ELFYAML::NoBitsSection
>(Sec
.get())) {
286 SHeader
.sh_entsize
= 0;
287 SHeader
.sh_size
= S
->Size
;
288 // SHT_NOBITS section does not have content
289 // so just to setup the section offset.
290 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
291 } else if (auto S
= dyn_cast
<ELFYAML::DynamicSection
>(Sec
.get())) {
292 if (!writeSectionContent(SHeader
, *S
, CBA
))
294 } else if (auto S
= dyn_cast
<ELFYAML::SymverSection
>(Sec
.get())) {
295 if (!writeSectionContent(SHeader
, *S
, CBA
))
297 } else if (auto S
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
.get())) {
298 if (!writeSectionContent(SHeader
, *S
, CBA
))
300 } else if (auto S
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
.get())) {
301 if (!writeSectionContent(SHeader
, *S
, CBA
))
304 llvm_unreachable("Unknown section type");
306 SHeaders
.push_back(SHeader
);
311 static size_t findFirstNonGlobal(ArrayRef
<ELFYAML::Symbol
> Symbols
) {
312 for (size_t I
= 0; I
< Symbols
.size(); ++I
)
313 if (Symbols
[I
].Binding
.value
!= ELF::STB_LOCAL
)
315 return Symbols
.size();
318 template <class ELFT
>
319 void ELFState
<ELFT
>::initSymtabSectionHeader(Elf_Shdr
&SHeader
,
321 ContiguousBlobAccumulator
&CBA
) {
323 bool IsStatic
= STType
== SymtabType::Static
;
324 SHeader
.sh_name
= DotShStrtab
.getOffset(IsStatic
? ".symtab" : ".dynsym");
325 SHeader
.sh_type
= IsStatic
? ELF::SHT_SYMTAB
: ELF::SHT_DYNSYM
;
326 SHeader
.sh_link
= IsStatic
? getDotStrTabSecNo() : getDotDynStrSecNo();
328 SHeader
.sh_flags
|= ELF::SHF_ALLOC
;
330 // One greater than symbol table index of the last local symbol.
331 const auto &Symbols
= IsStatic
? Doc
.Symbols
: Doc
.DynamicSymbols
;
332 SHeader
.sh_info
= findFirstNonGlobal(Symbols
) + 1;
333 SHeader
.sh_entsize
= sizeof(Elf_Sym
);
334 SHeader
.sh_addralign
= 8;
336 // Get the section index ignoring the SHT_NULL section.
338 IsStatic
? getDotSymTabSecNo() - 1 : getDotDynSymSecNo() - 1;
339 // If the symbol table section is explicitly described in the YAML
340 // then we should set the fields requested.
341 if (SecNdx
< Doc
.Sections
.size()) {
342 ELFYAML::Section
*Sec
= Doc
.Sections
[SecNdx
].get();
343 SHeader
.sh_addr
= Sec
->Address
;
344 if (auto S
= dyn_cast
<ELFYAML::RawContentSection
>(Sec
))
345 SHeader
.sh_info
= S
->Info
;
348 std::vector
<Elf_Sym
> Syms
;
350 // Ensure STN_UNDEF is present
356 addSymbols(Symbols
, Syms
, IsStatic
? DotStrtab
: DotDynstr
);
359 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
),
361 SHeader
.sh_size
= arrayDataSize(makeArrayRef(Syms
));
364 template <class ELFT
>
365 void ELFState
<ELFT
>::initStrtabSectionHeader(Elf_Shdr
&SHeader
, StringRef Name
,
366 StringTableBuilder
&STB
,
367 ContiguousBlobAccumulator
&CBA
) {
369 SHeader
.sh_name
= DotShStrtab
.getOffset(Name
);
370 SHeader
.sh_type
= ELF::SHT_STRTAB
;
371 STB
.write(CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
));
372 SHeader
.sh_size
= STB
.getSize();
373 SHeader
.sh_addralign
= 1;
375 // If .dynstr section is explicitly described in the YAML
376 // then we want to use its section address.
377 if (Name
== ".dynstr") {
378 // Take section index and ignore the SHT_NULL section.
379 unsigned SecNdx
= getDotDynStrSecNo() - 1;
380 if (SecNdx
< Doc
.Sections
.size())
381 SHeader
.sh_addr
= Doc
.Sections
[SecNdx
]->Address
;
383 // We assume that .dynstr is always allocatable.
384 SHeader
.sh_flags
|= ELF::SHF_ALLOC
;
388 template <class ELFT
>
389 void ELFState
<ELFT
>::setProgramHeaderLayout(std::vector
<Elf_Phdr
> &PHeaders
,
390 std::vector
<Elf_Shdr
> &SHeaders
) {
391 uint32_t PhdrIdx
= 0;
392 for (auto &YamlPhdr
: Doc
.ProgramHeaders
) {
393 Elf_Phdr
&PHeader
= PHeaders
[PhdrIdx
++];
395 std::vector
<Elf_Shdr
*> Sections
;
396 for (const ELFYAML::SectionName
&SecName
: YamlPhdr
.Sections
) {
398 if (SN2I
.lookup(SecName
.Section
, Index
)) {
399 WithColor::error() << "Unknown section referenced: '" << SecName
.Section
400 << "' by program header.\n";
403 Sections
.push_back(&SHeaders
[Index
]);
406 if (YamlPhdr
.Offset
) {
407 PHeader
.p_offset
= *YamlPhdr
.Offset
;
409 if (YamlPhdr
.Sections
.size())
410 PHeader
.p_offset
= UINT32_MAX
;
412 PHeader
.p_offset
= 0;
414 // Find the minimum offset for the program header.
415 for (Elf_Shdr
*SHeader
: Sections
)
416 PHeader
.p_offset
= std::min(PHeader
.p_offset
, SHeader
->sh_offset
);
419 // Find the maximum offset of the end of a section in order to set p_filesz,
420 // if not set explicitly.
421 if (YamlPhdr
.FileSize
) {
422 PHeader
.p_filesz
= *YamlPhdr
.FileSize
;
424 PHeader
.p_filesz
= 0;
425 for (Elf_Shdr
*SHeader
: Sections
) {
426 uint64_t EndOfSection
;
427 if (SHeader
->sh_type
== llvm::ELF::SHT_NOBITS
)
428 EndOfSection
= SHeader
->sh_offset
;
430 EndOfSection
= SHeader
->sh_offset
+ SHeader
->sh_size
;
431 uint64_t EndOfSegment
= PHeader
.p_offset
+ PHeader
.p_filesz
;
432 EndOfSegment
= std::max(EndOfSegment
, EndOfSection
);
433 PHeader
.p_filesz
= EndOfSegment
- PHeader
.p_offset
;
437 // If not set explicitly, find the memory size by adding the size of
438 // sections at the end of the segment. These should be empty (size of zero)
439 // and NOBITS sections.
440 if (YamlPhdr
.MemSize
) {
441 PHeader
.p_memsz
= *YamlPhdr
.MemSize
;
443 PHeader
.p_memsz
= PHeader
.p_filesz
;
444 for (Elf_Shdr
*SHeader
: Sections
)
445 if (SHeader
->sh_offset
== PHeader
.p_offset
+ PHeader
.p_filesz
)
446 PHeader
.p_memsz
+= SHeader
->sh_size
;
449 // Set the alignment of the segment to be the same as the maximum alignment
450 // of the sections with the same offset so that by default the segment
451 // has a valid and sensible alignment.
452 if (YamlPhdr
.Align
) {
453 PHeader
.p_align
= *YamlPhdr
.Align
;
456 for (Elf_Shdr
*SHeader
: Sections
)
457 if (SHeader
->sh_offset
== PHeader
.p_offset
)
458 PHeader
.p_align
= std::max(PHeader
.p_align
, SHeader
->sh_addralign
);
463 template <class ELFT
>
464 void ELFState
<ELFT
>::addSymbols(ArrayRef
<ELFYAML::Symbol
> Symbols
,
465 std::vector
<Elf_Sym
> &Syms
,
466 const StringTableBuilder
&Strtab
) {
467 for (const auto &Sym
: Symbols
) {
470 if (!Sym
.Name
.empty())
471 Symbol
.st_name
= Strtab
.getOffset(Sym
.Name
);
472 Symbol
.setBindingAndType(Sym
.Binding
, Sym
.Type
);
473 if (!Sym
.Section
.empty()) {
475 if (SN2I
.lookup(Sym
.Section
, Index
)) {
476 WithColor::error() << "Unknown section referenced: '" << Sym
.Section
477 << "' by YAML symbol " << Sym
.Name
<< ".\n";
480 Symbol
.st_shndx
= Index
;
481 } else if (Sym
.Index
) {
482 Symbol
.st_shndx
= *Sym
.Index
;
484 // else Symbol.st_shndex == SHN_UNDEF (== 0), since it was zero'd earlier.
485 Symbol
.st_value
= Sym
.Value
;
486 Symbol
.st_other
= Sym
.Other
;
487 Symbol
.st_size
= Sym
.Size
;
488 Syms
.push_back(Symbol
);
492 template <class ELFT
>
493 bool ELFState
<ELFT
>::writeSectionContent(
494 Elf_Shdr
&SHeader
, const ELFYAML::RawContentSection
&Section
,
495 ContiguousBlobAccumulator
&CBA
) {
496 assert(Section
.Size
>= Section
.Content
.binary_size() &&
497 "Section size and section content are inconsistent");
499 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
500 Section
.Content
.writeAsBinary(OS
);
501 OS
.write_zeros(Section
.Size
- Section
.Content
.binary_size());
504 SHeader
.sh_entsize
= *Section
.EntSize
;
505 else if (Section
.Type
== llvm::ELF::SHT_RELR
)
506 SHeader
.sh_entsize
= sizeof(Elf_Relr
);
508 SHeader
.sh_entsize
= 0;
509 SHeader
.sh_size
= Section
.Size
;
510 SHeader
.sh_info
= Section
.Info
;
514 static bool isMips64EL(const ELFYAML::Object
&Doc
) {
515 return Doc
.Header
.Machine
== ELFYAML::ELF_EM(llvm::ELF::EM_MIPS
) &&
516 Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
) &&
517 Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
520 template <class ELFT
>
522 ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
523 const ELFYAML::RelocationSection
&Section
,
524 ContiguousBlobAccumulator
&CBA
) {
525 assert((Section
.Type
== llvm::ELF::SHT_REL
||
526 Section
.Type
== llvm::ELF::SHT_RELA
) &&
527 "Section type is not SHT_REL nor SHT_RELA");
529 bool IsRela
= Section
.Type
== llvm::ELF::SHT_RELA
;
530 SHeader
.sh_entsize
= IsRela
? sizeof(Elf_Rela
) : sizeof(Elf_Rel
);
531 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Relocations
.size();
533 // For relocation section set link to .symtab by default.
534 if (Section
.Link
.empty())
535 SHeader
.sh_link
= getDotSymTabSecNo();
538 if (!Section
.RelocatableSec
.empty() &&
539 !convertSectionIndex(SN2I
, Section
.Name
, Section
.RelocatableSec
, Index
))
541 SHeader
.sh_info
= Index
;
543 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
545 for (const auto &Rel
: Section
.Relocations
) {
547 // If a relocation references a symbol, try to look one up in the symbol
548 // table. If it is not there, treat the value as a symbol index.
549 if (Rel
.Symbol
&& SymN2I
.lookup(*Rel
.Symbol
, SymIdx
) &&
550 !to_integer(*Rel
.Symbol
, SymIdx
)) {
551 WithColor::error() << "Unknown symbol referenced: '" << *Rel
.Symbol
552 << "' at YAML section '" << Section
.Name
<< "'.\n";
559 REntry
.r_offset
= Rel
.Offset
;
560 REntry
.r_addend
= Rel
.Addend
;
561 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
562 OS
.write((const char *)&REntry
, sizeof(REntry
));
566 REntry
.r_offset
= Rel
.Offset
;
567 REntry
.setSymbolAndType(SymIdx
, Rel
.Type
, isMips64EL(Doc
));
568 OS
.write((const char *)&REntry
, sizeof(REntry
));
574 template <class ELFT
>
575 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
576 const ELFYAML::Group
&Section
,
577 ContiguousBlobAccumulator
&CBA
) {
578 assert(Section
.Type
== llvm::ELF::SHT_GROUP
&&
579 "Section type is not SHT_GROUP");
581 SHeader
.sh_entsize
= 4;
582 SHeader
.sh_size
= SHeader
.sh_entsize
* Section
.Members
.size();
585 if (SymN2I
.lookup(Section
.Signature
, SymIdx
) &&
586 !to_integer(Section
.Signature
, SymIdx
)) {
587 WithColor::error() << "Unknown symbol referenced: '" << Section
.Signature
588 << "' at YAML section '" << Section
.Name
<< "'.\n";
591 SHeader
.sh_info
= SymIdx
;
594 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
596 for (const ELFYAML::SectionOrType
&Member
: Section
.Members
) {
597 unsigned int SectionIndex
= 0;
598 if (Member
.sectionNameOrType
== "GRP_COMDAT")
599 SectionIndex
= llvm::ELF::GRP_COMDAT
;
600 else if (!convertSectionIndex(SN2I
, Section
.Name
, Member
.sectionNameOrType
,
603 support::endian::write
<uint32_t>(OS
, SectionIndex
, ELFT::TargetEndianness
);
608 template <class ELFT
>
609 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
610 const ELFYAML::SymverSection
&Section
,
611 ContiguousBlobAccumulator
&CBA
) {
613 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
614 for (uint16_t Version
: Section
.Entries
)
615 support::endian::write
<uint16_t>(OS
, Version
, ELFT::TargetEndianness
);
617 SHeader
.sh_entsize
= 2;
618 SHeader
.sh_size
= Section
.Entries
.size() * SHeader
.sh_entsize
;
622 template <class ELFT
>
623 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
624 const ELFYAML::VerdefSection
&Section
,
625 ContiguousBlobAccumulator
&CBA
) {
626 typedef typename
ELFT::Verdef Elf_Verdef
;
627 typedef typename
ELFT::Verdaux Elf_Verdaux
;
629 CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
632 for (size_t I
= 0; I
< Section
.Entries
.size(); ++I
) {
633 const ELFYAML::VerdefEntry
&E
= Section
.Entries
[I
];
636 VerDef
.vd_version
= E
.Version
;
637 VerDef
.vd_flags
= E
.Flags
;
638 VerDef
.vd_ndx
= E
.VersionNdx
;
639 VerDef
.vd_hash
= E
.Hash
;
640 VerDef
.vd_aux
= sizeof(Elf_Verdef
);
641 VerDef
.vd_cnt
= E
.VerNames
.size();
642 if (I
== Section
.Entries
.size() - 1)
646 sizeof(Elf_Verdef
) + E
.VerNames
.size() * sizeof(Elf_Verdaux
);
647 OS
.write((const char *)&VerDef
, sizeof(Elf_Verdef
));
649 for (size_t J
= 0; J
< E
.VerNames
.size(); ++J
, ++AuxCnt
) {
651 VernAux
.vda_name
= DotDynstr
.getOffset(E
.VerNames
[J
]);
652 if (J
== E
.VerNames
.size() - 1)
653 VernAux
.vda_next
= 0;
655 VernAux
.vda_next
= sizeof(Elf_Verdaux
);
656 OS
.write((const char *)&VernAux
, sizeof(Elf_Verdaux
));
660 SHeader
.sh_size
= Section
.Entries
.size() * sizeof(Elf_Verdef
) +
661 AuxCnt
* sizeof(Elf_Verdaux
);
662 SHeader
.sh_info
= Section
.Info
;
667 template <class ELFT
>
668 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
669 const ELFYAML::VerneedSection
&Section
,
670 ContiguousBlobAccumulator
&CBA
) {
671 typedef typename
ELFT::Verneed Elf_Verneed
;
672 typedef typename
ELFT::Vernaux Elf_Vernaux
;
674 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
677 for (size_t I
= 0; I
< Section
.VerneedV
.size(); ++I
) {
678 const ELFYAML::VerneedEntry
&VE
= Section
.VerneedV
[I
];
681 VerNeed
.vn_version
= VE
.Version
;
682 VerNeed
.vn_file
= DotDynstr
.getOffset(VE
.File
);
683 if (I
== Section
.VerneedV
.size() - 1)
687 sizeof(Elf_Verneed
) + VE
.AuxV
.size() * sizeof(Elf_Vernaux
);
688 VerNeed
.vn_cnt
= VE
.AuxV
.size();
689 VerNeed
.vn_aux
= sizeof(Elf_Verneed
);
690 OS
.write((const char *)&VerNeed
, sizeof(Elf_Verneed
));
692 for (size_t J
= 0; J
< VE
.AuxV
.size(); ++J
, ++AuxCnt
) {
693 const ELFYAML::VernauxEntry
&VAuxE
= VE
.AuxV
[J
];
696 VernAux
.vna_hash
= VAuxE
.Hash
;
697 VernAux
.vna_flags
= VAuxE
.Flags
;
698 VernAux
.vna_other
= VAuxE
.Other
;
699 VernAux
.vna_name
= DotDynstr
.getOffset(VAuxE
.Name
);
700 if (J
== VE
.AuxV
.size() - 1)
701 VernAux
.vna_next
= 0;
703 VernAux
.vna_next
= sizeof(Elf_Vernaux
);
704 OS
.write((const char *)&VernAux
, sizeof(Elf_Vernaux
));
708 SHeader
.sh_size
= Section
.VerneedV
.size() * sizeof(Elf_Verneed
) +
709 AuxCnt
* sizeof(Elf_Vernaux
);
710 SHeader
.sh_info
= Section
.Info
;
715 template <class ELFT
>
716 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
717 const ELFYAML::MipsABIFlags
&Section
,
718 ContiguousBlobAccumulator
&CBA
) {
719 assert(Section
.Type
== llvm::ELF::SHT_MIPS_ABIFLAGS
&&
720 "Section type is not SHT_MIPS_ABIFLAGS");
722 object::Elf_Mips_ABIFlags
<ELFT
> Flags
;
724 SHeader
.sh_entsize
= sizeof(Flags
);
725 SHeader
.sh_size
= SHeader
.sh_entsize
;
727 auto &OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
728 Flags
.version
= Section
.Version
;
729 Flags
.isa_level
= Section
.ISALevel
;
730 Flags
.isa_rev
= Section
.ISARevision
;
731 Flags
.gpr_size
= Section
.GPRSize
;
732 Flags
.cpr1_size
= Section
.CPR1Size
;
733 Flags
.cpr2_size
= Section
.CPR2Size
;
734 Flags
.fp_abi
= Section
.FpABI
;
735 Flags
.isa_ext
= Section
.ISAExtension
;
736 Flags
.ases
= Section
.ASEs
;
737 Flags
.flags1
= Section
.Flags1
;
738 Flags
.flags2
= Section
.Flags2
;
739 OS
.write((const char *)&Flags
, sizeof(Flags
));
744 template <class ELFT
>
745 bool ELFState
<ELFT
>::writeSectionContent(Elf_Shdr
&SHeader
,
746 const ELFYAML::DynamicSection
&Section
,
747 ContiguousBlobAccumulator
&CBA
) {
748 typedef typename
ELFT::uint uintX_t
;
750 assert(Section
.Type
== llvm::ELF::SHT_DYNAMIC
&&
751 "Section type is not SHT_DYNAMIC");
753 if (!Section
.Entries
.empty() && Section
.Content
) {
755 << "Cannot specify both raw content and explicit entries "
756 "for dynamic section '"
757 << Section
.Name
<< "'.\n";
762 SHeader
.sh_size
= Section
.Content
->binary_size();
764 SHeader
.sh_size
= 2 * sizeof(uintX_t
) * Section
.Entries
.size();
766 SHeader
.sh_entsize
= *Section
.EntSize
;
768 SHeader
.sh_entsize
= sizeof(Elf_Dyn
);
770 raw_ostream
&OS
= CBA
.getOSAndAlignedOffset(SHeader
.sh_offset
, SHeader
.sh_addralign
);
771 for (const ELFYAML::DynamicEntry
&DE
: Section
.Entries
) {
772 support::endian::write
<uintX_t
>(OS
, DE
.Tag
, ELFT::TargetEndianness
);
773 support::endian::write
<uintX_t
>(OS
, DE
.Val
, ELFT::TargetEndianness
);
776 Section
.Content
->writeAsBinary(OS
);
781 template <class ELFT
> bool ELFState
<ELFT
>::buildSectionIndex() {
782 for (unsigned i
= 0, e
= Doc
.Sections
.size(); i
!= e
; ++i
) {
783 StringRef Name
= Doc
.Sections
[i
]->Name
;
784 DotShStrtab
.add(Name
);
785 // "+ 1" to take into account the SHT_NULL entry.
786 if (SN2I
.addName(Name
, i
+ 1)) {
787 WithColor::error() << "Repeated section name: '" << Name
788 << "' at YAML section number " << i
<< ".\n";
793 auto SecNo
= 1 + Doc
.Sections
.size();
794 // Add special sections after input sections, if necessary.
795 for (StringRef Name
: implicitSectionNames())
796 if (!SN2I
.addName(Name
, SecNo
)) {
797 // Account for this section, since it wasn't in the Doc
799 DotShStrtab
.add(Name
);
802 DotShStrtab
.finalize();
806 template <class ELFT
>
807 bool ELFState
<ELFT
>::buildSymbolIndex(ArrayRef
<ELFYAML::Symbol
> Symbols
) {
808 bool GlobalSymbolSeen
= false;
810 for (const auto &Sym
: Symbols
) {
813 StringRef Name
= Sym
.Name
;
814 if (Sym
.Binding
.value
== ELF::STB_LOCAL
&& GlobalSymbolSeen
) {
815 WithColor::error() << "Local symbol '" + Name
+
816 "' after global in Symbols list.\n";
819 if (Sym
.Binding
.value
!= ELF::STB_LOCAL
)
820 GlobalSymbolSeen
= true;
822 if (!Name
.empty() && SymN2I
.addName(Name
, I
)) {
823 WithColor::error() << "Repeated symbol name: '" << Name
<< "'.\n";
830 template <class ELFT
> void ELFState
<ELFT
>::finalizeStrings() {
831 // Add the regular symbol names to .strtab section.
832 for (const ELFYAML::Symbol
&Sym
: Doc
.Symbols
)
833 DotStrtab
.add(Sym
.Name
);
834 DotStrtab
.finalize();
836 if (Doc
.DynamicSymbols
.empty())
839 // Add the dynamic symbol names to .dynstr section.
840 for (const ELFYAML::Symbol
&Sym
: Doc
.DynamicSymbols
)
841 DotDynstr
.add(Sym
.Name
);
843 // SHT_GNU_verdef and SHT_GNU_verneed sections might also
844 // add strings to .dynstr section.
845 for (const std::unique_ptr
<ELFYAML::Section
> &Sec
: Doc
.Sections
) {
846 if (auto VerNeed
= dyn_cast
<ELFYAML::VerneedSection
>(Sec
.get())) {
847 for (const ELFYAML::VerneedEntry
&VE
: VerNeed
->VerneedV
) {
848 DotDynstr
.add(VE
.File
);
849 for (const ELFYAML::VernauxEntry
&Aux
: VE
.AuxV
)
850 DotDynstr
.add(Aux
.Name
);
852 } else if (auto VerDef
= dyn_cast
<ELFYAML::VerdefSection
>(Sec
.get())) {
853 for (const ELFYAML::VerdefEntry
&E
: VerDef
->Entries
)
854 for (StringRef Name
: E
.VerNames
)
859 DotDynstr
.finalize();
862 template <class ELFT
>
863 int ELFState
<ELFT
>::writeELF(raw_ostream
&OS
, const ELFYAML::Object
&Doc
) {
864 ELFState
<ELFT
> State(Doc
);
866 // Finalize .strtab and .dynstr sections. We do that early because want to
867 // finalize the string table builders before writing the content of the
868 // sections that might want to use them.
869 State
.finalizeStrings();
871 if (!State
.buildSectionIndex())
874 if (!State
.buildSymbolIndex(Doc
.Symbols
))
878 State
.initELFHeader(Header
);
880 // TODO: Flesh out section header support.
882 std::vector
<Elf_Phdr
> PHeaders
;
883 State
.initProgramHeaders(PHeaders
);
885 // XXX: This offset is tightly coupled with the order that we write
887 const size_t SectionContentBeginOffset
= Header
.e_ehsize
+
888 Header
.e_phentsize
* Header
.e_phnum
+
889 Header
.e_shentsize
* Header
.e_shnum
;
890 ContiguousBlobAccumulator
CBA(SectionContentBeginOffset
);
892 std::vector
<Elf_Shdr
> SHeaders
;
893 if (!State
.initSectionHeaders(SHeaders
, CBA
))
896 // Populate SHeaders with implicit sections not present in the Doc
897 for (StringRef Name
: State
.implicitSectionNames())
898 if (State
.SN2I
.get(Name
) >= SHeaders
.size())
899 SHeaders
.push_back({});
901 // Initialize the implicit sections
902 State
.initSymtabSectionHeader(SHeaders
[State
.SN2I
.get(".symtab")],
903 SymtabType::Static
, CBA
);
904 State
.initStrtabSectionHeader(SHeaders
[State
.SN2I
.get(".strtab")], ".strtab",
905 State
.DotStrtab
, CBA
);
906 State
.initStrtabSectionHeader(SHeaders
[State
.SN2I
.get(".shstrtab")],
907 ".shstrtab", State
.DotShStrtab
, CBA
);
908 if (!Doc
.DynamicSymbols
.empty()) {
909 State
.initSymtabSectionHeader(SHeaders
[State
.SN2I
.get(".dynsym")],
910 SymtabType::Dynamic
, CBA
);
911 State
.initStrtabSectionHeader(SHeaders
[State
.SN2I
.get(".dynstr")],
912 ".dynstr", State
.DotDynstr
, CBA
);
915 // Now we can decide segment offsets
916 State
.setProgramHeaderLayout(PHeaders
, SHeaders
);
918 OS
.write((const char *)&Header
, sizeof(Header
));
919 writeArrayData(OS
, makeArrayRef(PHeaders
));
920 writeArrayData(OS
, makeArrayRef(SHeaders
));
921 CBA
.writeBlobToStream(OS
);
925 template <class ELFT
>
926 std::vector
<StringRef
> ELFState
<ELFT
>::implicitSectionNames() const {
927 if (Doc
.DynamicSymbols
.empty())
928 return {".symtab", ".strtab", ".shstrtab"};
929 return {".symtab", ".strtab", ".shstrtab", ".dynsym", ".dynstr"};
932 int yaml2elf(llvm::ELFYAML::Object
&Doc
, raw_ostream
&Out
) {
933 bool IsLE
= Doc
.Header
.Data
== ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB
);
934 bool Is64Bit
= Doc
.Header
.Class
== ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64
);
937 return ELFState
<object::ELF64LE
>::writeELF(Out
, Doc
);
938 return ELFState
<object::ELF64BE
>::writeELF(Out
, Doc
);
941 return ELFState
<object::ELF32LE
>::writeELF(Out
, Doc
);
942 return ELFState
<object::ELF32BE
>::writeELF(Out
, Doc
);