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