xref: /aosp_15_r20/art/libelffile/elf/elf_builder.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBELFFILE_ELF_ELF_BUILDER_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_LIBELFFILE_ELF_ELF_BUILDER_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <vector>
21*795d594fSAndroid Build Coastguard Worker #include <deque>
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include "arch/instruction_set.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/array_ref.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/bit_utils.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/casts.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/leb128.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/unix_file/fd_file.h"
29*795d594fSAndroid Build Coastguard Worker #include "elf/elf_utils.h"
30*795d594fSAndroid Build Coastguard Worker #include "stream/error_delaying_output_stream.h"
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker namespace art {
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker // Writes ELF file.
35*795d594fSAndroid Build Coastguard Worker //
36*795d594fSAndroid Build Coastguard Worker // The basic layout of the elf file:
37*795d594fSAndroid Build Coastguard Worker //   Elf_Ehdr                    - The ELF header.
38*795d594fSAndroid Build Coastguard Worker //   Elf_Phdr[]                  - Program headers for the linker.
39*795d594fSAndroid Build Coastguard Worker //   .note.gnu.build-id          - Optional build ID section (SHA-1 digest).
40*795d594fSAndroid Build Coastguard Worker //   .rodata                     - Oat metadata.
41*795d594fSAndroid Build Coastguard Worker //   .text                       - Compiled code.
42*795d594fSAndroid Build Coastguard Worker //   .bss                        - Zero-initialized writeable section.
43*795d594fSAndroid Build Coastguard Worker //   .dex                        - Reserved NOBITS space for dex-related data.
44*795d594fSAndroid Build Coastguard Worker //   .dynstr                     - Names for .dynsym.
45*795d594fSAndroid Build Coastguard Worker //   .dynsym                     - A few oat-specific dynamic symbols.
46*795d594fSAndroid Build Coastguard Worker //   .hash                       - Hash-table for .dynsym.
47*795d594fSAndroid Build Coastguard Worker //   .dynamic                    - Tags which let the linker locate .dynsym.
48*795d594fSAndroid Build Coastguard Worker //   .strtab                     - Names for .symtab.
49*795d594fSAndroid Build Coastguard Worker //   .symtab                     - Debug symbols.
50*795d594fSAndroid Build Coastguard Worker //   .debug_frame                - Unwind information (CFI).
51*795d594fSAndroid Build Coastguard Worker //   .debug_info                 - Debug information.
52*795d594fSAndroid Build Coastguard Worker //   .debug_abbrev               - Decoding information for .debug_info.
53*795d594fSAndroid Build Coastguard Worker //   .debug_str                  - Strings for .debug_info.
54*795d594fSAndroid Build Coastguard Worker //   .debug_line                 - Line number tables.
55*795d594fSAndroid Build Coastguard Worker //   .shstrtab                   - Names of ELF sections.
56*795d594fSAndroid Build Coastguard Worker //   Elf_Shdr[]                  - Section headers.
57*795d594fSAndroid Build Coastguard Worker //
58*795d594fSAndroid Build Coastguard Worker // Some section are optional (the debug sections in particular).
59*795d594fSAndroid Build Coastguard Worker //
60*795d594fSAndroid Build Coastguard Worker // We try write the section data directly into the file without much
61*795d594fSAndroid Build Coastguard Worker // in-memory buffering.  This means we generally write sections based on the
62*795d594fSAndroid Build Coastguard Worker // dependency order (e.g. .dynamic points to .dynsym which points to .text).
63*795d594fSAndroid Build Coastguard Worker //
64*795d594fSAndroid Build Coastguard Worker // In the cases where we need to buffer, we write the larger section first
65*795d594fSAndroid Build Coastguard Worker // and buffer the smaller one (e.g. .strtab is bigger than .symtab).
66*795d594fSAndroid Build Coastguard Worker //
67*795d594fSAndroid Build Coastguard Worker // The debug sections are written last for easier stripping.
68*795d594fSAndroid Build Coastguard Worker //
69*795d594fSAndroid Build Coastguard Worker template <typename ElfTypes>
70*795d594fSAndroid Build Coastguard Worker class ElfBuilder final {
71*795d594fSAndroid Build Coastguard Worker  public:
72*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kMaxProgramHeaders = 16;
73*795d594fSAndroid Build Coastguard Worker   // SHA-1 digest.  Not using SHA_DIGEST_LENGTH from openssl/sha.h to avoid
74*795d594fSAndroid Build Coastguard Worker   // spreading this header dependency for just this single constant.
75*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kBuildIdLen = 20;
76*795d594fSAndroid Build Coastguard Worker 
77*795d594fSAndroid Build Coastguard Worker   using Elf_Addr = typename ElfTypes::Addr;
78*795d594fSAndroid Build Coastguard Worker   using Elf_Off = typename ElfTypes::Off;
79*795d594fSAndroid Build Coastguard Worker   using Elf_Word = typename ElfTypes::Word;
80*795d594fSAndroid Build Coastguard Worker   using Elf_Sword = typename ElfTypes::Sword;
81*795d594fSAndroid Build Coastguard Worker   using Elf_Ehdr = typename ElfTypes::Ehdr;
82*795d594fSAndroid Build Coastguard Worker   using Elf_Shdr = typename ElfTypes::Shdr;
83*795d594fSAndroid Build Coastguard Worker   using Elf_Sym = typename ElfTypes::Sym;
84*795d594fSAndroid Build Coastguard Worker   using Elf_Phdr = typename ElfTypes::Phdr;
85*795d594fSAndroid Build Coastguard Worker   using Elf_Dyn = typename ElfTypes::Dyn;
86*795d594fSAndroid Build Coastguard Worker 
87*795d594fSAndroid Build Coastguard Worker   // Base class of all sections.
88*795d594fSAndroid Build Coastguard Worker   class Section : public OutputStream {
89*795d594fSAndroid Build Coastguard Worker    public:
Section(ElfBuilder<ElfTypes> * owner,const std::string & name,Elf_Word type,Elf_Word flags,const Section * link,Elf_Word info,Elf_Word align,Elf_Word entsize)90*795d594fSAndroid Build Coastguard Worker     Section(ElfBuilder<ElfTypes>* owner,
91*795d594fSAndroid Build Coastguard Worker             const std::string& name,
92*795d594fSAndroid Build Coastguard Worker             Elf_Word type,
93*795d594fSAndroid Build Coastguard Worker             Elf_Word flags,
94*795d594fSAndroid Build Coastguard Worker             const Section* link,
95*795d594fSAndroid Build Coastguard Worker             Elf_Word info,
96*795d594fSAndroid Build Coastguard Worker             Elf_Word align,
97*795d594fSAndroid Build Coastguard Worker             Elf_Word entsize)
98*795d594fSAndroid Build Coastguard Worker         : OutputStream(name),
99*795d594fSAndroid Build Coastguard Worker           owner_(owner),
100*795d594fSAndroid Build Coastguard Worker           header_(),
101*795d594fSAndroid Build Coastguard Worker           section_index_(0),
102*795d594fSAndroid Build Coastguard Worker           name_(name),
103*795d594fSAndroid Build Coastguard Worker           link_(link),
104*795d594fSAndroid Build Coastguard Worker           phdr_flags_(PF_R),
105*795d594fSAndroid Build Coastguard Worker           phdr_type_(0) {
106*795d594fSAndroid Build Coastguard Worker       DCHECK_GE(align, 1u);
107*795d594fSAndroid Build Coastguard Worker       header_.sh_type = type;
108*795d594fSAndroid Build Coastguard Worker       header_.sh_flags = flags;
109*795d594fSAndroid Build Coastguard Worker       header_.sh_info = info;
110*795d594fSAndroid Build Coastguard Worker       header_.sh_addralign = align;
111*795d594fSAndroid Build Coastguard Worker       header_.sh_entsize = entsize;
112*795d594fSAndroid Build Coastguard Worker     }
113*795d594fSAndroid Build Coastguard Worker 
114*795d594fSAndroid Build Coastguard Worker     // Allocate chunk of virtual memory for this section from the owning ElfBuilder.
115*795d594fSAndroid Build Coastguard Worker     // This must be done at the start for all SHF_ALLOC sections (i.e. mmaped by linker).
116*795d594fSAndroid Build Coastguard Worker     // It is fine to allocate section but never call Start/End() (e.g. the .bss section).
AllocateVirtualMemory(Elf_Word size)117*795d594fSAndroid Build Coastguard Worker     void AllocateVirtualMemory(Elf_Word size) {
118*795d594fSAndroid Build Coastguard Worker       AllocateVirtualMemory(owner_->virtual_address_, size);
119*795d594fSAndroid Build Coastguard Worker     }
120*795d594fSAndroid Build Coastguard Worker 
AllocateVirtualMemory(Elf_Addr addr,Elf_Word size)121*795d594fSAndroid Build Coastguard Worker     void AllocateVirtualMemory(Elf_Addr addr, Elf_Word size) {
122*795d594fSAndroid Build Coastguard Worker       CHECK_NE(header_.sh_flags & SHF_ALLOC, 0u);
123*795d594fSAndroid Build Coastguard Worker       Elf_Word align = AddSection();
124*795d594fSAndroid Build Coastguard Worker       CHECK_EQ(header_.sh_addr, 0u);
125*795d594fSAndroid Build Coastguard Worker       header_.sh_addr = RoundUp(addr, align);
126*795d594fSAndroid Build Coastguard Worker       CHECK(header_.sh_size == 0u || header_.sh_size == size);
127*795d594fSAndroid Build Coastguard Worker       header_.sh_size = size;
128*795d594fSAndroid Build Coastguard Worker       CHECK_LE(owner_->virtual_address_, header_.sh_addr);
129*795d594fSAndroid Build Coastguard Worker       owner_->virtual_address_ = header_.sh_addr + header_.sh_size;
130*795d594fSAndroid Build Coastguard Worker     }
131*795d594fSAndroid Build Coastguard Worker 
132*795d594fSAndroid Build Coastguard Worker     // Start writing file data of this section.
Start()133*795d594fSAndroid Build Coastguard Worker     virtual void Start() {
134*795d594fSAndroid Build Coastguard Worker       CHECK(owner_->current_section_ == nullptr);
135*795d594fSAndroid Build Coastguard Worker       Elf_Word align = AddSection();
136*795d594fSAndroid Build Coastguard Worker       CHECK_EQ(header_.sh_offset, 0u);
137*795d594fSAndroid Build Coastguard Worker       header_.sh_offset = owner_->AlignFileOffset(align);
138*795d594fSAndroid Build Coastguard Worker       owner_->current_section_ = this;
139*795d594fSAndroid Build Coastguard Worker     }
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker     // Finish writing file data of this section.
End()142*795d594fSAndroid Build Coastguard Worker     virtual void End() {
143*795d594fSAndroid Build Coastguard Worker       CHECK(owner_->current_section_ == this);
144*795d594fSAndroid Build Coastguard Worker       Elf_Word position = GetPosition();
145*795d594fSAndroid Build Coastguard Worker       CHECK(header_.sh_size == 0u || header_.sh_size == position);
146*795d594fSAndroid Build Coastguard Worker       header_.sh_size = position;
147*795d594fSAndroid Build Coastguard Worker       owner_->current_section_ = nullptr;
148*795d594fSAndroid Build Coastguard Worker     }
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker     // Get the number of bytes written so far.
151*795d594fSAndroid Build Coastguard Worker     // Only valid while writing the section.
GetPosition()152*795d594fSAndroid Build Coastguard Worker     Elf_Word GetPosition() const {
153*795d594fSAndroid Build Coastguard Worker       CHECK(owner_->current_section_ == this);
154*795d594fSAndroid Build Coastguard Worker       off_t file_offset = owner_->stream_.Seek(0, kSeekCurrent);
155*795d594fSAndroid Build Coastguard Worker       DCHECK_GE(file_offset, (off_t)header_.sh_offset);
156*795d594fSAndroid Build Coastguard Worker       return file_offset - header_.sh_offset;
157*795d594fSAndroid Build Coastguard Worker     }
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker     // Get the location of this section in virtual memory.
GetAddress()160*795d594fSAndroid Build Coastguard Worker     Elf_Addr GetAddress() const {
161*795d594fSAndroid Build Coastguard Worker       DCHECK_NE(header_.sh_flags & SHF_ALLOC, 0u);
162*795d594fSAndroid Build Coastguard Worker       DCHECK_NE(header_.sh_addr, 0u);
163*795d594fSAndroid Build Coastguard Worker       return header_.sh_addr;
164*795d594fSAndroid Build Coastguard Worker     }
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker     // This function always succeeds to simplify code.
167*795d594fSAndroid Build Coastguard Worker     // Use builder's Good() to check the actual status.
WriteFully(const void * buffer,size_t byte_count)168*795d594fSAndroid Build Coastguard Worker     bool WriteFully(const void* buffer, size_t byte_count) override {
169*795d594fSAndroid Build Coastguard Worker       CHECK(owner_->current_section_ == this);
170*795d594fSAndroid Build Coastguard Worker       return owner_->stream_.WriteFully(buffer, byte_count);
171*795d594fSAndroid Build Coastguard Worker     }
172*795d594fSAndroid Build Coastguard Worker 
173*795d594fSAndroid Build Coastguard Worker     // This function always succeeds to simplify code.
174*795d594fSAndroid Build Coastguard Worker     // Use builder's Good() to check the actual status.
Seek(off_t offset,Whence whence)175*795d594fSAndroid Build Coastguard Worker     off_t Seek(off_t offset, Whence whence) override {
176*795d594fSAndroid Build Coastguard Worker       // Forward the seek as-is and trust the caller to use it reasonably.
177*795d594fSAndroid Build Coastguard Worker       return owner_->stream_.Seek(offset, whence);
178*795d594fSAndroid Build Coastguard Worker     }
179*795d594fSAndroid Build Coastguard Worker 
180*795d594fSAndroid Build Coastguard Worker     // This function flushes the output and returns whether it succeeded.
181*795d594fSAndroid Build Coastguard Worker     // If there was a previous failure, this does nothing and returns false, i.e. failed.
Flush()182*795d594fSAndroid Build Coastguard Worker     bool Flush() override {
183*795d594fSAndroid Build Coastguard Worker       return owner_->stream_.Flush();
184*795d594fSAndroid Build Coastguard Worker     }
185*795d594fSAndroid Build Coastguard Worker 
GetSectionIndex()186*795d594fSAndroid Build Coastguard Worker     Elf_Word GetSectionIndex() const {
187*795d594fSAndroid Build Coastguard Worker       DCHECK_NE(section_index_, 0u);
188*795d594fSAndroid Build Coastguard Worker       return section_index_;
189*795d594fSAndroid Build Coastguard Worker     }
190*795d594fSAndroid Build Coastguard Worker 
191*795d594fSAndroid Build Coastguard Worker     // Returns true if this section has been added.
Exists()192*795d594fSAndroid Build Coastguard Worker     bool Exists() const {
193*795d594fSAndroid Build Coastguard Worker       return section_index_ != 0;
194*795d594fSAndroid Build Coastguard Worker     }
195*795d594fSAndroid Build Coastguard Worker 
196*795d594fSAndroid Build Coastguard Worker    protected:
197*795d594fSAndroid Build Coastguard Worker     // Add this section to the list of generated ELF sections (if not there already).
198*795d594fSAndroid Build Coastguard Worker     // It also ensures the alignment is sufficient to generate valid program headers,
199*795d594fSAndroid Build Coastguard Worker     // since that depends on the previous section. It returns the required alignment.
AddSection()200*795d594fSAndroid Build Coastguard Worker     Elf_Word AddSection() {
201*795d594fSAndroid Build Coastguard Worker       if (section_index_ == 0) {
202*795d594fSAndroid Build Coastguard Worker         std::vector<Section*>& sections = owner_->sections_;
203*795d594fSAndroid Build Coastguard Worker         Elf_Word last = sections.empty() ? PF_R : sections.back()->phdr_flags_;
204*795d594fSAndroid Build Coastguard Worker         if (phdr_flags_ != last) {
205*795d594fSAndroid Build Coastguard Worker           header_.sh_addralign = kElfSegmentAlignment;  // Page-align if R/W/X flags changed.
206*795d594fSAndroid Build Coastguard Worker         }
207*795d594fSAndroid Build Coastguard Worker         sections.push_back(this);
208*795d594fSAndroid Build Coastguard Worker         section_index_ = sections.size();  // First ELF section has index 1.
209*795d594fSAndroid Build Coastguard Worker       }
210*795d594fSAndroid Build Coastguard Worker       return owner_->write_program_headers_ ? header_.sh_addralign : 1;
211*795d594fSAndroid Build Coastguard Worker     }
212*795d594fSAndroid Build Coastguard Worker 
213*795d594fSAndroid Build Coastguard Worker     ElfBuilder<ElfTypes>* owner_;
214*795d594fSAndroid Build Coastguard Worker     Elf_Shdr header_;
215*795d594fSAndroid Build Coastguard Worker     Elf_Word section_index_;
216*795d594fSAndroid Build Coastguard Worker     const std::string name_;
217*795d594fSAndroid Build Coastguard Worker     const Section* const link_;
218*795d594fSAndroid Build Coastguard Worker     Elf_Word phdr_flags_;
219*795d594fSAndroid Build Coastguard Worker     Elf_Word phdr_type_;
220*795d594fSAndroid Build Coastguard Worker 
221*795d594fSAndroid Build Coastguard Worker     friend class ElfBuilder;
222*795d594fSAndroid Build Coastguard Worker 
223*795d594fSAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(Section);
224*795d594fSAndroid Build Coastguard Worker   };
225*795d594fSAndroid Build Coastguard Worker 
226*795d594fSAndroid Build Coastguard Worker   class CachedSection : public Section {
227*795d594fSAndroid Build Coastguard Worker    public:
CachedSection(ElfBuilder<ElfTypes> * owner,const std::string & name,Elf_Word type,Elf_Word flags,const Section * link,Elf_Word info,Elf_Word align,Elf_Word entsize)228*795d594fSAndroid Build Coastguard Worker     CachedSection(ElfBuilder<ElfTypes>* owner,
229*795d594fSAndroid Build Coastguard Worker                   const std::string& name,
230*795d594fSAndroid Build Coastguard Worker                   Elf_Word type,
231*795d594fSAndroid Build Coastguard Worker                   Elf_Word flags,
232*795d594fSAndroid Build Coastguard Worker                   const Section* link,
233*795d594fSAndroid Build Coastguard Worker                   Elf_Word info,
234*795d594fSAndroid Build Coastguard Worker                   Elf_Word align,
235*795d594fSAndroid Build Coastguard Worker                   Elf_Word entsize)
236*795d594fSAndroid Build Coastguard Worker         : Section(owner, name, type, flags, link, info, align, entsize), cache_() { }
237*795d594fSAndroid Build Coastguard Worker 
Add(const void * data,size_t length)238*795d594fSAndroid Build Coastguard Worker     Elf_Word Add(const void* data, size_t length) {
239*795d594fSAndroid Build Coastguard Worker       Elf_Word offset = cache_.size();
240*795d594fSAndroid Build Coastguard Worker       const uint8_t* d = reinterpret_cast<const uint8_t*>(data);
241*795d594fSAndroid Build Coastguard Worker       cache_.insert(cache_.end(), d, d + length);
242*795d594fSAndroid Build Coastguard Worker       return offset;
243*795d594fSAndroid Build Coastguard Worker     }
244*795d594fSAndroid Build Coastguard Worker 
GetCacheSize()245*795d594fSAndroid Build Coastguard Worker     Elf_Word GetCacheSize() {
246*795d594fSAndroid Build Coastguard Worker       return cache_.size();
247*795d594fSAndroid Build Coastguard Worker     }
248*795d594fSAndroid Build Coastguard Worker 
Write()249*795d594fSAndroid Build Coastguard Worker     void Write() {
250*795d594fSAndroid Build Coastguard Worker       this->WriteFully(cache_.data(), cache_.size());
251*795d594fSAndroid Build Coastguard Worker       cache_.clear();
252*795d594fSAndroid Build Coastguard Worker       cache_.shrink_to_fit();
253*795d594fSAndroid Build Coastguard Worker     }
254*795d594fSAndroid Build Coastguard Worker 
WriteCachedSection()255*795d594fSAndroid Build Coastguard Worker     void WriteCachedSection() {
256*795d594fSAndroid Build Coastguard Worker       this->Start();
257*795d594fSAndroid Build Coastguard Worker       Write();
258*795d594fSAndroid Build Coastguard Worker       this->End();
259*795d594fSAndroid Build Coastguard Worker     }
260*795d594fSAndroid Build Coastguard Worker 
261*795d594fSAndroid Build Coastguard Worker    private:
262*795d594fSAndroid Build Coastguard Worker     std::vector<uint8_t> cache_;
263*795d594fSAndroid Build Coastguard Worker   };
264*795d594fSAndroid Build Coastguard Worker 
265*795d594fSAndroid Build Coastguard Worker   // Writer of .dynstr section.
266*795d594fSAndroid Build Coastguard Worker   class CachedStringSection final : public CachedSection {
267*795d594fSAndroid Build Coastguard Worker    public:
CachedStringSection(ElfBuilder<ElfTypes> * owner,const std::string & name,Elf_Word flags,Elf_Word align)268*795d594fSAndroid Build Coastguard Worker     CachedStringSection(ElfBuilder<ElfTypes>* owner,
269*795d594fSAndroid Build Coastguard Worker                         const std::string& name,
270*795d594fSAndroid Build Coastguard Worker                         Elf_Word flags,
271*795d594fSAndroid Build Coastguard Worker                         Elf_Word align)
272*795d594fSAndroid Build Coastguard Worker         : CachedSection(owner,
273*795d594fSAndroid Build Coastguard Worker                         name,
274*795d594fSAndroid Build Coastguard Worker                         SHT_STRTAB,
275*795d594fSAndroid Build Coastguard Worker                         flags,
276*795d594fSAndroid Build Coastguard Worker                         /* link= */ nullptr,
277*795d594fSAndroid Build Coastguard Worker                         /* info= */ 0,
278*795d594fSAndroid Build Coastguard Worker                         align,
279*795d594fSAndroid Build Coastguard Worker                         /* entsize= */ 0) { }
280*795d594fSAndroid Build Coastguard Worker 
Add(const std::string & name)281*795d594fSAndroid Build Coastguard Worker     Elf_Word Add(const std::string& name) {
282*795d594fSAndroid Build Coastguard Worker       if (CachedSection::GetCacheSize() == 0u) {
283*795d594fSAndroid Build Coastguard Worker         DCHECK(name.empty());
284*795d594fSAndroid Build Coastguard Worker       }
285*795d594fSAndroid Build Coastguard Worker       return CachedSection::Add(name.c_str(), name.length() + 1);
286*795d594fSAndroid Build Coastguard Worker     }
287*795d594fSAndroid Build Coastguard Worker   };
288*795d594fSAndroid Build Coastguard Worker 
289*795d594fSAndroid Build Coastguard Worker   // Writer of .strtab and .shstrtab sections.
290*795d594fSAndroid Build Coastguard Worker   class StringSection final : public Section {
291*795d594fSAndroid Build Coastguard Worker    public:
StringSection(ElfBuilder<ElfTypes> * owner,const std::string & name,Elf_Word flags,Elf_Word align)292*795d594fSAndroid Build Coastguard Worker     StringSection(ElfBuilder<ElfTypes>* owner,
293*795d594fSAndroid Build Coastguard Worker                   const std::string& name,
294*795d594fSAndroid Build Coastguard Worker                   Elf_Word flags,
295*795d594fSAndroid Build Coastguard Worker                   Elf_Word align)
296*795d594fSAndroid Build Coastguard Worker         : Section(owner,
297*795d594fSAndroid Build Coastguard Worker                   name,
298*795d594fSAndroid Build Coastguard Worker                   SHT_STRTAB,
299*795d594fSAndroid Build Coastguard Worker                   flags,
300*795d594fSAndroid Build Coastguard Worker                   /* link= */ nullptr,
301*795d594fSAndroid Build Coastguard Worker                   /* info= */ 0,
302*795d594fSAndroid Build Coastguard Worker                   align,
303*795d594fSAndroid Build Coastguard Worker                   /* entsize= */ 0) {
304*795d594fSAndroid Build Coastguard Worker       Reset();
305*795d594fSAndroid Build Coastguard Worker     }
306*795d594fSAndroid Build Coastguard Worker 
Reset()307*795d594fSAndroid Build Coastguard Worker     void Reset() {
308*795d594fSAndroid Build Coastguard Worker       current_offset_ = 0;
309*795d594fSAndroid Build Coastguard Worker       last_name_ = "";
310*795d594fSAndroid Build Coastguard Worker       last_offset_ = 0;
311*795d594fSAndroid Build Coastguard Worker     }
312*795d594fSAndroid Build Coastguard Worker 
Start()313*795d594fSAndroid Build Coastguard Worker     void Start() {
314*795d594fSAndroid Build Coastguard Worker       Section::Start();
315*795d594fSAndroid Build Coastguard Worker       Write("");  // ELF specification requires that the section starts with empty string.
316*795d594fSAndroid Build Coastguard Worker     }
317*795d594fSAndroid Build Coastguard Worker 
Write(std::string_view name)318*795d594fSAndroid Build Coastguard Worker     Elf_Word Write(std::string_view name) {
319*795d594fSAndroid Build Coastguard Worker       if (current_offset_ == 0) {
320*795d594fSAndroid Build Coastguard Worker         DCHECK(name.empty());
321*795d594fSAndroid Build Coastguard Worker       } else if (name == last_name_) {
322*795d594fSAndroid Build Coastguard Worker         return last_offset_;  // Very simple string de-duplication.
323*795d594fSAndroid Build Coastguard Worker       }
324*795d594fSAndroid Build Coastguard Worker       last_name_ = name;
325*795d594fSAndroid Build Coastguard Worker       last_offset_ = current_offset_;
326*795d594fSAndroid Build Coastguard Worker       this->WriteFully(name.data(), name.length());
327*795d594fSAndroid Build Coastguard Worker       char null_terminator = '\0';
328*795d594fSAndroid Build Coastguard Worker       this->WriteFully(&null_terminator, sizeof(null_terminator));
329*795d594fSAndroid Build Coastguard Worker       current_offset_ += name.length() + 1;
330*795d594fSAndroid Build Coastguard Worker       return last_offset_;
331*795d594fSAndroid Build Coastguard Worker     }
332*795d594fSAndroid Build Coastguard Worker 
333*795d594fSAndroid Build Coastguard Worker    private:
334*795d594fSAndroid Build Coastguard Worker     Elf_Word current_offset_;
335*795d594fSAndroid Build Coastguard Worker     std::string last_name_;
336*795d594fSAndroid Build Coastguard Worker     Elf_Word last_offset_;
337*795d594fSAndroid Build Coastguard Worker   };
338*795d594fSAndroid Build Coastguard Worker 
339*795d594fSAndroid Build Coastguard Worker   // Writer of .dynsym and .symtab sections.
340*795d594fSAndroid Build Coastguard Worker   class SymbolSection final : public Section {
341*795d594fSAndroid Build Coastguard Worker    public:
SymbolSection(ElfBuilder<ElfTypes> * owner,const std::string & name,Elf_Word type,Elf_Word flags,Section * strtab)342*795d594fSAndroid Build Coastguard Worker     SymbolSection(ElfBuilder<ElfTypes>* owner,
343*795d594fSAndroid Build Coastguard Worker                   const std::string& name,
344*795d594fSAndroid Build Coastguard Worker                   Elf_Word type,
345*795d594fSAndroid Build Coastguard Worker                   Elf_Word flags,
346*795d594fSAndroid Build Coastguard Worker                   Section* strtab)
347*795d594fSAndroid Build Coastguard Worker         : Section(owner,
348*795d594fSAndroid Build Coastguard Worker                   name,
349*795d594fSAndroid Build Coastguard Worker                   type,
350*795d594fSAndroid Build Coastguard Worker                   flags,
351*795d594fSAndroid Build Coastguard Worker                   strtab,
352*795d594fSAndroid Build Coastguard Worker                   /* info= */ 1,
353*795d594fSAndroid Build Coastguard Worker                   sizeof(Elf_Off),
354*795d594fSAndroid Build Coastguard Worker                   sizeof(Elf_Sym)) {
355*795d594fSAndroid Build Coastguard Worker       syms_.push_back(Elf_Sym());  // The symbol table always has to start with NULL symbol.
356*795d594fSAndroid Build Coastguard Worker     }
357*795d594fSAndroid Build Coastguard Worker 
358*795d594fSAndroid Build Coastguard Worker     // Buffer symbol for this section.  It will be written later.
Add(Elf_Word name,const Section * section,Elf_Addr addr,Elf_Word size,uint8_t binding,uint8_t type)359*795d594fSAndroid Build Coastguard Worker     void Add(Elf_Word name,
360*795d594fSAndroid Build Coastguard Worker              const Section* section,
361*795d594fSAndroid Build Coastguard Worker              Elf_Addr addr,
362*795d594fSAndroid Build Coastguard Worker              Elf_Word size,
363*795d594fSAndroid Build Coastguard Worker              uint8_t binding,
364*795d594fSAndroid Build Coastguard Worker              uint8_t type) {
365*795d594fSAndroid Build Coastguard Worker       Elf_Sym sym = Elf_Sym();
366*795d594fSAndroid Build Coastguard Worker       sym.st_name = name;
367*795d594fSAndroid Build Coastguard Worker       sym.st_value = addr;
368*795d594fSAndroid Build Coastguard Worker       sym.st_size = size;
369*795d594fSAndroid Build Coastguard Worker       sym.st_other = 0;
370*795d594fSAndroid Build Coastguard Worker       sym.st_info = (binding << 4) + (type & 0xf);
371*795d594fSAndroid Build Coastguard Worker       Add(sym, section);
372*795d594fSAndroid Build Coastguard Worker     }
373*795d594fSAndroid Build Coastguard Worker 
374*795d594fSAndroid Build Coastguard Worker     // Buffer symbol for this section.  It will be written later.
Add(Elf_Sym sym,const Section * section)375*795d594fSAndroid Build Coastguard Worker     void Add(Elf_Sym sym, const Section* section) {
376*795d594fSAndroid Build Coastguard Worker       if (section != nullptr) {
377*795d594fSAndroid Build Coastguard Worker         DCHECK_LE(section->GetAddress(), sym.st_value);
378*795d594fSAndroid Build Coastguard Worker         DCHECK_LE(sym.st_value, section->GetAddress() + section->header_.sh_size);
379*795d594fSAndroid Build Coastguard Worker         sym.st_shndx = section->GetSectionIndex();
380*795d594fSAndroid Build Coastguard Worker       } else {
381*795d594fSAndroid Build Coastguard Worker         sym.st_shndx = SHN_UNDEF;
382*795d594fSAndroid Build Coastguard Worker       }
383*795d594fSAndroid Build Coastguard Worker       syms_.push_back(sym);
384*795d594fSAndroid Build Coastguard Worker     }
385*795d594fSAndroid Build Coastguard Worker 
GetCacheSize()386*795d594fSAndroid Build Coastguard Worker     Elf_Word GetCacheSize() { return syms_.size() * sizeof(Elf_Sym); }
387*795d594fSAndroid Build Coastguard Worker 
WriteCachedSection()388*795d594fSAndroid Build Coastguard Worker     void WriteCachedSection() {
389*795d594fSAndroid Build Coastguard Worker       auto is_local = [](const Elf_Sym& sym) { return ELF_ST_BIND(sym.st_info) == STB_LOCAL; };
390*795d594fSAndroid Build Coastguard Worker       auto less_then = [is_local](const Elf_Sym& a, const Elf_Sym b) {
391*795d594fSAndroid Build Coastguard Worker         auto tuple_a = std::make_tuple(!is_local(a), a.st_value, a.st_name);
392*795d594fSAndroid Build Coastguard Worker         auto tuple_b = std::make_tuple(!is_local(b), b.st_value, b.st_name);
393*795d594fSAndroid Build Coastguard Worker         return tuple_a < tuple_b;  // Locals first, then sort by address and name offset.
394*795d594fSAndroid Build Coastguard Worker       };
395*795d594fSAndroid Build Coastguard Worker       if (!std::is_sorted(syms_.begin(), syms_.end(), less_then)) {
396*795d594fSAndroid Build Coastguard Worker         std::sort(syms_.begin(), syms_.end(), less_then);
397*795d594fSAndroid Build Coastguard Worker       }
398*795d594fSAndroid Build Coastguard Worker       auto locals_end = std::partition_point(syms_.begin(), syms_.end(), is_local);
399*795d594fSAndroid Build Coastguard Worker       this->header_.sh_info = locals_end - syms_.begin();  // Required by the spec.
400*795d594fSAndroid Build Coastguard Worker 
401*795d594fSAndroid Build Coastguard Worker       this->Start();
402*795d594fSAndroid Build Coastguard Worker       for (; !syms_.empty(); syms_.pop_front()) {
403*795d594fSAndroid Build Coastguard Worker         this->WriteFully(&syms_.front(), sizeof(Elf_Sym));
404*795d594fSAndroid Build Coastguard Worker       }
405*795d594fSAndroid Build Coastguard Worker       this->End();
406*795d594fSAndroid Build Coastguard Worker     }
407*795d594fSAndroid Build Coastguard Worker 
408*795d594fSAndroid Build Coastguard Worker    private:
409*795d594fSAndroid Build Coastguard Worker     std::deque<Elf_Sym> syms_;  // Buffered/cached content of the whole section.
410*795d594fSAndroid Build Coastguard Worker   };
411*795d594fSAndroid Build Coastguard Worker 
412*795d594fSAndroid Build Coastguard Worker   class BuildIdSection final : public Section {
413*795d594fSAndroid Build Coastguard Worker    public:
BuildIdSection(ElfBuilder<ElfTypes> * owner,const std::string & name,Elf_Word type,Elf_Word flags,const Section * link,Elf_Word info,Elf_Word align,Elf_Word entsize)414*795d594fSAndroid Build Coastguard Worker     BuildIdSection(ElfBuilder<ElfTypes>* owner,
415*795d594fSAndroid Build Coastguard Worker                    const std::string& name,
416*795d594fSAndroid Build Coastguard Worker                    Elf_Word type,
417*795d594fSAndroid Build Coastguard Worker                    Elf_Word flags,
418*795d594fSAndroid Build Coastguard Worker                    const Section* link,
419*795d594fSAndroid Build Coastguard Worker                    Elf_Word info,
420*795d594fSAndroid Build Coastguard Worker                    Elf_Word align,
421*795d594fSAndroid Build Coastguard Worker                    Elf_Word entsize)
422*795d594fSAndroid Build Coastguard Worker         : Section(owner, name, type, flags, link, info, align, entsize),
423*795d594fSAndroid Build Coastguard Worker           digest_start_(-1) {
424*795d594fSAndroid Build Coastguard Worker     }
425*795d594fSAndroid Build Coastguard Worker 
GetSize()426*795d594fSAndroid Build Coastguard Worker     Elf_Word GetSize() {
427*795d594fSAndroid Build Coastguard Worker       return 16 + kBuildIdLen;
428*795d594fSAndroid Build Coastguard Worker     }
429*795d594fSAndroid Build Coastguard Worker 
Write()430*795d594fSAndroid Build Coastguard Worker     void Write() {
431*795d594fSAndroid Build Coastguard Worker       // The size fields are 32-bit on both 32-bit and 64-bit systems, confirmed
432*795d594fSAndroid Build Coastguard Worker       // with the 64-bit linker and libbfd code. The size of name and desc must
433*795d594fSAndroid Build Coastguard Worker       // be a multiple of 4 and it currently is.
434*795d594fSAndroid Build Coastguard Worker       this->WriteUint32(4);  // namesz.
435*795d594fSAndroid Build Coastguard Worker       this->WriteUint32(kBuildIdLen);  // descsz.
436*795d594fSAndroid Build Coastguard Worker       this->WriteUint32(3);  // type = NT_GNU_BUILD_ID.
437*795d594fSAndroid Build Coastguard Worker       this->WriteFully("GNU", 4);  // name.
438*795d594fSAndroid Build Coastguard Worker       digest_start_ = this->Seek(0, kSeekCurrent);
439*795d594fSAndroid Build Coastguard Worker       static_assert(kBuildIdLen % 4 == 0, "expecting a mutliple of 4 for build ID length");
440*795d594fSAndroid Build Coastguard Worker       this->WriteFully(std::string(kBuildIdLen, '\0').c_str(), kBuildIdLen);  // desc.
441*795d594fSAndroid Build Coastguard Worker       DCHECK_EQ(this->GetPosition(), GetSize());
442*795d594fSAndroid Build Coastguard Worker     }
443*795d594fSAndroid Build Coastguard Worker 
GetDigestStart()444*795d594fSAndroid Build Coastguard Worker     off_t GetDigestStart() {
445*795d594fSAndroid Build Coastguard Worker       CHECK_GT(digest_start_, 0);
446*795d594fSAndroid Build Coastguard Worker       return digest_start_;
447*795d594fSAndroid Build Coastguard Worker     }
448*795d594fSAndroid Build Coastguard Worker 
449*795d594fSAndroid Build Coastguard Worker    private:
WriteUint32(uint32_t v)450*795d594fSAndroid Build Coastguard Worker     bool WriteUint32(uint32_t v) {
451*795d594fSAndroid Build Coastguard Worker       return this->WriteFully(&v, sizeof(v));
452*795d594fSAndroid Build Coastguard Worker     }
453*795d594fSAndroid Build Coastguard Worker 
454*795d594fSAndroid Build Coastguard Worker     // File offset where the build ID digest starts.
455*795d594fSAndroid Build Coastguard Worker     // Populated with zeros first, then updated with the actual value as the
456*795d594fSAndroid Build Coastguard Worker     // very last thing in the output file creation.
457*795d594fSAndroid Build Coastguard Worker     off_t digest_start_;
458*795d594fSAndroid Build Coastguard Worker   };
459*795d594fSAndroid Build Coastguard Worker 
ElfBuilder(InstructionSet isa,OutputStream * output)460*795d594fSAndroid Build Coastguard Worker   ElfBuilder(InstructionSet isa, OutputStream* output)
461*795d594fSAndroid Build Coastguard Worker       : isa_(isa),
462*795d594fSAndroid Build Coastguard Worker         stream_(output),
463*795d594fSAndroid Build Coastguard Worker         rodata_(this, ".rodata", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, kElfSegmentAlignment, 0),
464*795d594fSAndroid Build Coastguard Worker         text_(this, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, nullptr, 0,
465*795d594fSAndroid Build Coastguard Worker             kElfSegmentAlignment, 0),
466*795d594fSAndroid Build Coastguard Worker         data_img_rel_ro_(this, ".data.img.rel.ro", SHT_PROGBITS, SHF_ALLOC, nullptr, 0,
467*795d594fSAndroid Build Coastguard Worker             kElfSegmentAlignment, 0),
468*795d594fSAndroid Build Coastguard Worker         bss_(this, ".bss", SHT_NOBITS, SHF_ALLOC, nullptr, 0, kElfSegmentAlignment, 0),
469*795d594fSAndroid Build Coastguard Worker         dex_(this, ".dex", SHT_NOBITS, SHF_ALLOC, nullptr, 0, kElfSegmentAlignment, 0),
470*795d594fSAndroid Build Coastguard Worker         dynstr_(this, ".dynstr", SHF_ALLOC, kElfSegmentAlignment),
471*795d594fSAndroid Build Coastguard Worker         dynsym_(this, ".dynsym", SHT_DYNSYM, SHF_ALLOC, &dynstr_),
472*795d594fSAndroid Build Coastguard Worker         hash_(this, ".hash", SHT_HASH, SHF_ALLOC, &dynsym_, 0, sizeof(Elf_Word), sizeof(Elf_Word)),
473*795d594fSAndroid Build Coastguard Worker         dynamic_(this, ".dynamic", SHT_DYNAMIC, SHF_ALLOC, &dynstr_, 0, kElfSegmentAlignment,
474*795d594fSAndroid Build Coastguard Worker             sizeof(Elf_Dyn)),
475*795d594fSAndroid Build Coastguard Worker         strtab_(this, ".strtab", 0, 1),
476*795d594fSAndroid Build Coastguard Worker         symtab_(this, ".symtab", SHT_SYMTAB, 0, &strtab_),
477*795d594fSAndroid Build Coastguard Worker         debug_frame_(this, ".debug_frame", SHT_PROGBITS, 0, nullptr, 0, sizeof(Elf_Addr), 0),
478*795d594fSAndroid Build Coastguard Worker         debug_frame_hdr_(
479*795d594fSAndroid Build Coastguard Worker             this, ".debug_frame_hdr.android", SHT_PROGBITS, 0, nullptr, 0, sizeof(Elf_Addr), 0),
480*795d594fSAndroid Build Coastguard Worker         debug_info_(this, ".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0),
481*795d594fSAndroid Build Coastguard Worker         debug_line_(this, ".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0),
482*795d594fSAndroid Build Coastguard Worker         shstrtab_(this, ".shstrtab", 0, 1),
483*795d594fSAndroid Build Coastguard Worker         build_id_(this, ".note.gnu.build-id", SHT_NOTE, SHF_ALLOC, nullptr, 0, 4, 0),
484*795d594fSAndroid Build Coastguard Worker         current_section_(nullptr),
485*795d594fSAndroid Build Coastguard Worker         started_(false),
486*795d594fSAndroid Build Coastguard Worker         finished_(false),
487*795d594fSAndroid Build Coastguard Worker         write_program_headers_(false),
488*795d594fSAndroid Build Coastguard Worker         loaded_size_(0u),
489*795d594fSAndroid Build Coastguard Worker         virtual_address_(0) {
490*795d594fSAndroid Build Coastguard Worker     text_.phdr_flags_ = PF_R | PF_X;
491*795d594fSAndroid Build Coastguard Worker     data_img_rel_ro_.phdr_flags_ = PF_R | PF_W;  // Shall be made read-only at run time.
492*795d594fSAndroid Build Coastguard Worker     bss_.phdr_flags_ = PF_R | PF_W;
493*795d594fSAndroid Build Coastguard Worker     dex_.phdr_flags_ = PF_R;
494*795d594fSAndroid Build Coastguard Worker     dynamic_.phdr_flags_ = PF_R | PF_W;
495*795d594fSAndroid Build Coastguard Worker     dynamic_.phdr_type_ = PT_DYNAMIC;
496*795d594fSAndroid Build Coastguard Worker     build_id_.phdr_type_ = PT_NOTE;
497*795d594fSAndroid Build Coastguard Worker   }
~ElfBuilder()498*795d594fSAndroid Build Coastguard Worker   ~ElfBuilder() {}
499*795d594fSAndroid Build Coastguard Worker 
GetIsa()500*795d594fSAndroid Build Coastguard Worker   InstructionSet GetIsa() { return isa_; }
GetBuildId()501*795d594fSAndroid Build Coastguard Worker   BuildIdSection* GetBuildId() { return &build_id_; }
GetRoData()502*795d594fSAndroid Build Coastguard Worker   Section* GetRoData() { return &rodata_; }
GetText()503*795d594fSAndroid Build Coastguard Worker   Section* GetText() { return &text_; }
GetDataImgRelRo()504*795d594fSAndroid Build Coastguard Worker   Section* GetDataImgRelRo() { return &data_img_rel_ro_; }
GetBss()505*795d594fSAndroid Build Coastguard Worker   Section* GetBss() { return &bss_; }
GetDex()506*795d594fSAndroid Build Coastguard Worker   Section* GetDex() { return &dex_; }
GetStrTab()507*795d594fSAndroid Build Coastguard Worker   StringSection* GetStrTab() { return &strtab_; }
GetSymTab()508*795d594fSAndroid Build Coastguard Worker   SymbolSection* GetSymTab() { return &symtab_; }
GetDebugFrame()509*795d594fSAndroid Build Coastguard Worker   Section* GetDebugFrame() { return &debug_frame_; }
GetDebugFrameHdr()510*795d594fSAndroid Build Coastguard Worker   Section* GetDebugFrameHdr() { return &debug_frame_hdr_; }
GetDebugInfo()511*795d594fSAndroid Build Coastguard Worker   Section* GetDebugInfo() { return &debug_info_; }
GetDebugLine()512*795d594fSAndroid Build Coastguard Worker   Section* GetDebugLine() { return &debug_line_; }
513*795d594fSAndroid Build Coastguard Worker 
WriteSection(const char * name,const std::vector<uint8_t> * buffer)514*795d594fSAndroid Build Coastguard Worker   void WriteSection(const char* name, const std::vector<uint8_t>* buffer) {
515*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<Section> s(new Section(this, name, SHT_PROGBITS, 0, nullptr, 0, 1, 0));
516*795d594fSAndroid Build Coastguard Worker     s->Start();
517*795d594fSAndroid Build Coastguard Worker     s->WriteFully(buffer->data(), buffer->size());
518*795d594fSAndroid Build Coastguard Worker     s->End();
519*795d594fSAndroid Build Coastguard Worker     other_sections_.push_back(std::move(s));
520*795d594fSAndroid Build Coastguard Worker   }
521*795d594fSAndroid Build Coastguard Worker 
522*795d594fSAndroid Build Coastguard Worker   // Reserve space for ELF header and program headers.
523*795d594fSAndroid Build Coastguard Worker   // We do not know the number of headers until later, so
524*795d594fSAndroid Build Coastguard Worker   // it is easiest to just reserve a fixed amount of space.
525*795d594fSAndroid Build Coastguard Worker   // Program headers are required for loading by the linker.
526*795d594fSAndroid Build Coastguard Worker   // It is possible to omit them for ELF files used for debugging.
527*795d594fSAndroid Build Coastguard Worker   void Start(bool write_program_headers = true) {
528*795d594fSAndroid Build Coastguard Worker     int size = sizeof(Elf_Ehdr);
529*795d594fSAndroid Build Coastguard Worker     if (write_program_headers) {
530*795d594fSAndroid Build Coastguard Worker       size += sizeof(Elf_Phdr) * kMaxProgramHeaders;
531*795d594fSAndroid Build Coastguard Worker     }
532*795d594fSAndroid Build Coastguard Worker     stream_.Seek(size, kSeekSet);
533*795d594fSAndroid Build Coastguard Worker     started_ = true;
534*795d594fSAndroid Build Coastguard Worker     virtual_address_ += size;
535*795d594fSAndroid Build Coastguard Worker     write_program_headers_ = write_program_headers;
536*795d594fSAndroid Build Coastguard Worker   }
537*795d594fSAndroid Build Coastguard Worker 
End()538*795d594fSAndroid Build Coastguard Worker   off_t End() {
539*795d594fSAndroid Build Coastguard Worker     DCHECK(started_);
540*795d594fSAndroid Build Coastguard Worker     DCHECK(!finished_);
541*795d594fSAndroid Build Coastguard Worker     finished_ = true;
542*795d594fSAndroid Build Coastguard Worker 
543*795d594fSAndroid Build Coastguard Worker     // Note: loaded_size_ == 0 for tests that don't write .rodata, .text, .bss,
544*795d594fSAndroid Build Coastguard Worker     // .dynstr, dynsym, .hash and .dynamic. These tests should not read loaded_size_.
545*795d594fSAndroid Build Coastguard Worker     CHECK(loaded_size_ == 0 || loaded_size_ == RoundUp(virtual_address_, kElfSegmentAlignment))
546*795d594fSAndroid Build Coastguard Worker         << loaded_size_ << " " << virtual_address_;
547*795d594fSAndroid Build Coastguard Worker 
548*795d594fSAndroid Build Coastguard Worker     // Write section names and finish the section headers.
549*795d594fSAndroid Build Coastguard Worker     shstrtab_.Start();
550*795d594fSAndroid Build Coastguard Worker     shstrtab_.Write("");
551*795d594fSAndroid Build Coastguard Worker     for (auto* section : sections_) {
552*795d594fSAndroid Build Coastguard Worker       section->header_.sh_name = shstrtab_.Write(section->name_);
553*795d594fSAndroid Build Coastguard Worker       if (section->link_ != nullptr) {
554*795d594fSAndroid Build Coastguard Worker         section->header_.sh_link = section->link_->GetSectionIndex();
555*795d594fSAndroid Build Coastguard Worker       }
556*795d594fSAndroid Build Coastguard Worker       if (section->header_.sh_offset == 0) {
557*795d594fSAndroid Build Coastguard Worker         section->header_.sh_type = SHT_NOBITS;
558*795d594fSAndroid Build Coastguard Worker       }
559*795d594fSAndroid Build Coastguard Worker     }
560*795d594fSAndroid Build Coastguard Worker     shstrtab_.End();
561*795d594fSAndroid Build Coastguard Worker 
562*795d594fSAndroid Build Coastguard Worker     // Write section headers at the end of the ELF file.
563*795d594fSAndroid Build Coastguard Worker     std::vector<Elf_Shdr> shdrs;
564*795d594fSAndroid Build Coastguard Worker     shdrs.reserve(1u + sections_.size());
565*795d594fSAndroid Build Coastguard Worker     shdrs.push_back(Elf_Shdr());  // NULL at index 0.
566*795d594fSAndroid Build Coastguard Worker     for (auto* section : sections_) {
567*795d594fSAndroid Build Coastguard Worker       shdrs.push_back(section->header_);
568*795d594fSAndroid Build Coastguard Worker     }
569*795d594fSAndroid Build Coastguard Worker     Elf_Off section_headers_offset;
570*795d594fSAndroid Build Coastguard Worker     section_headers_offset = AlignFileOffset(sizeof(Elf_Off));
571*795d594fSAndroid Build Coastguard Worker     stream_.WriteFully(shdrs.data(), shdrs.size() * sizeof(shdrs[0]));
572*795d594fSAndroid Build Coastguard Worker     off_t file_size = stream_.Seek(0, kSeekCurrent);
573*795d594fSAndroid Build Coastguard Worker 
574*795d594fSAndroid Build Coastguard Worker     // Flush everything else before writing the program headers. This should prevent
575*795d594fSAndroid Build Coastguard Worker     // the OS from reordering writes, so that we don't end up with valid headers
576*795d594fSAndroid Build Coastguard Worker     // and partially written data if we suddenly lose power, for example.
577*795d594fSAndroid Build Coastguard Worker     stream_.Flush();
578*795d594fSAndroid Build Coastguard Worker 
579*795d594fSAndroid Build Coastguard Worker     // The main ELF header.
580*795d594fSAndroid Build Coastguard Worker     Elf_Ehdr elf_header = MakeElfHeader(isa_);
581*795d594fSAndroid Build Coastguard Worker     elf_header.e_shoff = section_headers_offset;
582*795d594fSAndroid Build Coastguard Worker     elf_header.e_shnum = shdrs.size();
583*795d594fSAndroid Build Coastguard Worker     elf_header.e_shstrndx = shstrtab_.GetSectionIndex();
584*795d594fSAndroid Build Coastguard Worker 
585*795d594fSAndroid Build Coastguard Worker     // Program headers (i.e. mmap instructions).
586*795d594fSAndroid Build Coastguard Worker     std::vector<Elf_Phdr> phdrs;
587*795d594fSAndroid Build Coastguard Worker     if (write_program_headers_) {
588*795d594fSAndroid Build Coastguard Worker       phdrs = MakeProgramHeaders();
589*795d594fSAndroid Build Coastguard Worker       CHECK_LE(phdrs.size(), kMaxProgramHeaders);
590*795d594fSAndroid Build Coastguard Worker       elf_header.e_phoff = sizeof(Elf_Ehdr);
591*795d594fSAndroid Build Coastguard Worker       elf_header.e_phnum = phdrs.size();
592*795d594fSAndroid Build Coastguard Worker     }
593*795d594fSAndroid Build Coastguard Worker 
594*795d594fSAndroid Build Coastguard Worker     stream_.Seek(0, kSeekSet);
595*795d594fSAndroid Build Coastguard Worker     stream_.WriteFully(&elf_header, sizeof(elf_header));
596*795d594fSAndroid Build Coastguard Worker     stream_.WriteFully(phdrs.data(), phdrs.size() * sizeof(phdrs[0]));
597*795d594fSAndroid Build Coastguard Worker     stream_.Flush();
598*795d594fSAndroid Build Coastguard Worker 
599*795d594fSAndroid Build Coastguard Worker     return file_size;
600*795d594fSAndroid Build Coastguard Worker   }
601*795d594fSAndroid Build Coastguard Worker 
602*795d594fSAndroid Build Coastguard Worker   // This has the same effect as running the "strip" command line tool.
603*795d594fSAndroid Build Coastguard Worker   // It removes all debugging sections (but it keeps mini-debug-info).
604*795d594fSAndroid Build Coastguard Worker   // It returns the ELF file size (as the caller needs to truncate it).
Strip()605*795d594fSAndroid Build Coastguard Worker   off_t Strip() {
606*795d594fSAndroid Build Coastguard Worker     DCHECK(finished_);
607*795d594fSAndroid Build Coastguard Worker     finished_ = false;
608*795d594fSAndroid Build Coastguard Worker     Elf_Off end = 0;
609*795d594fSAndroid Build Coastguard Worker     std::vector<Section*> non_debug_sections;
610*795d594fSAndroid Build Coastguard Worker     for (Section* section : sections_) {
611*795d594fSAndroid Build Coastguard Worker       if (section == &shstrtab_ ||  // Section names will be recreated.
612*795d594fSAndroid Build Coastguard Worker           section == &symtab_ ||
613*795d594fSAndroid Build Coastguard Worker           section == &strtab_ ||
614*795d594fSAndroid Build Coastguard Worker           section->name_.find(".debug_") == 0) {
615*795d594fSAndroid Build Coastguard Worker         section->header_.sh_offset = 0;
616*795d594fSAndroid Build Coastguard Worker         section->header_.sh_size = 0;
617*795d594fSAndroid Build Coastguard Worker         section->section_index_ = 0;
618*795d594fSAndroid Build Coastguard Worker       } else {
619*795d594fSAndroid Build Coastguard Worker         if (section->header_.sh_type != SHT_NOBITS) {
620*795d594fSAndroid Build Coastguard Worker           DCHECK_LE(section->header_.sh_offset, end + kElfSegmentAlignment)
621*795d594fSAndroid Build Coastguard Worker               << "Large gap between sections";
622*795d594fSAndroid Build Coastguard Worker           end = std::max<off_t>(end, section->header_.sh_offset + section->header_.sh_size);
623*795d594fSAndroid Build Coastguard Worker         }
624*795d594fSAndroid Build Coastguard Worker         non_debug_sections.push_back(section);
625*795d594fSAndroid Build Coastguard Worker       }
626*795d594fSAndroid Build Coastguard Worker     }
627*795d594fSAndroid Build Coastguard Worker     shstrtab_.Reset();
628*795d594fSAndroid Build Coastguard Worker     // Write the non-debug section headers, program headers, and ELF header again.
629*795d594fSAndroid Build Coastguard Worker     sections_ = std::move(non_debug_sections);
630*795d594fSAndroid Build Coastguard Worker     stream_.Seek(end, kSeekSet);
631*795d594fSAndroid Build Coastguard Worker     return End();
632*795d594fSAndroid Build Coastguard Worker   }
633*795d594fSAndroid Build Coastguard Worker 
634*795d594fSAndroid Build Coastguard Worker   // The running program does not have access to section headers
635*795d594fSAndroid Build Coastguard Worker   // and the loader is not supposed to use them either.
636*795d594fSAndroid Build Coastguard Worker   // The dynamic sections therefore replicates some of the layout
637*795d594fSAndroid Build Coastguard Worker   // information like the address and size of .rodata and .text.
638*795d594fSAndroid Build Coastguard Worker   // It also contains other metadata like the SONAME.
639*795d594fSAndroid Build Coastguard Worker   // The .dynamic section is found using the PT_DYNAMIC program header.
PrepareDynamicSection(const std::string & elf_file_path,Elf_Word rodata_size,Elf_Word text_size,Elf_Word data_img_rel_ro_size,Elf_Word data_img_rel_ro_app_image_offset,Elf_Word bss_size,Elf_Word bss_methods_offset,Elf_Word bss_roots_offset,Elf_Word dex_size)640*795d594fSAndroid Build Coastguard Worker   void PrepareDynamicSection(const std::string& elf_file_path,
641*795d594fSAndroid Build Coastguard Worker                              Elf_Word rodata_size,
642*795d594fSAndroid Build Coastguard Worker                              Elf_Word text_size,
643*795d594fSAndroid Build Coastguard Worker                              Elf_Word data_img_rel_ro_size,
644*795d594fSAndroid Build Coastguard Worker                              Elf_Word data_img_rel_ro_app_image_offset,
645*795d594fSAndroid Build Coastguard Worker                              Elf_Word bss_size,
646*795d594fSAndroid Build Coastguard Worker                              Elf_Word bss_methods_offset,
647*795d594fSAndroid Build Coastguard Worker                              Elf_Word bss_roots_offset,
648*795d594fSAndroid Build Coastguard Worker                              Elf_Word dex_size) {
649*795d594fSAndroid Build Coastguard Worker     std::string soname(elf_file_path);
650*795d594fSAndroid Build Coastguard Worker     size_t directory_separator_pos = soname.rfind('/');
651*795d594fSAndroid Build Coastguard Worker     if (directory_separator_pos != std::string::npos) {
652*795d594fSAndroid Build Coastguard Worker       soname = soname.substr(directory_separator_pos + 1);
653*795d594fSAndroid Build Coastguard Worker     }
654*795d594fSAndroid Build Coastguard Worker 
655*795d594fSAndroid Build Coastguard Worker     // Allocate all pre-dynamic sections.
656*795d594fSAndroid Build Coastguard Worker     rodata_.AllocateVirtualMemory(rodata_size);
657*795d594fSAndroid Build Coastguard Worker     text_.AllocateVirtualMemory(text_size);
658*795d594fSAndroid Build Coastguard Worker     if (data_img_rel_ro_size != 0) {
659*795d594fSAndroid Build Coastguard Worker       data_img_rel_ro_.AllocateVirtualMemory(data_img_rel_ro_size);
660*795d594fSAndroid Build Coastguard Worker     }
661*795d594fSAndroid Build Coastguard Worker     if (bss_size != 0) {
662*795d594fSAndroid Build Coastguard Worker       bss_.AllocateVirtualMemory(bss_size);
663*795d594fSAndroid Build Coastguard Worker     }
664*795d594fSAndroid Build Coastguard Worker     if (dex_size != 0) {
665*795d594fSAndroid Build Coastguard Worker       dex_.AllocateVirtualMemory(dex_size);
666*795d594fSAndroid Build Coastguard Worker     }
667*795d594fSAndroid Build Coastguard Worker 
668*795d594fSAndroid Build Coastguard Worker     // Cache .dynstr, .dynsym and .hash data.
669*795d594fSAndroid Build Coastguard Worker     dynstr_.Add("");  // dynstr should start with empty string.
670*795d594fSAndroid Build Coastguard Worker     Elf_Word oatdata = dynstr_.Add("oatdata");
671*795d594fSAndroid Build Coastguard Worker     dynsym_.Add(oatdata, &rodata_, rodata_.GetAddress(), rodata_size, STB_GLOBAL, STT_OBJECT);
672*795d594fSAndroid Build Coastguard Worker     if (text_size != 0u) {
673*795d594fSAndroid Build Coastguard Worker       // The runtime does not care about the size of this symbol (it uses the "lastword" symbol).
674*795d594fSAndroid Build Coastguard Worker       // We use size 0 (meaning "unknown size" in ELF) to prevent overlap with the debug symbols.
675*795d594fSAndroid Build Coastguard Worker       Elf_Word oatexec = dynstr_.Add("oatexec");
676*795d594fSAndroid Build Coastguard Worker       dynsym_.Add(oatexec, &text_, text_.GetAddress(), /* size= */ 0, STB_GLOBAL, STT_OBJECT);
677*795d594fSAndroid Build Coastguard Worker       Elf_Word oatlastword = dynstr_.Add("oatlastword");
678*795d594fSAndroid Build Coastguard Worker       Elf_Word oatlastword_address = text_.GetAddress() + text_size - 4;
679*795d594fSAndroid Build Coastguard Worker       dynsym_.Add(oatlastword, &text_, oatlastword_address, 4, STB_GLOBAL, STT_OBJECT);
680*795d594fSAndroid Build Coastguard Worker     } else if (rodata_size != 0) {
681*795d594fSAndroid Build Coastguard Worker       // rodata_ can be size 0 for dwarf_test.
682*795d594fSAndroid Build Coastguard Worker       Elf_Word oatlastword = dynstr_.Add("oatlastword");
683*795d594fSAndroid Build Coastguard Worker       Elf_Word oatlastword_address = rodata_.GetAddress() + rodata_size - 4;
684*795d594fSAndroid Build Coastguard Worker       dynsym_.Add(oatlastword, &rodata_, oatlastword_address, 4, STB_GLOBAL, STT_OBJECT);
685*795d594fSAndroid Build Coastguard Worker     }
686*795d594fSAndroid Build Coastguard Worker     DCHECK_LE(data_img_rel_ro_app_image_offset, data_img_rel_ro_size);
687*795d594fSAndroid Build Coastguard Worker     if (data_img_rel_ro_size != 0u) {
688*795d594fSAndroid Build Coastguard Worker       Elf_Word oatdataimgrelro = dynstr_.Add("oatdataimgrelro");
689*795d594fSAndroid Build Coastguard Worker       dynsym_.Add(oatdataimgrelro,
690*795d594fSAndroid Build Coastguard Worker                   &data_img_rel_ro_,
691*795d594fSAndroid Build Coastguard Worker                   data_img_rel_ro_.GetAddress(),
692*795d594fSAndroid Build Coastguard Worker                   data_img_rel_ro_size,
693*795d594fSAndroid Build Coastguard Worker                   STB_GLOBAL,
694*795d594fSAndroid Build Coastguard Worker                   STT_OBJECT);
695*795d594fSAndroid Build Coastguard Worker       Elf_Word oatdataimgrelrolastword = dynstr_.Add("oatdataimgrelrolastword");
696*795d594fSAndroid Build Coastguard Worker       dynsym_.Add(oatdataimgrelrolastword,
697*795d594fSAndroid Build Coastguard Worker                   &data_img_rel_ro_,
698*795d594fSAndroid Build Coastguard Worker                   data_img_rel_ro_.GetAddress() + data_img_rel_ro_size - 4,
699*795d594fSAndroid Build Coastguard Worker                   4,
700*795d594fSAndroid Build Coastguard Worker                   STB_GLOBAL,
701*795d594fSAndroid Build Coastguard Worker                   STT_OBJECT);
702*795d594fSAndroid Build Coastguard Worker       if (data_img_rel_ro_app_image_offset != data_img_rel_ro_size) {
703*795d594fSAndroid Build Coastguard Worker         Elf_Word oatdataimgrelroappimage = dynstr_.Add("oatdataimgrelroappimage");
704*795d594fSAndroid Build Coastguard Worker         dynsym_.Add(oatdataimgrelroappimage,
705*795d594fSAndroid Build Coastguard Worker                     &data_img_rel_ro_,
706*795d594fSAndroid Build Coastguard Worker                     data_img_rel_ro_.GetAddress() + data_img_rel_ro_app_image_offset,
707*795d594fSAndroid Build Coastguard Worker                     data_img_rel_ro_app_image_offset,
708*795d594fSAndroid Build Coastguard Worker                     STB_GLOBAL,
709*795d594fSAndroid Build Coastguard Worker                     STT_OBJECT);
710*795d594fSAndroid Build Coastguard Worker       }
711*795d594fSAndroid Build Coastguard Worker     }
712*795d594fSAndroid Build Coastguard Worker     DCHECK_LE(bss_roots_offset, bss_size);
713*795d594fSAndroid Build Coastguard Worker     if (bss_size != 0u) {
714*795d594fSAndroid Build Coastguard Worker       Elf_Word oatbss = dynstr_.Add("oatbss");
715*795d594fSAndroid Build Coastguard Worker       dynsym_.Add(oatbss, &bss_, bss_.GetAddress(), bss_roots_offset, STB_GLOBAL, STT_OBJECT);
716*795d594fSAndroid Build Coastguard Worker       DCHECK_LE(bss_methods_offset, bss_roots_offset);
717*795d594fSAndroid Build Coastguard Worker       DCHECK_LE(bss_roots_offset, bss_size);
718*795d594fSAndroid Build Coastguard Worker       // Add a symbol marking the start of the methods part of the .bss, if not empty.
719*795d594fSAndroid Build Coastguard Worker       if (bss_methods_offset != bss_roots_offset) {
720*795d594fSAndroid Build Coastguard Worker         Elf_Word bss_methods_address = bss_.GetAddress() + bss_methods_offset;
721*795d594fSAndroid Build Coastguard Worker         Elf_Word bss_methods_size = bss_roots_offset - bss_methods_offset;
722*795d594fSAndroid Build Coastguard Worker         Elf_Word oatbssroots = dynstr_.Add("oatbssmethods");
723*795d594fSAndroid Build Coastguard Worker         dynsym_.Add(
724*795d594fSAndroid Build Coastguard Worker             oatbssroots, &bss_, bss_methods_address, bss_methods_size, STB_GLOBAL, STT_OBJECT);
725*795d594fSAndroid Build Coastguard Worker       }
726*795d594fSAndroid Build Coastguard Worker       // Add a symbol marking the start of the GC roots part of the .bss, if not empty.
727*795d594fSAndroid Build Coastguard Worker       if (bss_roots_offset != bss_size) {
728*795d594fSAndroid Build Coastguard Worker         Elf_Word bss_roots_address = bss_.GetAddress() + bss_roots_offset;
729*795d594fSAndroid Build Coastguard Worker         Elf_Word bss_roots_size = bss_size - bss_roots_offset;
730*795d594fSAndroid Build Coastguard Worker         Elf_Word oatbssroots = dynstr_.Add("oatbssroots");
731*795d594fSAndroid Build Coastguard Worker         dynsym_.Add(
732*795d594fSAndroid Build Coastguard Worker             oatbssroots, &bss_, bss_roots_address, bss_roots_size, STB_GLOBAL, STT_OBJECT);
733*795d594fSAndroid Build Coastguard Worker       }
734*795d594fSAndroid Build Coastguard Worker       Elf_Word oatbsslastword = dynstr_.Add("oatbsslastword");
735*795d594fSAndroid Build Coastguard Worker       Elf_Word bsslastword_address = bss_.GetAddress() + bss_size - 4;
736*795d594fSAndroid Build Coastguard Worker       dynsym_.Add(oatbsslastword, &bss_, bsslastword_address, 4, STB_GLOBAL, STT_OBJECT);
737*795d594fSAndroid Build Coastguard Worker     }
738*795d594fSAndroid Build Coastguard Worker     if (dex_size != 0u) {
739*795d594fSAndroid Build Coastguard Worker       Elf_Word oatdex = dynstr_.Add("oatdex");
740*795d594fSAndroid Build Coastguard Worker       dynsym_.Add(oatdex, &dex_, dex_.GetAddress(), /* size= */ 0, STB_GLOBAL, STT_OBJECT);
741*795d594fSAndroid Build Coastguard Worker       Elf_Word oatdexlastword = dynstr_.Add("oatdexlastword");
742*795d594fSAndroid Build Coastguard Worker       Elf_Word oatdexlastword_address = dex_.GetAddress() + dex_size - 4;
743*795d594fSAndroid Build Coastguard Worker       dynsym_.Add(oatdexlastword, &dex_, oatdexlastword_address, 4, STB_GLOBAL, STT_OBJECT);
744*795d594fSAndroid Build Coastguard Worker     }
745*795d594fSAndroid Build Coastguard Worker 
746*795d594fSAndroid Build Coastguard Worker     Elf_Word soname_offset = dynstr_.Add(soname);
747*795d594fSAndroid Build Coastguard Worker 
748*795d594fSAndroid Build Coastguard Worker     // We do not really need a hash-table since there is so few entries.
749*795d594fSAndroid Build Coastguard Worker     // However, the hash-table is the only way the linker can actually
750*795d594fSAndroid Build Coastguard Worker     // determine the number of symbols in .dynsym so it is required.
751*795d594fSAndroid Build Coastguard Worker     int count = dynsym_.GetCacheSize() / sizeof(Elf_Sym);  // Includes NULL.
752*795d594fSAndroid Build Coastguard Worker     std::vector<Elf_Word> hash;
753*795d594fSAndroid Build Coastguard Worker     hash.push_back(1);  // Number of buckets.
754*795d594fSAndroid Build Coastguard Worker     hash.push_back(count);  // Number of chains.
755*795d594fSAndroid Build Coastguard Worker     // Buckets.  Having just one makes it linear search.
756*795d594fSAndroid Build Coastguard Worker     hash.push_back(1);  // Point to first non-NULL symbol.
757*795d594fSAndroid Build Coastguard Worker     // Chains.  This creates linked list of symbols.
758*795d594fSAndroid Build Coastguard Worker     hash.push_back(0);  // Placeholder entry for the NULL symbol.
759*795d594fSAndroid Build Coastguard Worker     for (int i = 1; i < count - 1; i++) {
760*795d594fSAndroid Build Coastguard Worker       hash.push_back(i + 1);  // Each symbol points to the next one.
761*795d594fSAndroid Build Coastguard Worker     }
762*795d594fSAndroid Build Coastguard Worker     hash.push_back(0);  // Last symbol terminates the chain.
763*795d594fSAndroid Build Coastguard Worker     hash_.Add(hash.data(), hash.size() * sizeof(hash[0]));
764*795d594fSAndroid Build Coastguard Worker 
765*795d594fSAndroid Build Coastguard Worker     // Allocate all remaining sections.
766*795d594fSAndroid Build Coastguard Worker     dynstr_.AllocateVirtualMemory(dynstr_.GetCacheSize());
767*795d594fSAndroid Build Coastguard Worker     dynsym_.AllocateVirtualMemory(dynsym_.GetCacheSize());
768*795d594fSAndroid Build Coastguard Worker     hash_.AllocateVirtualMemory(hash_.GetCacheSize());
769*795d594fSAndroid Build Coastguard Worker 
770*795d594fSAndroid Build Coastguard Worker     Elf_Dyn dyns[] = {
771*795d594fSAndroid Build Coastguard Worker       { .d_tag = DT_HASH,   .d_un = { .d_ptr = hash_.GetAddress() }, },
772*795d594fSAndroid Build Coastguard Worker       { .d_tag = DT_STRTAB, .d_un = { .d_ptr = dynstr_.GetAddress() }, },
773*795d594fSAndroid Build Coastguard Worker       { .d_tag = DT_SYMTAB, .d_un = { .d_ptr = dynsym_.GetAddress() }, },
774*795d594fSAndroid Build Coastguard Worker       { .d_tag = DT_SYMENT, .d_un = { .d_ptr = sizeof(Elf_Sym) }, },
775*795d594fSAndroid Build Coastguard Worker       { .d_tag = DT_STRSZ,  .d_un = { .d_ptr = dynstr_.GetCacheSize() }, },
776*795d594fSAndroid Build Coastguard Worker       { .d_tag = DT_SONAME, .d_un = { .d_ptr = soname_offset }, },
777*795d594fSAndroid Build Coastguard Worker       { .d_tag = DT_NULL,   .d_un = { .d_ptr = 0 }, },
778*795d594fSAndroid Build Coastguard Worker     };
779*795d594fSAndroid Build Coastguard Worker     dynamic_.Add(&dyns, sizeof(dyns));
780*795d594fSAndroid Build Coastguard Worker     dynamic_.AllocateVirtualMemory(dynamic_.GetCacheSize());
781*795d594fSAndroid Build Coastguard Worker 
782*795d594fSAndroid Build Coastguard Worker     loaded_size_ = RoundUp(virtual_address_, kElfSegmentAlignment);
783*795d594fSAndroid Build Coastguard Worker   }
784*795d594fSAndroid Build Coastguard Worker 
WriteDynamicSection()785*795d594fSAndroid Build Coastguard Worker   void WriteDynamicSection() {
786*795d594fSAndroid Build Coastguard Worker     dynstr_.WriteCachedSection();
787*795d594fSAndroid Build Coastguard Worker     dynsym_.WriteCachedSection();
788*795d594fSAndroid Build Coastguard Worker     hash_.WriteCachedSection();
789*795d594fSAndroid Build Coastguard Worker     dynamic_.WriteCachedSection();
790*795d594fSAndroid Build Coastguard Worker   }
791*795d594fSAndroid Build Coastguard Worker 
GetLoadedSize()792*795d594fSAndroid Build Coastguard Worker   Elf_Word GetLoadedSize() {
793*795d594fSAndroid Build Coastguard Worker     CHECK_NE(loaded_size_, 0u);
794*795d594fSAndroid Build Coastguard Worker     return loaded_size_;
795*795d594fSAndroid Build Coastguard Worker   }
796*795d594fSAndroid Build Coastguard Worker 
WriteBuildIdSection()797*795d594fSAndroid Build Coastguard Worker   void WriteBuildIdSection() {
798*795d594fSAndroid Build Coastguard Worker     build_id_.Start();
799*795d594fSAndroid Build Coastguard Worker     build_id_.Write();
800*795d594fSAndroid Build Coastguard Worker     build_id_.End();
801*795d594fSAndroid Build Coastguard Worker   }
802*795d594fSAndroid Build Coastguard Worker 
WriteBuildId(uint8_t build_id[kBuildIdLen])803*795d594fSAndroid Build Coastguard Worker   void WriteBuildId(uint8_t build_id[kBuildIdLen]) {
804*795d594fSAndroid Build Coastguard Worker     stream_.Seek(build_id_.GetDigestStart(), kSeekSet);
805*795d594fSAndroid Build Coastguard Worker     stream_.WriteFully(build_id, kBuildIdLen);
806*795d594fSAndroid Build Coastguard Worker     stream_.Flush();
807*795d594fSAndroid Build Coastguard Worker   }
808*795d594fSAndroid Build Coastguard Worker 
809*795d594fSAndroid Build Coastguard Worker   // Returns true if all writes and seeks on the output stream succeeded.
Good()810*795d594fSAndroid Build Coastguard Worker   bool Good() {
811*795d594fSAndroid Build Coastguard Worker     return stream_.Good();
812*795d594fSAndroid Build Coastguard Worker   }
813*795d594fSAndroid Build Coastguard Worker 
814*795d594fSAndroid Build Coastguard Worker   // Returns the builder's internal stream.
GetStream()815*795d594fSAndroid Build Coastguard Worker   OutputStream* GetStream() {
816*795d594fSAndroid Build Coastguard Worker     return &stream_;
817*795d594fSAndroid Build Coastguard Worker   }
818*795d594fSAndroid Build Coastguard Worker 
AlignFileOffset(size_t alignment)819*795d594fSAndroid Build Coastguard Worker   off_t AlignFileOffset(size_t alignment) {
820*795d594fSAndroid Build Coastguard Worker      return stream_.Seek(RoundUp(stream_.Seek(0, kSeekCurrent), alignment), kSeekSet);
821*795d594fSAndroid Build Coastguard Worker   }
822*795d594fSAndroid Build Coastguard Worker 
GetIsaFromHeader(const Elf_Ehdr & header)823*795d594fSAndroid Build Coastguard Worker   static InstructionSet GetIsaFromHeader(const Elf_Ehdr& header) {
824*795d594fSAndroid Build Coastguard Worker     switch (header.e_machine) {
825*795d594fSAndroid Build Coastguard Worker       case EM_ARM:
826*795d594fSAndroid Build Coastguard Worker         return InstructionSet::kThumb2;
827*795d594fSAndroid Build Coastguard Worker       case EM_AARCH64:
828*795d594fSAndroid Build Coastguard Worker         return InstructionSet::kArm64;
829*795d594fSAndroid Build Coastguard Worker       case EM_RISCV:
830*795d594fSAndroid Build Coastguard Worker         return InstructionSet::kRiscv64;
831*795d594fSAndroid Build Coastguard Worker       case EM_386:
832*795d594fSAndroid Build Coastguard Worker         return InstructionSet::kX86;
833*795d594fSAndroid Build Coastguard Worker       case EM_X86_64:
834*795d594fSAndroid Build Coastguard Worker         return InstructionSet::kX86_64;
835*795d594fSAndroid Build Coastguard Worker     }
836*795d594fSAndroid Build Coastguard Worker     LOG(FATAL) << "Unknown architecture: " << header.e_machine;
837*795d594fSAndroid Build Coastguard Worker     UNREACHABLE();
838*795d594fSAndroid Build Coastguard Worker   }
839*795d594fSAndroid Build Coastguard Worker 
840*795d594fSAndroid Build Coastguard Worker  private:
MakeElfHeader(InstructionSet isa)841*795d594fSAndroid Build Coastguard Worker   static Elf_Ehdr MakeElfHeader(InstructionSet isa) {
842*795d594fSAndroid Build Coastguard Worker     Elf_Ehdr elf_header = Elf_Ehdr();
843*795d594fSAndroid Build Coastguard Worker     switch (isa) {
844*795d594fSAndroid Build Coastguard Worker       case InstructionSet::kArm:
845*795d594fSAndroid Build Coastguard Worker         // Fall through.
846*795d594fSAndroid Build Coastguard Worker       case InstructionSet::kThumb2: {
847*795d594fSAndroid Build Coastguard Worker         elf_header.e_machine = EM_ARM;
848*795d594fSAndroid Build Coastguard Worker         elf_header.e_flags = EF_ARM_EABI_VER5;
849*795d594fSAndroid Build Coastguard Worker         break;
850*795d594fSAndroid Build Coastguard Worker       }
851*795d594fSAndroid Build Coastguard Worker       case InstructionSet::kArm64: {
852*795d594fSAndroid Build Coastguard Worker         elf_header.e_machine = EM_AARCH64;
853*795d594fSAndroid Build Coastguard Worker         elf_header.e_flags = 0;
854*795d594fSAndroid Build Coastguard Worker         break;
855*795d594fSAndroid Build Coastguard Worker       }
856*795d594fSAndroid Build Coastguard Worker       case InstructionSet::kRiscv64: {
857*795d594fSAndroid Build Coastguard Worker         elf_header.e_machine = EM_RISCV;
858*795d594fSAndroid Build Coastguard Worker         elf_header.e_flags = EF_RISCV_RVC | EF_RISCV_FLOAT_ABI_DOUBLE;
859*795d594fSAndroid Build Coastguard Worker         break;
860*795d594fSAndroid Build Coastguard Worker       }
861*795d594fSAndroid Build Coastguard Worker       case InstructionSet::kX86: {
862*795d594fSAndroid Build Coastguard Worker         elf_header.e_machine = EM_386;
863*795d594fSAndroid Build Coastguard Worker         elf_header.e_flags = 0;
864*795d594fSAndroid Build Coastguard Worker         break;
865*795d594fSAndroid Build Coastguard Worker       }
866*795d594fSAndroid Build Coastguard Worker       case InstructionSet::kX86_64: {
867*795d594fSAndroid Build Coastguard Worker         elf_header.e_machine = EM_X86_64;
868*795d594fSAndroid Build Coastguard Worker         elf_header.e_flags = 0;
869*795d594fSAndroid Build Coastguard Worker         break;
870*795d594fSAndroid Build Coastguard Worker       }
871*795d594fSAndroid Build Coastguard Worker       case InstructionSet::kNone: {
872*795d594fSAndroid Build Coastguard Worker         LOG(FATAL) << "No instruction set";
873*795d594fSAndroid Build Coastguard Worker         break;
874*795d594fSAndroid Build Coastguard Worker       }
875*795d594fSAndroid Build Coastguard Worker       default: {
876*795d594fSAndroid Build Coastguard Worker         LOG(FATAL) << "Unknown instruction set " << isa;
877*795d594fSAndroid Build Coastguard Worker       }
878*795d594fSAndroid Build Coastguard Worker     }
879*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(GetIsaFromHeader(elf_header),
880*795d594fSAndroid Build Coastguard Worker               (isa == InstructionSet::kArm) ? InstructionSet::kThumb2 : isa);
881*795d594fSAndroid Build Coastguard Worker 
882*795d594fSAndroid Build Coastguard Worker     elf_header.e_ident[EI_MAG0]       = ELFMAG0;
883*795d594fSAndroid Build Coastguard Worker     elf_header.e_ident[EI_MAG1]       = ELFMAG1;
884*795d594fSAndroid Build Coastguard Worker     elf_header.e_ident[EI_MAG2]       = ELFMAG2;
885*795d594fSAndroid Build Coastguard Worker     elf_header.e_ident[EI_MAG3]       = ELFMAG3;
886*795d594fSAndroid Build Coastguard Worker     elf_header.e_ident[EI_CLASS]      = (sizeof(Elf_Addr) == sizeof(Elf32_Addr))
887*795d594fSAndroid Build Coastguard Worker                                          ? ELFCLASS32 : ELFCLASS64;
888*795d594fSAndroid Build Coastguard Worker     elf_header.e_ident[EI_DATA]       = ELFDATA2LSB;
889*795d594fSAndroid Build Coastguard Worker     elf_header.e_ident[EI_VERSION]    = EV_CURRENT;
890*795d594fSAndroid Build Coastguard Worker     elf_header.e_ident[EI_OSABI]      = ELFOSABI_LINUX;
891*795d594fSAndroid Build Coastguard Worker     elf_header.e_ident[EI_ABIVERSION] = 0;
892*795d594fSAndroid Build Coastguard Worker     elf_header.e_type = ET_DYN;
893*795d594fSAndroid Build Coastguard Worker     elf_header.e_version = 1;
894*795d594fSAndroid Build Coastguard Worker     elf_header.e_entry = 0;
895*795d594fSAndroid Build Coastguard Worker     elf_header.e_ehsize = sizeof(Elf_Ehdr);
896*795d594fSAndroid Build Coastguard Worker     elf_header.e_phentsize = sizeof(Elf_Phdr);
897*795d594fSAndroid Build Coastguard Worker     elf_header.e_shentsize = sizeof(Elf_Shdr);
898*795d594fSAndroid Build Coastguard Worker     return elf_header;
899*795d594fSAndroid Build Coastguard Worker   }
900*795d594fSAndroid Build Coastguard Worker 
901*795d594fSAndroid Build Coastguard Worker   // Create program headers based on written sections.
MakeProgramHeaders()902*795d594fSAndroid Build Coastguard Worker   std::vector<Elf_Phdr> MakeProgramHeaders() {
903*795d594fSAndroid Build Coastguard Worker     CHECK(!sections_.empty());
904*795d594fSAndroid Build Coastguard Worker     std::vector<Elf_Phdr> phdrs;
905*795d594fSAndroid Build Coastguard Worker     {
906*795d594fSAndroid Build Coastguard Worker       // The program headers must start with PT_PHDR which is used in
907*795d594fSAndroid Build Coastguard Worker       // loaded process to determine the number of program headers.
908*795d594fSAndroid Build Coastguard Worker       Elf_Phdr phdr = Elf_Phdr();
909*795d594fSAndroid Build Coastguard Worker       phdr.p_type    = PT_PHDR;
910*795d594fSAndroid Build Coastguard Worker       phdr.p_flags   = PF_R;
911*795d594fSAndroid Build Coastguard Worker       phdr.p_offset  = phdr.p_vaddr = phdr.p_paddr = sizeof(Elf_Ehdr);
912*795d594fSAndroid Build Coastguard Worker       phdr.p_filesz  = phdr.p_memsz = 0;  // We need to fill this later.
913*795d594fSAndroid Build Coastguard Worker       phdr.p_align   = sizeof(Elf_Off);
914*795d594fSAndroid Build Coastguard Worker       phdrs.push_back(phdr);
915*795d594fSAndroid Build Coastguard Worker       // Tell the linker to mmap the start of file to memory.
916*795d594fSAndroid Build Coastguard Worker       Elf_Phdr load = Elf_Phdr();
917*795d594fSAndroid Build Coastguard Worker       load.p_type    = PT_LOAD;
918*795d594fSAndroid Build Coastguard Worker       load.p_flags   = PF_R;
919*795d594fSAndroid Build Coastguard Worker       load.p_offset  = load.p_vaddr = load.p_paddr = 0;
920*795d594fSAndroid Build Coastguard Worker       load.p_filesz  = load.p_memsz = sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * kMaxProgramHeaders;
921*795d594fSAndroid Build Coastguard Worker       load.p_align   = kElfSegmentAlignment;
922*795d594fSAndroid Build Coastguard Worker       phdrs.push_back(load);
923*795d594fSAndroid Build Coastguard Worker     }
924*795d594fSAndroid Build Coastguard Worker     // Create program headers for sections.
925*795d594fSAndroid Build Coastguard Worker     for (auto* section : sections_) {
926*795d594fSAndroid Build Coastguard Worker       const Elf_Shdr& shdr = section->header_;
927*795d594fSAndroid Build Coastguard Worker       if ((shdr.sh_flags & SHF_ALLOC) != 0 && shdr.sh_size != 0) {
928*795d594fSAndroid Build Coastguard Worker         DCHECK(shdr.sh_addr != 0u) << "Allocate virtual memory for the section";
929*795d594fSAndroid Build Coastguard Worker         // PT_LOAD tells the linker to mmap part of the file.
930*795d594fSAndroid Build Coastguard Worker         // The linker can only mmap page-aligned sections.
931*795d594fSAndroid Build Coastguard Worker         // Single PT_LOAD may contain several ELF sections.
932*795d594fSAndroid Build Coastguard Worker         Elf_Phdr& prev = phdrs.back();
933*795d594fSAndroid Build Coastguard Worker         Elf_Phdr load = Elf_Phdr();
934*795d594fSAndroid Build Coastguard Worker         load.p_type   = PT_LOAD;
935*795d594fSAndroid Build Coastguard Worker         load.p_flags  = section->phdr_flags_;
936*795d594fSAndroid Build Coastguard Worker         load.p_offset = shdr.sh_offset;
937*795d594fSAndroid Build Coastguard Worker         load.p_vaddr  = load.p_paddr = shdr.sh_addr;
938*795d594fSAndroid Build Coastguard Worker         load.p_filesz = (shdr.sh_type != SHT_NOBITS ? shdr.sh_size : 0u);
939*795d594fSAndroid Build Coastguard Worker         load.p_memsz  = shdr.sh_size;
940*795d594fSAndroid Build Coastguard Worker         load.p_align  = shdr.sh_addralign;
941*795d594fSAndroid Build Coastguard Worker         if (prev.p_type == load.p_type &&
942*795d594fSAndroid Build Coastguard Worker             prev.p_flags == load.p_flags &&
943*795d594fSAndroid Build Coastguard Worker             prev.p_filesz == prev.p_memsz &&  // Do not merge .bss
944*795d594fSAndroid Build Coastguard Worker             load.p_filesz == load.p_memsz) {  // Do not merge .bss
945*795d594fSAndroid Build Coastguard Worker           // Merge this PT_LOAD with the previous one.
946*795d594fSAndroid Build Coastguard Worker           Elf_Word size = shdr.sh_offset + shdr.sh_size - prev.p_offset;
947*795d594fSAndroid Build Coastguard Worker           prev.p_filesz = size;
948*795d594fSAndroid Build Coastguard Worker           prev.p_memsz  = size;
949*795d594fSAndroid Build Coastguard Worker         } else {
950*795d594fSAndroid Build Coastguard Worker           // If we are adding new load, it must be aligned.
951*795d594fSAndroid Build Coastguard Worker           CHECK_EQ(shdr.sh_addralign, (Elf_Word)kElfSegmentAlignment);
952*795d594fSAndroid Build Coastguard Worker           phdrs.push_back(load);
953*795d594fSAndroid Build Coastguard Worker         }
954*795d594fSAndroid Build Coastguard Worker       }
955*795d594fSAndroid Build Coastguard Worker     }
956*795d594fSAndroid Build Coastguard Worker     for (auto* section : sections_) {
957*795d594fSAndroid Build Coastguard Worker       const Elf_Shdr& shdr = section->header_;
958*795d594fSAndroid Build Coastguard Worker       if ((shdr.sh_flags & SHF_ALLOC) != 0 && shdr.sh_size != 0) {
959*795d594fSAndroid Build Coastguard Worker         // Other PT_* types allow the program to locate interesting
960*795d594fSAndroid Build Coastguard Worker         // parts of memory at runtime. They must overlap with PT_LOAD.
961*795d594fSAndroid Build Coastguard Worker         if (section->phdr_type_ != 0) {
962*795d594fSAndroid Build Coastguard Worker           Elf_Phdr phdr = Elf_Phdr();
963*795d594fSAndroid Build Coastguard Worker           phdr.p_type   = section->phdr_type_;
964*795d594fSAndroid Build Coastguard Worker           phdr.p_flags  = section->phdr_flags_;
965*795d594fSAndroid Build Coastguard Worker           phdr.p_offset = shdr.sh_offset;
966*795d594fSAndroid Build Coastguard Worker           phdr.p_vaddr  = phdr.p_paddr = shdr.sh_addr;
967*795d594fSAndroid Build Coastguard Worker           phdr.p_filesz = phdr.p_memsz = shdr.sh_size;
968*795d594fSAndroid Build Coastguard Worker           phdr.p_align  = shdr.sh_addralign;
969*795d594fSAndroid Build Coastguard Worker           phdrs.push_back(phdr);
970*795d594fSAndroid Build Coastguard Worker         }
971*795d594fSAndroid Build Coastguard Worker       }
972*795d594fSAndroid Build Coastguard Worker     }
973*795d594fSAndroid Build Coastguard Worker     // Set the size of the initial PT_PHDR.
974*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(phdrs[0].p_type, (Elf_Word)PT_PHDR);
975*795d594fSAndroid Build Coastguard Worker     phdrs[0].p_filesz = phdrs[0].p_memsz = phdrs.size() * sizeof(Elf_Phdr);
976*795d594fSAndroid Build Coastguard Worker 
977*795d594fSAndroid Build Coastguard Worker     return phdrs;
978*795d594fSAndroid Build Coastguard Worker   }
979*795d594fSAndroid Build Coastguard Worker 
980*795d594fSAndroid Build Coastguard Worker   InstructionSet isa_;
981*795d594fSAndroid Build Coastguard Worker 
982*795d594fSAndroid Build Coastguard Worker   ErrorDelayingOutputStream stream_;
983*795d594fSAndroid Build Coastguard Worker 
984*795d594fSAndroid Build Coastguard Worker   Section rodata_;
985*795d594fSAndroid Build Coastguard Worker   Section text_;
986*795d594fSAndroid Build Coastguard Worker   Section data_img_rel_ro_;
987*795d594fSAndroid Build Coastguard Worker   Section bss_;
988*795d594fSAndroid Build Coastguard Worker   Section dex_;
989*795d594fSAndroid Build Coastguard Worker   CachedStringSection dynstr_;
990*795d594fSAndroid Build Coastguard Worker   SymbolSection dynsym_;
991*795d594fSAndroid Build Coastguard Worker   CachedSection hash_;
992*795d594fSAndroid Build Coastguard Worker   CachedSection dynamic_;
993*795d594fSAndroid Build Coastguard Worker   StringSection strtab_;
994*795d594fSAndroid Build Coastguard Worker   SymbolSection symtab_;
995*795d594fSAndroid Build Coastguard Worker   Section debug_frame_;
996*795d594fSAndroid Build Coastguard Worker   Section debug_frame_hdr_;
997*795d594fSAndroid Build Coastguard Worker   Section debug_info_;
998*795d594fSAndroid Build Coastguard Worker   Section debug_line_;
999*795d594fSAndroid Build Coastguard Worker   StringSection shstrtab_;
1000*795d594fSAndroid Build Coastguard Worker   BuildIdSection build_id_;
1001*795d594fSAndroid Build Coastguard Worker   std::vector<std::unique_ptr<Section>> other_sections_;
1002*795d594fSAndroid Build Coastguard Worker 
1003*795d594fSAndroid Build Coastguard Worker   // List of used section in the order in which they were written.
1004*795d594fSAndroid Build Coastguard Worker   std::vector<Section*> sections_;
1005*795d594fSAndroid Build Coastguard Worker   Section* current_section_;  // The section which is currently being written.
1006*795d594fSAndroid Build Coastguard Worker 
1007*795d594fSAndroid Build Coastguard Worker   bool started_;
1008*795d594fSAndroid Build Coastguard Worker   bool finished_;
1009*795d594fSAndroid Build Coastguard Worker   bool write_program_headers_;
1010*795d594fSAndroid Build Coastguard Worker 
1011*795d594fSAndroid Build Coastguard Worker   // The size of the memory taken by the ELF file when loaded.
1012*795d594fSAndroid Build Coastguard Worker   size_t loaded_size_;
1013*795d594fSAndroid Build Coastguard Worker 
1014*795d594fSAndroid Build Coastguard Worker   // Used for allocation of virtual address space.
1015*795d594fSAndroid Build Coastguard Worker   Elf_Addr virtual_address_;
1016*795d594fSAndroid Build Coastguard Worker 
1017*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ElfBuilder);
1018*795d594fSAndroid Build Coastguard Worker };
1019*795d594fSAndroid Build Coastguard Worker 
1020*795d594fSAndroid Build Coastguard Worker }  // namespace art
1021*795d594fSAndroid Build Coastguard Worker 
1022*795d594fSAndroid Build Coastguard Worker #endif  // ART_LIBELFFILE_ELF_ELF_BUILDER_H_
1023