elf_writer_quick.cc revision c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899
16a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom/* 26a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Copyright (C) 2012 The Android Open Source Project 36a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * 46a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 56a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * you may not use this file except in compliance with the License. 66a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * You may obtain a copy of the License at 76a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * 86a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 96a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * 106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Unless required by applicable law or agreed to in writing, software 116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * See the License for the specific language governing permissions and 146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * limitations under the License. 156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom */ 166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "elf_writer_quick.h" 186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "base/logging.h" 206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "base/unix_file/fd_file.h" 217940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h" 22c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom#include "file_output_stream.h" 236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "globals.h" 246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "oat.h" 25c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom#include "oat_writer.h" 266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "utils.h" 276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromnamespace art { 296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian CarlstromElfWriterQuick::ElfWriterQuick(const CompilerDriver& driver, File* elf_file) 316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom : ElfWriter(driver, elf_file) {} 326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian CarlstromElfWriterQuick::~ElfWriterQuick() {} 346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrombool ElfWriterQuick::Create(File* elf_file, 36c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom OatWriter& oat_writer, 376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::vector<const DexFile*>& dex_files, 386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::string& android_root, 396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom bool is_host, 406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const CompilerDriver& driver) { 416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ElfWriterQuick elf_writer(driver, elf_file); 42c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom return elf_writer.Write(oat_writer, dex_files, android_root, is_host); 436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 45c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrombool ElfWriterQuick::Write(OatWriter& oat_writer, 466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::vector<const DexFile*>& dex_files_unused, 476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::string& android_root_unused, 486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom bool is_host_unused) { 496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const bool debug = false; 506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Ehdr | 526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr PHDR | 546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr LOAD R | .dynsym .dynstr .hash .rodata 556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr LOAD R X | .text 566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr LOAD RW | .dynamic 576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr DYNAMIC | .dynamic 586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .dynsym | 606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Sym STN_UNDEF | 616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Sym oatdata | 626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Sym oatexec | 636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Sym oatlastword | 646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .dynstr | 666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | \0 | 676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatdata\0 | 686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatexec\0 | 696a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatlastword\0 | 706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | boot.oat\0 | 716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .hash | 736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Word nbucket = 1 | 746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Word nchain = 3 | 756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Word bucket[0] = 0| 766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Word chain[0] = 1| 776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Word chain[1] = 2| 786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Word chain[2] = 3| 796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .rodata | 816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatdata..oatexec-4 | 826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .text | 846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatexec..oatlastword | 856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .dynamic | 876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_SONAME | 886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_HASH | 896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_SYMTAB | 906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_SYMENT | 916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_STRTAB | 926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_STRSZ | 936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_NULL | 946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .shstrtab | 966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | \0 | 976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .dynamic\0 | 986a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .dynsym\0 | 996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .dynstr\0 | 1006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .hash\0 | 1016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .rodata\0 | 1026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .text\0 | 1036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .shstrtab\0 | 1046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 1056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr NULL | 1066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .dynsym | 1076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .dynstr | 1086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .hash | 1096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .text | 1106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .rodata | 1116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .dynamic | 1126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .shstrtab | 1136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 1146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // phase 1: computing offsets 1166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t expected_offset = 0; 1176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Elf32_Ehdr 1196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += sizeof(llvm::ELF::Elf32_Ehdr); 1206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // PHDR 1226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t phdr_alignment = sizeof(llvm::ELF::Elf32_Word); 1236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t phdr_offset = expected_offset; 1246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_PHDR = 0; 1256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_LOAD_R__ = 1; 1266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_LOAD_R_X = 2; 1276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_LOAD_RW_ = 3; 1286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_DYNAMIC = 4; 1296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_NUM = 5; 1306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t phdr_size = sizeof(llvm::ELF::Elf32_Phdr) * PH_NUM; 1316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += phdr_size; 1326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (debug) { 1336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "phdr_offset=" << phdr_offset << std::hex << " " << phdr_offset; 1346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "phdr_size=" << phdr_size << std::hex << " " << phdr_size; 1356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 1366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .dynsym 1386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynsym_alignment = sizeof(llvm::ELF::Elf32_Word); 1396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynsym_offset = expected_offset = RoundUp(expected_offset, dynsym_alignment); 1406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SYM_UNDEF = 0; // aka STN_UNDEF 1416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SYM_OATDATA = 1; 1426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SYM_OATEXEC = 2; 1436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SYM_OATLASTWORD = 3; 1446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SYM_NUM = 4; 1456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynsym_size = sizeof(llvm::ELF::Elf32_Sym) * SYM_NUM; 1466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += dynsym_size; 1476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (debug) { 1486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "dynsym_offset=" << dynsym_offset << std::hex << " " << dynsym_offset; 1496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "dynsym_size=" << dynsym_size << std::hex << " " << dynsym_size; 1506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 1516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .dynstr 1536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynstr_alignment = 1; 1546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynstr_offset = expected_offset = RoundUp(expected_offset, dynstr_alignment); 1556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string dynstr; 1566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynstr += '\0'; 1576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynstr_oatdata_offset = dynstr.size(); 1586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynstr += "oatdata"; 1596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynstr += '\0'; 1606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynstr_oatexec_offset = dynstr.size(); 1616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynstr += "oatexec"; 1626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynstr += '\0'; 1636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynstr_oatlastword_offset = dynstr.size(); 1646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynstr += "oatlastword"; 1656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynstr += '\0'; 1666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynstr_soname_offset = dynstr.size(); 1676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string file_name(elf_file_->GetPath()); 1686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom size_t directory_separator_pos = file_name.rfind('/'); 1696a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (directory_separator_pos != std::string::npos) { 1706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom file_name = file_name.substr(directory_separator_pos + 1); 1716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 1726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynstr += file_name; 1736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynstr += '\0'; 1746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynstr_size = dynstr.size(); 1756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += dynstr_size; 1766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (debug) { 1776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "dynstr_offset=" << dynstr_offset << std::hex << " " << dynstr_offset; 1786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "dynstr_size=" << dynstr_size << std::hex << " " << dynstr_size; 1796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 1806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .hash 1826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t hash_alignment = sizeof(llvm::ELF::Elf32_Word); // Even for 64-bit 1836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t hash_offset = expected_offset = RoundUp(expected_offset, hash_alignment); 1846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t HASH_NBUCKET = 0; 1856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t HASH_NCHAIN = 1; 1866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t HASH_BUCKET0 = 2; 1876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t HASH_NUM = HASH_BUCKET0 + 1 + SYM_NUM; 1886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t hash_size = sizeof(llvm::ELF::Elf32_Word) * HASH_NUM; 1896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += hash_size; 1906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (debug) { 1916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "hash_offset=" << hash_offset << std::hex << " " << hash_offset; 1926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "hash_size=" << hash_size << std::hex << " " << hash_size; 1936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 1946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .rodata 1966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t oat_data_alignment = kPageSize; 1976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t oat_data_offset = expected_offset = RoundUp(expected_offset, oat_data_alignment); 198c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom const OatHeader& oat_header = oat_writer.GetOatHeader(); 199c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom CHECK(oat_header.IsValid()); 200c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom uint32_t oat_data_size = oat_header.GetExecutableOffset(); 2016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += oat_data_size; 2026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (debug) { 2036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "oat_data_offset=" << oat_data_offset << std::hex << " " << oat_data_offset; 2046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "oat_data_size=" << oat_data_size << std::hex << " " << oat_data_size; 2056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 2066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .text 2086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t oat_exec_alignment = kPageSize; 2096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK_ALIGNED(expected_offset, kPageSize); 2106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t oat_exec_offset = expected_offset = RoundUp(expected_offset, oat_exec_alignment); 211c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom uint32_t oat_exec_size = oat_writer.GetSize() - oat_data_size; 2126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += oat_exec_size; 213c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom CHECK_EQ(oat_data_offset + oat_writer.GetSize(), expected_offset); 2146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (debug) { 2156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "oat_exec_offset=" << oat_exec_offset << std::hex << " " << oat_exec_offset; 2166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "oat_exec_size=" << oat_exec_size << std::hex << " " << oat_exec_size; 2176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 2186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .dynamic 2206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // alignment would naturally be sizeof(llvm::ELF::Elf32_Word), but we want this in a new segment 2216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynamic_alignment = kPageSize; 2226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynamic_offset = expected_offset = RoundUp(expected_offset, dynamic_alignment); 2236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t DH_SONAME = 0; 2246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t DH_HASH = 1; 2256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t DH_SYMTAB = 2; 2266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t DH_SYMENT = 3; 2276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t DH_STRTAB = 4; 2286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t DH_STRSZ = 5; 2296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t DH_NULL = 6; 2306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t DH_NUM = 7; 2316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t dynamic_size = sizeof(llvm::ELF::Elf32_Dyn) * DH_NUM; 2326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += dynamic_size; 2336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (debug) { 2346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "dynamic_offset=" << dynamic_offset << std::hex << " " << dynamic_offset; 2356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "dynamic_size=" << dynamic_size << std::hex << " " << dynamic_size; 2366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 2376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .shstrtab 2396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_alignment = 1; 2406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_offset = expected_offset = RoundUp(expected_offset, shstrtab_alignment); 2416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string shstrtab; 2426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += '\0'; 2436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_dynamic_offset = shstrtab.size(); 2446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK_EQ(1U, shstrtab_dynamic_offset); 2456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += ".dynamic"; 2466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += '\0'; 2476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_dynsym_offset = shstrtab.size(); 2486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += ".dynsym"; 2496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += '\0'; 2506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_dynstr_offset = shstrtab.size(); 2516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += ".dynstr"; 2526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += '\0'; 2536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_hash_offset = shstrtab.size(); 2546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += ".hash"; 2556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += '\0'; 2566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_rodata_offset = shstrtab.size(); 2576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += ".rodata"; 2586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += '\0'; 2596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_text_offset = shstrtab.size(); 2606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += ".text"; 2616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += '\0'; 2626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_shstrtab_offset = shstrtab.size(); 2636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += ".shstrtab"; 2646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom shstrtab += '\0'; 2656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shstrtab_size = shstrtab.size(); 2666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += shstrtab_size; 2676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (debug) { 2686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "shstrtab_offset=" << shstrtab_offset << std::hex << " " << shstrtab_offset; 2696a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "shstrtab_size=" << shstrtab_size << std::hex << " " << shstrtab_size; 2706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 2716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // section headers (after all sections) 2736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shdr_alignment = sizeof(llvm::ELF::Elf32_Word); 2746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shdr_offset = expected_offset = RoundUp(expected_offset, shdr_alignment); 2756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SH_NULL = 0; 2766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SH_DYNSYM = 1; 2776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SH_DYNSTR = 2; 2786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SH_HASH = 3; 2796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SH_RODATA = 4; 2806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SH_TEXT = 5; 2816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SH_DYNAMIC = 6; 2826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SH_SHSTRTAB = 7; 2836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t SH_NUM = 8; 2846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t shdr_size = sizeof(llvm::ELF::Elf32_Shdr) * SH_NUM; 2856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom expected_offset += shdr_size; 2866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (debug) { 2876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "shdr_offset=" << shdr_offset << std::hex << " " << shdr_offset; 2886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "shdr_size=" << shdr_size << std::hex << " " << shdr_size; 2896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 2906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // phase 2: initializing data 2926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Elf32_Ehdr 2946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::Elf32_Ehdr elf_header; 2956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom memset(&elf_header, 0, sizeof(elf_header)); 2966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ident[llvm::ELF::EI_MAG0] = llvm::ELF::ElfMagic[0]; 2976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ident[llvm::ELF::EI_MAG1] = llvm::ELF::ElfMagic[1]; 2986a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ident[llvm::ELF::EI_MAG2] = llvm::ELF::ElfMagic[2]; 2996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ident[llvm::ELF::EI_MAG3] = llvm::ELF::ElfMagic[3]; 3006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS32; 3016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB; 3026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ident[llvm::ELF::EI_VERSION] = llvm::ELF::EV_CURRENT; 3036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ident[llvm::ELF::EI_OSABI] = llvm::ELF::ELFOSABI_LINUX; 3046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ident[llvm::ELF::EI_ABIVERSION] = 0; 3056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_type = llvm::ELF::ET_DYN; 3066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom switch (compiler_driver_->GetInstructionSet()) { 3076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom case kThumb2: { 3086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_machine = llvm::ELF::EM_ARM; 3096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_flags = llvm::ELF::EF_ARM_EABI_VER5; 3106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom break; 3116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom case kX86: { 3136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_machine = llvm::ELF::EM_386; 3146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_flags = 0; 3156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom break; 3166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom case kMips: { 3186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_machine = llvm::ELF::EM_MIPS; 3196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_flags = (llvm::ELF::EF_MIPS_NOREORDER | 3206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::EF_MIPS_PIC | 3216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::EF_MIPS_CPIC | 3226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::EF_MIPS_ABI_O32 | 3236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::EF_MIPS_ARCH_32R2); 3246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom break; 3256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom case kArm: 3276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom default: { 3286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(FATAL) << "Unknown instruction set: " << compiler_driver_->GetInstructionSet(); 3296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom break; 3306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_version = 1; 3336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_entry = 0; 3346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_phoff = phdr_offset; 3356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_shoff = shdr_offset; 3366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_ehsize = sizeof(llvm::ELF::Elf32_Ehdr); 3376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_phentsize = sizeof(llvm::ELF::Elf32_Phdr); 3386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_phnum = PH_NUM; 3396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_shentsize = sizeof(llvm::ELF::Elf32_Shdr); 3406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_shnum = SH_NUM; 3416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom elf_header.e_shstrndx = SH_SHSTRTAB; 3426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // PHDR 3446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::Elf32_Phdr program_headers[PH_NUM]; 3456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom memset(&program_headers, 0, sizeof(program_headers)); 3466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_type = llvm::ELF::PT_PHDR; 3486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_offset = phdr_offset; 3496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_vaddr = phdr_offset; 3506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_paddr = phdr_offset; 3516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_filesz = sizeof(program_headers); 3526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_memsz = sizeof(program_headers); 3536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_flags = llvm::ELF::PF_R; 3546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_align = phdr_alignment; 3556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_type = llvm::ELF::PT_LOAD; 3576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_offset = 0; 3586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_vaddr = 0; 3596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_paddr = 0; 3606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_filesz = oat_data_offset + oat_data_size; 3616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_memsz = oat_data_offset + oat_data_size; 3626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_flags = llvm::ELF::PF_R; 3636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_align = oat_data_alignment; 3646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R_X].p_type = llvm::ELF::PT_LOAD; 3666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R_X].p_offset = oat_exec_offset; 3676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R_X].p_vaddr = oat_exec_offset; 3686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R_X].p_paddr = oat_exec_offset; 3696a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R_X].p_filesz = oat_exec_size; 3706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R_X].p_memsz = oat_exec_size; 3716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R_X].p_flags = llvm::ELF::PF_R | llvm::ELF::PF_X; 3726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R_X].p_align = oat_exec_alignment; 3736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: PF_W for DYNAMIC is considered processor specific, do we need it? 3756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_RW_].p_type = llvm::ELF::PT_LOAD; 3766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_RW_].p_offset = dynamic_offset; 3776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_RW_].p_vaddr = dynamic_offset; 3786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_RW_].p_paddr = dynamic_offset; 3796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_RW_].p_filesz = dynamic_size; 3806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_RW_].p_memsz = dynamic_size; 3816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_RW_].p_flags = llvm::ELF::PF_R | llvm::ELF::PF_W; 3826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_RW_].p_align = dynamic_alignment; 3836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: PF_W for DYNAMIC is considered processor specific, do we need it? 3856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_DYNAMIC].p_type = llvm::ELF::PT_DYNAMIC; 3866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_DYNAMIC].p_offset = dynamic_offset; 3876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_DYNAMIC].p_vaddr = dynamic_offset; 3886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_DYNAMIC].p_paddr = dynamic_offset; 3896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_DYNAMIC].p_filesz = dynamic_size; 3906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_DYNAMIC].p_memsz = dynamic_size; 3916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_DYNAMIC].p_flags = llvm::ELF::PF_R | llvm::ELF::PF_W; 3926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_DYNAMIC].p_align = dynamic_alignment; 3936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .dynsym 3956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::Elf32_Sym dynsym[SYM_NUM]; 3966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom memset(&dynsym, 0, sizeof(dynsym)); 3976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3986a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_UNDEF].st_name = 0; 3996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_UNDEF].st_value = 0; 4006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_UNDEF].st_size = 0; 4016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_UNDEF].st_info = 0; 4026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_UNDEF].st_other = 0; 4036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_UNDEF].st_shndx = 0; 4046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATDATA].st_name = dynstr_oatdata_offset; 4066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATDATA].st_value = oat_data_offset; 4076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATDATA].st_size = oat_data_size; 4086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATDATA].setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_OBJECT); 4096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATDATA].st_other = llvm::ELF::STV_DEFAULT; 4106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATDATA].st_shndx = SH_RODATA; 4116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATEXEC].st_name = dynstr_oatexec_offset; 4136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATEXEC].st_value = oat_exec_offset; 4146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATEXEC].st_size = oat_exec_size; 4156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATEXEC].setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_OBJECT); 4166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATEXEC].st_other = llvm::ELF::STV_DEFAULT; 4176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATEXEC].st_shndx = SH_TEXT; 4186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATLASTWORD].st_name = dynstr_oatlastword_offset; 4206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATLASTWORD].st_value = oat_exec_offset + oat_exec_size - 4; 4216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATLASTWORD].st_size = 4; 4226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATLASTWORD].setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_OBJECT); 4236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATLASTWORD].st_other = llvm::ELF::STV_DEFAULT; 4246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynsym[SYM_OATLASTWORD].st_shndx = SH_TEXT; 4256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .dynstr initialized above as dynstr 4276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .hash 4296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::Elf32_Word hash[HASH_NUM]; // Note this is Elf32_Word even on 64-bit 4306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom hash[HASH_NBUCKET] = 1; 4316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom hash[HASH_NCHAIN] = SYM_NUM; 4326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom hash[HASH_BUCKET0] = SYM_OATDATA; 4336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom hash[HASH_BUCKET0 + 1 + SYM_UNDEF] = SYM_UNDEF; 4346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom hash[HASH_BUCKET0 + 1 + SYM_OATDATA] = SYM_OATEXEC; 4356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom hash[HASH_BUCKET0 + 1 + SYM_OATEXEC] = SYM_OATLASTWORD; 4366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom hash[HASH_BUCKET0 + 1 + SYM_OATLASTWORD] = SYM_UNDEF; 4376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .rodata and .text content come from oat_contents 4396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .dynamic 4416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::Elf32_Dyn dynamic_headers[DH_NUM]; 4426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom memset(&dynamic_headers, 0, sizeof(dynamic_headers)); 4436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_SONAME].d_tag = llvm::ELF::DT_SONAME; 4456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_SONAME].d_un.d_val = dynstr_soname_offset; 4466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_HASH].d_tag = llvm::ELF::DT_HASH; 4486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_HASH].d_un.d_ptr = hash_offset; 4496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_SYMTAB].d_tag = llvm::ELF::DT_SYMTAB; 4516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_SYMTAB].d_un.d_ptr = dynsym_offset; 4526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_SYMENT].d_tag = llvm::ELF::DT_SYMENT; 4546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_SYMENT].d_un.d_val = sizeof(llvm::ELF::Elf32_Sym); 4556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_STRTAB].d_tag = llvm::ELF::DT_STRTAB; 4576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_STRTAB].d_un.d_ptr = dynstr_offset; 4586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_STRSZ].d_tag = llvm::ELF::DT_STRSZ; 4606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_STRSZ].d_un.d_val = dynstr_size; 4616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_NULL].d_tag = llvm::ELF::DT_NULL; 4636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom dynamic_headers[DH_NULL].d_un.d_val = 0; 4646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .shstrtab initialized above as shstrtab 4666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // section headers (after all sections) 4686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::Elf32_Shdr section_headers[SH_NUM]; 4696a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom memset(§ion_headers, 0, sizeof(section_headers)); 4706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_name = 0; 4726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_type = llvm::ELF::SHT_NULL; 4736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_flags = 0; 4746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_addr = 0; 4756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_offset = 0; 4766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_size = 0; 4776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_link = 0; 4786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_info = 0; 4796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_addralign = 0; 4806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_NULL].sh_entsize = 0; 4816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_name = shstrtab_dynsym_offset; 4836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_type = llvm::ELF::SHT_DYNSYM; 4846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_flags = llvm::ELF::SHF_ALLOC; 4856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_addr = dynsym_offset; 4866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_offset = dynsym_offset; 4876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_size = dynsym_size; 4886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_link = SH_DYNSTR; 4896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_info = 1; // 1 because we have not STB_LOCAL symbols 4906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_addralign = dynsym_alignment; 4916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSYM].sh_entsize = sizeof(llvm::ELF::Elf32_Sym); 4926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_name = shstrtab_dynstr_offset; 4946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_type = llvm::ELF::SHT_STRTAB; 4956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_flags = llvm::ELF::SHF_ALLOC; 4966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_addr = dynstr_offset; 4976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_offset = dynstr_offset; 4986a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_size = dynstr_size; 4996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_link = 0; 5006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_info = 0; 5016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_addralign = dynstr_alignment; 5026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNSTR].sh_entsize = 0; 5036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_name = shstrtab_hash_offset; 5056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_type = llvm::ELF::SHT_HASH; 5066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_flags = llvm::ELF::SHF_ALLOC; 5076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_addr = hash_offset; 5086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_offset = hash_offset; 5096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_size = hash_size; 5106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_link = SH_DYNSYM; 5116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_info = 0; 5126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_addralign = hash_alignment; 5136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_HASH].sh_entsize = sizeof(llvm::ELF::Elf32_Word); // This is Elf32_Word even on 64-bit 5146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_name = shstrtab_rodata_offset; 5166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_type = llvm::ELF::SHT_PROGBITS; 5176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_flags = llvm::ELF::SHF_ALLOC; 5186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_addr = oat_data_offset; 5196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_offset = oat_data_offset; 5206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_size = oat_data_size; 5216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_link = 0; 5226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_info = 0; 5236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_addralign = oat_data_alignment; 5246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_RODATA].sh_entsize = 0; 5256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_name = shstrtab_text_offset; 5276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_type = llvm::ELF::SHT_PROGBITS; 5286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_flags = llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR; 5296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_addr = oat_exec_offset; 5306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_offset = oat_exec_offset; 5316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_size = oat_exec_size; 5326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_link = 0; 5336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_info = 0; 5346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_addralign = oat_exec_alignment; 5356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_TEXT].sh_entsize = 0; 5366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: SHF_WRITE for .dynamic is considered processor specific, do we need it? 5386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_name = shstrtab_dynamic_offset; 5396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_type = llvm::ELF::SHT_DYNAMIC; 5406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_flags = llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC; 5416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_addr = dynamic_offset; 5426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_offset = dynamic_offset; 5436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_size = dynamic_size; 5446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_link = SH_DYNSTR; 5456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_info = 0; 5466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_addralign = dynamic_alignment; 5476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_DYNAMIC].sh_entsize = sizeof(llvm::ELF::Elf32_Dyn); 5486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_name = shstrtab_shstrtab_offset; 5506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_type = llvm::ELF::SHT_STRTAB; 5516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_flags = 0; 5526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_addr = shstrtab_offset; 5536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_offset = shstrtab_offset; 5546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_size = shstrtab_size; 5556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_link = 0; 5566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_info = 0; 5576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_addralign = shstrtab_alignment; 5586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom section_headers[SH_SHSTRTAB].sh_entsize = 0; 5596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // phase 3: writing file 5616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Elf32_Ehdr 5636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!elf_file_->WriteFully(&elf_header, sizeof(elf_header))) { 5646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to write ELF header for " << elf_file_->GetPath(); 5656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 5666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 5676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // PHDR 5696a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (static_cast<off_t>(phdr_offset) != lseek(elf_file_->Fd(), 0, SEEK_CUR)) { 5706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to be at expected ELF program header offset phdr_offset " 5716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom << " for " << elf_file_->GetPath(); 5726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 5736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 5746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!elf_file_->WriteFully(program_headers, sizeof(program_headers))) { 5756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to write ELF program headers for " << elf_file_->GetPath(); 5766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 5776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 5786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .dynsym 5806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom DCHECK_LE(phdr_offset + phdr_size, dynsym_offset); 5816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (static_cast<off_t>(dynsym_offset) != lseek(elf_file_->Fd(), dynsym_offset, SEEK_SET)) { 5826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to seek to .dynsym offset location " << dynsym_offset 5836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom << " for " << elf_file_->GetPath(); 5846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 5856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 5866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!elf_file_->WriteFully(dynsym, sizeof(dynsym))) { 5876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to write .dynsym for " << elf_file_->GetPath(); 5886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 5896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 5906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 5916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .dynstr 5926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom DCHECK_LE(dynsym_offset + dynsym_size, dynstr_offset); 5936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (static_cast<off_t>(dynstr_offset) != lseek(elf_file_->Fd(), dynstr_offset, SEEK_SET)) { 5946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to seek to .dynstr offset " << dynstr_offset 5956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom << " for " << elf_file_->GetPath(); 5966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 5976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 5986a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!elf_file_->WriteFully(&dynstr[0], dynsym_size)) { 5996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to write .dynsym for " << elf_file_->GetPath(); 6006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 6036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .hash 6046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom DCHECK_LE(dynstr_offset + dynstr_size, hash_offset); 6056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (static_cast<off_t>(hash_offset) != lseek(elf_file_->Fd(), hash_offset, SEEK_SET)) { 6066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to seek to .hash offset " << hash_offset 6076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom << " for " << elf_file_->GetPath(); 6086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!elf_file_->WriteFully(hash, sizeof(hash))) { 6116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to write .dynsym for " << elf_file_->GetPath(); 6126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 6156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .rodata .text 6166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom DCHECK_LE(hash_offset + hash_size, oat_data_offset); 6176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (static_cast<off_t>(oat_data_offset) != lseek(elf_file_->Fd(), oat_data_offset, SEEK_SET)) { 6186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to seek to .rodata offset " << oat_data_offset 6196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom << " for " << elf_file_->GetPath(); 6206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 622c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom FileOutputStream output_stream(elf_file_); 623c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom if (!oat_writer.Write(output_stream)) { 6246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath(); 6256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 6286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .dynamic 629c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom DCHECK_LE(oat_data_offset + oat_writer.GetSize(), dynamic_offset); 6306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (static_cast<off_t>(dynamic_offset) != lseek(elf_file_->Fd(), dynamic_offset, SEEK_SET)) { 6316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to seek to .dynamic offset " << dynamic_offset 6326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom << " for " << elf_file_->GetPath(); 6336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!elf_file_->WriteFully(&dynamic_headers[0], dynamic_size)) { 6366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to write .dynamic for " << elf_file_->GetPath(); 6376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 6406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // .shstrtab 6416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom DCHECK_LE(dynamic_offset + dynamic_size, shstrtab_offset); 6426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (static_cast<off_t>(shstrtab_offset) != lseek(elf_file_->Fd(), shstrtab_offset, SEEK_SET)) { 6436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to seek to .shstrtab offset " << shstrtab_offset 6446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom << " for " << elf_file_->GetPath(); 6456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!elf_file_->WriteFully(&shstrtab[0], shstrtab_size)) { 6486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to write .shstrtab for " << elf_file_->GetPath(); 6496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 6526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // section headers (after all sections) 6536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom DCHECK_LE(shstrtab_offset + shstrtab_size, shdr_offset); 6546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (static_cast<off_t>(shdr_offset) != lseek(elf_file_->Fd(), shdr_offset, SEEK_SET)) { 6556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to seek to ELF section headers offset " << shdr_offset 6566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom << " for " << elf_file_->GetPath(); 6576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!elf_file_->WriteFully(section_headers, sizeof(section_headers))) { 6606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to write ELF section headers for " << elf_file_->GetPath(); 6616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 6626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 6636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 6646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "ELF file written successfully: " << elf_file_->GetPath(); 6656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return true; 6666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 6676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 6686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} // namespace art 669