elf_writer_quick.cc revision 18a49cc2f956dec648e0a13186d42374023d47a7
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 "elf_writer_quick.h" 18 19#include <unordered_map> 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_file.h" 27#include "elf_utils.h" 28#include "file_output_stream.h" 29#include "globals.h" 30#include "leb128.h" 31#include "oat.h" 32#include "oat_writer.h" 33#include "utils.h" 34 35namespace art { 36 37template <typename Elf_Word, typename Elf_Shdr> 38static constexpr Elf_Word NextOffset(const Elf_Shdr& cur, const Elf_Shdr& prev) { 39 return RoundUp(prev.sh_size + prev.sh_offset, cur.sh_addralign); 40} 41 42static uint8_t MakeStInfo(uint8_t binding, uint8_t type) { 43 return ((binding) << 4) + ((type) & 0xf); 44} 45 46static void PushByte(std::vector<uint8_t>* buf, int data) { 47 buf->push_back(data & 0xff); 48} 49 50static uint32_t PushStr(std::vector<uint8_t>* buf, const char* str, const char* def = nullptr) { 51 if (str == nullptr) { 52 str = def; 53 } 54 55 uint32_t offset = buf->size(); 56 for (size_t i = 0; str[i] != '\0'; ++i) { 57 buf->push_back(str[i]); 58 } 59 buf->push_back('\0'); 60 return offset; 61} 62 63static uint32_t PushStr(std::vector<uint8_t>* buf, const std::string &str) { 64 uint32_t offset = buf->size(); 65 buf->insert(buf->end(), str.begin(), str.end()); 66 buf->push_back('\0'); 67 return offset; 68} 69 70static void UpdateWord(std::vector<uint8_t>* buf, int offset, int data) { 71 (*buf)[offset+0] = data; 72 (*buf)[offset+1] = data >> 8; 73 (*buf)[offset+2] = data >> 16; 74 (*buf)[offset+3] = data >> 24; 75} 76 77static void PushHalf(std::vector<uint8_t>* buf, int data) { 78 buf->push_back(data & 0xff); 79 buf->push_back((data >> 8) & 0xff); 80} 81 82template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 83 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 84 typename Elf_Phdr, typename Elf_Shdr> 85bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 86 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::Init() { 87 // The basic layout of the elf file. Order may be different in final output. 88 // +-------------------------+ 89 // | Elf_Ehdr | 90 // +-------------------------+ 91 // | Elf_Phdr PHDR | 92 // | Elf_Phdr LOAD R | .dynsym .dynstr .hash .rodata 93 // | Elf_Phdr LOAD R X | .text 94 // | Elf_Phdr LOAD RW | .dynamic 95 // | Elf_Phdr DYNAMIC | .dynamic 96 // +-------------------------+ 97 // | .dynsym | 98 // | Elf_Sym STN_UNDEF | 99 // | Elf_Sym oatdata | 100 // | Elf_Sym oatexec | 101 // | Elf_Sym oatlastword | 102 // +-------------------------+ 103 // | .dynstr | 104 // | \0 | 105 // | oatdata\0 | 106 // | oatexec\0 | 107 // | oatlastword\0 | 108 // | boot.oat\0 | 109 // +-------------------------+ 110 // | .hash | 111 // | Elf_Word nbucket = b | 112 // | Elf_Word nchain = c | 113 // | Elf_Word bucket[0] | 114 // | ... | 115 // | Elf_Word bucket[b - 1] | 116 // | Elf_Word chain[0] | 117 // | ... | 118 // | Elf_Word chain[c - 1] | 119 // +-------------------------+ 120 // | .rodata | 121 // | oatdata..oatexec-4 | 122 // +-------------------------+ 123 // | .text | 124 // | oatexec..oatlastword | 125 // +-------------------------+ 126 // | .dynamic | 127 // | Elf_Dyn DT_SONAME | 128 // | Elf_Dyn DT_HASH | 129 // | Elf_Dyn DT_SYMTAB | 130 // | Elf_Dyn DT_SYMENT | 131 // | Elf_Dyn DT_STRTAB | 132 // | Elf_Dyn DT_STRSZ | 133 // | Elf_Dyn DT_NULL | 134 // +-------------------------+ (Optional) 135 // | .strtab | (Optional) 136 // | program symbol names | (Optional) 137 // +-------------------------+ (Optional) 138 // | .symtab | (Optional) 139 // | program symbols | (Optional) 140 // +-------------------------+ 141 // | .shstrtab | 142 // | \0 | 143 // | .dynamic\0 | 144 // | .dynsym\0 | 145 // | .dynstr\0 | 146 // | .hash\0 | 147 // | .rodata\0 | 148 // | .text\0 | 149 // | .shstrtab\0 | 150 // | .symtab\0 | (Optional) 151 // | .strtab\0 | (Optional) 152 // | .debug_str\0 | (Optional) 153 // | .debug_info\0 | (Optional) 154 // | .eh_frame\0 | (Optional) 155 // | .debug_line\0 | (Optional) 156 // | .debug_abbrev\0 | (Optional) 157 // +-------------------------+ (Optional) 158 // | .debug_info | (Optional) 159 // +-------------------------+ (Optional) 160 // | .debug_abbrev | (Optional) 161 // +-------------------------+ (Optional) 162 // | .eh_frame | (Optional) 163 // +-------------------------+ (Optional) 164 // | .debug_line | (Optional) 165 // +-------------------------+ (Optional) 166 // | .debug_str | (Optional) 167 // +-------------------------+ (Optional) 168 // | Elf_Shdr NULL | 169 // | Elf_Shdr .dynsym | 170 // | Elf_Shdr .dynstr | 171 // | Elf_Shdr .hash | 172 // | Elf_Shdr .text | 173 // | Elf_Shdr .rodata | 174 // | Elf_Shdr .dynamic | 175 // | Elf_Shdr .shstrtab | 176 // | Elf_Shdr .debug_info | (Optional) 177 // | Elf_Shdr .debug_abbrev | (Optional) 178 // | Elf_Shdr .eh_frame | (Optional) 179 // | Elf_Shdr .debug_line | (Optional) 180 // | Elf_Shdr .debug_str | (Optional) 181 // +-------------------------+ 182 183 if (fatal_error_) { 184 return false; 185 } 186 // Step 1. Figure out all the offsets. 187 188 if (debug_logging_) { 189 LOG(INFO) << "phdr_offset=" << PHDR_OFFSET << std::hex << " " << PHDR_OFFSET; 190 LOG(INFO) << "phdr_size=" << PHDR_SIZE << std::hex << " " << PHDR_SIZE; 191 } 192 193 memset(&program_headers_, 0, sizeof(program_headers_)); 194 program_headers_[PH_PHDR].p_type = PT_PHDR; 195 program_headers_[PH_PHDR].p_offset = PHDR_OFFSET; 196 program_headers_[PH_PHDR].p_vaddr = PHDR_OFFSET; 197 program_headers_[PH_PHDR].p_paddr = PHDR_OFFSET; 198 program_headers_[PH_PHDR].p_filesz = sizeof(program_headers_); 199 program_headers_[PH_PHDR].p_memsz = sizeof(program_headers_); 200 program_headers_[PH_PHDR].p_flags = PF_R; 201 program_headers_[PH_PHDR].p_align = sizeof(Elf_Word); 202 203 program_headers_[PH_LOAD_R__].p_type = PT_LOAD; 204 program_headers_[PH_LOAD_R__].p_offset = 0; 205 program_headers_[PH_LOAD_R__].p_vaddr = 0; 206 program_headers_[PH_LOAD_R__].p_paddr = 0; 207 program_headers_[PH_LOAD_R__].p_flags = PF_R; 208 209 program_headers_[PH_LOAD_R_X].p_type = PT_LOAD; 210 program_headers_[PH_LOAD_R_X].p_flags = PF_R | PF_X; 211 212 program_headers_[PH_LOAD_RW_].p_type = PT_LOAD; 213 program_headers_[PH_LOAD_RW_].p_flags = PF_R | PF_W; 214 215 program_headers_[PH_DYNAMIC].p_type = PT_DYNAMIC; 216 program_headers_[PH_DYNAMIC].p_flags = PF_R | PF_W; 217 218 // Get the dynstr string. 219 dynstr_ = dynsym_builder_.GenerateStrtab(); 220 221 // Add the SONAME to the dynstr. 222 dynstr_soname_offset_ = dynstr_.size(); 223 std::string file_name(elf_file_->GetPath()); 224 size_t directory_separator_pos = file_name.rfind('/'); 225 if (directory_separator_pos != std::string::npos) { 226 file_name = file_name.substr(directory_separator_pos + 1); 227 } 228 dynstr_ += file_name; 229 dynstr_ += '\0'; 230 if (debug_logging_) { 231 LOG(INFO) << "dynstr size (bytes) =" << dynstr_.size() 232 << std::hex << " " << dynstr_.size(); 233 LOG(INFO) << "dynsym size (elements)=" << dynsym_builder_.GetSize() 234 << std::hex << " " << dynsym_builder_.GetSize(); 235 } 236 237 // Get the section header string table. 238 shstrtab_ += '\0'; 239 240 // Setup sym_undef 241 memset(&null_hdr_, 0, sizeof(null_hdr_)); 242 null_hdr_.sh_type = SHT_NULL; 243 null_hdr_.sh_link = SHN_UNDEF; 244 section_ptrs_.push_back(&null_hdr_); 245 246 section_index_ = 1; 247 248 // setup .dynsym 249 section_ptrs_.push_back(&dynsym_builder_.section_); 250 AssignSectionStr(&dynsym_builder_, &shstrtab_); 251 dynsym_builder_.section_index_ = section_index_++; 252 253 // Setup .dynstr 254 section_ptrs_.push_back(&dynsym_builder_.strtab_.section_); 255 AssignSectionStr(&dynsym_builder_.strtab_, &shstrtab_); 256 dynsym_builder_.strtab_.section_index_ = section_index_++; 257 258 // Setup .hash 259 section_ptrs_.push_back(&hash_builder_.section_); 260 AssignSectionStr(&hash_builder_, &shstrtab_); 261 hash_builder_.section_index_ = section_index_++; 262 263 // Setup .rodata 264 section_ptrs_.push_back(&rodata_builder_.section_); 265 AssignSectionStr(&rodata_builder_, &shstrtab_); 266 rodata_builder_.section_index_ = section_index_++; 267 268 // Setup .text 269 section_ptrs_.push_back(&text_builder_.section_); 270 AssignSectionStr(&text_builder_, &shstrtab_); 271 text_builder_.section_index_ = section_index_++; 272 273 // Setup .dynamic 274 section_ptrs_.push_back(&dynamic_builder_.section_); 275 AssignSectionStr(&dynamic_builder_, &shstrtab_); 276 dynamic_builder_.section_index_ = section_index_++; 277 278 // Fill in the hash section. 279 hash_ = dynsym_builder_.GenerateHashContents(); 280 281 if (debug_logging_) { 282 LOG(INFO) << ".hash size (bytes)=" << hash_.size() * sizeof(Elf_Word) 283 << std::hex << " " << hash_.size() * sizeof(Elf_Word); 284 } 285 286 Elf_Word base_offset = sizeof(Elf_Ehdr) + sizeof(program_headers_); 287 288 // Get the layout in the sections. 289 // 290 // Get the layout of the dynsym section. 291 dynsym_builder_.section_.sh_offset = RoundUp(base_offset, dynsym_builder_.section_.sh_addralign); 292 dynsym_builder_.section_.sh_addr = dynsym_builder_.section_.sh_offset; 293 dynsym_builder_.section_.sh_size = dynsym_builder_.GetSize() * sizeof(Elf_Sym); 294 dynsym_builder_.section_.sh_link = dynsym_builder_.GetLink(); 295 296 // Get the layout of the dynstr section. 297 dynsym_builder_.strtab_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr> 298 (dynsym_builder_.strtab_.section_, 299 dynsym_builder_.section_); 300 dynsym_builder_.strtab_.section_.sh_addr = dynsym_builder_.strtab_.section_.sh_offset; 301 dynsym_builder_.strtab_.section_.sh_size = dynstr_.size(); 302 dynsym_builder_.strtab_.section_.sh_link = dynsym_builder_.strtab_.GetLink(); 303 304 // Get the layout of the hash section 305 hash_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr> 306 (hash_builder_.section_, 307 dynsym_builder_.strtab_.section_); 308 hash_builder_.section_.sh_addr = hash_builder_.section_.sh_offset; 309 hash_builder_.section_.sh_size = hash_.size() * sizeof(Elf_Word); 310 hash_builder_.section_.sh_link = hash_builder_.GetLink(); 311 312 // Get the layout of the rodata section. 313 rodata_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr> 314 (rodata_builder_.section_, 315 hash_builder_.section_); 316 rodata_builder_.section_.sh_addr = rodata_builder_.section_.sh_offset; 317 rodata_builder_.section_.sh_size = rodata_builder_.size_; 318 rodata_builder_.section_.sh_link = rodata_builder_.GetLink(); 319 320 // Get the layout of the text section. 321 text_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr> 322 (text_builder_.section_, rodata_builder_.section_); 323 text_builder_.section_.sh_addr = text_builder_.section_.sh_offset; 324 text_builder_.section_.sh_size = text_builder_.size_; 325 text_builder_.section_.sh_link = text_builder_.GetLink(); 326 CHECK_ALIGNED(rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size, kPageSize); 327 328 // Get the layout of the dynamic section. 329 dynamic_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr> 330 (dynamic_builder_.section_, 331 text_builder_.section_); 332 dynamic_builder_.section_.sh_addr = dynamic_builder_.section_.sh_offset; 333 dynamic_builder_.section_.sh_size = dynamic_builder_.GetSize() * sizeof(Elf_Dyn); 334 dynamic_builder_.section_.sh_link = dynamic_builder_.GetLink(); 335 336 if (debug_logging_) { 337 LOG(INFO) << "dynsym off=" << dynsym_builder_.section_.sh_offset 338 << " dynsym size=" << dynsym_builder_.section_.sh_size; 339 LOG(INFO) << "dynstr off=" << dynsym_builder_.strtab_.section_.sh_offset 340 << " dynstr size=" << dynsym_builder_.strtab_.section_.sh_size; 341 LOG(INFO) << "hash off=" << hash_builder_.section_.sh_offset 342 << " hash size=" << hash_builder_.section_.sh_size; 343 LOG(INFO) << "rodata off=" << rodata_builder_.section_.sh_offset 344 << " rodata size=" << rodata_builder_.section_.sh_size; 345 LOG(INFO) << "text off=" << text_builder_.section_.sh_offset 346 << " text size=" << text_builder_.section_.sh_size; 347 LOG(INFO) << "dynamic off=" << dynamic_builder_.section_.sh_offset 348 << " dynamic size=" << dynamic_builder_.section_.sh_size; 349 } 350 351 return true; 352} 353 354template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 355 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 356 typename Elf_Phdr, typename Elf_Shdr> 357bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 358 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::Write() { 359 std::vector<ElfFilePiece> pieces; 360 Elf_Shdr prev = dynamic_builder_.section_; 361 std::string strtab; 362 363 if (IncludingDebugSymbols()) { 364 // Setup .symtab 365 section_ptrs_.push_back(&symtab_builder_.section_); 366 AssignSectionStr(&symtab_builder_, &shstrtab_); 367 symtab_builder_.section_index_ = section_index_++; 368 369 // Setup .strtab 370 section_ptrs_.push_back(&symtab_builder_.strtab_.section_); 371 AssignSectionStr(&symtab_builder_.strtab_, &shstrtab_); 372 symtab_builder_.strtab_.section_index_ = section_index_++; 373 374 strtab = symtab_builder_.GenerateStrtab(); 375 if (debug_logging_) { 376 LOG(INFO) << "strtab size (bytes) =" << strtab.size() 377 << std::hex << " " << strtab.size(); 378 LOG(INFO) << "symtab size (elements) =" << symtab_builder_.GetSize() 379 << std::hex << " " << symtab_builder_.GetSize(); 380 } 381 } 382 383 // Setup all the other sections. 384 for (ElfRawSectionBuilder *builder = other_builders_.data(), 385 *end = builder + other_builders_.size(); 386 builder != end; ++builder) { 387 section_ptrs_.push_back(&builder->section_); 388 AssignSectionStr(builder, &shstrtab_); 389 builder->section_index_ = section_index_++; 390 } 391 392 // Setup shstrtab 393 section_ptrs_.push_back(&shstrtab_builder_.section_); 394 AssignSectionStr(&shstrtab_builder_, &shstrtab_); 395 shstrtab_builder_.section_index_ = section_index_++; 396 397 if (debug_logging_) { 398 LOG(INFO) << ".shstrtab size (bytes) =" << shstrtab_.size() 399 << std::hex << " " << shstrtab_.size(); 400 LOG(INFO) << "section list size (elements)=" << section_ptrs_.size() 401 << std::hex << " " << section_ptrs_.size(); 402 } 403 404 if (IncludingDebugSymbols()) { 405 // Get the layout of the symtab section. 406 symtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr> 407 (symtab_builder_.section_, 408 dynamic_builder_.section_); 409 symtab_builder_.section_.sh_addr = 0; 410 // Add to leave space for the null symbol. 411 symtab_builder_.section_.sh_size = symtab_builder_.GetSize() * sizeof(Elf_Sym); 412 symtab_builder_.section_.sh_link = symtab_builder_.GetLink(); 413 414 // Get the layout of the dynstr section. 415 symtab_builder_.strtab_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr> 416 (symtab_builder_.strtab_.section_, 417 symtab_builder_.section_); 418 symtab_builder_.strtab_.section_.sh_addr = 0; 419 symtab_builder_.strtab_.section_.sh_size = strtab.size(); 420 symtab_builder_.strtab_.section_.sh_link = symtab_builder_.strtab_.GetLink(); 421 422 prev = symtab_builder_.strtab_.section_; 423 if (debug_logging_) { 424 LOG(INFO) << "symtab off=" << symtab_builder_.section_.sh_offset 425 << " symtab size=" << symtab_builder_.section_.sh_size; 426 LOG(INFO) << "strtab off=" << symtab_builder_.strtab_.section_.sh_offset 427 << " strtab size=" << symtab_builder_.strtab_.section_.sh_size; 428 } 429 } 430 431 // Get the layout of the extra sections. (This will deal with the debug 432 // sections if they are there) 433 for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) { 434 it->section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr>(it->section_, prev); 435 it->section_.sh_addr = 0; 436 it->section_.sh_size = it->GetBuffer()->size(); 437 it->section_.sh_link = it->GetLink(); 438 pieces.push_back(ElfFilePiece(it->name_, it->section_.sh_offset, 439 it->GetBuffer()->data(), it->GetBuffer()->size())); 440 prev = it->section_; 441 if (debug_logging_) { 442 LOG(INFO) << it->name_ << " off=" << it->section_.sh_offset 443 << " " << it->name_ << " size=" << it->section_.sh_size; 444 } 445 } 446 447 // Get the layout of the shstrtab section 448 shstrtab_builder_.section_.sh_offset = NextOffset<Elf_Word, Elf_Shdr> 449 (shstrtab_builder_.section_, prev); 450 shstrtab_builder_.section_.sh_addr = 0; 451 shstrtab_builder_.section_.sh_size = shstrtab_.size(); 452 shstrtab_builder_.section_.sh_link = shstrtab_builder_.GetLink(); 453 if (debug_logging_) { 454 LOG(INFO) << "shstrtab off=" << shstrtab_builder_.section_.sh_offset 455 << " shstrtab size=" << shstrtab_builder_.section_.sh_size; 456 } 457 458 // The section list comes after come after. 459 Elf_Word sections_offset = RoundUp( 460 shstrtab_builder_.section_.sh_offset + shstrtab_builder_.section_.sh_size, 461 sizeof(Elf_Word)); 462 463 // Setup the actual symbol arrays. 464 std::vector<Elf_Sym> dynsym = dynsym_builder_.GenerateSymtab(); 465 CHECK_EQ(dynsym.size() * sizeof(Elf_Sym), dynsym_builder_.section_.sh_size); 466 std::vector<Elf_Sym> symtab; 467 if (IncludingDebugSymbols()) { 468 symtab = symtab_builder_.GenerateSymtab(); 469 CHECK_EQ(symtab.size() * sizeof(Elf_Sym), symtab_builder_.section_.sh_size); 470 } 471 472 // Setup the dynamic section. 473 // This will add the 2 values we cannot know until now time, namely the size 474 // and the soname_offset. 475 std::vector<Elf_Dyn> dynamic = dynamic_builder_.GetDynamics(dynstr_.size(), 476 dynstr_soname_offset_); 477 CHECK_EQ(dynamic.size() * sizeof(Elf_Dyn), dynamic_builder_.section_.sh_size); 478 479 // Finish setup of the program headers now that we know the layout of the 480 // whole file. 481 Elf_Word load_r_size = rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size; 482 program_headers_[PH_LOAD_R__].p_filesz = load_r_size; 483 program_headers_[PH_LOAD_R__].p_memsz = load_r_size; 484 program_headers_[PH_LOAD_R__].p_align = rodata_builder_.section_.sh_addralign; 485 486 Elf_Word load_rx_size = text_builder_.section_.sh_size; 487 program_headers_[PH_LOAD_R_X].p_offset = text_builder_.section_.sh_offset; 488 program_headers_[PH_LOAD_R_X].p_vaddr = text_builder_.section_.sh_offset; 489 program_headers_[PH_LOAD_R_X].p_paddr = text_builder_.section_.sh_offset; 490 program_headers_[PH_LOAD_R_X].p_filesz = load_rx_size; 491 program_headers_[PH_LOAD_R_X].p_memsz = load_rx_size; 492 program_headers_[PH_LOAD_R_X].p_align = text_builder_.section_.sh_addralign; 493 494 program_headers_[PH_LOAD_RW_].p_offset = dynamic_builder_.section_.sh_offset; 495 program_headers_[PH_LOAD_RW_].p_vaddr = dynamic_builder_.section_.sh_offset; 496 program_headers_[PH_LOAD_RW_].p_paddr = dynamic_builder_.section_.sh_offset; 497 program_headers_[PH_LOAD_RW_].p_filesz = dynamic_builder_.section_.sh_size; 498 program_headers_[PH_LOAD_RW_].p_memsz = dynamic_builder_.section_.sh_size; 499 program_headers_[PH_LOAD_RW_].p_align = dynamic_builder_.section_.sh_addralign; 500 501 program_headers_[PH_DYNAMIC].p_offset = dynamic_builder_.section_.sh_offset; 502 program_headers_[PH_DYNAMIC].p_vaddr = dynamic_builder_.section_.sh_offset; 503 program_headers_[PH_DYNAMIC].p_paddr = dynamic_builder_.section_.sh_offset; 504 program_headers_[PH_DYNAMIC].p_filesz = dynamic_builder_.section_.sh_size; 505 program_headers_[PH_DYNAMIC].p_memsz = dynamic_builder_.section_.sh_size; 506 program_headers_[PH_DYNAMIC].p_align = dynamic_builder_.section_.sh_addralign; 507 508 // Finish setup of the Ehdr values. 509 elf_header_.e_phoff = PHDR_OFFSET; 510 elf_header_.e_shoff = sections_offset; 511 elf_header_.e_phnum = PH_NUM; 512 elf_header_.e_shnum = section_ptrs_.size(); 513 elf_header_.e_shstrndx = shstrtab_builder_.section_index_; 514 515 // Add the rest of the pieces to the list. 516 pieces.push_back(ElfFilePiece("Elf Header", 0, &elf_header_, sizeof(elf_header_))); 517 pieces.push_back(ElfFilePiece("Program headers", PHDR_OFFSET, 518 &program_headers_, sizeof(program_headers_))); 519 pieces.push_back(ElfFilePiece(".dynamic", dynamic_builder_.section_.sh_offset, 520 dynamic.data(), dynamic_builder_.section_.sh_size)); 521 pieces.push_back(ElfFilePiece(".dynsym", dynsym_builder_.section_.sh_offset, 522 dynsym.data(), dynsym.size() * sizeof(Elf_Sym))); 523 pieces.push_back(ElfFilePiece(".dynstr", dynsym_builder_.strtab_.section_.sh_offset, 524 dynstr_.c_str(), dynstr_.size())); 525 pieces.push_back(ElfFilePiece(".hash", hash_builder_.section_.sh_offset, 526 hash_.data(), hash_.size() * sizeof(Elf_Word))); 527 pieces.push_back(ElfFilePiece(".rodata", rodata_builder_.section_.sh_offset, 528 nullptr, rodata_builder_.section_.sh_size)); 529 pieces.push_back(ElfFilePiece(".text", text_builder_.section_.sh_offset, 530 nullptr, text_builder_.section_.sh_size)); 531 if (IncludingDebugSymbols()) { 532 pieces.push_back(ElfFilePiece(".symtab", symtab_builder_.section_.sh_offset, 533 symtab.data(), symtab.size() * sizeof(Elf_Sym))); 534 pieces.push_back(ElfFilePiece(".strtab", symtab_builder_.strtab_.section_.sh_offset, 535 strtab.c_str(), strtab.size())); 536 } 537 pieces.push_back(ElfFilePiece(".shstrtab", shstrtab_builder_.section_.sh_offset, 538 &shstrtab_[0], shstrtab_.size())); 539 for (uint32_t i = 0; i < section_ptrs_.size(); ++i) { 540 // Just add all the sections in induvidually since they are all over the 541 // place on the heap/stack. 542 Elf_Word cur_off = sections_offset + i * sizeof(Elf_Shdr); 543 pieces.push_back(ElfFilePiece("section table piece", cur_off, 544 section_ptrs_[i], sizeof(Elf_Shdr))); 545 } 546 547 if (!WriteOutFile(pieces)) { 548 LOG(ERROR) << "Unable to write to file " << elf_file_->GetPath(); 549 return false; 550 } 551 // write out the actual oat file data. 552 Elf_Word oat_data_offset = rodata_builder_.section_.sh_offset; 553 if (static_cast<off_t>(oat_data_offset) != lseek(elf_file_->Fd(), oat_data_offset, SEEK_SET)) { 554 PLOG(ERROR) << "Failed to seek to .rodata offset " << oat_data_offset 555 << " for " << elf_file_->GetPath(); 556 return false; 557 } 558 std::unique_ptr<BufferedOutputStream> output_stream( 559 new BufferedOutputStream(new FileOutputStream(elf_file_))); 560 if (!oat_writer_->Write(output_stream.get())) { 561 PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath(); 562 return false; 563 } 564 565 return true; 566} 567 568template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 569 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 570 typename Elf_Phdr, typename Elf_Shdr> 571bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 572 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::WriteOutFile(const std::vector<ElfFilePiece>& pieces) { 573 // TODO It would be nice if this checked for overlap. 574 for (auto it = pieces.begin(); it != pieces.end(); ++it) { 575 if (it->data_) { 576 if (static_cast<off_t>(it->offset_) != lseek(elf_file_->Fd(), it->offset_, SEEK_SET)) { 577 PLOG(ERROR) << "Failed to seek to " << it->dbg_name_ << " offset location " 578 << it->offset_ << " for " << elf_file_->GetPath(); 579 return false; 580 } 581 if (!elf_file_->WriteFully(it->data_, it->size_)) { 582 PLOG(ERROR) << "Failed to write " << it->dbg_name_ << " for " << elf_file_->GetPath(); 583 return false; 584 } 585 } 586 } 587 return true; 588} 589 590template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 591 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 592 typename Elf_Phdr, typename Elf_Shdr> 593void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 594 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::SetupDynamic() { 595 dynamic_builder_.AddDynamicTag(DT_HASH, 0, &hash_builder_); 596 dynamic_builder_.AddDynamicTag(DT_STRTAB, 0, &dynsym_builder_.strtab_); 597 dynamic_builder_.AddDynamicTag(DT_SYMTAB, 0, &dynsym_builder_); 598 dynamic_builder_.AddDynamicTag(DT_SYMENT, sizeof(Elf_Sym)); 599} 600 601template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 602 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 603 typename Elf_Phdr, typename Elf_Shdr> 604void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 605 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::SetupRequiredSymbols() { 606 dynsym_builder_.AddSymbol("oatdata", &rodata_builder_, 0, true, 607 rodata_builder_.size_, STB_GLOBAL, STT_OBJECT); 608 dynsym_builder_.AddSymbol("oatexec", &text_builder_, 0, true, 609 text_builder_.size_, STB_GLOBAL, STT_OBJECT); 610 dynsym_builder_.AddSymbol("oatlastword", &text_builder_, text_builder_.size_ - 4, 611 true, 4, STB_GLOBAL, STT_OBJECT); 612} 613 614template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 615 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 616 typename Elf_Phdr, typename Elf_Shdr> 617void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 618 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfDynamicBuilder::AddDynamicTag(Elf_Sword tag, Elf_Word d_un) { 619 if (tag == DT_NULL) { 620 return; 621 } 622 dynamics_.push_back({nullptr, tag, d_un}); 623} 624 625template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 626 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 627 typename Elf_Phdr, typename Elf_Shdr> 628void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 629 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfDynamicBuilder::AddDynamicTag(Elf_Sword tag, Elf_Word d_un, 630 ElfSectionBuilder* section) { 631 if (tag == DT_NULL) { 632 return; 633 } 634 dynamics_.push_back({section, tag, d_un}); 635} 636 637template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 638 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 639 typename Elf_Phdr, typename Elf_Shdr> 640std::vector<Elf_Dyn> ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 641 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfDynamicBuilder::GetDynamics(Elf_Word strsz, 642 Elf_Word soname) { 643 std::vector<Elf_Dyn> ret; 644 for (auto it = dynamics_.cbegin(); it != dynamics_.cend(); ++it) { 645 if (it->section_) { 646 // We are adding an address relative to a section. 647 ret.push_back( 648 {it->tag_, {it->off_ + it->section_->section_.sh_addr}}); 649 } else { 650 ret.push_back({it->tag_, {it->off_}}); 651 } 652 } 653 ret.push_back({DT_STRSZ, {strsz}}); 654 ret.push_back({DT_SONAME, {soname}}); 655 ret.push_back({DT_NULL, {0}}); 656 return ret; 657} 658 659template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 660 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 661 typename Elf_Phdr, typename Elf_Shdr> 662std::vector<Elf_Sym> ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 663 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfSymtabBuilder::GenerateSymtab() { 664 std::vector<Elf_Sym> ret; 665 Elf_Sym undef_sym; 666 memset(&undef_sym, 0, sizeof(undef_sym)); 667 undef_sym.st_shndx = SHN_UNDEF; 668 ret.push_back(undef_sym); 669 670 for (auto it = symbols_.cbegin(); it != symbols_.cend(); ++it) { 671 Elf_Sym sym; 672 memset(&sym, 0, sizeof(sym)); 673 sym.st_name = it->name_idx_; 674 if (it->is_relative_) { 675 sym.st_value = it->addr_ + it->section_->section_.sh_offset; 676 } else { 677 sym.st_value = it->addr_; 678 } 679 sym.st_size = it->size_; 680 sym.st_other = it->other_; 681 sym.st_shndx = it->section_->section_index_; 682 sym.st_info = it->info_; 683 684 ret.push_back(sym); 685 } 686 return ret; 687} 688 689template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 690 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 691 typename Elf_Phdr, typename Elf_Shdr> 692std::string ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 693 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfSymtabBuilder::GenerateStrtab() { 694 std::string tab; 695 tab += '\0'; 696 for (auto it = symbols_.begin(); it != symbols_.end(); ++it) { 697 it->name_idx_ = tab.size(); 698 tab += it->name_; 699 tab += '\0'; 700 } 701 strtab_.section_.sh_size = tab.size(); 702 return tab; 703} 704 705template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 706 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 707 typename Elf_Phdr, typename Elf_Shdr> 708void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 709 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::AssignSectionStr( 710 ElfSectionBuilder* builder, std::string* strtab) { 711 builder->section_.sh_name = strtab->size(); 712 *strtab += builder->name_; 713 *strtab += '\0'; 714 if (debug_logging_) { 715 LOG(INFO) << "adding section name \"" << builder->name_ << "\" " 716 << "to shstrtab at offset " << builder->section_.sh_name; 717 } 718} 719 720// from bionic 721static unsigned elfhash(const char *_name) { 722 const unsigned char *name = (const unsigned char *) _name; 723 unsigned h = 0, g; 724 725 while (*name) { 726 h = (h << 4) + *name++; 727 g = h & 0xf0000000; 728 h ^= g; 729 h ^= g >> 24; 730 } 731 return h; 732} 733 734template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 735 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 736 typename Elf_Phdr, typename Elf_Shdr> 737std::vector<Elf_Word> ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 738 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfSymtabBuilder::GenerateHashContents() { 739 // Here is how The ELF hash table works. 740 // There are 3 arrays to worry about. 741 // * The symbol table where the symbol information is. 742 // * The bucket array which is an array of indexes into the symtab and chain. 743 // * The chain array which is also an array of indexes into the symtab and chain. 744 // 745 // Lets say the state is something like this. 746 // +--------+ +--------+ +-----------+ 747 // | symtab | | bucket | | chain | 748 // | null | | 1 | | STN_UNDEF | 749 // | <sym1> | | 4 | | 2 | 750 // | <sym2> | | | | 5 | 751 // | <sym3> | | | | STN_UNDEF | 752 // | <sym4> | | | | 3 | 753 // | <sym5> | | | | STN_UNDEF | 754 // +--------+ +--------+ +-----------+ 755 // 756 // The lookup process (in python psudocode) is 757 // 758 // def GetSym(name): 759 // # NB STN_UNDEF == 0 760 // indx = bucket[elfhash(name) % num_buckets] 761 // while indx != STN_UNDEF: 762 // if GetSymbolName(symtab[indx]) == name: 763 // return symtab[indx] 764 // indx = chain[indx] 765 // return SYMBOL_NOT_FOUND 766 // 767 // Between bucket and chain arrays every symtab index must be present exactly 768 // once (except for STN_UNDEF, which must be present 1 + num_bucket times). 769 770 // Select number of buckets. 771 // This is essentially arbitrary. 772 Elf_Word nbuckets; 773 Elf_Word chain_size = GetSize(); 774 if (symbols_.size() < 8) { 775 nbuckets = 2; 776 } else if (symbols_.size() < 32) { 777 nbuckets = 4; 778 } else if (symbols_.size() < 256) { 779 nbuckets = 16; 780 } else { 781 // Have about 32 ids per bucket. 782 nbuckets = RoundUp(symbols_.size()/32, 2); 783 } 784 std::vector<Elf_Word> hash; 785 hash.push_back(nbuckets); 786 hash.push_back(chain_size); 787 uint32_t bucket_offset = hash.size(); 788 uint32_t chain_offset = bucket_offset + nbuckets; 789 hash.resize(hash.size() + nbuckets + chain_size, 0); 790 791 Elf_Word* buckets = hash.data() + bucket_offset; 792 Elf_Word* chain = hash.data() + chain_offset; 793 794 // Set up the actual hash table. 795 for (Elf_Word i = 0; i < symbols_.size(); i++) { 796 // Add 1 since we need to have the null symbol that is not in the symbols 797 // list. 798 Elf_Word index = i + 1; 799 Elf_Word hash_val = static_cast<Elf_Word>(elfhash(symbols_[i].name_.c_str())) % nbuckets; 800 if (buckets[hash_val] == 0) { 801 buckets[hash_val] = index; 802 } else { 803 hash_val = buckets[hash_val]; 804 CHECK_LT(hash_val, chain_size); 805 while (chain[hash_val] != 0) { 806 hash_val = chain[hash_val]; 807 CHECK_LT(hash_val, chain_size); 808 } 809 chain[hash_val] = index; 810 // Check for loops. Works because if this is non-empty then there must be 811 // another cell which already contains the same symbol index as this one, 812 // which means some symbol has more then one name, which isn't allowed. 813 CHECK_EQ(chain[index], static_cast<Elf_Word>(0)); 814 } 815 } 816 817 return hash; 818} 819 820template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 821 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 822 typename Elf_Phdr, typename Elf_Shdr> 823void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 824 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::SetupEhdr() { 825 memset(&elf_header_, 0, sizeof(elf_header_)); 826 elf_header_.e_ident[EI_MAG0] = ELFMAG0; 827 elf_header_.e_ident[EI_MAG1] = ELFMAG1; 828 elf_header_.e_ident[EI_MAG2] = ELFMAG2; 829 elf_header_.e_ident[EI_MAG3] = ELFMAG3; 830 elf_header_.e_ident[EI_CLASS] = ELFCLASS32; 831 elf_header_.e_ident[EI_DATA] = ELFDATA2LSB; 832 elf_header_.e_ident[EI_VERSION] = EV_CURRENT; 833 elf_header_.e_ident[EI_OSABI] = ELFOSABI_LINUX; 834 elf_header_.e_ident[EI_ABIVERSION] = 0; 835 elf_header_.e_type = ET_DYN; 836 elf_header_.e_version = 1; 837 elf_header_.e_entry = 0; 838 elf_header_.e_ehsize = sizeof(Elf_Ehdr); 839 elf_header_.e_phentsize = sizeof(Elf_Phdr); 840 elf_header_.e_shentsize = sizeof(Elf_Shdr); 841 elf_header_.e_phoff = sizeof(Elf_Ehdr); 842} 843 844template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 845 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 846 typename Elf_Phdr, typename Elf_Shdr> 847void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 848 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfBuilder::SetISA(InstructionSet isa) { 849 switch (isa) { 850 case kArm: 851 // Fall through. 852 case kThumb2: { 853 elf_header_.e_machine = EM_ARM; 854 elf_header_.e_flags = EF_ARM_EABI_VER5; 855 break; 856 } 857 case kArm64: { 858 elf_header_.e_machine = EM_AARCH64; 859 elf_header_.e_flags = 0; 860 break; 861 } 862 case kX86: { 863 elf_header_.e_machine = EM_386; 864 elf_header_.e_flags = 0; 865 break; 866 } 867 case kX86_64: { 868 elf_header_.e_machine = EM_X86_64; 869 elf_header_.e_flags = 0; 870 break; 871 } 872 case kMips: { 873 elf_header_.e_machine = EM_MIPS; 874 elf_header_.e_flags = (EF_MIPS_NOREORDER | 875 EF_MIPS_PIC | 876 EF_MIPS_CPIC | 877 EF_MIPS_ABI_O32 | 878 EF_MIPS_ARCH_32R2); 879 break; 880 } 881 default: { 882 fatal_error_ = true; 883 LOG(FATAL) << "Unknown instruction set: " << isa; 884 break; 885 } 886 } 887} 888 889template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 890 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 891 typename Elf_Phdr, typename Elf_Shdr> 892void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 893 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ElfSymtabBuilder::AddSymbol( 894 const std::string& name, const ElfSectionBuilder* section, Elf_Addr addr, 895 bool is_relative, Elf_Word size, uint8_t binding, uint8_t type, uint8_t other) { 896 CHECK(section); 897 ElfSymtabBuilder::ElfSymbolState state {name, section, addr, size, is_relative, 898 MakeStInfo(binding, type), other, 0}; 899 symbols_.push_back(state); 900} 901 902template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 903 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 904 typename Elf_Phdr, typename Elf_Shdr> 905bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 906 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file, 907 OatWriter* oat_writer, 908 const std::vector<const DexFile*>& dex_files, 909 const std::string& android_root, 910 bool is_host, 911 const CompilerDriver& driver) { 912 ElfWriterQuick elf_writer(driver, elf_file); 913 return elf_writer.Write(oat_writer, dex_files, android_root, is_host); 914} 915 916template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 917 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 918 typename Elf_Phdr, typename Elf_Shdr> 919// Add patch information to this section. Each patch is a Elf_Word that 920// identifies an offset from the start of the text section 921void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 922 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::ReservePatchSpace(std::vector<uint8_t>* buffer, bool debug) { 923 size_t size = 924 compiler_driver_->GetCodeToPatch().size() + 925 compiler_driver_->GetMethodsToPatch().size() + 926 compiler_driver_->GetClassesToPatch().size(); 927 if (size == 0) { 928 if (debug) { 929 LOG(INFO) << "No patches to record"; 930 } 931 return; 932 } 933 buffer->resize(size * sizeof(uintptr_t)); 934 if (debug) { 935 LOG(INFO) << "Patches reserved for " << size; 936 } 937} 938 939std::vector<uint8_t>* ConstructCIEFrameX86(bool is_x86_64) { 940 std::vector<uint8_t>* cfi_info = new std::vector<uint8_t>; 941 942 // Length (will be filled in later in this routine). 943 if (is_x86_64) { 944 PushWord(cfi_info, 0xffffffff); // Indicates 64bit 945 PushWord(cfi_info, 0); 946 PushWord(cfi_info, 0); 947 } else { 948 PushWord(cfi_info, 0); 949 } 950 951 // CIE id: always 0. 952 if (is_x86_64) { 953 PushWord(cfi_info, 0); 954 PushWord(cfi_info, 0); 955 } else { 956 PushWord(cfi_info, 0); 957 } 958 959 // Version: always 1. 960 cfi_info->push_back(0x01); 961 962 // Augmentation: 'zR\0' 963 cfi_info->push_back(0x7a); 964 cfi_info->push_back(0x52); 965 cfi_info->push_back(0x0); 966 967 // Code alignment: 1. 968 EncodeUnsignedLeb128(1, cfi_info); 969 970 // Data alignment. 971 if (is_x86_64) { 972 EncodeSignedLeb128(-8, cfi_info); 973 } else { 974 EncodeSignedLeb128(-4, cfi_info); 975 } 976 977 // Return address register. 978 if (is_x86_64) { 979 // R16(RIP) 980 cfi_info->push_back(0x10); 981 } else { 982 // R8(EIP) 983 cfi_info->push_back(0x08); 984 } 985 986 // Augmentation length: 1. 987 cfi_info->push_back(1); 988 989 // Augmentation data. 990 if (is_x86_64) { 991 // 0x04 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata8). 992 cfi_info->push_back(0x04); 993 } else { 994 // 0x03 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4). 995 cfi_info->push_back(0x03); 996 } 997 998 // Initial instructions. 999 if (is_x86_64) { 1000 // DW_CFA_def_cfa R7(RSP) 8. 1001 cfi_info->push_back(0x0c); 1002 cfi_info->push_back(0x07); 1003 cfi_info->push_back(0x08); 1004 1005 // DW_CFA_offset R16(RIP) 1 (* -8). 1006 cfi_info->push_back(0x90); 1007 cfi_info->push_back(0x01); 1008 } else { 1009 // DW_CFA_def_cfa R4(ESP) 4. 1010 cfi_info->push_back(0x0c); 1011 cfi_info->push_back(0x04); 1012 cfi_info->push_back(0x04); 1013 1014 // DW_CFA_offset R8(EIP) 1 (* -4). 1015 cfi_info->push_back(0x88); 1016 cfi_info->push_back(0x01); 1017 } 1018 1019 // Padding to a multiple of 4 1020 while ((cfi_info->size() & 3) != 0) { 1021 // DW_CFA_nop is encoded as 0. 1022 cfi_info->push_back(0); 1023 } 1024 1025 // Set the length of the CIE inside the generated bytes. 1026 if (is_x86_64) { 1027 uint32_t length = cfi_info->size() - 12; 1028 UpdateWord(cfi_info, 4, length); 1029 } else { 1030 uint32_t length = cfi_info->size() - 4; 1031 UpdateWord(cfi_info, 0, length); 1032 } 1033 return cfi_info; 1034} 1035 1036std::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) { 1037 switch (isa) { 1038 case kX86: 1039 return ConstructCIEFrameX86(false); 1040 case kX86_64: 1041 return ConstructCIEFrameX86(true); 1042 1043 default: 1044 // Not implemented. 1045 return nullptr; 1046 } 1047} 1048 1049template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 1050 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 1051 typename Elf_Phdr, typename Elf_Shdr> 1052bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 1053 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer, 1054 const std::vector<const DexFile*>& dex_files_unused, 1055 const std::string& android_root_unused, 1056 bool is_host_unused) { 1057 constexpr bool debug = false; 1058 const OatHeader& oat_header = oat_writer->GetOatHeader(); 1059 Elf_Word oat_data_size = oat_header.GetExecutableOffset(); 1060 uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size; 1061 1062 std::unique_ptr<ElfBuilder> builder(new ElfBuilder( 1063 oat_writer, 1064 elf_file_, 1065 compiler_driver_->GetInstructionSet(), 1066 0, 1067 oat_data_size, 1068 oat_data_size, 1069 oat_exec_size, 1070 compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(), 1071 debug)); 1072 1073 if (!builder->Init()) { 1074 return false; 1075 } 1076 1077 if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) { 1078 WriteDebugSymbols(builder.get(), oat_writer); 1079 } 1080 1081 if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) { 1082 ElfRawSectionBuilder oat_patches(".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, 1083 sizeof(uintptr_t), sizeof(uintptr_t)); 1084 ReservePatchSpace(oat_patches.GetBuffer(), debug); 1085 builder->RegisterRawSection(oat_patches); 1086 } 1087 1088 return builder->Write(); 1089} 1090 1091template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 1092 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 1093 typename Elf_Phdr, typename Elf_Shdr> 1094void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 1095 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::WriteDebugSymbols(ElfBuilder* builder, OatWriter* oat_writer) { 1096 std::unique_ptr<std::vector<uint8_t>> cfi_info( 1097 ConstructCIEFrame(compiler_driver_->GetInstructionSet())); 1098 1099 Elf_Addr text_section_address = builder->text_builder_.section_.sh_addr; 1100 1101 // Iterate over the compiled methods. 1102 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo(); 1103 ElfSymtabBuilder* symtab = &builder->symtab_builder_; 1104 for (auto it = method_info.begin(); it != method_info.end(); ++it) { 1105 symtab->AddSymbol(it->method_name_, &builder->text_builder_, it->low_pc_, true, 1106 it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC); 1107 1108 // Include CFI for compiled method, if possible. 1109 if (cfi_info.get() != nullptr) { 1110 DCHECK(it->compiled_method_ != nullptr); 1111 1112 // Copy in the FDE, if present 1113 const std::vector<uint8_t>* fde = it->compiled_method_->GetCFIInfo(); 1114 if (fde != nullptr) { 1115 // Copy the information into cfi_info and then fix the address in the new copy. 1116 int cur_offset = cfi_info->size(); 1117 cfi_info->insert(cfi_info->end(), fde->begin(), fde->end()); 1118 1119 bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff; 1120 1121 // Set the 'CIE_pointer' field. 1122 uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4); 1123 uint64_t offset_to_update = CIE_pointer; 1124 if (is_64bit) { 1125 (*cfi_info)[offset_to_update+0] = CIE_pointer; 1126 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8; 1127 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16; 1128 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24; 1129 (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32; 1130 (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40; 1131 (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48; 1132 (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56; 1133 } else { 1134 (*cfi_info)[offset_to_update+0] = CIE_pointer; 1135 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8; 1136 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16; 1137 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24; 1138 } 1139 1140 // Set the 'initial_location' field. 1141 offset_to_update += is_64bit ? 8 : 4; 1142 if (is_64bit) { 1143 const uint64_t quick_code_start = it->low_pc_ + text_section_address; 1144 (*cfi_info)[offset_to_update+0] = quick_code_start; 1145 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8; 1146 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16; 1147 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24; 1148 (*cfi_info)[offset_to_update+4] = quick_code_start >> 32; 1149 (*cfi_info)[offset_to_update+5] = quick_code_start >> 40; 1150 (*cfi_info)[offset_to_update+6] = quick_code_start >> 48; 1151 (*cfi_info)[offset_to_update+7] = quick_code_start >> 56; 1152 } else { 1153 const uint32_t quick_code_start = it->low_pc_ + text_section_address; 1154 (*cfi_info)[offset_to_update+0] = quick_code_start; 1155 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8; 1156 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16; 1157 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24; 1158 } 1159 } 1160 } 1161 } 1162 1163 bool hasCFI = (cfi_info.get() != nullptr); 1164 bool hasLineInfo = false; 1165 for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) { 1166 if (dbg_info.dbgstream_ != nullptr && 1167 !dbg_info.compiled_method_->GetSrcMappingTable().empty()) { 1168 hasLineInfo = true; 1169 break; 1170 } 1171 } 1172 1173 if (hasLineInfo || hasCFI) { 1174 ElfRawSectionBuilder debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 1175 ElfRawSectionBuilder debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 1176 ElfRawSectionBuilder debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 1177 ElfRawSectionBuilder debug_line(".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 1178 1179 FillInCFIInformation(oat_writer, debug_info.GetBuffer(), 1180 debug_abbrev.GetBuffer(), debug_str.GetBuffer(), 1181 hasLineInfo ? debug_line.GetBuffer() : nullptr, 1182 text_section_address); 1183 1184 builder->RegisterRawSection(debug_info); 1185 builder->RegisterRawSection(debug_abbrev); 1186 1187 if (hasCFI) { 1188 ElfRawSectionBuilder eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0); 1189 eh_frame.SetBuffer(std::move(*cfi_info.get())); 1190 builder->RegisterRawSection(eh_frame); 1191 } 1192 1193 if (hasLineInfo) { 1194 builder->RegisterRawSection(debug_line); 1195 } 1196 1197 builder->RegisterRawSection(debug_str); 1198 } 1199} 1200 1201class LineTableGenerator FINAL : public Leb128Encoder { 1202 public: 1203 LineTableGenerator(int line_base, int line_range, int opcode_base, 1204 std::vector<uint8_t>* data, uintptr_t current_address, 1205 size_t current_line) 1206 : Leb128Encoder(data), line_base_(line_base), line_range_(line_range), 1207 opcode_base_(opcode_base), current_address_(current_address), 1208 current_line_(current_line) {} 1209 1210 void PutDelta(unsigned delta_addr, int delta_line) { 1211 current_line_ += delta_line; 1212 current_address_ += delta_addr; 1213 1214 if (delta_line >= line_base_ && delta_line < line_base_ + line_range_) { 1215 unsigned special_opcode = (delta_line - line_base_) + 1216 (line_range_ * delta_addr) + opcode_base_; 1217 if (special_opcode <= 255) { 1218 PushByte(data_, special_opcode); 1219 return; 1220 } 1221 } 1222 1223 // generate standart opcode for address advance 1224 if (delta_addr != 0) { 1225 PushByte(data_, DW_LNS_advance_pc); 1226 PushBackUnsigned(delta_addr); 1227 } 1228 1229 // generate standart opcode for line delta 1230 if (delta_line != 0) { 1231 PushByte(data_, DW_LNS_advance_line); 1232 PushBackSigned(delta_line); 1233 } 1234 1235 // generate standart opcode for new LTN entry 1236 PushByte(data_, DW_LNS_copy); 1237 } 1238 1239 void SetAddr(uintptr_t addr) { 1240 if (current_address_ == addr) { 1241 return; 1242 } 1243 1244 current_address_ = addr; 1245 1246 PushByte(data_, 0); // extended opcode: 1247 PushByte(data_, 1 + 4); // length: opcode_size + address_size 1248 PushByte(data_, DW_LNE_set_address); 1249 PushWord(data_, addr); 1250 } 1251 1252 void SetLine(unsigned line) { 1253 int delta_line = line - current_line_; 1254 if (delta_line) { 1255 current_line_ = line; 1256 PushByte(data_, DW_LNS_advance_line); 1257 PushBackSigned(delta_line); 1258 } 1259 } 1260 1261 void SetFile(unsigned file_index) { 1262 PushByte(data_, DW_LNS_set_file); 1263 PushBackUnsigned(file_index); 1264 } 1265 1266 void EndSequence() { 1267 // End of Line Table Program 1268 // 0(=ext), 1(len), DW_LNE_end_sequence 1269 PushByte(data_, 0); 1270 PushByte(data_, 1); 1271 PushByte(data_, DW_LNE_end_sequence); 1272 } 1273 1274 private: 1275 const int line_base_; 1276 const int line_range_; 1277 const int opcode_base_; 1278 uintptr_t current_address_; 1279 size_t current_line_; 1280 1281 DISALLOW_COPY_AND_ASSIGN(LineTableGenerator); 1282}; 1283 1284// TODO: rewriting it using DexFile::DecodeDebugInfo needs unneeded stuff. 1285static void GetLineInfoForJava(const uint8_t* dbgstream, const SrcMap& pc2dex, 1286 SrcMap* result, uint32_t start_pc = 0) { 1287 if (dbgstream == nullptr) { 1288 return; 1289 } 1290 1291 int adjopcode; 1292 uint32_t dex_offset = 0; 1293 uint32_t java_line = DecodeUnsignedLeb128(&dbgstream); 1294 1295 // skip parameters 1296 for (uint32_t param_count = DecodeUnsignedLeb128(&dbgstream); param_count != 0; --param_count) { 1297 DecodeUnsignedLeb128(&dbgstream); 1298 } 1299 1300 for (bool is_end = false; is_end == false; ) { 1301 uint8_t opcode = *dbgstream; 1302 dbgstream++; 1303 switch (opcode) { 1304 case DexFile::DBG_END_SEQUENCE: 1305 is_end = true; 1306 break; 1307 1308 case DexFile::DBG_ADVANCE_PC: 1309 dex_offset += DecodeUnsignedLeb128(&dbgstream); 1310 break; 1311 1312 case DexFile::DBG_ADVANCE_LINE: 1313 java_line += DecodeSignedLeb128(&dbgstream); 1314 break; 1315 1316 case DexFile::DBG_START_LOCAL: 1317 case DexFile::DBG_START_LOCAL_EXTENDED: 1318 DecodeUnsignedLeb128(&dbgstream); 1319 DecodeUnsignedLeb128(&dbgstream); 1320 DecodeUnsignedLeb128(&dbgstream); 1321 1322 if (opcode == DexFile::DBG_START_LOCAL_EXTENDED) { 1323 DecodeUnsignedLeb128(&dbgstream); 1324 } 1325 break; 1326 1327 case DexFile::DBG_END_LOCAL: 1328 case DexFile::DBG_RESTART_LOCAL: 1329 DecodeUnsignedLeb128(&dbgstream); 1330 break; 1331 1332 case DexFile::DBG_SET_PROLOGUE_END: 1333 case DexFile::DBG_SET_EPILOGUE_BEGIN: 1334 case DexFile::DBG_SET_FILE: 1335 break; 1336 1337 default: 1338 adjopcode = opcode - DexFile::DBG_FIRST_SPECIAL; 1339 dex_offset += adjopcode / DexFile::DBG_LINE_RANGE; 1340 java_line += DexFile::DBG_LINE_BASE + (adjopcode % DexFile::DBG_LINE_RANGE); 1341 1342 for (SrcMap::const_iterator found = pc2dex.FindByTo(dex_offset); 1343 found != pc2dex.end() && found->to_ == static_cast<int32_t>(dex_offset); 1344 found++) { 1345 result->push_back({found->from_ + start_pc, static_cast<int32_t>(java_line)}); 1346 } 1347 break; 1348 } 1349 } 1350} 1351 1352template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 1353 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 1354 typename Elf_Phdr, typename Elf_Shdr> 1355void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 1356 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::FillInCFIInformation(OatWriter* oat_writer, 1357 std::vector<uint8_t>* dbg_info, 1358 std::vector<uint8_t>* dbg_abbrev, 1359 std::vector<uint8_t>* dbg_str, 1360 std::vector<uint8_t>* dbg_line, 1361 uint32_t text_section_offset) { 1362 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo(); 1363 1364 uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat"); 1365 1366 // Create the debug_abbrev section with boilerplate information. 1367 // We only care about low_pc and high_pc right now for the compilation 1368 // unit and methods. 1369 1370 // Tag 1: Compilation unit: DW_TAG_compile_unit. 1371 PushByte(dbg_abbrev, 1); 1372 PushByte(dbg_abbrev, DW_TAG_compile_unit); 1373 1374 // There are children (the methods). 1375 PushByte(dbg_abbrev, DW_CHILDREN_yes); 1376 1377 // DW_AT_producer DW_FORM_data1. 1378 // REVIEW: we can get rid of dbg_str section if 1379 // DW_FORM_string (immediate string) was used everywhere instead of 1380 // DW_FORM_strp (ref to string from .debug_str section). 1381 // DW_FORM_strp makes sense only if we reuse the strings. 1382 PushByte(dbg_abbrev, DW_AT_producer); 1383 PushByte(dbg_abbrev, DW_FORM_strp); 1384 1385 // DW_LANG_Java DW_FORM_data1. 1386 PushByte(dbg_abbrev, DW_AT_language); 1387 PushByte(dbg_abbrev, DW_FORM_data1); 1388 1389 // DW_AT_low_pc DW_FORM_addr. 1390 PushByte(dbg_abbrev, DW_AT_low_pc); 1391 PushByte(dbg_abbrev, DW_FORM_addr); 1392 1393 // DW_AT_high_pc DW_FORM_addr. 1394 PushByte(dbg_abbrev, DW_AT_high_pc); 1395 PushByte(dbg_abbrev, DW_FORM_addr); 1396 1397 if (dbg_line != nullptr) { 1398 // DW_AT_stmt_list DW_FORM_sec_offset. 1399 PushByte(dbg_abbrev, DW_AT_stmt_list); 1400 PushByte(dbg_abbrev, DW_FORM_sec_offset); 1401 } 1402 1403 // End of DW_TAG_compile_unit. 1404 PushHalf(dbg_abbrev, 0); 1405 1406 // Tag 2: Compilation unit: DW_TAG_subprogram. 1407 PushByte(dbg_abbrev, 2); 1408 PushByte(dbg_abbrev, DW_TAG_subprogram); 1409 1410 // There are no children. 1411 PushByte(dbg_abbrev, DW_CHILDREN_no); 1412 1413 // Name of the method. 1414 PushByte(dbg_abbrev, DW_AT_name); 1415 PushByte(dbg_abbrev, DW_FORM_strp); 1416 1417 // DW_AT_low_pc DW_FORM_addr. 1418 PushByte(dbg_abbrev, DW_AT_low_pc); 1419 PushByte(dbg_abbrev, DW_FORM_addr); 1420 1421 // DW_AT_high_pc DW_FORM_addr. 1422 PushByte(dbg_abbrev, DW_AT_high_pc); 1423 PushByte(dbg_abbrev, DW_FORM_addr); 1424 1425 // End of DW_TAG_subprogram. 1426 PushHalf(dbg_abbrev, 0); 1427 1428 // Start the debug_info section with the header information 1429 // 'unit_length' will be filled in later. 1430 int cunit_length = dbg_info->size(); 1431 PushWord(dbg_info, 0); 1432 1433 // 'version' - 3. 1434 PushHalf(dbg_info, 3); 1435 1436 // Offset into .debug_abbrev section (always 0). 1437 PushWord(dbg_info, 0); 1438 1439 // Address size: 4. 1440 PushByte(dbg_info, 4); 1441 1442 // Start the description for the compilation unit. 1443 // This uses tag 1. 1444 PushByte(dbg_info, 1); 1445 1446 // The producer is Android dex2oat. 1447 PushWord(dbg_info, producer_str_offset); 1448 1449 // The language is Java. 1450 PushByte(dbg_info, DW_LANG_Java); 1451 1452 // low_pc and high_pc. 1453 uint32_t cunit_low_pc = 0 - 1; 1454 uint32_t cunit_high_pc = 0; 1455 int cunit_low_pc_pos = dbg_info->size(); 1456 PushWord(dbg_info, 0); 1457 PushWord(dbg_info, 0); 1458 1459 if (dbg_line == nullptr) { 1460 for (size_t i = 0; i < method_info.size(); ++i) { 1461 const OatWriter::DebugInfo &dbg = method_info[i]; 1462 1463 cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_); 1464 cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_); 1465 1466 // Start a new TAG: subroutine (2). 1467 PushByte(dbg_info, 2); 1468 1469 // Enter name, low_pc, high_pc. 1470 PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_)); 1471 PushWord(dbg_info, dbg.low_pc_ + text_section_offset); 1472 PushWord(dbg_info, dbg.high_pc_ + text_section_offset); 1473 } 1474 } else { 1475 // TODO: in gdb info functions <regexp> - reports Java functions, but 1476 // source file is <unknown> because .debug_line is formed as one 1477 // compilation unit. To fix this it is possible to generate 1478 // a separate compilation unit for every distinct Java source. 1479 // Each of the these compilation units can have several non-adjacent 1480 // method ranges. 1481 1482 // Line number table offset 1483 PushWord(dbg_info, dbg_line->size()); 1484 1485 size_t lnt_length = dbg_line->size(); 1486 PushWord(dbg_line, 0); 1487 1488 PushHalf(dbg_line, 4); // LNT Version DWARF v4 => 4 1489 1490 size_t lnt_hdr_length = dbg_line->size(); 1491 PushWord(dbg_line, 0); // TODO: 64-bit uses 8-byte here 1492 1493 PushByte(dbg_line, 1); // minimum_instruction_length (ubyte) 1494 PushByte(dbg_line, 1); // maximum_operations_per_instruction (ubyte) = always 1 1495 PushByte(dbg_line, 1); // default_is_stmt (ubyte) 1496 1497 const int8_t LINE_BASE = -5; 1498 PushByte(dbg_line, LINE_BASE); // line_base (sbyte) 1499 1500 const uint8_t LINE_RANGE = 14; 1501 PushByte(dbg_line, LINE_RANGE); // line_range (ubyte) 1502 1503 const uint8_t OPCODE_BASE = 13; 1504 PushByte(dbg_line, OPCODE_BASE); // opcode_base (ubyte) 1505 1506 // Standard_opcode_lengths (array of ubyte). 1507 PushByte(dbg_line, 0); PushByte(dbg_line, 1); PushByte(dbg_line, 1); 1508 PushByte(dbg_line, 1); PushByte(dbg_line, 1); PushByte(dbg_line, 0); 1509 PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1); 1510 PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1); 1511 1512 PushByte(dbg_line, 0); // include_directories (sequence of path names) = EMPTY 1513 1514 // File_names (sequence of file entries). 1515 std::unordered_map<const char*, size_t> files; 1516 for (size_t i = 0; i < method_info.size(); ++i) { 1517 const OatWriter::DebugInfo &dbg = method_info[i]; 1518 // TODO: add package directory to the file name 1519 const char* file_name = dbg.src_file_name_ == nullptr ? "null" : dbg.src_file_name_; 1520 auto found = files.find(file_name); 1521 if (found == files.end()) { 1522 size_t file_index = 1 + files.size(); 1523 files[file_name] = file_index; 1524 PushStr(dbg_line, file_name); 1525 PushByte(dbg_line, 0); // include directory index = LEB128(0) - no directory 1526 PushByte(dbg_line, 0); // modification time = LEB128(0) - NA 1527 PushByte(dbg_line, 0); // file length = LEB128(0) - NA 1528 } 1529 } 1530 PushByte(dbg_line, 0); // End of file_names. 1531 1532 // Set lnt header length. 1533 UpdateWord(dbg_line, lnt_hdr_length, dbg_line->size() - lnt_hdr_length - 4); 1534 1535 // Generate Line Number Program code, one long program for all methods. 1536 LineTableGenerator line_table_generator(LINE_BASE, LINE_RANGE, OPCODE_BASE, 1537 dbg_line, 0, 1); 1538 1539 SrcMap pc2java_map; 1540 for (size_t i = 0; i < method_info.size(); ++i) { 1541 const OatWriter::DebugInfo &dbg = method_info[i]; 1542 const char* file_name = (dbg.src_file_name_ == nullptr) ? "null" : dbg.src_file_name_; 1543 size_t file_index = files[file_name]; 1544 DCHECK_NE(file_index, 0U) << file_name; 1545 1546 cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_); 1547 cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_); 1548 1549 // Start a new TAG: subroutine (2). 1550 PushByte(dbg_info, 2); 1551 1552 // Enter name, low_pc, high_pc. 1553 PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_)); 1554 PushWord(dbg_info, dbg.low_pc_ + text_section_offset); 1555 PushWord(dbg_info, dbg.high_pc_ + text_section_offset); 1556 1557 pc2java_map.clear(); 1558 GetLineInfoForJava(dbg.dbgstream_, dbg.compiled_method_->GetSrcMappingTable(), 1559 &pc2java_map, dbg.low_pc_); 1560 pc2java_map.DeltaFormat({dbg.low_pc_, 1}, dbg.high_pc_); 1561 1562 line_table_generator.SetFile(file_index); 1563 line_table_generator.SetAddr(dbg.low_pc_ + text_section_offset); 1564 line_table_generator.SetLine(1); 1565 for (auto& src_map_elem : pc2java_map) { 1566 line_table_generator.PutDelta(src_map_elem.from_, src_map_elem.to_); 1567 } 1568 } 1569 1570 // End Sequence should have the highest address set. 1571 line_table_generator.SetAddr(cunit_high_pc + text_section_offset); 1572 line_table_generator.EndSequence(); 1573 1574 // set lnt length 1575 UpdateWord(dbg_line, lnt_length, dbg_line->size() - lnt_length - 4); 1576 } 1577 1578 // One byte terminator 1579 PushByte(dbg_info, 0); 1580 1581 // Fill in cunit's low_pc and high_pc. 1582 UpdateWord(dbg_info, cunit_low_pc_pos, cunit_low_pc + text_section_offset); 1583 UpdateWord(dbg_info, cunit_low_pc_pos + 4, cunit_high_pc + text_section_offset); 1584 1585 // We have now walked all the methods. Fill in lengths. 1586 UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4); 1587} 1588 1589// Explicit instantiations 1590template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn, 1591 Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>; 1592template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn, 1593 Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>; 1594 1595} // namespace art 1596