1*9880d681SAndroid Build Coastguard Worker //===- yaml2elf - Convert YAML to a ELF object file -----------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker ///
10*9880d681SAndroid Build Coastguard Worker /// \file
11*9880d681SAndroid Build Coastguard Worker /// \brief The ELF component of yaml2obj.
12*9880d681SAndroid Build Coastguard Worker ///
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "yaml2obj.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/StringTableBuilder.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ELFObjectFile.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ObjectYAML/ELFYAML.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/YAMLTraits.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker using namespace llvm;
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker // This class is used to build up a contiguous binary blob while keeping
28*9880d681SAndroid Build Coastguard Worker // track of an offset in the output (which notionally begins at
29*9880d681SAndroid Build Coastguard Worker // `InitialOffset`).
30*9880d681SAndroid Build Coastguard Worker namespace {
31*9880d681SAndroid Build Coastguard Worker class ContiguousBlobAccumulator {
32*9880d681SAndroid Build Coastguard Worker const uint64_t InitialOffset;
33*9880d681SAndroid Build Coastguard Worker SmallVector<char, 128> Buf;
34*9880d681SAndroid Build Coastguard Worker raw_svector_ostream OS;
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker /// \returns The new offset.
padToAlignment(unsigned Align)37*9880d681SAndroid Build Coastguard Worker uint64_t padToAlignment(unsigned Align) {
38*9880d681SAndroid Build Coastguard Worker if (Align == 0)
39*9880d681SAndroid Build Coastguard Worker Align = 1;
40*9880d681SAndroid Build Coastguard Worker uint64_t CurrentOffset = InitialOffset + OS.tell();
41*9880d681SAndroid Build Coastguard Worker uint64_t AlignedOffset = alignTo(CurrentOffset, Align);
42*9880d681SAndroid Build Coastguard Worker for (; CurrentOffset != AlignedOffset; ++CurrentOffset)
43*9880d681SAndroid Build Coastguard Worker OS.write('\0');
44*9880d681SAndroid Build Coastguard Worker return AlignedOffset; // == CurrentOffset;
45*9880d681SAndroid Build Coastguard Worker }
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker public:
ContiguousBlobAccumulator(uint64_t InitialOffset_)48*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator(uint64_t InitialOffset_)
49*9880d681SAndroid Build Coastguard Worker : InitialOffset(InitialOffset_), Buf(), OS(Buf) {}
50*9880d681SAndroid Build Coastguard Worker template <class Integer>
getOSAndAlignedOffset(Integer & Offset,unsigned Align)51*9880d681SAndroid Build Coastguard Worker raw_ostream &getOSAndAlignedOffset(Integer &Offset, unsigned Align) {
52*9880d681SAndroid Build Coastguard Worker Offset = padToAlignment(Align);
53*9880d681SAndroid Build Coastguard Worker return OS;
54*9880d681SAndroid Build Coastguard Worker }
writeBlobToStream(raw_ostream & Out)55*9880d681SAndroid Build Coastguard Worker void writeBlobToStream(raw_ostream &Out) { Out << OS.str(); }
56*9880d681SAndroid Build Coastguard Worker };
57*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker // Used to keep track of section and symbol names, so that in the YAML file
60*9880d681SAndroid Build Coastguard Worker // sections and symbols can be referenced by name instead of by index.
61*9880d681SAndroid Build Coastguard Worker namespace {
62*9880d681SAndroid Build Coastguard Worker class NameToIdxMap {
63*9880d681SAndroid Build Coastguard Worker StringMap<int> Map;
64*9880d681SAndroid Build Coastguard Worker public:
65*9880d681SAndroid Build Coastguard Worker /// \returns true if name is already present in the map.
addName(StringRef Name,unsigned i)66*9880d681SAndroid Build Coastguard Worker bool addName(StringRef Name, unsigned i) {
67*9880d681SAndroid Build Coastguard Worker return !Map.insert(std::make_pair(Name, (int)i)).second;
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker /// \returns true if name is not present in the map
lookup(StringRef Name,unsigned & Idx) const70*9880d681SAndroid Build Coastguard Worker bool lookup(StringRef Name, unsigned &Idx) const {
71*9880d681SAndroid Build Coastguard Worker StringMap<int>::const_iterator I = Map.find(Name);
72*9880d681SAndroid Build Coastguard Worker if (I == Map.end())
73*9880d681SAndroid Build Coastguard Worker return true;
74*9880d681SAndroid Build Coastguard Worker Idx = I->getValue();
75*9880d681SAndroid Build Coastguard Worker return false;
76*9880d681SAndroid Build Coastguard Worker }
77*9880d681SAndroid Build Coastguard Worker };
78*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker template <class T>
arrayDataSize(ArrayRef<T> A)81*9880d681SAndroid Build Coastguard Worker static size_t arrayDataSize(ArrayRef<T> A) {
82*9880d681SAndroid Build Coastguard Worker return A.size() * sizeof(T);
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker template <class T>
writeArrayData(raw_ostream & OS,ArrayRef<T> A)86*9880d681SAndroid Build Coastguard Worker static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) {
87*9880d681SAndroid Build Coastguard Worker OS.write((const char *)A.data(), arrayDataSize(A));
88*9880d681SAndroid Build Coastguard Worker }
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker template <class T>
zero(T & Obj)91*9880d681SAndroid Build Coastguard Worker static void zero(T &Obj) {
92*9880d681SAndroid Build Coastguard Worker memset(&Obj, 0, sizeof(Obj));
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker namespace {
96*9880d681SAndroid Build Coastguard Worker /// \brief "Single point of truth" for the ELF file construction.
97*9880d681SAndroid Build Coastguard Worker /// TODO: This class still has a ways to go before it is truly a "single
98*9880d681SAndroid Build Coastguard Worker /// point of truth".
99*9880d681SAndroid Build Coastguard Worker template <class ELFT>
100*9880d681SAndroid Build Coastguard Worker class ELFState {
101*9880d681SAndroid Build Coastguard Worker typedef typename object::ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
102*9880d681SAndroid Build Coastguard Worker typedef typename object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
103*9880d681SAndroid Build Coastguard Worker typedef typename object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
104*9880d681SAndroid Build Coastguard Worker typedef typename object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
105*9880d681SAndroid Build Coastguard Worker typedef typename object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker /// \brief The future ".strtab" section.
108*9880d681SAndroid Build Coastguard Worker StringTableBuilder DotStrtab{StringTableBuilder::ELF};
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker /// \brief The future ".shstrtab" section.
111*9880d681SAndroid Build Coastguard Worker StringTableBuilder DotShStrtab{StringTableBuilder::ELF};
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker NameToIdxMap SN2I;
114*9880d681SAndroid Build Coastguard Worker NameToIdxMap SymN2I;
115*9880d681SAndroid Build Coastguard Worker const ELFYAML::Object &Doc;
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker bool buildSectionIndex();
118*9880d681SAndroid Build Coastguard Worker bool buildSymbolIndex(std::size_t &StartIndex,
119*9880d681SAndroid Build Coastguard Worker const std::vector<ELFYAML::Symbol> &Symbols);
120*9880d681SAndroid Build Coastguard Worker void initELFHeader(Elf_Ehdr &Header);
121*9880d681SAndroid Build Coastguard Worker bool initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
122*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA);
123*9880d681SAndroid Build Coastguard Worker void initSymtabSectionHeader(Elf_Shdr &SHeader,
124*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA);
125*9880d681SAndroid Build Coastguard Worker void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
126*9880d681SAndroid Build Coastguard Worker StringTableBuilder &STB,
127*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA);
128*9880d681SAndroid Build Coastguard Worker void addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
129*9880d681SAndroid Build Coastguard Worker std::vector<Elf_Sym> &Syms, unsigned SymbolBinding);
130*9880d681SAndroid Build Coastguard Worker void writeSectionContent(Elf_Shdr &SHeader,
131*9880d681SAndroid Build Coastguard Worker const ELFYAML::RawContentSection &Section,
132*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA);
133*9880d681SAndroid Build Coastguard Worker bool writeSectionContent(Elf_Shdr &SHeader,
134*9880d681SAndroid Build Coastguard Worker const ELFYAML::RelocationSection &Section,
135*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA);
136*9880d681SAndroid Build Coastguard Worker bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group,
137*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA);
138*9880d681SAndroid Build Coastguard Worker bool writeSectionContent(Elf_Shdr &SHeader,
139*9880d681SAndroid Build Coastguard Worker const ELFYAML::MipsABIFlags &Section,
140*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA);
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker // - SHT_NULL entry (placed first, i.e. 0'th entry)
143*9880d681SAndroid Build Coastguard Worker // - symbol table (.symtab) (placed third to last)
144*9880d681SAndroid Build Coastguard Worker // - string table (.strtab) (placed second to last)
145*9880d681SAndroid Build Coastguard Worker // - section header string table (.shstrtab) (placed last)
getDotSymTabSecNo() const146*9880d681SAndroid Build Coastguard Worker unsigned getDotSymTabSecNo() const { return Doc.Sections.size() + 1; }
getDotStrTabSecNo() const147*9880d681SAndroid Build Coastguard Worker unsigned getDotStrTabSecNo() const { return Doc.Sections.size() + 2; }
getDotShStrTabSecNo() const148*9880d681SAndroid Build Coastguard Worker unsigned getDotShStrTabSecNo() const { return Doc.Sections.size() + 3; }
getSectionCount() const149*9880d681SAndroid Build Coastguard Worker unsigned getSectionCount() const { return Doc.Sections.size() + 4; }
150*9880d681SAndroid Build Coastguard Worker
ELFState(const ELFYAML::Object & D)151*9880d681SAndroid Build Coastguard Worker ELFState(const ELFYAML::Object &D) : Doc(D) {}
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker public:
154*9880d681SAndroid Build Coastguard Worker static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc);
155*9880d681SAndroid Build Coastguard Worker };
156*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker template <class ELFT>
initELFHeader(Elf_Ehdr & Header)159*9880d681SAndroid Build Coastguard Worker void ELFState<ELFT>::initELFHeader(Elf_Ehdr &Header) {
160*9880d681SAndroid Build Coastguard Worker using namespace llvm::ELF;
161*9880d681SAndroid Build Coastguard Worker zero(Header);
162*9880d681SAndroid Build Coastguard Worker Header.e_ident[EI_MAG0] = 0x7f;
163*9880d681SAndroid Build Coastguard Worker Header.e_ident[EI_MAG1] = 'E';
164*9880d681SAndroid Build Coastguard Worker Header.e_ident[EI_MAG2] = 'L';
165*9880d681SAndroid Build Coastguard Worker Header.e_ident[EI_MAG3] = 'F';
166*9880d681SAndroid Build Coastguard Worker Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
167*9880d681SAndroid Build Coastguard Worker bool IsLittleEndian = ELFT::TargetEndianness == support::little;
168*9880d681SAndroid Build Coastguard Worker Header.e_ident[EI_DATA] = IsLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
169*9880d681SAndroid Build Coastguard Worker Header.e_ident[EI_VERSION] = EV_CURRENT;
170*9880d681SAndroid Build Coastguard Worker Header.e_ident[EI_OSABI] = Doc.Header.OSABI;
171*9880d681SAndroid Build Coastguard Worker Header.e_ident[EI_ABIVERSION] = 0;
172*9880d681SAndroid Build Coastguard Worker Header.e_type = Doc.Header.Type;
173*9880d681SAndroid Build Coastguard Worker Header.e_machine = Doc.Header.Machine;
174*9880d681SAndroid Build Coastguard Worker Header.e_version = EV_CURRENT;
175*9880d681SAndroid Build Coastguard Worker Header.e_entry = Doc.Header.Entry;
176*9880d681SAndroid Build Coastguard Worker Header.e_flags = Doc.Header.Flags;
177*9880d681SAndroid Build Coastguard Worker Header.e_ehsize = sizeof(Elf_Ehdr);
178*9880d681SAndroid Build Coastguard Worker Header.e_shentsize = sizeof(Elf_Shdr);
179*9880d681SAndroid Build Coastguard Worker // Immediately following the ELF header.
180*9880d681SAndroid Build Coastguard Worker Header.e_shoff = sizeof(Header);
181*9880d681SAndroid Build Coastguard Worker Header.e_shnum = getSectionCount();
182*9880d681SAndroid Build Coastguard Worker Header.e_shstrndx = getDotShStrTabSecNo();
183*9880d681SAndroid Build Coastguard Worker }
184*9880d681SAndroid Build Coastguard Worker
185*9880d681SAndroid Build Coastguard Worker template <class ELFT>
initSectionHeaders(std::vector<Elf_Shdr> & SHeaders,ContiguousBlobAccumulator & CBA)186*9880d681SAndroid Build Coastguard Worker bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
187*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA) {
188*9880d681SAndroid Build Coastguard Worker // Ensure SHN_UNDEF entry is present. An all-zero section header is a
189*9880d681SAndroid Build Coastguard Worker // valid SHN_UNDEF entry since SHT_NULL == 0.
190*9880d681SAndroid Build Coastguard Worker Elf_Shdr SHeader;
191*9880d681SAndroid Build Coastguard Worker zero(SHeader);
192*9880d681SAndroid Build Coastguard Worker SHeaders.push_back(SHeader);
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker for (const auto &Sec : Doc.Sections)
195*9880d681SAndroid Build Coastguard Worker DotShStrtab.add(Sec->Name);
196*9880d681SAndroid Build Coastguard Worker DotShStrtab.finalize();
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker for (const auto &Sec : Doc.Sections) {
199*9880d681SAndroid Build Coastguard Worker zero(SHeader);
200*9880d681SAndroid Build Coastguard Worker SHeader.sh_name = DotShStrtab.getOffset(Sec->Name);
201*9880d681SAndroid Build Coastguard Worker SHeader.sh_type = Sec->Type;
202*9880d681SAndroid Build Coastguard Worker SHeader.sh_flags = Sec->Flags;
203*9880d681SAndroid Build Coastguard Worker SHeader.sh_addr = Sec->Address;
204*9880d681SAndroid Build Coastguard Worker SHeader.sh_addralign = Sec->AddressAlign;
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Worker if (!Sec->Link.empty()) {
207*9880d681SAndroid Build Coastguard Worker unsigned Index;
208*9880d681SAndroid Build Coastguard Worker if (SN2I.lookup(Sec->Link, Index)) {
209*9880d681SAndroid Build Coastguard Worker errs() << "error: Unknown section referenced: '" << Sec->Link
210*9880d681SAndroid Build Coastguard Worker << "' at YAML section '" << Sec->Name << "'.\n";
211*9880d681SAndroid Build Coastguard Worker return false;
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker SHeader.sh_link = Index;
214*9880d681SAndroid Build Coastguard Worker }
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec.get()))
217*9880d681SAndroid Build Coastguard Worker writeSectionContent(SHeader, *S, CBA);
218*9880d681SAndroid Build Coastguard Worker else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec.get())) {
219*9880d681SAndroid Build Coastguard Worker if (S->Link.empty())
220*9880d681SAndroid Build Coastguard Worker // For relocation section set link to .symtab by default.
221*9880d681SAndroid Build Coastguard Worker SHeader.sh_link = getDotSymTabSecNo();
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker unsigned Index;
224*9880d681SAndroid Build Coastguard Worker if (SN2I.lookup(S->Info, Index)) {
225*9880d681SAndroid Build Coastguard Worker if (S->Info.getAsInteger(0, Index)) {
226*9880d681SAndroid Build Coastguard Worker errs() << "error: Unknown section referenced: '" << S->Info
227*9880d681SAndroid Build Coastguard Worker << "' at YAML section '" << S->Name << "'.\n";
228*9880d681SAndroid Build Coastguard Worker return false;
229*9880d681SAndroid Build Coastguard Worker }
230*9880d681SAndroid Build Coastguard Worker }
231*9880d681SAndroid Build Coastguard Worker SHeader.sh_info = Index;
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Worker if (!writeSectionContent(SHeader, *S, CBA))
234*9880d681SAndroid Build Coastguard Worker return false;
235*9880d681SAndroid Build Coastguard Worker } else if (auto S = dyn_cast<ELFYAML::Group>(Sec.get())) {
236*9880d681SAndroid Build Coastguard Worker unsigned SymIdx;
237*9880d681SAndroid Build Coastguard Worker if (SymN2I.lookup(S->Info, SymIdx)) {
238*9880d681SAndroid Build Coastguard Worker errs() << "error: Unknown symbol referenced: '" << S->Info
239*9880d681SAndroid Build Coastguard Worker << "' at YAML section '" << S->Name << "'.\n";
240*9880d681SAndroid Build Coastguard Worker return false;
241*9880d681SAndroid Build Coastguard Worker }
242*9880d681SAndroid Build Coastguard Worker SHeader.sh_info = SymIdx;
243*9880d681SAndroid Build Coastguard Worker if (!writeSectionContent(SHeader, *S, CBA))
244*9880d681SAndroid Build Coastguard Worker return false;
245*9880d681SAndroid Build Coastguard Worker } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec.get())) {
246*9880d681SAndroid Build Coastguard Worker if (!writeSectionContent(SHeader, *S, CBA))
247*9880d681SAndroid Build Coastguard Worker return false;
248*9880d681SAndroid Build Coastguard Worker } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec.get())) {
249*9880d681SAndroid Build Coastguard Worker SHeader.sh_entsize = 0;
250*9880d681SAndroid Build Coastguard Worker SHeader.sh_size = S->Size;
251*9880d681SAndroid Build Coastguard Worker // SHT_NOBITS section does not have content
252*9880d681SAndroid Build Coastguard Worker // so just to setup the section offset.
253*9880d681SAndroid Build Coastguard Worker CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
254*9880d681SAndroid Build Coastguard Worker } else
255*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown section type");
256*9880d681SAndroid Build Coastguard Worker
257*9880d681SAndroid Build Coastguard Worker SHeaders.push_back(SHeader);
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker return true;
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker template <class ELFT>
initSymtabSectionHeader(Elf_Shdr & SHeader,ContiguousBlobAccumulator & CBA)263*9880d681SAndroid Build Coastguard Worker void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
264*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA) {
265*9880d681SAndroid Build Coastguard Worker zero(SHeader);
266*9880d681SAndroid Build Coastguard Worker SHeader.sh_name = DotShStrtab.getOffset(".symtab");
267*9880d681SAndroid Build Coastguard Worker SHeader.sh_type = ELF::SHT_SYMTAB;
268*9880d681SAndroid Build Coastguard Worker SHeader.sh_link = getDotStrTabSecNo();
269*9880d681SAndroid Build Coastguard Worker // One greater than symbol table index of the last local symbol.
270*9880d681SAndroid Build Coastguard Worker SHeader.sh_info = Doc.Symbols.Local.size() + 1;
271*9880d681SAndroid Build Coastguard Worker SHeader.sh_entsize = sizeof(Elf_Sym);
272*9880d681SAndroid Build Coastguard Worker SHeader.sh_addralign = 8;
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker std::vector<Elf_Sym> Syms;
275*9880d681SAndroid Build Coastguard Worker {
276*9880d681SAndroid Build Coastguard Worker // Ensure STN_UNDEF is present
277*9880d681SAndroid Build Coastguard Worker Elf_Sym Sym;
278*9880d681SAndroid Build Coastguard Worker zero(Sym);
279*9880d681SAndroid Build Coastguard Worker Syms.push_back(Sym);
280*9880d681SAndroid Build Coastguard Worker }
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker // Add symbol names to .strtab.
283*9880d681SAndroid Build Coastguard Worker for (const auto &Sym : Doc.Symbols.Local)
284*9880d681SAndroid Build Coastguard Worker DotStrtab.add(Sym.Name);
285*9880d681SAndroid Build Coastguard Worker for (const auto &Sym : Doc.Symbols.Global)
286*9880d681SAndroid Build Coastguard Worker DotStrtab.add(Sym.Name);
287*9880d681SAndroid Build Coastguard Worker for (const auto &Sym : Doc.Symbols.Weak)
288*9880d681SAndroid Build Coastguard Worker DotStrtab.add(Sym.Name);
289*9880d681SAndroid Build Coastguard Worker DotStrtab.finalize();
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker addSymbols(Doc.Symbols.Local, Syms, ELF::STB_LOCAL);
292*9880d681SAndroid Build Coastguard Worker addSymbols(Doc.Symbols.Global, Syms, ELF::STB_GLOBAL);
293*9880d681SAndroid Build Coastguard Worker addSymbols(Doc.Symbols.Weak, Syms, ELF::STB_WEAK);
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Worker writeArrayData(
296*9880d681SAndroid Build Coastguard Worker CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign),
297*9880d681SAndroid Build Coastguard Worker makeArrayRef(Syms));
298*9880d681SAndroid Build Coastguard Worker SHeader.sh_size = arrayDataSize(makeArrayRef(Syms));
299*9880d681SAndroid Build Coastguard Worker }
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker template <class ELFT>
initStrtabSectionHeader(Elf_Shdr & SHeader,StringRef Name,StringTableBuilder & STB,ContiguousBlobAccumulator & CBA)302*9880d681SAndroid Build Coastguard Worker void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
303*9880d681SAndroid Build Coastguard Worker StringTableBuilder &STB,
304*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA) {
305*9880d681SAndroid Build Coastguard Worker zero(SHeader);
306*9880d681SAndroid Build Coastguard Worker SHeader.sh_name = DotShStrtab.getOffset(Name);
307*9880d681SAndroid Build Coastguard Worker SHeader.sh_type = ELF::SHT_STRTAB;
308*9880d681SAndroid Build Coastguard Worker CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign)
309*9880d681SAndroid Build Coastguard Worker << STB.data();
310*9880d681SAndroid Build Coastguard Worker SHeader.sh_size = STB.data().size();
311*9880d681SAndroid Build Coastguard Worker SHeader.sh_addralign = 1;
312*9880d681SAndroid Build Coastguard Worker }
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Worker template <class ELFT>
addSymbols(const std::vector<ELFYAML::Symbol> & Symbols,std::vector<Elf_Sym> & Syms,unsigned SymbolBinding)315*9880d681SAndroid Build Coastguard Worker void ELFState<ELFT>::addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
316*9880d681SAndroid Build Coastguard Worker std::vector<Elf_Sym> &Syms,
317*9880d681SAndroid Build Coastguard Worker unsigned SymbolBinding) {
318*9880d681SAndroid Build Coastguard Worker for (const auto &Sym : Symbols) {
319*9880d681SAndroid Build Coastguard Worker Elf_Sym Symbol;
320*9880d681SAndroid Build Coastguard Worker zero(Symbol);
321*9880d681SAndroid Build Coastguard Worker if (!Sym.Name.empty())
322*9880d681SAndroid Build Coastguard Worker Symbol.st_name = DotStrtab.getOffset(Sym.Name);
323*9880d681SAndroid Build Coastguard Worker Symbol.setBindingAndType(SymbolBinding, Sym.Type);
324*9880d681SAndroid Build Coastguard Worker if (!Sym.Section.empty()) {
325*9880d681SAndroid Build Coastguard Worker unsigned Index;
326*9880d681SAndroid Build Coastguard Worker if (SN2I.lookup(Sym.Section, Index)) {
327*9880d681SAndroid Build Coastguard Worker errs() << "error: Unknown section referenced: '" << Sym.Section
328*9880d681SAndroid Build Coastguard Worker << "' by YAML symbol " << Sym.Name << ".\n";
329*9880d681SAndroid Build Coastguard Worker exit(1);
330*9880d681SAndroid Build Coastguard Worker }
331*9880d681SAndroid Build Coastguard Worker Symbol.st_shndx = Index;
332*9880d681SAndroid Build Coastguard Worker } // else Symbol.st_shndex == SHN_UNDEF (== 0), since it was zero'd earlier.
333*9880d681SAndroid Build Coastguard Worker Symbol.st_value = Sym.Value;
334*9880d681SAndroid Build Coastguard Worker Symbol.st_other = Sym.Other;
335*9880d681SAndroid Build Coastguard Worker Symbol.st_size = Sym.Size;
336*9880d681SAndroid Build Coastguard Worker Syms.push_back(Symbol);
337*9880d681SAndroid Build Coastguard Worker }
338*9880d681SAndroid Build Coastguard Worker }
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker template <class ELFT>
341*9880d681SAndroid Build Coastguard Worker void
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RawContentSection & Section,ContiguousBlobAccumulator & CBA)342*9880d681SAndroid Build Coastguard Worker ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
343*9880d681SAndroid Build Coastguard Worker const ELFYAML::RawContentSection &Section,
344*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA) {
345*9880d681SAndroid Build Coastguard Worker assert(Section.Size >= Section.Content.binary_size() &&
346*9880d681SAndroid Build Coastguard Worker "Section size and section content are inconsistent");
347*9880d681SAndroid Build Coastguard Worker raw_ostream &OS =
348*9880d681SAndroid Build Coastguard Worker CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
349*9880d681SAndroid Build Coastguard Worker Section.Content.writeAsBinary(OS);
350*9880d681SAndroid Build Coastguard Worker for (auto i = Section.Content.binary_size(); i < Section.Size; ++i)
351*9880d681SAndroid Build Coastguard Worker OS.write(0);
352*9880d681SAndroid Build Coastguard Worker SHeader.sh_entsize = 0;
353*9880d681SAndroid Build Coastguard Worker SHeader.sh_size = Section.Size;
354*9880d681SAndroid Build Coastguard Worker }
355*9880d681SAndroid Build Coastguard Worker
isMips64EL(const ELFYAML::Object & Doc)356*9880d681SAndroid Build Coastguard Worker static bool isMips64EL(const ELFYAML::Object &Doc) {
357*9880d681SAndroid Build Coastguard Worker return Doc.Header.Machine == ELFYAML::ELF_EM(llvm::ELF::EM_MIPS) &&
358*9880d681SAndroid Build Coastguard Worker Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) &&
359*9880d681SAndroid Build Coastguard Worker Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
360*9880d681SAndroid Build Coastguard Worker }
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker template <class ELFT>
363*9880d681SAndroid Build Coastguard Worker bool
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RelocationSection & Section,ContiguousBlobAccumulator & CBA)364*9880d681SAndroid Build Coastguard Worker ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
365*9880d681SAndroid Build Coastguard Worker const ELFYAML::RelocationSection &Section,
366*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA) {
367*9880d681SAndroid Build Coastguard Worker assert((Section.Type == llvm::ELF::SHT_REL ||
368*9880d681SAndroid Build Coastguard Worker Section.Type == llvm::ELF::SHT_RELA) &&
369*9880d681SAndroid Build Coastguard Worker "Section type is not SHT_REL nor SHT_RELA");
370*9880d681SAndroid Build Coastguard Worker
371*9880d681SAndroid Build Coastguard Worker bool IsRela = Section.Type == llvm::ELF::SHT_RELA;
372*9880d681SAndroid Build Coastguard Worker SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
373*9880d681SAndroid Build Coastguard Worker SHeader.sh_size = SHeader.sh_entsize * Section.Relocations.size();
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
376*9880d681SAndroid Build Coastguard Worker
377*9880d681SAndroid Build Coastguard Worker for (const auto &Rel : Section.Relocations) {
378*9880d681SAndroid Build Coastguard Worker unsigned SymIdx = 0;
379*9880d681SAndroid Build Coastguard Worker // Some special relocation, R_ARM_v4BX for instance, does not have
380*9880d681SAndroid Build Coastguard Worker // an external reference. So it ignores the return value of lookup()
381*9880d681SAndroid Build Coastguard Worker // here.
382*9880d681SAndroid Build Coastguard Worker SymN2I.lookup(Rel.Symbol, SymIdx);
383*9880d681SAndroid Build Coastguard Worker
384*9880d681SAndroid Build Coastguard Worker if (IsRela) {
385*9880d681SAndroid Build Coastguard Worker Elf_Rela REntry;
386*9880d681SAndroid Build Coastguard Worker zero(REntry);
387*9880d681SAndroid Build Coastguard Worker REntry.r_offset = Rel.Offset;
388*9880d681SAndroid Build Coastguard Worker REntry.r_addend = Rel.Addend;
389*9880d681SAndroid Build Coastguard Worker REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc));
390*9880d681SAndroid Build Coastguard Worker OS.write((const char *)&REntry, sizeof(REntry));
391*9880d681SAndroid Build Coastguard Worker } else {
392*9880d681SAndroid Build Coastguard Worker Elf_Rel REntry;
393*9880d681SAndroid Build Coastguard Worker zero(REntry);
394*9880d681SAndroid Build Coastguard Worker REntry.r_offset = Rel.Offset;
395*9880d681SAndroid Build Coastguard Worker REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc));
396*9880d681SAndroid Build Coastguard Worker OS.write((const char *)&REntry, sizeof(REntry));
397*9880d681SAndroid Build Coastguard Worker }
398*9880d681SAndroid Build Coastguard Worker }
399*9880d681SAndroid Build Coastguard Worker return true;
400*9880d681SAndroid Build Coastguard Worker }
401*9880d681SAndroid Build Coastguard Worker
402*9880d681SAndroid Build Coastguard Worker template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::Group & Section,ContiguousBlobAccumulator & CBA)403*9880d681SAndroid Build Coastguard Worker bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
404*9880d681SAndroid Build Coastguard Worker const ELFYAML::Group &Section,
405*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA) {
406*9880d681SAndroid Build Coastguard Worker typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word;
407*9880d681SAndroid Build Coastguard Worker assert(Section.Type == llvm::ELF::SHT_GROUP &&
408*9880d681SAndroid Build Coastguard Worker "Section type is not SHT_GROUP");
409*9880d681SAndroid Build Coastguard Worker
410*9880d681SAndroid Build Coastguard Worker SHeader.sh_entsize = sizeof(Elf_Word);
411*9880d681SAndroid Build Coastguard Worker SHeader.sh_size = SHeader.sh_entsize * Section.Members.size();
412*9880d681SAndroid Build Coastguard Worker
413*9880d681SAndroid Build Coastguard Worker auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
414*9880d681SAndroid Build Coastguard Worker
415*9880d681SAndroid Build Coastguard Worker for (auto member : Section.Members) {
416*9880d681SAndroid Build Coastguard Worker Elf_Word SIdx;
417*9880d681SAndroid Build Coastguard Worker unsigned int sectionIndex = 0;
418*9880d681SAndroid Build Coastguard Worker if (member.sectionNameOrType == "GRP_COMDAT")
419*9880d681SAndroid Build Coastguard Worker sectionIndex = llvm::ELF::GRP_COMDAT;
420*9880d681SAndroid Build Coastguard Worker else if (SN2I.lookup(member.sectionNameOrType, sectionIndex)) {
421*9880d681SAndroid Build Coastguard Worker errs() << "error: Unknown section referenced: '"
422*9880d681SAndroid Build Coastguard Worker << member.sectionNameOrType << "' at YAML section' "
423*9880d681SAndroid Build Coastguard Worker << Section.Name << "\n";
424*9880d681SAndroid Build Coastguard Worker return false;
425*9880d681SAndroid Build Coastguard Worker }
426*9880d681SAndroid Build Coastguard Worker SIdx = sectionIndex;
427*9880d681SAndroid Build Coastguard Worker OS.write((const char *)&SIdx, sizeof(SIdx));
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker return true;
430*9880d681SAndroid Build Coastguard Worker }
431*9880d681SAndroid Build Coastguard Worker
432*9880d681SAndroid Build Coastguard Worker template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::MipsABIFlags & Section,ContiguousBlobAccumulator & CBA)433*9880d681SAndroid Build Coastguard Worker bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
434*9880d681SAndroid Build Coastguard Worker const ELFYAML::MipsABIFlags &Section,
435*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator &CBA) {
436*9880d681SAndroid Build Coastguard Worker assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS &&
437*9880d681SAndroid Build Coastguard Worker "Section type is not SHT_MIPS_ABIFLAGS");
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Worker object::Elf_Mips_ABIFlags<ELFT> Flags;
440*9880d681SAndroid Build Coastguard Worker zero(Flags);
441*9880d681SAndroid Build Coastguard Worker SHeader.sh_entsize = sizeof(Flags);
442*9880d681SAndroid Build Coastguard Worker SHeader.sh_size = SHeader.sh_entsize;
443*9880d681SAndroid Build Coastguard Worker
444*9880d681SAndroid Build Coastguard Worker auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
445*9880d681SAndroid Build Coastguard Worker Flags.version = Section.Version;
446*9880d681SAndroid Build Coastguard Worker Flags.isa_level = Section.ISALevel;
447*9880d681SAndroid Build Coastguard Worker Flags.isa_rev = Section.ISARevision;
448*9880d681SAndroid Build Coastguard Worker Flags.gpr_size = Section.GPRSize;
449*9880d681SAndroid Build Coastguard Worker Flags.cpr1_size = Section.CPR1Size;
450*9880d681SAndroid Build Coastguard Worker Flags.cpr2_size = Section.CPR2Size;
451*9880d681SAndroid Build Coastguard Worker Flags.fp_abi = Section.FpABI;
452*9880d681SAndroid Build Coastguard Worker Flags.isa_ext = Section.ISAExtension;
453*9880d681SAndroid Build Coastguard Worker Flags.ases = Section.ASEs;
454*9880d681SAndroid Build Coastguard Worker Flags.flags1 = Section.Flags1;
455*9880d681SAndroid Build Coastguard Worker Flags.flags2 = Section.Flags2;
456*9880d681SAndroid Build Coastguard Worker OS.write((const char *)&Flags, sizeof(Flags));
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker return true;
459*9880d681SAndroid Build Coastguard Worker }
460*9880d681SAndroid Build Coastguard Worker
buildSectionIndex()461*9880d681SAndroid Build Coastguard Worker template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
462*9880d681SAndroid Build Coastguard Worker SN2I.addName(".symtab", getDotSymTabSecNo());
463*9880d681SAndroid Build Coastguard Worker SN2I.addName(".strtab", getDotStrTabSecNo());
464*9880d681SAndroid Build Coastguard Worker SN2I.addName(".shstrtab", getDotShStrTabSecNo());
465*9880d681SAndroid Build Coastguard Worker
466*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
467*9880d681SAndroid Build Coastguard Worker StringRef Name = Doc.Sections[i]->Name;
468*9880d681SAndroid Build Coastguard Worker if (Name.empty())
469*9880d681SAndroid Build Coastguard Worker continue;
470*9880d681SAndroid Build Coastguard Worker // "+ 1" to take into account the SHT_NULL entry.
471*9880d681SAndroid Build Coastguard Worker if (SN2I.addName(Name, i + 1)) {
472*9880d681SAndroid Build Coastguard Worker errs() << "error: Repeated section name: '" << Name
473*9880d681SAndroid Build Coastguard Worker << "' at YAML section number " << i << ".\n";
474*9880d681SAndroid Build Coastguard Worker return false;
475*9880d681SAndroid Build Coastguard Worker }
476*9880d681SAndroid Build Coastguard Worker }
477*9880d681SAndroid Build Coastguard Worker return true;
478*9880d681SAndroid Build Coastguard Worker }
479*9880d681SAndroid Build Coastguard Worker
480*9880d681SAndroid Build Coastguard Worker template <class ELFT>
481*9880d681SAndroid Build Coastguard Worker bool
buildSymbolIndex(std::size_t & StartIndex,const std::vector<ELFYAML::Symbol> & Symbols)482*9880d681SAndroid Build Coastguard Worker ELFState<ELFT>::buildSymbolIndex(std::size_t &StartIndex,
483*9880d681SAndroid Build Coastguard Worker const std::vector<ELFYAML::Symbol> &Symbols) {
484*9880d681SAndroid Build Coastguard Worker for (const auto &Sym : Symbols) {
485*9880d681SAndroid Build Coastguard Worker ++StartIndex;
486*9880d681SAndroid Build Coastguard Worker if (Sym.Name.empty())
487*9880d681SAndroid Build Coastguard Worker continue;
488*9880d681SAndroid Build Coastguard Worker if (SymN2I.addName(Sym.Name, StartIndex)) {
489*9880d681SAndroid Build Coastguard Worker errs() << "error: Repeated symbol name: '" << Sym.Name << "'.\n";
490*9880d681SAndroid Build Coastguard Worker return false;
491*9880d681SAndroid Build Coastguard Worker }
492*9880d681SAndroid Build Coastguard Worker }
493*9880d681SAndroid Build Coastguard Worker return true;
494*9880d681SAndroid Build Coastguard Worker }
495*9880d681SAndroid Build Coastguard Worker
496*9880d681SAndroid Build Coastguard Worker template <class ELFT>
writeELF(raw_ostream & OS,const ELFYAML::Object & Doc)497*9880d681SAndroid Build Coastguard Worker int ELFState<ELFT>::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
498*9880d681SAndroid Build Coastguard Worker ELFState<ELFT> State(Doc);
499*9880d681SAndroid Build Coastguard Worker if (!State.buildSectionIndex())
500*9880d681SAndroid Build Coastguard Worker return 1;
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker std::size_t StartSymIndex = 0;
503*9880d681SAndroid Build Coastguard Worker if (!State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Local) ||
504*9880d681SAndroid Build Coastguard Worker !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Global) ||
505*9880d681SAndroid Build Coastguard Worker !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Weak))
506*9880d681SAndroid Build Coastguard Worker return 1;
507*9880d681SAndroid Build Coastguard Worker
508*9880d681SAndroid Build Coastguard Worker Elf_Ehdr Header;
509*9880d681SAndroid Build Coastguard Worker State.initELFHeader(Header);
510*9880d681SAndroid Build Coastguard Worker
511*9880d681SAndroid Build Coastguard Worker // TODO: Flesh out section header support.
512*9880d681SAndroid Build Coastguard Worker // TODO: Program headers.
513*9880d681SAndroid Build Coastguard Worker
514*9880d681SAndroid Build Coastguard Worker // XXX: This offset is tightly coupled with the order that we write
515*9880d681SAndroid Build Coastguard Worker // things to `OS`.
516*9880d681SAndroid Build Coastguard Worker const size_t SectionContentBeginOffset =
517*9880d681SAndroid Build Coastguard Worker Header.e_ehsize + Header.e_shentsize * Header.e_shnum;
518*9880d681SAndroid Build Coastguard Worker ContiguousBlobAccumulator CBA(SectionContentBeginOffset);
519*9880d681SAndroid Build Coastguard Worker
520*9880d681SAndroid Build Coastguard Worker // Doc might not contain .symtab, .strtab and .shstrtab sections,
521*9880d681SAndroid Build Coastguard Worker // but we will emit them, so make sure to add them to ShStrTabSHeader.
522*9880d681SAndroid Build Coastguard Worker State.DotShStrtab.add(".symtab");
523*9880d681SAndroid Build Coastguard Worker State.DotShStrtab.add(".strtab");
524*9880d681SAndroid Build Coastguard Worker State.DotShStrtab.add(".shstrtab");
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Worker std::vector<Elf_Shdr> SHeaders;
527*9880d681SAndroid Build Coastguard Worker if(!State.initSectionHeaders(SHeaders, CBA))
528*9880d681SAndroid Build Coastguard Worker return 1;
529*9880d681SAndroid Build Coastguard Worker
530*9880d681SAndroid Build Coastguard Worker // .symtab section.
531*9880d681SAndroid Build Coastguard Worker Elf_Shdr SymtabSHeader;
532*9880d681SAndroid Build Coastguard Worker State.initSymtabSectionHeader(SymtabSHeader, CBA);
533*9880d681SAndroid Build Coastguard Worker SHeaders.push_back(SymtabSHeader);
534*9880d681SAndroid Build Coastguard Worker
535*9880d681SAndroid Build Coastguard Worker // .strtab string table header.
536*9880d681SAndroid Build Coastguard Worker Elf_Shdr DotStrTabSHeader;
537*9880d681SAndroid Build Coastguard Worker State.initStrtabSectionHeader(DotStrTabSHeader, ".strtab", State.DotStrtab,
538*9880d681SAndroid Build Coastguard Worker CBA);
539*9880d681SAndroid Build Coastguard Worker SHeaders.push_back(DotStrTabSHeader);
540*9880d681SAndroid Build Coastguard Worker
541*9880d681SAndroid Build Coastguard Worker // .shstrtab string table header.
542*9880d681SAndroid Build Coastguard Worker Elf_Shdr ShStrTabSHeader;
543*9880d681SAndroid Build Coastguard Worker State.initStrtabSectionHeader(ShStrTabSHeader, ".shstrtab", State.DotShStrtab,
544*9880d681SAndroid Build Coastguard Worker CBA);
545*9880d681SAndroid Build Coastguard Worker SHeaders.push_back(ShStrTabSHeader);
546*9880d681SAndroid Build Coastguard Worker
547*9880d681SAndroid Build Coastguard Worker OS.write((const char *)&Header, sizeof(Header));
548*9880d681SAndroid Build Coastguard Worker writeArrayData(OS, makeArrayRef(SHeaders));
549*9880d681SAndroid Build Coastguard Worker CBA.writeBlobToStream(OS);
550*9880d681SAndroid Build Coastguard Worker return 0;
551*9880d681SAndroid Build Coastguard Worker }
552*9880d681SAndroid Build Coastguard Worker
is64Bit(const ELFYAML::Object & Doc)553*9880d681SAndroid Build Coastguard Worker static bool is64Bit(const ELFYAML::Object &Doc) {
554*9880d681SAndroid Build Coastguard Worker return Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
555*9880d681SAndroid Build Coastguard Worker }
556*9880d681SAndroid Build Coastguard Worker
isLittleEndian(const ELFYAML::Object & Doc)557*9880d681SAndroid Build Coastguard Worker static bool isLittleEndian(const ELFYAML::Object &Doc) {
558*9880d681SAndroid Build Coastguard Worker return Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
559*9880d681SAndroid Build Coastguard Worker }
560*9880d681SAndroid Build Coastguard Worker
yaml2elf(llvm::ELFYAML::Object & Doc,raw_ostream & Out)561*9880d681SAndroid Build Coastguard Worker int yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out) {
562*9880d681SAndroid Build Coastguard Worker using object::ELFType;
563*9880d681SAndroid Build Coastguard Worker typedef ELFType<support::little, true> LE64;
564*9880d681SAndroid Build Coastguard Worker typedef ELFType<support::big, true> BE64;
565*9880d681SAndroid Build Coastguard Worker typedef ELFType<support::little, false> LE32;
566*9880d681SAndroid Build Coastguard Worker typedef ELFType<support::big, false> BE32;
567*9880d681SAndroid Build Coastguard Worker if (is64Bit(Doc)) {
568*9880d681SAndroid Build Coastguard Worker if (isLittleEndian(Doc))
569*9880d681SAndroid Build Coastguard Worker return ELFState<LE64>::writeELF(Out, Doc);
570*9880d681SAndroid Build Coastguard Worker else
571*9880d681SAndroid Build Coastguard Worker return ELFState<BE64>::writeELF(Out, Doc);
572*9880d681SAndroid Build Coastguard Worker } else {
573*9880d681SAndroid Build Coastguard Worker if (isLittleEndian(Doc))
574*9880d681SAndroid Build Coastguard Worker return ELFState<LE32>::writeELF(Out, Doc);
575*9880d681SAndroid Build Coastguard Worker else
576*9880d681SAndroid Build Coastguard Worker return ELFState<BE32>::writeELF(Out, Doc);
577*9880d681SAndroid Build Coastguard Worker }
578*9880d681SAndroid Build Coastguard Worker }
579