elf_writer_quick.cc revision b12f34742be4adaa804cc0d388ba51603bb95955
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" 21c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom#include "buffered_output_stream.h" 227940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h" 2350cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#include "elf_utils.h" 24c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom#include "file_output_stream.h" 256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "globals.h" 266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "oat.h" 27c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom#include "oat_writer.h" 286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "utils.h" 296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromnamespace art { 316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 32b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromstatic constexpr Elf32_Word NextOffset(const Elf32_Shdr& cur, const Elf32_Shdr& prev) { 33b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return RoundUp(prev.sh_size + prev.sh_offset, cur.sh_addralign); 34ad13cb2db8c4a64298ed85c82ae7366ee73f7640Alex Light} 35ad13cb2db8c4a64298ed85c82ae7366ee73f7640Alex Light 36b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromstatic uint8_t MakeStInfo(uint8_t binding, uint8_t type) { 37b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return ((binding) << 4) + ((type) & 0xf); 38b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 39b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 40b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrombool ElfWriterQuick::ElfBuilder::Write() { 41b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // The basic layout of the elf file. Order may be different in final output. 426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Ehdr | 446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr PHDR | 466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr LOAD R | .dynsym .dynstr .hash .rodata 476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr LOAD R X | .text 486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr LOAD RW | .dynamic 496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Phdr DYNAMIC | .dynamic 506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .dynsym | 526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Sym STN_UNDEF | 536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Sym oatdata | 546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Sym oatexec | 556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Sym oatlastword | 566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .dynstr | 586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | \0 | 596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatdata\0 | 606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatexec\0 | 616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatlastword\0 | 626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | boot.oat\0 | 636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .hash | 65b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | Elf32_Word nbucket = b | 66b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | Elf32_Word nchain = c | 67b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | Elf32_Word bucket[0] | 68b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | ... | 69b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | Elf32_Word bucket[b - 1]| 70b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | Elf32_Word chain[0] | 71b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | ... | 72b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | Elf32_Word chain[c - 1] | 736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .rodata | 756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatdata..oatexec-4 | 766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .text | 786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | oatexec..oatlastword | 796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | .dynamic | 816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_SONAME | 826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_HASH | 836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_SYMTAB | 846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_SYMENT | 856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_STRTAB | 866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_STRSZ | 876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Dyn DT_NULL | 88b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // +-------------------------+ (Optional) 89b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .strtab | (Optional) 90b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | program symbol names | (Optional) 91b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // +-------------------------+ (Optional) 92b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .symtab | (Optional) 93b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | program symbols | (Optional) 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 | 104b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .symtab\0 | (Optional) 105b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .strtab\0 | (Optional) 106b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .debug_str\0 | (Optional) 107b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .debug_info\0 | (Optional) 108b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .debug_frame\0 | (Optional) 109b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .debug_abbrev\0 | (Optional) 110b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // +-------------------------+ (Optional) 111b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .debug_str | (Optional) 112b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // +-------------------------+ (Optional) 113b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .debug_info | (Optional) 114b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // +-------------------------+ (Optional) 115b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .debug_frame | (Optional) 116b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // +-------------------------+ (Optional) 117b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | .debug_abbrev | (Optional) 1186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 1196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr NULL | 1206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .dynsym | 1216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .dynstr | 1226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .hash | 1236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .text | 1246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .rodata | 1256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .dynamic | 1266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // | Elf32_Shdr .shstrtab | 127b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | Elf32_Shdr .debug_str | (Optional) 128ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // | Elf32_Shdr .debug_info | (Optional) 12935f72251e722cad03a08e8ceacbd5c244eab5c29Brian Carlstrom // | Elf32_Shdr .debug_frame | (Optional) 130b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | Elf32_Shdr .debug_abbrev| (Optional) 1316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // +-------------------------+ 1326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 134b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (fatal_error_) { 135b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return false; 136b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 137b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Step 1. Figure out all the offsets. 1386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 139b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // What phdr is. 140b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom uint32_t phdr_offset = sizeof(Elf32_Ehdr); 1416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_PHDR = 0; 1426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_LOAD_R__ = 1; 1436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_LOAD_R_X = 2; 1446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_LOAD_RW_ = 3; 1456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_DYNAMIC = 4; 1466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const uint8_t PH_NUM = 5; 14750cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray uint32_t phdr_size = sizeof(Elf32_Phdr) * PH_NUM; 148b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (debug_logging_) { 1496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "phdr_offset=" << phdr_offset << std::hex << " " << phdr_offset; 1506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "phdr_size=" << phdr_size << std::hex << " " << phdr_size; 1516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 15250cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray Elf32_Phdr program_headers[PH_NUM]; 1536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom memset(&program_headers, 0, sizeof(program_headers)); 15450cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_PHDR].p_type = PT_PHDR; 1556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_offset = phdr_offset; 1566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_vaddr = phdr_offset; 1576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_paddr = phdr_offset; 1586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_filesz = sizeof(program_headers); 1596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_PHDR].p_memsz = sizeof(program_headers); 16050cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_PHDR].p_flags = PF_R; 161b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_PHDR].p_align = sizeof(Elf32_Word); 1626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 16350cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_LOAD_R__].p_type = PT_LOAD; 1646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_offset = 0; 1656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_vaddr = 0; 1666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom program_headers[PH_LOAD_R__].p_paddr = 0; 16750cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_LOAD_R__].p_flags = PF_R; 1686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 16950cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_LOAD_R_X].p_type = PT_LOAD; 17050cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_LOAD_R_X].p_flags = PF_R | PF_X; 1716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 17250cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_LOAD_RW_].p_type = PT_LOAD; 17350cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_LOAD_RW_].p_flags = PF_R | PF_W; 1746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 17550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_DYNAMIC].p_type = PT_DYNAMIC; 17650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray program_headers[PH_DYNAMIC].p_flags = PF_R | PF_W; 1776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 178b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the dynstr string. 179b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::string dynstr(dynsym_builder_.GenerateStrtab()); 180b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 181b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Add the SONAME to the dynstr. 182b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom uint32_t dynstr_soname_offset = dynstr.size(); 183b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::string file_name(elf_file_->GetPath()); 184b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom size_t directory_separator_pos = file_name.rfind('/'); 185b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (directory_separator_pos != std::string::npos) { 186b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom file_name = file_name.substr(directory_separator_pos + 1); 187b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 188b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynstr += file_name; 189b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynstr += '\0'; 190b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (debug_logging_) { 191b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "dynstr size (bytes) =" << dynstr.size() 192b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << std::hex << " " << dynstr.size(); 193b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "dynsym size (elements)=" << dynsym_builder_.size() 194b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << std::hex << " " << dynsym_builder_.size(); 195b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 196b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 197b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // get the strtab 198b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::string strtab; 199b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (IncludingDebugSymbols()) { 200b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom strtab = symtab_builder_.GenerateStrtab(); 201b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (debug_logging_) { 202b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "strtab size (bytes) =" << strtab.size() 203b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << std::hex << " " << strtab.size(); 204b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "symtab size (elements) =" << symtab_builder_.size() 205b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << std::hex << " " << symtab_builder_.size(); 206b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 207ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 208ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 209b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the section header string table. 210b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::vector<Elf32_Shdr*> section_ptrs; 211b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::string shstrtab; 212b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom shstrtab += '\0'; 2136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 214b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup sym_undef 215b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Shdr null_hdr; 216b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom memset(&null_hdr, 0, sizeof(null_hdr)); 217b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom null_hdr.sh_type = SHT_NULL; 218b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom null_hdr.sh_link = SHN_UNDEF; 219b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&null_hdr); 220b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 221b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom uint32_t section_index = 1; 222b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 223b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // setup .dynsym 224b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&dynsym_builder_.section_); 225b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(&dynsym_builder_, &shstrtab); 226b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.section_index_ = section_index++; 227b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 228b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup .dynstr 229b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&dynsym_builder_.strtab_.section_); 230b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(&dynsym_builder_.strtab_, &shstrtab); 231b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.strtab_.section_index_ = section_index++; 232b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 233b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup .hash 234b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&hash_builder_.section_); 235b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(&hash_builder_, &shstrtab); 236b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash_builder_.section_index_ = section_index++; 237b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 238b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup .rodata 239b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&rodata_builder_.section_); 240b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(&rodata_builder_, &shstrtab); 241b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom rodata_builder_.section_index_ = section_index++; 242b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 243b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup .text 244b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&text_builder_.section_); 245b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(&text_builder_, &shstrtab); 246b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom text_builder_.section_index_ = section_index++; 247b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 248b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup .dynamic 249b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&dynamic_builder_.section_); 250b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(&dynamic_builder_, &shstrtab); 251b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.section_index_ = section_index++; 252b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 253b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (IncludingDebugSymbols()) { 254b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup .symtab 255b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&symtab_builder_.section_); 256b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(&symtab_builder_, &shstrtab); 257b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.section_index_ = section_index++; 258b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 259b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup .strtab 260b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&symtab_builder_.strtab_.section_); 261b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(&symtab_builder_.strtab_, &shstrtab); 262b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.strtab_.section_index_ = section_index++; 263b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 264b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfRawSectionBuilder* it = other_builders_.data(); 265b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom for (uint32_t cnt = 0; cnt < other_builders_.size(); ++it, ++cnt) { 266b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup all the other sections. 267b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&it->section_); 268b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(it, &shstrtab); 269b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom it->section_index_ = section_index++; 270b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 271b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 272b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup shstrtab 273b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs.push_back(&shstrtab_builder_.section_); 274b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom AssignSectionStr(&shstrtab_builder_, &shstrtab); 275b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom shstrtab_builder_.section_index_ = section_index++; 276b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 277b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (debug_logging_) { 278b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << ".shstrtab size (bytes) =" << shstrtab.size() 279b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << std::hex << " " << shstrtab.size(); 280b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "section list size (elements)=" << section_ptrs.size() 281b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << std::hex << " " << section_ptrs.size(); 282b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 283b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 284b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Fill in the hash section. 285b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::vector<Elf32_Word> hash = dynsym_builder_.GenerateHashContents(); 286b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 287b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (debug_logging_) { 288b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << ".hash size (bytes)=" << hash.size() * sizeof(Elf32_Word) 289b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << std::hex << " " << hash.size() * sizeof(Elf32_Word); 290b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 291b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 292b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word base_offset = sizeof(Elf32_Ehdr) + sizeof(program_headers); 293b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::vector<ElfFilePiece> pieces; 294b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 295b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout in the sections. 296b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // 297b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the dynsym section. 298b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.section_.sh_offset = RoundUp(base_offset, dynsym_builder_.section_.sh_addralign); 299b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.section_.sh_addr = dynsym_builder_.section_.sh_offset; 300b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.section_.sh_size = dynsym_builder_.size()*sizeof(Elf32_Sym); 301b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.section_.sh_link = dynsym_builder_.GetLink(); 302b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 303b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the dynstr section. 304b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.strtab_.section_.sh_offset = NextOffset(dynsym_builder_.strtab_.section_, 305b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.section_); 306b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.strtab_.section_.sh_addr = dynsym_builder_.strtab_.section_.sh_offset; 307b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.strtab_.section_.sh_size = dynstr.size(); 308b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.strtab_.section_.sh_link = dynsym_builder_.strtab_.GetLink(); 309b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 310b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the hash section 311b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash_builder_.section_.sh_offset = NextOffset(hash_builder_.section_, 312b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.strtab_.section_); 313b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash_builder_.section_.sh_addr = hash_builder_.section_.sh_offset; 314b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash_builder_.section_.sh_size = hash.size() * sizeof(Elf32_Word); 315b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash_builder_.section_.sh_link = hash_builder_.GetLink(); 316b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 317b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the rodata section. 318b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom rodata_builder_.section_.sh_offset = NextOffset(rodata_builder_.section_, 319b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash_builder_.section_); 320b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom rodata_builder_.section_.sh_addr = rodata_builder_.section_.sh_offset; 321b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom rodata_builder_.section_.sh_size = rodata_builder_.size_; 322b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom rodata_builder_.section_.sh_link = rodata_builder_.GetLink(); 323b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 324b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the text section. 325b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom text_builder_.section_.sh_offset = NextOffset(text_builder_.section_, rodata_builder_.section_); 326b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom text_builder_.section_.sh_addr = text_builder_.section_.sh_offset; 327b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom text_builder_.section_.sh_size = text_builder_.size_; 328b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom text_builder_.section_.sh_link = text_builder_.GetLink(); 329b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom CHECK_ALIGNED(rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size, kPageSize); 330b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 331b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the dynamic section. 332b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.section_.sh_offset = NextOffset(dynamic_builder_.section_, 333b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom text_builder_.section_); 334b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.section_.sh_addr = dynamic_builder_.section_.sh_offset; 335b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.section_.sh_size = dynamic_builder_.size()*sizeof(Elf32_Dyn); 336b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.section_.sh_link = dynamic_builder_.GetLink(); 337b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 338b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Shdr prev = dynamic_builder_.section_; 339b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (IncludingDebugSymbols()) { 340b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the symtab section. 341b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.section_.sh_offset = NextOffset(symtab_builder_.section_, 342b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.section_); 343b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.section_.sh_addr = 0; 344b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Add to leave space for the null symbol. 345b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.section_.sh_size = symtab_builder_.size()*sizeof(Elf32_Sym); 346b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.section_.sh_link = symtab_builder_.GetLink(); 347b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 348b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the dynstr section. 349b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.strtab_.section_.sh_offset = NextOffset(symtab_builder_.strtab_.section_, 350b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.section_); 351b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.strtab_.section_.sh_addr = 0; 352b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.strtab_.section_.sh_size = strtab.size(); 353b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab_builder_.strtab_.section_.sh_link = symtab_builder_.strtab_.GetLink(); 354b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 355b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom prev = symtab_builder_.strtab_.section_; 356b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 357b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (debug_logging_) { 358b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "dynsym off=" << dynsym_builder_.section_.sh_offset 359b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " dynsym size=" << dynsym_builder_.section_.sh_size; 360b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "dynstr off=" << dynsym_builder_.strtab_.section_.sh_offset 361b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " dynstr size=" << dynsym_builder_.strtab_.section_.sh_size; 362b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "hash off=" << hash_builder_.section_.sh_offset 363b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " hash size=" << hash_builder_.section_.sh_size; 364b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "rodata off=" << rodata_builder_.section_.sh_offset 365b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " rodata size=" << rodata_builder_.section_.sh_size; 366b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "text off=" << text_builder_.section_.sh_offset 367b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " text size=" << text_builder_.section_.sh_size; 368b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "dynamic off=" << dynamic_builder_.section_.sh_offset 369b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " dynamic size=" << dynamic_builder_.section_.sh_size; 370b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (IncludingDebugSymbols()) { 371b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "symtab off=" << symtab_builder_.section_.sh_offset 372b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " symtab size=" << symtab_builder_.section_.sh_size; 373b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "strtab off=" << symtab_builder_.strtab_.section_.sh_offset 374b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " strtab size=" << symtab_builder_.strtab_.section_.sh_size; 375b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 3766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 377b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the extra sections. (This will deal with the debug 378b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // sections if they are there) 379b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) { 380b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom it->section_.sh_offset = NextOffset(it->section_, prev); 381b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom it->section_.sh_addr = 0; 382b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom it->section_.sh_size = it->GetBuffer()->size(); 383b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom it->section_.sh_link = it->GetLink(); 384b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(it->name_, it->section_.sh_offset, 385b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom it->GetBuffer()->data(), it->GetBuffer()->size())); 386b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom prev = it->section_; 387b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (debug_logging_) { 388b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << it->name_ << " off=" << it->section_.sh_offset 389b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " " << it->name_ << " size=" << it->section_.sh_size; 390b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 3916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 392b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Get the layout of the shstrtab section 393b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom shstrtab_builder_.section_.sh_offset = NextOffset(shstrtab_builder_.section_, prev); 394b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom shstrtab_builder_.section_.sh_addr = 0; 395b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom shstrtab_builder_.section_.sh_size = shstrtab.size(); 396b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom shstrtab_builder_.section_.sh_link = shstrtab_builder_.GetLink(); 397b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (debug_logging_) { 398b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "shstrtab off=" << shstrtab_builder_.section_.sh_offset 399b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << " shstrtab size=" << shstrtab_builder_.section_.sh_size; 400b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 401b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 402b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // The section list comes after come after. 403b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word sections_offset = RoundUp( 404b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom shstrtab_builder_.section_.sh_offset + shstrtab_builder_.section_.sh_size, 405b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom sizeof(Elf32_Word)); 406b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 407b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup the actual symbol arrays. 408b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::vector<Elf32_Sym> dynsym = dynsym_builder_.GenerateSymtab(); 409b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom CHECK_EQ(dynsym.size()*sizeof(Elf32_Sym), dynsym_builder_.section_.sh_size); 410b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::vector<Elf32_Sym> symtab; 411b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (IncludingDebugSymbols()) { 412b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab = symtab_builder_.GenerateSymtab(); 413b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom CHECK_EQ(symtab.size()*sizeof(Elf32_Sym), symtab_builder_.section_.sh_size); 414b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 415b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 416b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Setup the dynamic section. 417b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // This will add the 2 values we cannot know until now time, namely the size 418b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // and the soname_offset. 419b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::vector<Elf32_Dyn> dynamic = dynamic_builder_.GetDynamics(dynstr.size(), 420b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynstr_soname_offset); 421b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom CHECK_EQ(dynamic.size()*sizeof(Elf32_Dyn), dynamic_builder_.section_.sh_size); 422b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 423b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Finish setup of the program headers now that we know the layout of the 424b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // whole file. 425b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word load_r_size = rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size; 426b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_R__].p_filesz = load_r_size; 427b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_R__].p_memsz = load_r_size; 428b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_R__].p_align = rodata_builder_.section_.sh_addralign; 429b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 430b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word load_rx_size = text_builder_.section_.sh_size; 431b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_R_X].p_offset = text_builder_.section_.sh_offset; 432b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_R_X].p_vaddr = text_builder_.section_.sh_offset; 433b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_R_X].p_paddr = text_builder_.section_.sh_offset; 434b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_R_X].p_filesz = load_rx_size; 435b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_R_X].p_memsz = load_rx_size; 436b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_R_X].p_align = text_builder_.section_.sh_addralign; 437b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 438b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_RW_].p_offset = dynamic_builder_.section_.sh_offset; 439b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_RW_].p_vaddr = dynamic_builder_.section_.sh_offset; 440b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_RW_].p_paddr = dynamic_builder_.section_.sh_offset; 441b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_RW_].p_filesz = dynamic_builder_.section_.sh_size; 442b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_RW_].p_memsz = dynamic_builder_.section_.sh_size; 443b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_LOAD_RW_].p_align = dynamic_builder_.section_.sh_addralign; 444b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 445b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_DYNAMIC].p_offset = dynamic_builder_.section_.sh_offset; 446b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_DYNAMIC].p_vaddr = dynamic_builder_.section_.sh_offset; 447b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_DYNAMIC].p_paddr = dynamic_builder_.section_.sh_offset; 448b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_DYNAMIC].p_filesz = dynamic_builder_.section_.sh_size; 449b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_DYNAMIC].p_memsz = dynamic_builder_.section_.sh_size; 450b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom program_headers[PH_DYNAMIC].p_align = dynamic_builder_.section_.sh_addralign; 451b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 452b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Finish setup of the Ehdr values. 453b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_phoff = phdr_offset; 454b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_shoff = sections_offset; 455b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_phnum = PH_NUM; 456b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_shnum = section_ptrs.size(); 457b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_shstrndx = shstrtab_builder_.section_index_; 458b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 459b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Add the rest of the pieces to the list. 460b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece("Elf Header", 0, &elf_header_, sizeof(elf_header_))); 461b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece("Program headers", phdr_offset, 462b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom &program_headers, sizeof(program_headers))); 463b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(".dynamic", dynamic_builder_.section_.sh_offset, 464b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic.data(), dynamic_builder_.section_.sh_size)); 465b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(".dynsym", dynsym_builder_.section_.sh_offset, 466b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym.data(), dynsym.size()*sizeof(Elf32_Sym))); 467b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(".dynstr", dynsym_builder_.strtab_.section_.sh_offset, 468b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynstr.c_str(), dynstr.size())); 469b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(".hash", hash_builder_.section_.sh_offset, 470b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash.data(), hash.size() * sizeof(Elf32_Word))); 471b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(".rodata", rodata_builder_.section_.sh_offset, 472b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom NULL, rodata_builder_.section_.sh_size)); 473b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(".text", text_builder_.section_.sh_offset, 474b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom NULL, text_builder_.section_.sh_size)); 475b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (IncludingDebugSymbols()) { 476b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(".symtab", symtab_builder_.section_.sh_offset, 477b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symtab.data(), symtab.size() * sizeof(Elf32_Sym))); 478b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(".strtab", symtab_builder_.strtab_.section_.sh_offset, 479b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom strtab.c_str(), strtab.size())); 480b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 481b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece(".shstrtab", shstrtab_builder_.section_.sh_offset, 482b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom &shstrtab[0], shstrtab.size())); 483b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom for (uint32_t i = 0; i < section_ptrs.size(); ++i) { 484b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Just add all the sections in induvidually since they are all over the 485b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // place on the heap/stack. 486b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word cur_off = sections_offset + i * sizeof(Elf32_Shdr); 487b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom pieces.push_back(ElfFilePiece("section table piece", cur_off, 488b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom section_ptrs[i], sizeof(Elf32_Shdr))); 489b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 490b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 491b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (!WriteOutFile(pieces)) { 492b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(ERROR) << "Unable to write to file " << elf_file_->GetPath(); 4936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 4946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 495b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // write out the actual oat file data. 496b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word oat_data_offset = rodata_builder_.section_.sh_offset; 497b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (static_cast<off_t>(oat_data_offset) != lseek(elf_file_->Fd(), oat_data_offset, SEEK_SET)) { 498b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom PLOG(ERROR) << "Failed to seek to .rodata offset " << oat_data_offset 4996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom << " for " << elf_file_->GetPath(); 5006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 5016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 502b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::unique_ptr<BufferedOutputStream> output_stream( 503b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom new BufferedOutputStream(new FileOutputStream(elf_file_))); 504b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (!oat_writer_->Write(output_stream.get())) { 505b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath(); 5066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 5076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 5086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 509b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return true; 510b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 5116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 512b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrombool ElfWriterQuick::ElfBuilder::WriteOutFile(const std::vector<ElfFilePiece>& pieces) { 513b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // TODO It would be nice if this checked for overlap. 514b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom for (auto it = pieces.begin(); it != pieces.end(); ++it) { 515b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (it->data_) { 516b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (static_cast<off_t>(it->offset_) != lseek(elf_file_->Fd(), it->offset_, SEEK_SET)) { 517b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom PLOG(ERROR) << "Failed to seek to " << it->dbg_name_ << " offset location " 518b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << it->offset_ << " for " << elf_file_->GetPath(); 519b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return false; 520b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 521b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (!elf_file_->WriteFully(it->data_, it->size_)) { 522b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom PLOG(ERROR) << "Failed to write " << it->dbg_name_ << " for " << elf_file_->GetPath(); 523b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return false; 524b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 525b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 5266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 527b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return true; 528b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 529b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 530b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromvoid ElfWriterQuick::ElfBuilder::SetupDynamic() { 531b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.AddDynamicTag(DT_HASH, 0, &hash_builder_); 532b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.AddDynamicTag(DT_STRTAB, 0, &dynsym_builder_.strtab_); 533b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.AddDynamicTag(DT_SYMTAB, 0, &dynsym_builder_); 534b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamic_builder_.AddDynamicTag(DT_SYMENT, sizeof(Elf32_Sym)); 535b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 536b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 537b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromvoid ElfWriterQuick::ElfBuilder::SetupRequiredSymbols() { 538b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.AddSymbol("oatdata", &rodata_builder_, 0, true, 539b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom rodata_builder_.size_, STB_GLOBAL, STT_OBJECT); 540b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.AddSymbol("oatexec", &text_builder_, 0, true, 541b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom text_builder_.size_, STB_GLOBAL, STT_OBJECT); 542b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynsym_builder_.AddSymbol("oatlastword", &text_builder_, text_builder_.size_ - 4, 543b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom true, 4, STB_GLOBAL, STT_OBJECT); 544b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 545b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 546b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromvoid ElfWriterQuick::ElfDynamicBuilder::AddDynamicTag(Elf32_Sword tag, Elf32_Sword d_un) { 547b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (tag == DT_NULL) { 548b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return; 5496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 550b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamics_.push_back({NULL, tag, d_un}); 551b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 5526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 553b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromvoid ElfWriterQuick::ElfDynamicBuilder::AddDynamicTag(Elf32_Sword tag, Elf32_Sword d_un, 554b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfSectionBuilder* section) { 555b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (tag == DT_NULL) { 556b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return; 5576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 558b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom dynamics_.push_back({section, tag, d_un}); 559b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 560b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 561b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromstd::vector<Elf32_Dyn> ElfWriterQuick::ElfDynamicBuilder::GetDynamics(Elf32_Sword strsz, 562b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Sword soname) { 563b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::vector<Elf32_Dyn> ret; 564b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom for (auto it = dynamics_.cbegin(); it != dynamics_.cend(); ++it) { 565b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (it->section_) { 566b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // We are adding an address relative to a section. 567b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ret.push_back( 568b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom {it->tag_, {it->off_ + static_cast<Elf32_Sword>(it->section_->section_.sh_addr)}}); 569b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } else { 570b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ret.push_back({it->tag_, {it->off_}}); 571b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 5726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 573b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ret.push_back({DT_STRSZ, {strsz}}); 574b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ret.push_back({DT_SONAME, {soname}}); 575b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ret.push_back({DT_NULL, {0}}); 576b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return ret; 577b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 5786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 579b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromstd::vector<Elf32_Sym> ElfWriterQuick::ElfSymtabBuilder::GenerateSymtab() { 580b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::vector<Elf32_Sym> ret; 581b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Sym undef_sym; 582b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom memset(&undef_sym, 0, sizeof(undef_sym)); 583b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom undef_sym.st_shndx = SHN_UNDEF; 584b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ret.push_back(undef_sym); 585b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 586b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom for (auto it = symbols_.cbegin(); it != symbols_.cend(); ++it) { 587b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Sym sym; 588b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom memset(&sym, 0, sizeof(sym)); 589b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom sym.st_name = it->name_idx_; 590b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (it->is_relative_) { 591b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom sym.st_value = it->addr_ + it->section_->section_.sh_offset; 592b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } else { 593b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom sym.st_value = it->addr_; 594b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 595b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom sym.st_size = it->size_; 596b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom sym.st_other = it->other_; 597b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom sym.st_shndx = it->section_->section_index_; 598b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom sym.st_info = it->info_; 599b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 600b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ret.push_back(sym); 6016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 602b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return ret; 603b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 604b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 605b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromstd::string ElfWriterQuick::ElfSymtabBuilder::GenerateStrtab() { 606b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::string tab; 607b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom tab += '\0'; 608b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom for (auto it = symbols_.begin(); it != symbols_.end(); ++it) { 609b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom it->name_idx_ = tab.size(); 610b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom tab += it->name_; 611b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom tab += '\0'; 6126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 613b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom strtab_.section_.sh_size = tab.size(); 614b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return tab; 615b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 6166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 617b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromvoid ElfWriterQuick::ElfBuilder::AssignSectionStr( 618b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfSectionBuilder* builder, std::string* strtab) { 619b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom builder->section_.sh_name = strtab->size(); 620b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom *strtab += builder->name_; 621b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom *strtab += '\0'; 622b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (debug_logging_) { 623b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(INFO) << "adding section name \"" << builder->name_ << "\" " 624b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom << "to shstrtab at offset " << builder->section_.sh_name; 62535f72251e722cad03a08e8ceacbd5c244eab5c29Brian Carlstrom } 626b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 627b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 628b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom// from bionic 629b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromstatic unsigned elfhash(const char *_name) { 630b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom const unsigned char *name = (const unsigned char *) _name; 631b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom unsigned h = 0, g; 632b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 633b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom while (*name) { 634b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom h = (h << 4) + *name++; 635b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom g = h & 0xf0000000; 636b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom h ^= g; 637b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom h ^= g >> 24; 638ad13cb2db8c4a64298ed85c82ae7366ee73f7640Alex Light } 639b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return h; 640b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 641ad13cb2db8c4a64298ed85c82ae7366ee73f7640Alex Light 642b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 643b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromstd::vector<Elf32_Word> ElfWriterQuick::ElfSymtabBuilder::GenerateHashContents() { 644b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Here is how The ELF hash table works. 645b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // There are 3 arrays to worry about. 646b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // * The symbol table where the symbol information is. 647b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // * The bucket array which is an array of indexes into the symtab and chain. 648b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // * The chain array which is also an array of indexes into the symtab and chain. 649b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // 650b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Lets say the state is something like this. 651b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // +--------+ +--------+ +-----------+ 652b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | symtab | | bucket | | chain | 653b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | NULL | | 1 | | STN_UNDEF | 654b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | <sym1> | | 4 | | 2 | 655b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | <sym2> | | | | 5 | 656b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | <sym3> | | | | STN_UNDEF | 657b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | <sym4> | | | | 3 | 658b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // | <sym5> | | | | STN_UNDEF | 659b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // +--------+ +--------+ +-----------+ 660b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // 661b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // The lookup process (in python psudocode) is 662b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // 663b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // def GetSym(name): 664b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // # NB STN_UNDEF == 0 665b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // indx = bucket[elfhash(name) % num_buckets] 666b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // while indx != STN_UNDEF: 667b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // if GetSymbolName(symtab[indx]) == name: 668b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // return symtab[indx] 669b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // indx = chain[indx] 670b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // return SYMBOL_NOT_FOUND 671b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // 672b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Between bucket and chain arrays every symtab index must be present exactly 673b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // once (except for STN_UNDEF, which must be present 1 + num_bucket times). 674b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 675b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Select number of buckets. 676b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // This is essentially arbitrary. 677b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word nbuckets; 678b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word chain_size = size(); 679b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (symbols_.size() < 8) { 680b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom nbuckets = 2; 681b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } else if (symbols_.size() < 32) { 682b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom nbuckets = 4; 683b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } else if (symbols_.size() < 256) { 684b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom nbuckets = 16; 685b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } else { 686b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Have about 32 ids per bucket. 687b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom nbuckets = RoundUp(symbols_.size()/32, 2); 688b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 689b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom std::vector<Elf32_Word> hash; 690b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash.push_back(nbuckets); 691b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash.push_back(chain_size); 692b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom uint32_t bucket_offset = hash.size(); 693b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom uint32_t chain_offset = bucket_offset + nbuckets; 694b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash.resize(hash.size() + nbuckets + chain_size, 0); 695b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 696b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word* buckets = hash.data() + bucket_offset; 697b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word* chain = hash.data() + chain_offset; 698b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 699b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Set up the actual hash table. 700b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom for (Elf32_Word i = 0; i < symbols_.size(); i++) { 701b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Add 1 since we need to have the null symbol that is not in the symbols 702b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // list. 703b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word index = i + 1; 704b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word hash_val = static_cast<Elf32_Word>(elfhash(symbols_[i].name_.c_str())) % nbuckets; 705b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom if (buckets[hash_val] == 0) { 706b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom buckets[hash_val] = index; 707b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } else { 708b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash_val = buckets[hash_val]; 709b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom CHECK_LT(hash_val, chain_size); 710b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom while (chain[hash_val] != 0) { 711b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom hash_val = chain[hash_val]; 712b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom CHECK_LT(hash_val, chain_size); 713b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 714b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom chain[hash_val] = index; 715b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Check for loops. Works because if this is non-empty then there must be 716b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // another cell which already contains the same symbol index as this one, 717b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // which means some symbol has more then one name, which isn't allowed. 718b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom CHECK_EQ(chain[index], static_cast<Elf32_Word>(0)); 71935f72251e722cad03a08e8ceacbd5c244eab5c29Brian Carlstrom } 720b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom } 721b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 722b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return hash; 723b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 724b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 725b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromvoid ElfWriterQuick::ElfBuilder::SetupEhdr() { 726b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom memset(&elf_header_, 0, sizeof(elf_header_)); 727b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ident[EI_MAG0] = ELFMAG0; 728b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ident[EI_MAG1] = ELFMAG1; 729b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ident[EI_MAG2] = ELFMAG2; 730b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ident[EI_MAG3] = ELFMAG3; 731b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ident[EI_CLASS] = ELFCLASS32; 732b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ident[EI_DATA] = ELFDATA2LSB; 733b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ident[EI_VERSION] = EV_CURRENT; 734b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ident[EI_OSABI] = ELFOSABI_LINUX; 735b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ident[EI_ABIVERSION] = 0; 736b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_type = ET_DYN; 737b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_version = 1; 738b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_entry = 0; 739b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_ehsize = sizeof(Elf32_Ehdr); 740b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_phentsize = sizeof(Elf32_Phdr); 741b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_shentsize = sizeof(Elf32_Shdr); 742b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_phoff = sizeof(Elf32_Ehdr); 743b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 744ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 745b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromvoid ElfWriterQuick::ElfBuilder::SetISA(InstructionSet isa) { 746b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom switch (isa) { 747b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom case kArm: 748b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom // Fall through. 749b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom case kThumb2: { 750b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_machine = EM_ARM; 751b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_flags = EF_ARM_EABI_VER5; 752b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom break; 753ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 754b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom case kArm64: { 755b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_machine = EM_AARCH64; 756b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_flags = 0; 757b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom break; 758ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 759b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom case kX86: { 760b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_machine = EM_386; 761b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_flags = 0; 762b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom break; 763ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 764b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom case kX86_64: { 765b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_machine = EM_X86_64; 766b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_flags = 0; 767b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom break; 768ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 769b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom case kMips: { 770b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_machine = EM_MIPS; 771b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom elf_header_.e_flags = (EF_MIPS_NOREORDER | 772b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom EF_MIPS_PIC | 773b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom EF_MIPS_CPIC | 774b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom EF_MIPS_ABI_O32 | 775b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom EF_MIPS_ARCH_32R2); 776b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom break; 777ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 778b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom default: { 779b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom fatal_error_ = true; 780b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom LOG(FATAL) << "Unknown instruction set: " << isa; 781b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom break; 782ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 783ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 784b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 785ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 786b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstromvoid ElfWriterQuick::ElfSymtabBuilder::AddSymbol( 787b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom const std::string& name, const ElfSectionBuilder* section, Elf32_Addr addr, 788b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom bool is_relative, Elf32_Word size, uint8_t binding, uint8_t type, uint8_t other) { 789b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom CHECK(section); 790b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfSymtabBuilder::ElfSymbolState state {name, section, addr, size, is_relative, 791b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom MakeStInfo(binding, type), other, 0}; 792b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom symbols_.push_back(state); 793b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 794b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 795b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrombool ElfWriterQuick::Create(File* elf_file, 796b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom OatWriter* oat_writer, 797b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom const std::vector<const DexFile*>& dex_files, 798b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom const std::string& android_root, 799b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom bool is_host, 800b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom const CompilerDriver& driver) { 801b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfWriterQuick elf_writer(driver, elf_file); 802b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return elf_writer.Write(oat_writer, dex_files, android_root, is_host); 803b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 804b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 805b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrombool ElfWriterQuick::Write(OatWriter* oat_writer, 806b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom const std::vector<const DexFile*>& dex_files_unused, 807b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom const std::string& android_root_unused, 808b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom bool is_host_unused) { 809b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom const bool debug = false; 810b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom const OatHeader& oat_header = oat_writer->GetOatHeader(); 811b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom Elf32_Word oat_data_size = oat_header.GetExecutableOffset(); 812b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size; 813b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 814b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfBuilder builder(oat_writer, elf_file_, compiler_driver_->GetInstructionSet(), 0, 815b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom oat_data_size, oat_data_size, oat_exec_size, false, debug); 816b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 817b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom bool generateDebugInformation = compiler_driver_->GetCallFrameInformation() != nullptr; 818ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell if (generateDebugInformation) { 819b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfRawSectionBuilder debug_info(".debug_info", SHT_PROGBITS, 0, NULL, 0, 1, 0); 820b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfRawSectionBuilder debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, NULL, 0, 1, 0); 821b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfRawSectionBuilder debug_str(".debug_str", SHT_PROGBITS, 0, NULL, 0, 1, 0); 822b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom ElfRawSectionBuilder debug_frame(".debug_frame", SHT_PROGBITS, 0, NULL, 0, 4, 0); 823b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom debug_frame.SetBuffer(*compiler_driver_->GetCallFrameInformation()); 824b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 825b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom FillInCFIInformation(oat_writer, debug_info.GetBuffer(), 826b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom debug_abbrev.GetBuffer(), debug_str.GetBuffer()); 827b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom builder.RegisterRawSection(debug_info); 828b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom builder.RegisterRawSection(debug_abbrev); 829b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom builder.RegisterRawSection(debug_frame); 830b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom builder.RegisterRawSection(debug_str); 8316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 8326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 833b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom return builder.Write(); 834b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 835ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 836ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendellstatic void UpdateWord(std::vector<uint8_t>*buf, int offset, int data) { 837ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell (*buf)[offset+0] = data; 838ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell (*buf)[offset+1] = data >> 8; 839ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell (*buf)[offset+2] = data >> 16; 840ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell (*buf)[offset+3] = data >> 24; 841ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell} 842ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 843ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendellstatic void PushWord(std::vector<uint8_t>*buf, int data) { 844ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell buf->push_back(data & 0xff); 845ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell buf->push_back((data >> 8) & 0xff); 846ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell buf->push_back((data >> 16) & 0xff); 847ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell buf->push_back((data >> 24) & 0xff); 848ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell} 849ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 850ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendellstatic void PushHalf(std::vector<uint8_t>*buf, int data) { 851ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell buf->push_back(data & 0xff); 852ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell buf->push_back((data >> 8) & 0xff); 853ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell} 854ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 855ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell// DWARF constants needed to generate CFI information. 856ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendellenum { 857ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Tag encodings. 858ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_TAG_compile_unit = 0x11, 859ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_TAG_subprogram = 0X2e, 860ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 861ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Attribute encodings. 862ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_AT_name = 0x03, 863ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_AT_low_pc = 0x11, 864ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_AT_high_pc = 0x12, 865ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_AT_language = 0x13, 866ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 867ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Constant encoding. 868ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_CHILDREN_no = 0x00, 869ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_CHILDREN_yes = 0x01, 870ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 871ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Attribute form encodings. 872ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_FORM_addr = 0x01, 873ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_FORM_data1 = 0x0b, 874ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_FORM_strp = 0x0e, 875ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 876ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Language encoding. 877ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell DW_LANG_Java = 0x000b 878ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell}; 879ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 880ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendellvoid ElfWriterQuick::FillInCFIInformation(OatWriter* oat_writer, 881ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell std::vector<uint8_t>* dbg_info, 882ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell std::vector<uint8_t>* dbg_abbrev, 883ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell std::vector<uint8_t>* dbg_str) { 884ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Create the debug_abbrev section with boilerplate information. 885ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // We only care about low_pc and high_pc right now for the compilation 886ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // unit and methods. 887ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 888ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Tag 1: Compilation unit: DW_TAG_compile_unit. 889ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(1); 890ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_TAG_compile_unit); 891ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 892ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // There are children (the methods). 893ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_CHILDREN_yes); 894ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 895ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // DW_LANG_Java DW_FORM_data1. 896ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_AT_language); 897ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_FORM_data1); 898ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 899ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // DW_AT_low_pc DW_FORM_addr. 900ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_AT_low_pc); 901ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_FORM_addr); 902ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 903ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // DW_AT_high_pc DW_FORM_addr. 904ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_AT_high_pc); 905ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_FORM_addr); 906ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 907ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // End of DW_TAG_compile_unit. 908ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushHalf(dbg_abbrev, 0); 909ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 910ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Tag 2: Compilation unit: DW_TAG_subprogram. 911ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(2); 912ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_TAG_subprogram); 913ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 914ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // There are no children. 915ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_CHILDREN_no); 916ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 917ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Name of the method. 918ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_AT_name); 919ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_FORM_strp); 920ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 921ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // DW_AT_low_pc DW_FORM_addr. 922ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_AT_low_pc); 923ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_FORM_addr); 924ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 925ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // DW_AT_high_pc DW_FORM_addr. 926ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_AT_high_pc); 927ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_abbrev->push_back(DW_FORM_addr); 928ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 929ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // End of DW_TAG_subprogram. 930ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushHalf(dbg_abbrev, 0); 931ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 932ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Start the debug_info section with the header information 933ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // 'unit_length' will be filled in later. 934ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushWord(dbg_info, 0); 935ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 936ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // 'version' - 3. 937ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushHalf(dbg_info, 3); 938ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 939ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Offset into .debug_abbrev section (always 0). 940ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushWord(dbg_info, 0); 941ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 942ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Address size: 4. 943ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_info->push_back(4); 944ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 945ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Start the description for the compilation unit. 946ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // This uses tag 1. 947ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_info->push_back(1); 948ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 949ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // The language is Java. 950ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_info->push_back(DW_LANG_Java); 951ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 952ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Leave space for low_pc and high_pc. 953ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell int low_pc_offset = dbg_info->size(); 954ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushWord(dbg_info, 0); 955ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushWord(dbg_info, 0); 956ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 957ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Walk through the information in the method table, and enter into dbg_info. 958ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell const std::vector<OatWriter::DebugInfo>& dbg = oat_writer->GetCFIMethodInfo(); 959ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell uint32_t low_pc = 0xFFFFFFFFU; 960ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell uint32_t high_pc = 0; 961ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 962ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell for (uint32_t i = 0; i < dbg.size(); i++) { 963ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell const OatWriter::DebugInfo& info = dbg[i]; 964ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell if (info.low_pc_ < low_pc) { 965ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell low_pc = info.low_pc_; 966ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 967ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell if (info.high_pc_ > high_pc) { 968ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell high_pc = info.high_pc_; 969ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 970ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 971ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Start a new TAG: subroutine (2). 972ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_info->push_back(2); 973ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 974ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Enter the name into the string table (and NUL terminate). 975ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell uint32_t str_offset = dbg_str->size(); 976ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_str->insert(dbg_str->end(), info.method_name_.begin(), info.method_name_.end()); 977ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_str->push_back('\0'); 978ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 979ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Enter name, low_pc, high_pc. 980ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushWord(dbg_info, str_offset); 981ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushWord(dbg_info, info.low_pc_); 982ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell PushWord(dbg_info, info.high_pc_); 983ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell } 984ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 985ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // One byte terminator 986ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell dbg_info->push_back(0); 987ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 988ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // We have now walked all the methods. Fill in lengths and low/high PCs. 989ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell UpdateWord(dbg_info, 0, dbg_info->size() - 4); 990ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell UpdateWord(dbg_info, low_pc_offset, low_pc); 991ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell UpdateWord(dbg_info, low_pc_offset + 4, high_pc); 9926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 9936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 9946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} // namespace art 995