elf_writer_quick.cc revision 8683038c1f59bea790d8c7691e40eed7f6250e4a
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_builder.h" 27#include "elf_file.h" 28#include "elf_utils.h" 29#include "file_output_stream.h" 30#include "globals.h" 31#include "leb128.h" 32#include "oat.h" 33#include "oat_writer.h" 34#include "utils.h" 35 36namespace art { 37 38static void PushByte(std::vector<uint8_t>* buf, int data) { 39 buf->push_back(data & 0xff); 40} 41 42static uint32_t PushStr(std::vector<uint8_t>* buf, const char* str, const char* def = nullptr) { 43 if (str == nullptr) { 44 str = def; 45 } 46 47 uint32_t offset = buf->size(); 48 for (size_t i = 0; str[i] != '\0'; ++i) { 49 buf->push_back(str[i]); 50 } 51 buf->push_back('\0'); 52 return offset; 53} 54 55static uint32_t PushStr(std::vector<uint8_t>* buf, const std::string &str) { 56 uint32_t offset = buf->size(); 57 buf->insert(buf->end(), str.begin(), str.end()); 58 buf->push_back('\0'); 59 return offset; 60} 61 62static void UpdateWord(std::vector<uint8_t>* buf, int offset, int data) { 63 (*buf)[offset+0] = data; 64 (*buf)[offset+1] = data >> 8; 65 (*buf)[offset+2] = data >> 16; 66 (*buf)[offset+3] = data >> 24; 67} 68 69static void PushHalf(std::vector<uint8_t>* buf, int data) { 70 buf->push_back(data & 0xff); 71 buf->push_back((data >> 8) & 0xff); 72} 73 74template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 75 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 76 typename Elf_Phdr, typename Elf_Shdr> 77bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 78 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file, 79 OatWriter* oat_writer, 80 const std::vector<const DexFile*>& dex_files, 81 const std::string& android_root, 82 bool is_host, 83 const CompilerDriver& driver) { 84 ElfWriterQuick elf_writer(driver, elf_file); 85 return elf_writer.Write(oat_writer, dex_files, android_root, is_host); 86} 87 88std::vector<uint8_t>* ConstructCIEFrameX86(bool is_x86_64) { 89 std::vector<uint8_t>* cfi_info = new std::vector<uint8_t>; 90 91 // Length (will be filled in later in this routine). 92 if (is_x86_64) { 93 PushWord(cfi_info, 0xffffffff); // Indicates 64bit 94 PushWord(cfi_info, 0); 95 PushWord(cfi_info, 0); 96 } else { 97 PushWord(cfi_info, 0); 98 } 99 100 // CIE id: always 0. 101 if (is_x86_64) { 102 PushWord(cfi_info, 0); 103 PushWord(cfi_info, 0); 104 } else { 105 PushWord(cfi_info, 0); 106 } 107 108 // Version: always 1. 109 cfi_info->push_back(0x01); 110 111 // Augmentation: 'zR\0' 112 cfi_info->push_back(0x7a); 113 cfi_info->push_back(0x52); 114 cfi_info->push_back(0x0); 115 116 // Code alignment: 1. 117 EncodeUnsignedLeb128(1, cfi_info); 118 119 // Data alignment. 120 if (is_x86_64) { 121 EncodeSignedLeb128(-8, cfi_info); 122 } else { 123 EncodeSignedLeb128(-4, cfi_info); 124 } 125 126 // Return address register. 127 if (is_x86_64) { 128 // R16(RIP) 129 cfi_info->push_back(0x10); 130 } else { 131 // R8(EIP) 132 cfi_info->push_back(0x08); 133 } 134 135 // Augmentation length: 1. 136 cfi_info->push_back(1); 137 138 // Augmentation data. 139 if (is_x86_64) { 140 // 0x04 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata8). 141 cfi_info->push_back(0x04); 142 } else { 143 // 0x03 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4). 144 cfi_info->push_back(0x03); 145 } 146 147 // Initial instructions. 148 if (is_x86_64) { 149 // DW_CFA_def_cfa R7(RSP) 8. 150 cfi_info->push_back(0x0c); 151 cfi_info->push_back(0x07); 152 cfi_info->push_back(0x08); 153 154 // DW_CFA_offset R16(RIP) 1 (* -8). 155 cfi_info->push_back(0x90); 156 cfi_info->push_back(0x01); 157 } else { 158 // DW_CFA_def_cfa R4(ESP) 4. 159 cfi_info->push_back(0x0c); 160 cfi_info->push_back(0x04); 161 cfi_info->push_back(0x04); 162 163 // DW_CFA_offset R8(EIP) 1 (* -4). 164 cfi_info->push_back(0x88); 165 cfi_info->push_back(0x01); 166 } 167 168 // Padding to a multiple of 4 169 while ((cfi_info->size() & 3) != 0) { 170 // DW_CFA_nop is encoded as 0. 171 cfi_info->push_back(0); 172 } 173 174 // Set the length of the CIE inside the generated bytes. 175 if (is_x86_64) { 176 uint32_t length = cfi_info->size() - 12; 177 UpdateWord(cfi_info, 4, length); 178 } else { 179 uint32_t length = cfi_info->size() - 4; 180 UpdateWord(cfi_info, 0, length); 181 } 182 return cfi_info; 183} 184 185std::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) { 186 switch (isa) { 187 case kX86: 188 return ConstructCIEFrameX86(false); 189 case kX86_64: 190 return ConstructCIEFrameX86(true); 191 192 default: 193 // Not implemented. 194 return nullptr; 195 } 196} 197 198class OatWriterWrapper FINAL : public CodeOutput { 199 public: 200 explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {} 201 202 void SetCodeOffset(size_t offset) { 203 oat_writer_->SetOatDataOffset(offset); 204 } 205 bool Write(OutputStream* out) OVERRIDE { 206 return oat_writer_->Write(out); 207 } 208 private: 209 OatWriter* const oat_writer_; 210}; 211 212template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 213 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 214 typename Elf_Phdr, typename Elf_Shdr> 215static void WriteDebugSymbols(const CompilerDriver* compiler_driver, 216 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 217 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder, 218 OatWriter* oat_writer); 219 220template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 221 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 222 typename Elf_Phdr, typename Elf_Shdr> 223bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 224 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer, 225 const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED, 226 const std::string& android_root_unused ATTRIBUTE_UNUSED, 227 bool is_host_unused ATTRIBUTE_UNUSED) { 228 constexpr bool debug = false; 229 const OatHeader& oat_header = oat_writer->GetOatHeader(); 230 Elf_Word oat_data_size = oat_header.GetExecutableOffset(); 231 uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size; 232 233 OatWriterWrapper wrapper(oat_writer); 234 235 std::unique_ptr<ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 236 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> > builder( 237 new ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 238 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>( 239 &wrapper, 240 elf_file_, 241 compiler_driver_->GetInstructionSet(), 242 0, 243 oat_data_size, 244 oat_data_size, 245 oat_exec_size, 246 compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(), 247 debug)); 248 249 if (!builder->Init()) { 250 return false; 251 } 252 253 if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) { 254 WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer); 255 } 256 257 if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) { 258 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> oat_patches( 259 ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, sizeof(uintptr_t), sizeof(uintptr_t)); 260 const std::vector<uintptr_t>& locations = oat_writer->GetAbsolutePatchLocations(); 261 const uint8_t* begin = reinterpret_cast<const uint8_t*>(&locations[0]); 262 const uint8_t* end = begin + locations.size() * sizeof(locations[0]); 263 oat_patches.GetBuffer()->assign(begin, end); 264 if (debug) { 265 LOG(INFO) << "Prepared .oat_patches for " << locations.size() << " patches."; 266 } 267 builder->RegisterRawSection(oat_patches); 268 } 269 270 return builder->Write(); 271} 272 273class LineTableGenerator FINAL : public Leb128Encoder { 274 public: 275 LineTableGenerator(int line_base, int line_range, int opcode_base, 276 std::vector<uint8_t>* data, uintptr_t current_address, 277 size_t current_line) 278 : Leb128Encoder(data), line_base_(line_base), line_range_(line_range), 279 opcode_base_(opcode_base), current_address_(current_address), 280 current_line_(current_line), current_file_index_(0) {} 281 282 void PutDelta(unsigned delta_addr, int delta_line) { 283 current_line_ += delta_line; 284 current_address_ += delta_addr; 285 286 if (delta_line >= line_base_ && delta_line < line_base_ + line_range_) { 287 unsigned special_opcode = (delta_line - line_base_) + 288 (line_range_ * delta_addr) + opcode_base_; 289 if (special_opcode <= 255) { 290 PushByte(data_, special_opcode); 291 return; 292 } 293 } 294 295 // generate standart opcode for address advance 296 if (delta_addr != 0) { 297 PushByte(data_, DW_LNS_advance_pc); 298 PushBackUnsigned(delta_addr); 299 } 300 301 // generate standart opcode for line delta 302 if (delta_line != 0) { 303 PushByte(data_, DW_LNS_advance_line); 304 PushBackSigned(delta_line); 305 } 306 307 // generate standart opcode for new LTN entry 308 PushByte(data_, DW_LNS_copy); 309 } 310 311 void SetAddr(uintptr_t addr) { 312 if (current_address_ == addr) { 313 return; 314 } 315 316 current_address_ = addr; 317 318 PushByte(data_, 0); // extended opcode: 319 PushByte(data_, 1 + 4); // length: opcode_size + address_size 320 PushByte(data_, DW_LNE_set_address); 321 PushWord(data_, addr); 322 } 323 324 void SetLine(unsigned line) { 325 int delta_line = line - current_line_; 326 if (delta_line) { 327 current_line_ = line; 328 PushByte(data_, DW_LNS_advance_line); 329 PushBackSigned(delta_line); 330 } 331 } 332 333 void SetFile(unsigned file_index) { 334 if (current_file_index_ != file_index) { 335 current_file_index_ = file_index; 336 PushByte(data_, DW_LNS_set_file); 337 PushBackUnsigned(file_index); 338 } 339 } 340 341 void EndSequence() { 342 // End of Line Table Program 343 // 0(=ext), 1(len), DW_LNE_end_sequence 344 PushByte(data_, 0); 345 PushByte(data_, 1); 346 PushByte(data_, DW_LNE_end_sequence); 347 } 348 349 private: 350 const int line_base_; 351 const int line_range_; 352 const int opcode_base_; 353 uintptr_t current_address_; 354 size_t current_line_; 355 unsigned current_file_index_; 356 357 DISALLOW_COPY_AND_ASSIGN(LineTableGenerator); 358}; 359 360// TODO: rewriting it using DexFile::DecodeDebugInfo needs unneeded stuff. 361static void GetLineInfoForJava(const uint8_t* dbgstream, const SrcMap& pc2dex, 362 SrcMap* result, uint32_t start_pc = 0) { 363 if (dbgstream == nullptr) { 364 return; 365 } 366 367 int adjopcode; 368 uint32_t dex_offset = 0; 369 uint32_t java_line = DecodeUnsignedLeb128(&dbgstream); 370 371 // skip parameters 372 for (uint32_t param_count = DecodeUnsignedLeb128(&dbgstream); param_count != 0; --param_count) { 373 DecodeUnsignedLeb128(&dbgstream); 374 } 375 376 for (bool is_end = false; is_end == false; ) { 377 uint8_t opcode = *dbgstream; 378 dbgstream++; 379 switch (opcode) { 380 case DexFile::DBG_END_SEQUENCE: 381 is_end = true; 382 break; 383 384 case DexFile::DBG_ADVANCE_PC: 385 dex_offset += DecodeUnsignedLeb128(&dbgstream); 386 break; 387 388 case DexFile::DBG_ADVANCE_LINE: 389 java_line += DecodeSignedLeb128(&dbgstream); 390 break; 391 392 case DexFile::DBG_START_LOCAL: 393 case DexFile::DBG_START_LOCAL_EXTENDED: 394 DecodeUnsignedLeb128(&dbgstream); 395 DecodeUnsignedLeb128(&dbgstream); 396 DecodeUnsignedLeb128(&dbgstream); 397 398 if (opcode == DexFile::DBG_START_LOCAL_EXTENDED) { 399 DecodeUnsignedLeb128(&dbgstream); 400 } 401 break; 402 403 case DexFile::DBG_END_LOCAL: 404 case DexFile::DBG_RESTART_LOCAL: 405 DecodeUnsignedLeb128(&dbgstream); 406 break; 407 408 case DexFile::DBG_SET_PROLOGUE_END: 409 case DexFile::DBG_SET_EPILOGUE_BEGIN: 410 case DexFile::DBG_SET_FILE: 411 break; 412 413 default: 414 adjopcode = opcode - DexFile::DBG_FIRST_SPECIAL; 415 dex_offset += adjopcode / DexFile::DBG_LINE_RANGE; 416 java_line += DexFile::DBG_LINE_BASE + (adjopcode % DexFile::DBG_LINE_RANGE); 417 418 for (SrcMap::const_iterator found = pc2dex.FindByTo(dex_offset); 419 found != pc2dex.end() && found->to_ == static_cast<int32_t>(dex_offset); 420 found++) { 421 result->push_back({found->from_ + start_pc, static_cast<int32_t>(java_line)}); 422 } 423 break; 424 } 425 } 426} 427 428/* 429 * @brief Generate the DWARF debug_info and debug_abbrev sections 430 * @param oat_writer The Oat file Writer. 431 * @param dbg_info Compilation unit information. 432 * @param dbg_abbrev Abbreviations used to generate dbg_info. 433 * @param dbg_str Debug strings. 434 */ 435static void FillInCFIInformation(OatWriter* oat_writer, 436 std::vector<uint8_t>* dbg_info, 437 std::vector<uint8_t>* dbg_abbrev, 438 std::vector<uint8_t>* dbg_str, 439 std::vector<uint8_t>* dbg_line, 440 uint32_t text_section_offset) { 441 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo(); 442 443 uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat"); 444 445 // Create the debug_abbrev section with boilerplate information. 446 // We only care about low_pc and high_pc right now for the compilation 447 // unit and methods. 448 449 // Tag 1: Compilation unit: DW_TAG_compile_unit. 450 PushByte(dbg_abbrev, 1); 451 PushByte(dbg_abbrev, DW_TAG_compile_unit); 452 453 // There are children (the methods). 454 PushByte(dbg_abbrev, DW_CHILDREN_yes); 455 456 // DW_AT_producer DW_FORM_data1. 457 // REVIEW: we can get rid of dbg_str section if 458 // DW_FORM_string (immediate string) was used everywhere instead of 459 // DW_FORM_strp (ref to string from .debug_str section). 460 // DW_FORM_strp makes sense only if we reuse the strings. 461 PushByte(dbg_abbrev, DW_AT_producer); 462 PushByte(dbg_abbrev, DW_FORM_strp); 463 464 // DW_LANG_Java DW_FORM_data1. 465 PushByte(dbg_abbrev, DW_AT_language); 466 PushByte(dbg_abbrev, DW_FORM_data1); 467 468 // DW_AT_low_pc DW_FORM_addr. 469 PushByte(dbg_abbrev, DW_AT_low_pc); 470 PushByte(dbg_abbrev, DW_FORM_addr); 471 472 // DW_AT_high_pc DW_FORM_addr. 473 PushByte(dbg_abbrev, DW_AT_high_pc); 474 PushByte(dbg_abbrev, DW_FORM_addr); 475 476 if (dbg_line != nullptr) { 477 // DW_AT_stmt_list DW_FORM_sec_offset. 478 PushByte(dbg_abbrev, DW_AT_stmt_list); 479 PushByte(dbg_abbrev, DW_FORM_sec_offset); 480 } 481 482 // End of DW_TAG_compile_unit. 483 PushHalf(dbg_abbrev, 0); 484 485 // Tag 2: Compilation unit: DW_TAG_subprogram. 486 PushByte(dbg_abbrev, 2); 487 PushByte(dbg_abbrev, DW_TAG_subprogram); 488 489 // There are no children. 490 PushByte(dbg_abbrev, DW_CHILDREN_no); 491 492 // Name of the method. 493 PushByte(dbg_abbrev, DW_AT_name); 494 PushByte(dbg_abbrev, DW_FORM_strp); 495 496 // DW_AT_low_pc DW_FORM_addr. 497 PushByte(dbg_abbrev, DW_AT_low_pc); 498 PushByte(dbg_abbrev, DW_FORM_addr); 499 500 // DW_AT_high_pc DW_FORM_addr. 501 PushByte(dbg_abbrev, DW_AT_high_pc); 502 PushByte(dbg_abbrev, DW_FORM_addr); 503 504 // End of DW_TAG_subprogram. 505 PushHalf(dbg_abbrev, 0); 506 507 // Start the debug_info section with the header information 508 // 'unit_length' will be filled in later. 509 int cunit_length = dbg_info->size(); 510 PushWord(dbg_info, 0); 511 512 // 'version' - 3. 513 PushHalf(dbg_info, 3); 514 515 // Offset into .debug_abbrev section (always 0). 516 PushWord(dbg_info, 0); 517 518 // Address size: 4. 519 PushByte(dbg_info, 4); 520 521 // Start the description for the compilation unit. 522 // This uses tag 1. 523 PushByte(dbg_info, 1); 524 525 // The producer is Android dex2oat. 526 PushWord(dbg_info, producer_str_offset); 527 528 // The language is Java. 529 PushByte(dbg_info, DW_LANG_Java); 530 531 // low_pc and high_pc. 532 uint32_t cunit_low_pc = 0 - 1; 533 uint32_t cunit_high_pc = 0; 534 int cunit_low_pc_pos = dbg_info->size(); 535 PushWord(dbg_info, 0); 536 PushWord(dbg_info, 0); 537 538 if (dbg_line == nullptr) { 539 for (size_t i = 0; i < method_info.size(); ++i) { 540 const OatWriter::DebugInfo &dbg = method_info[i]; 541 542 cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_); 543 cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_); 544 545 // Start a new TAG: subroutine (2). 546 PushByte(dbg_info, 2); 547 548 // Enter name, low_pc, high_pc. 549 PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_)); 550 PushWord(dbg_info, dbg.low_pc_ + text_section_offset); 551 PushWord(dbg_info, dbg.high_pc_ + text_section_offset); 552 } 553 } else { 554 // TODO: in gdb info functions <regexp> - reports Java functions, but 555 // source file is <unknown> because .debug_line is formed as one 556 // compilation unit. To fix this it is possible to generate 557 // a separate compilation unit for every distinct Java source. 558 // Each of the these compilation units can have several non-adjacent 559 // method ranges. 560 561 // Line number table offset 562 PushWord(dbg_info, dbg_line->size()); 563 564 size_t lnt_length = dbg_line->size(); 565 PushWord(dbg_line, 0); 566 567 PushHalf(dbg_line, 4); // LNT Version DWARF v4 => 4 568 569 size_t lnt_hdr_length = dbg_line->size(); 570 PushWord(dbg_line, 0); // TODO: 64-bit uses 8-byte here 571 572 PushByte(dbg_line, 1); // minimum_instruction_length (ubyte) 573 PushByte(dbg_line, 1); // maximum_operations_per_instruction (ubyte) = always 1 574 PushByte(dbg_line, 1); // default_is_stmt (ubyte) 575 576 const int8_t LINE_BASE = -5; 577 PushByte(dbg_line, LINE_BASE); // line_base (sbyte) 578 579 const uint8_t LINE_RANGE = 14; 580 PushByte(dbg_line, LINE_RANGE); // line_range (ubyte) 581 582 const uint8_t OPCODE_BASE = 13; 583 PushByte(dbg_line, OPCODE_BASE); // opcode_base (ubyte) 584 585 // Standard_opcode_lengths (array of ubyte). 586 PushByte(dbg_line, 0); PushByte(dbg_line, 1); PushByte(dbg_line, 1); 587 PushByte(dbg_line, 1); PushByte(dbg_line, 1); PushByte(dbg_line, 0); 588 PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1); 589 PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1); 590 591 PushByte(dbg_line, 0); // include_directories (sequence of path names) = EMPTY 592 593 // File_names (sequence of file entries). 594 std::unordered_map<const char*, size_t> files; 595 for (size_t i = 0; i < method_info.size(); ++i) { 596 const OatWriter::DebugInfo &dbg = method_info[i]; 597 // TODO: add package directory to the file name 598 const char* file_name = dbg.src_file_name_ == nullptr ? "null" : dbg.src_file_name_; 599 auto found = files.find(file_name); 600 if (found == files.end()) { 601 size_t file_index = 1 + files.size(); 602 files[file_name] = file_index; 603 PushStr(dbg_line, file_name); 604 PushByte(dbg_line, 0); // include directory index = LEB128(0) - no directory 605 PushByte(dbg_line, 0); // modification time = LEB128(0) - NA 606 PushByte(dbg_line, 0); // file length = LEB128(0) - NA 607 } 608 } 609 PushByte(dbg_line, 0); // End of file_names. 610 611 // Set lnt header length. 612 UpdateWord(dbg_line, lnt_hdr_length, dbg_line->size() - lnt_hdr_length - 4); 613 614 // Generate Line Number Program code, one long program for all methods. 615 LineTableGenerator line_table_generator(LINE_BASE, LINE_RANGE, OPCODE_BASE, 616 dbg_line, 0, 1); 617 618 SrcMap pc2java_map; 619 for (size_t i = 0; i < method_info.size(); ++i) { 620 const OatWriter::DebugInfo &dbg = method_info[i]; 621 const char* file_name = (dbg.src_file_name_ == nullptr) ? "null" : dbg.src_file_name_; 622 size_t file_index = files[file_name]; 623 DCHECK_NE(file_index, 0U) << file_name; 624 625 cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_); 626 cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_); 627 628 // Start a new TAG: subroutine (2). 629 PushByte(dbg_info, 2); 630 631 // Enter name, low_pc, high_pc. 632 PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_)); 633 PushWord(dbg_info, dbg.low_pc_ + text_section_offset); 634 PushWord(dbg_info, dbg.high_pc_ + text_section_offset); 635 636 GetLineInfoForJava(dbg.dbgstream_, dbg.compiled_method_->GetSrcMappingTable(), 637 &pc2java_map, dbg.low_pc_); 638 pc2java_map.DeltaFormat({dbg.low_pc_, 1}, dbg.high_pc_); 639 if (!pc2java_map.empty()) { 640 line_table_generator.SetFile(file_index); 641 line_table_generator.SetAddr(dbg.low_pc_ + text_section_offset); 642 line_table_generator.SetLine(1); 643 for (auto& src_map_elem : pc2java_map) { 644 line_table_generator.PutDelta(src_map_elem.from_, src_map_elem.to_); 645 } 646 pc2java_map.clear(); 647 } 648 } 649 650 // End Sequence should have the highest address set. 651 line_table_generator.SetAddr(cunit_high_pc + text_section_offset); 652 line_table_generator.EndSequence(); 653 654 // set lnt length 655 UpdateWord(dbg_line, lnt_length, dbg_line->size() - lnt_length - 4); 656 } 657 658 // One byte terminator 659 PushByte(dbg_info, 0); 660 661 // Fill in cunit's low_pc and high_pc. 662 UpdateWord(dbg_info, cunit_low_pc_pos, cunit_low_pc + text_section_offset); 663 UpdateWord(dbg_info, cunit_low_pc_pos + 4, cunit_high_pc + text_section_offset); 664 665 // We have now walked all the methods. Fill in lengths. 666 UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4); 667} 668 669template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 670 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 671 typename Elf_Phdr, typename Elf_Shdr> 672// Do not inline to avoid Clang stack frame problems. b/18738594 673NO_INLINE 674static void WriteDebugSymbols(const CompilerDriver* compiler_driver, 675 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 676 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder, 677 OatWriter* oat_writer) { 678 std::unique_ptr<std::vector<uint8_t>> cfi_info( 679 ConstructCIEFrame(compiler_driver->GetInstructionSet())); 680 681 Elf_Addr text_section_address = builder->GetTextBuilder().GetSection()->sh_addr; 682 683 // Iterate over the compiled methods. 684 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo(); 685 ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab = 686 builder->GetSymtabBuilder(); 687 for (auto it = method_info.begin(); it != method_info.end(); ++it) { 688 symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), it->low_pc_, true, 689 it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC); 690 691 // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2 692 // instructions, so that disassembler tools can correctly disassemble. 693 if (it->compiled_method_->GetInstructionSet() == kThumb2) { 694 symtab->AddSymbol("$t", &builder->GetTextBuilder(), it->low_pc_ & ~1, true, 695 0, STB_LOCAL, STT_NOTYPE); 696 } 697 698 // Include CFI for compiled method, if possible. 699 if (cfi_info.get() != nullptr) { 700 DCHECK(it->compiled_method_ != nullptr); 701 702 // Copy in the FDE, if present 703 const std::vector<uint8_t>* fde = it->compiled_method_->GetCFIInfo(); 704 if (fde != nullptr) { 705 // Copy the information into cfi_info and then fix the address in the new copy. 706 int cur_offset = cfi_info->size(); 707 cfi_info->insert(cfi_info->end(), fde->begin(), fde->end()); 708 709 bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff; 710 711 // Set the 'CIE_pointer' field. 712 uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4); 713 uint64_t offset_to_update = CIE_pointer; 714 if (is_64bit) { 715 (*cfi_info)[offset_to_update+0] = CIE_pointer; 716 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8; 717 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16; 718 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24; 719 (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32; 720 (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40; 721 (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48; 722 (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56; 723 } else { 724 (*cfi_info)[offset_to_update+0] = CIE_pointer; 725 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8; 726 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16; 727 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24; 728 } 729 730 // Set the 'initial_location' field. 731 offset_to_update += is_64bit ? 8 : 4; 732 if (is_64bit) { 733 const uint64_t quick_code_start = it->low_pc_ + text_section_address; 734 (*cfi_info)[offset_to_update+0] = quick_code_start; 735 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8; 736 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16; 737 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24; 738 (*cfi_info)[offset_to_update+4] = quick_code_start >> 32; 739 (*cfi_info)[offset_to_update+5] = quick_code_start >> 40; 740 (*cfi_info)[offset_to_update+6] = quick_code_start >> 48; 741 (*cfi_info)[offset_to_update+7] = quick_code_start >> 56; 742 } else { 743 const uint32_t quick_code_start = it->low_pc_ + text_section_address; 744 (*cfi_info)[offset_to_update+0] = quick_code_start; 745 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8; 746 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16; 747 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24; 748 } 749 } 750 } 751 } 752 753 bool hasCFI = (cfi_info.get() != nullptr); 754 bool hasLineInfo = false; 755 for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) { 756 if (dbg_info.dbgstream_ != nullptr && 757 !dbg_info.compiled_method_->GetSrcMappingTable().empty()) { 758 hasLineInfo = true; 759 break; 760 } 761 } 762 763 if (hasLineInfo || hasCFI) { 764 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_info(".debug_info", 765 SHT_PROGBITS, 766 0, nullptr, 0, 1, 0); 767 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_abbrev(".debug_abbrev", 768 SHT_PROGBITS, 769 0, nullptr, 0, 1, 0); 770 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_str(".debug_str", 771 SHT_PROGBITS, 772 0, nullptr, 0, 1, 0); 773 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_line(".debug_line", 774 SHT_PROGBITS, 775 0, nullptr, 0, 1, 0); 776 777 FillInCFIInformation(oat_writer, debug_info.GetBuffer(), 778 debug_abbrev.GetBuffer(), debug_str.GetBuffer(), 779 hasLineInfo ? debug_line.GetBuffer() : nullptr, 780 text_section_address); 781 782 builder->RegisterRawSection(debug_info); 783 builder->RegisterRawSection(debug_abbrev); 784 785 if (hasCFI) { 786 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> eh_frame(".eh_frame", 787 SHT_PROGBITS, 788 SHF_ALLOC, 789 nullptr, 0, 4, 0); 790 eh_frame.SetBuffer(std::move(*cfi_info.get())); 791 builder->RegisterRawSection(eh_frame); 792 } 793 794 if (hasLineInfo) { 795 builder->RegisterRawSection(debug_line); 796 } 797 798 builder->RegisterRawSection(debug_str); 799 } 800} 801 802// Explicit instantiations 803template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn, 804 Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>; 805template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn, 806 Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>; 807 808} // namespace art 809