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