1 /* Copyright (C) 2007-2010 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 13 /* 14 * Contains implementation of a class DwarfCU, that encapsulates a compilation 15 * unit in the .debug_info section of the mapped ELF file. 16 */ 17 18 #include "string.h" 19 #include "stdio.h" 20 #include "elf_file.h" 21 #include "dwarf_cu.h" 22 #include "dwarf_utils.h" 23 24 DwarfCU::DwarfCU(ElfFile* elf) 25 : elf_file_(elf), 26 cu_die_(NULL), 27 prev_cu_(NULL) { 28 } 29 30 DwarfCU::~DwarfCU() { 31 if (cu_die_ != NULL) { 32 delete cu_die_; 33 } 34 abbrs_.empty(); 35 } 36 37 DwarfCU* DwarfCU::create_instance(ElfFile* elf, const void* hdr) { 38 DwarfCU* ret; 39 40 /* 64-bit DWARF CU has first 4 bytes in its header set to 0xFFFFFFFF. */ 41 if (*reinterpret_cast<const Elf_Word*>(hdr) == 0xFFFFFFFF) { 42 ret = new(elf) DwarfCUImpl<Dwarf64_CUHdr, Dwarf64_Off> 43 (elf, reinterpret_cast<const Dwarf64_CUHdr*>(hdr)); 44 } else { 45 ret = new(elf) DwarfCUImpl<Dwarf32_CUHdr, Dwarf32_Off> 46 (elf, reinterpret_cast<const Dwarf32_CUHdr*>(hdr)); 47 } 48 assert(ret != NULL); 49 if (ret == NULL) { 50 _set_errno(ENOMEM); 51 } 52 return ret; 53 } 54 55 const Elf_Byte* DwarfCU::process_attrib(const Elf_Byte* prop, 56 Dwarf_Form form, 57 Dwarf_Value* attr_value) const { 58 assert(form != 0); 59 Dwarf_Value tmp_val; 60 Dwarf_Value leb128; 61 62 attr_value->type = DWARF_VALUE_UNKNOWN; 63 attr_value->encoded_size = 0; 64 attr_value->u64 = 0; 65 66 switch (form) { 67 /* Property is a block of data, contained in .debug_info section. Block 68 * size is encoded with 1 byte value, and block data immediately follows 69 * block size. */ 70 case DW_FORM_block1: 71 attr_value->type = DWARF_VALUE_BLOCK; 72 attr_value->block.block_size = *prop; 73 attr_value->block.block_ptr = prop + 1; 74 attr_value->encoded_size = 75 static_cast<Elf_Word>(attr_value->block.block_size + 1); 76 break; 77 78 /* Property is a block of data, contained in .debug_info section. Block 79 * size is encoded with 2 bytes value, and block data immediately follows 80 * block size. */ 81 case DW_FORM_block2: 82 attr_value->type = DWARF_VALUE_BLOCK; 83 attr_value->block.block_size = 84 elf_file_->pull_val(reinterpret_cast<const Elf_Half*>(prop)); 85 attr_value->block.block_ptr = prop + 2; 86 attr_value->encoded_size = 87 static_cast<Elf_Word>(attr_value->block.block_size + 2); 88 break; 89 90 /* Property is a block of data, contained in .debug_info section. Block 91 * size is encoded with 4 bytes value, and block data immediately follows 92 * block size. */ 93 case DW_FORM_block4: 94 attr_value->type = DWARF_VALUE_BLOCK; 95 attr_value->block.block_size = 96 elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop)); 97 attr_value->block.block_ptr = prop + 4; 98 attr_value->encoded_size = 99 static_cast<Elf_Word>(attr_value->block.block_size + 4); 100 break; 101 102 /* Property is a block of data, contained in .debug_info section. Block 103 * size is encoded with unsigned LEB128 value, and block data immediately 104 * follows block size. */ 105 case DW_FORM_block: 106 reinterpret_cast<const Dwarf_Leb128*>(prop)->process_unsigned(&leb128); 107 attr_value->type = DWARF_VALUE_BLOCK; 108 attr_value->block.block_size = leb128.u32; 109 attr_value->block.block_ptr = prop + leb128.encoded_size; 110 attr_value->encoded_size = 111 static_cast<Elf_Word>(attr_value->block.block_size + 112 leb128.encoded_size); 113 break; 114 115 /* Property is unsigned 1 byte value. */ 116 case DW_FORM_flag: 117 case DW_FORM_data1: 118 case DW_FORM_ref1: 119 attr_value->type = DWARF_VALUE_U8; 120 attr_value->u8 = *prop; 121 attr_value->encoded_size = 1; 122 break; 123 124 /* Property is unsigned 2 bytes value. */ 125 case DW_FORM_data2: 126 case DW_FORM_ref2: 127 attr_value->type = DWARF_VALUE_U16; 128 attr_value->u16 = 129 elf_file_->pull_val(reinterpret_cast<const Elf_Half*>(prop)); 130 attr_value->encoded_size = 2; 131 break; 132 133 /* Property is unsigned 4 bytes value. */ 134 case DW_FORM_data4: 135 case DW_FORM_ref4: 136 attr_value->type = DWARF_VALUE_U32; 137 attr_value->u32 = 138 elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop)); 139 attr_value->encoded_size = 4; 140 break; 141 142 /* Property is unsigned 8 bytes value. */ 143 case DW_FORM_data8: 144 case DW_FORM_ref8: 145 case DW_FORM_ref_sig8: 146 attr_value->type = DWARF_VALUE_U64; 147 attr_value->u64 = 148 elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop)); 149 attr_value->encoded_size = 8; 150 break; 151 152 /* Property is signed LEB128 value. */ 153 case DW_FORM_sdata: 154 reinterpret_cast<const Dwarf_Leb128*>(prop)->process_signed(attr_value); 155 break; 156 157 /* Property is unsigned LEB128 value. */ 158 case DW_FORM_ref_udata: 159 case DW_FORM_udata: 160 reinterpret_cast<const Dwarf_Leb128*>(prop)->process_unsigned(attr_value); 161 break; 162 163 /* Property is a string contained directly in .debug_info section. */ 164 case DW_FORM_string: 165 attr_value->type = DWARF_VALUE_STR; 166 attr_value->str = reinterpret_cast<const char*>(prop); 167 attr_value->encoded_size = strlen(attr_value->str) + 1; 168 break; 169 170 /* Property is an offset of a string contained in .debug_str section. 171 * We will process the reference here, converting it into the actual 172 * string value. */ 173 case DW_FORM_strp: 174 attr_value->type = DWARF_VALUE_STR; 175 if (elf_file_->is_DWARF_64()) { 176 Elf_Xword str_offset = 177 elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop)); 178 attr_value->str = elf_file_->get_debug_str(str_offset); 179 attr_value->encoded_size = 8; 180 } else { 181 Elf_Word str_offset = 182 elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop)); 183 attr_value->str = elf_file_->get_debug_str(str_offset); 184 attr_value->encoded_size = 4; 185 } 186 break; 187 188 /* Property is an address. */ 189 case DW_FORM_addr: 190 if (addr_sizeof_ == 4) { 191 attr_value->type = DWARF_VALUE_PTR32; 192 attr_value->u32 = 193 elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop)); 194 } else { 195 attr_value->type = DWARF_VALUE_PTR64; 196 attr_value->u64 = 197 elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop)); 198 } 199 attr_value->encoded_size = addr_sizeof_; 200 break; 201 202 /* Reference from the beginning of .debug_info section. */ 203 case DW_FORM_ref_addr: 204 /* DWARF3+ requires that encoding size of this property must be 4 bytes 205 * in 32-bit DWARF, and 8 bytes in 64-bit DWARF, while DWARF2- requires 206 * encoding size to be equal to CU's pointer size. */ 207 if (is_DWARF3_or_higher()) { 208 if (elf_file_->is_DWARF_64()) { 209 attr_value->type = DWARF_VALUE_U64; 210 attr_value->u64 = 211 elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop)); 212 attr_value->encoded_size = 4; 213 } else { 214 attr_value->type = DWARF_VALUE_U32; 215 attr_value->u32 = 216 elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop)); 217 attr_value->encoded_size = 8; 218 } 219 } else { 220 if (addr_sizeof_ == 4) { 221 attr_value->type = DWARF_VALUE_U32; 222 attr_value->u32 = 223 elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop)); 224 } else { 225 attr_value->type = DWARF_VALUE_U64; 226 attr_value->u64 = 227 elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop)); 228 } 229 attr_value->encoded_size = addr_sizeof_; 230 } 231 break; 232 233 /* Reference to a section, other than .debug_info, or .debug_str */ 234 case DW_FORM_sec_offset: 235 if (elf_file_->is_DWARF_64()) { 236 attr_value->type = DWARF_VALUE_U64; 237 attr_value->u64 = 238 elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop)); 239 attr_value->encoded_size = 4; 240 } else { 241 attr_value->type = DWARF_VALUE_U32; 242 attr_value->u32 = 243 elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop)); 244 attr_value->encoded_size = 8; 245 } 246 break; 247 248 /* This is a replacement for DW_FORM_flag, which doesn't consume memory 249 * in .debug_info section, and only by the fact of its existence it is 250 * equal to DW_FORM_flag with value set to 1. */ 251 case DW_FORM_flag_present: 252 attr_value->type = DWARF_VALUE_U8; 253 attr_value->u8 = 1; 254 attr_value->encoded_size = 0; 255 break; 256 257 /* Encodes the actual form to be used. */ 258 case DW_FORM_indirect: 259 // Starts with ULEB128 260 prop = reinterpret_cast<const Elf_Byte*> 261 (reinterpret_cast<const Dwarf_Leb128*> 262 (prop)->process_unsigned(&tmp_val)); 263 /* ULEB128 encodes the actual form to be used to process this entry. */ 264 process_attrib(prop, tmp_val.u16, attr_value); 265 attr_value->encoded_size += tmp_val.encoded_size; 266 break; 267 268 /* This form is defined for DWARF4, and has no documentation whatsoever. */ 269 case DW_FORM_exprloc: 270 default: 271 attr_value->type = DWARF_VALUE_U32; 272 attr_value->u32 = 273 elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop)); 274 attr_value->encoded_size = 4; 275 break; 276 } 277 278 return prop + attr_value->encoded_size; 279 } 280 281 void DwarfCU::dump() const { 282 printf("\n\n>>>>>>>>>>>>>>> CU %p (version %u, address size %u)\n", 283 cu_die_->die(), static_cast<Elf_Word>(version_), 284 static_cast<Elf_Word>(addr_sizeof_)); 285 printf(">>>>> Build dir path: %s\n", comp_dir_path()); 286 printf(">>>>> Build file path: %s\n", rel_cu_path()); 287 if (cu_die_ != NULL) { 288 cu_die_->dump(false); 289 } 290 } 291 292 //============================================================================= 293 // DwarfCUImpl implementation 294 //============================================================================= 295 296 template <typename Dwarf_CUHdr, typename Dwarf_Off> 297 DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::DwarfCUImpl(ElfFile* elf, 298 const Dwarf_CUHdr* hdr) 299 : DwarfCU(elf), 300 cu_header_(hdr) { 301 /* Cache CU's DIE abbreviation descriptor in the array. This MUST be done 302 * BEFORE first call to array's cache_to() method. */ 303 const Dwarf_Abbr_DIE* cu_abbr_die = reinterpret_cast<const Dwarf_Abbr_DIE*> 304 (INC_CPTR(elf->get_debug_abbrev_data(), 305 elf->pull_val(hdr->abbrev_offset))); 306 abbrs_.add(cu_abbr_die); 307 308 cu_size_ = elf->pull_val(hdr->size_hdr.size); 309 version_ = elf->pull_val(hdr->version); 310 addr_sizeof_ = hdr->address_size; 311 memset(&stmtl_header_, 0, sizeof(stmtl_header_)); 312 } 313 314 template <typename Dwarf_CUHdr, typename Dwarf_Off> 315 bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::parse( 316 const DwarfParseContext* parse_context, 317 const void** next_cu_die) { 318 /* Start parsing with the DIE for this CU. */ 319 if (process_DIE(parse_context, get_DIE(), NULL) == NULL) { 320 return false; 321 } 322 323 /* CU area size (thus, next CU header offset) in .debug_info section equals 324 * to CU size, plus number of bytes, required to encode CU size in CU header 325 * (4 for 32-bit CU, and 12 for 64-bit CU. */ 326 *next_cu_die = 327 INC_CPTR(cu_header_, cu_size_ + ELFF_FIELD_OFFSET(Dwarf_CUHdr, version)); 328 329 return true; 330 } 331 332 template <typename Dwarf_CUHdr, typename Dwarf_Off> 333 const Elf_Byte* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::process_DIE( 334 const DwarfParseContext* parse_context, 335 const Dwarf_DIE* die, 336 DIEObject* parent_obj) { 337 while (is_attrib_ptr_valid(die) && !die->is_separator()) { 338 Dwarf_AbbrNum abbr_num; 339 Dwarf_Tag die_tag; 340 Elf_Word sibling_off = 0; 341 342 /* Get DIE's abbreviation number, and advance to DIE's properties. */ 343 const Elf_Byte* die_attr = die->process(&abbr_num); 344 345 /* Get abbreviation for the current DIE. */ 346 const Dwarf_Abbr_DIE* die_abbr = abbrs_.cache_to(abbr_num); 347 if (die_abbr == NULL) { 348 return NULL; 349 } 350 351 /* Get base DIE properties, and advance to the DIE's 352 * attribute descriptors. */ 353 const Dwarf_Abbr_AT* at_abbr = die_abbr->process(NULL, &die_tag); 354 355 /* Instantiate DIE object for this DIE, and get list of properties, 356 * that should be collected while processing that DIE. */ 357 DIEObject* die_obj = 358 create_die_object(parse_context, die, parent_obj, die_tag); 359 if (die_obj == NULL && errno != 0) { 360 return NULL; 361 } 362 363 if (die_obj != NULL) { 364 if (parent_obj != NULL) { 365 /* Update list of parent's children. */ 366 die_obj->link_sibling(parent_obj->last_child()); 367 parent_obj->link_child(die_obj); 368 } else { 369 /* NULL parent object is allowed only for CU DIE itself. */ 370 assert(cu_die_ == NULL && die_tag == DW_TAG_compile_unit); 371 if (cu_die_ == NULL && die_tag != DW_TAG_compile_unit) { 372 _set_errno(EINVAL); 373 return NULL; 374 } 375 cu_die_ = die_obj; 376 /* This CU DIE object will be used as a parent for all DIE 377 * objects, created in this method. */ 378 parent_obj = cu_die_; 379 } 380 } 381 382 // Loop through all DIE properties. 383 while (elf_file_->is_valid_abbr_ptr(at_abbr, sizeof(Dwarf_Abbr_AT)) && 384 !at_abbr->is_separator()) { 385 Dwarf_At at_value; 386 Dwarf_Form at_form; 387 Dwarf_Value attr_value; 388 389 // Obtain next property value. 390 at_abbr = at_abbr->process(&at_value, &at_form); 391 die_attr = process_attrib(die_attr, at_form, &attr_value); 392 393 if (at_value == DW_AT_sibling) { 394 /* DW_AT_sibling means that next DIE is a child of the one that's 395 * being currently processed. We need to cache value of this property 396 * in order to correctly calculate next sibling of this DIE after 397 * child's DIE has been processed. */ 398 assert(sibling_off == 0); 399 sibling_off = attr_value.u32; 400 } 401 } 402 403 /* Next DIE immediately follows last property for the current DIE. */ 404 die = reinterpret_cast<const Dwarf_DIE*>(die_attr); 405 if (sibling_off != 0) { 406 // Process child DIE. 407 process_DIE(parse_context, die, die_obj != NULL ? die_obj : parent_obj); 408 // Next sibling DIE offset is relative to this CU's header beginning. 409 die = INC_CPTR_T(Dwarf_DIE, cu_header_, sibling_off); 410 } 411 } 412 413 return INC_CPTR_T(Elf_Byte, die, 1); 414 } 415 416 template <typename Dwarf_CUHdr, typename Dwarf_Off> 417 DIEObject* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::create_die_object( 418 const DwarfParseContext* parse_context, 419 const Dwarf_DIE* die, 420 DIEObject* parent, 421 Dwarf_Tag tag) { 422 DIEObject* ret = NULL; 423 424 /* We will always create a DIE object for CU DIE. */ 425 if (tag == DW_TAG_compile_unit || collect_die(parse_context, tag)) { 426 ret = new(elf_file_) DIEObject(die, this, parent); 427 assert(ret != NULL); 428 if (ret == NULL) { 429 _set_errno(ENOMEM); 430 } 431 } else { 432 _set_errno(0); 433 } 434 return ret; 435 } 436 437 template <typename Dwarf_CUHdr, typename Dwarf_Off> 438 bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::init_stmtl() { 439 if (stmtl_header_.unit_length != 0) { 440 return true; 441 } 442 443 assert(cu_die_ != NULL); 444 if (cu_die_ == NULL) { 445 _set_errno(EINVAL); 446 return false; 447 } 448 449 DIEAttrib stmtl; 450 if (!cu_die()->get_attrib(DW_AT_stmt_list, &stmtl)) { 451 _set_errno(EINVAL); 452 return false; 453 } 454 455 const void* stmtl_start = 456 INC_CPTR(elf_file()->get_debug_line_data(), stmtl.value()->u32); 457 if (*reinterpret_cast<const Elf_Word*>(stmtl_start) == 0xFFFFFFFF) { 458 cache_stmtl<Dwarf64_STMTLHdr>(reinterpret_cast<const Dwarf64_STMTLHdr*>(stmtl_start)); 459 } else { 460 cache_stmtl<Dwarf32_STMTLHdr>(reinterpret_cast<const Dwarf32_STMTLHdr*>(stmtl_start)); 461 } 462 463 return true; 464 } 465 466 template <typename Dwarf_CUHdr, typename Dwarf_Off> 467 bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::get_pc_address_file_info( 468 Elf_Xword address, 469 Dwarf_AddressInfo* info) { 470 /* Make sure STMTL header is cached. */ 471 if (!init_stmtl()) { 472 return false; 473 } 474 /* Flags address match, that should trigger return next time 475 * source line gets adjusted. */ 476 bool found = false; 477 /* Create new state machine. */ 478 DwarfStateMachine state(stmtl_header_.default_is_stmt != 0); 479 480 /* Start the "Line Number Program" */ 481 const Elf_Byte* go = stmtl_header_.start; 482 while (go < stmtl_header_.end) { 483 const Elf_Byte op = *go; 484 go++; 485 486 if (op == 0) { 487 /* This is an extended opcode. */ 488 Dwarf_Value op_size; 489 490 /* First ULEB128 contains opcode size, (excluding ULEB128 itself). */ 491 go = reinterpret_cast<const Elf_Byte*> 492 (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&op_size)); 493 /* Next is the extended opcode. */ 494 const Elf_Byte* ex_op_ptr = go; 495 switch (*ex_op_ptr) { 496 case DW_LNE_end_sequence: 497 state.end_sequence_ = true; 498 state.reset(stmtl_header_.default_is_stmt != 0); 499 found = false; 500 break; 501 502 case DW_LNE_set_address: { 503 Elf_Xword prev_address = state.address_; 504 if (is_CU_address_64()) { 505 state.address_ = 506 elf_file()->pull_val(reinterpret_cast<const Elf_Xword*>(ex_op_ptr + 1)); 507 } else { 508 state.address_ = 509 elf_file()->pull_val(reinterpret_cast<const Elf_Word*>(ex_op_ptr + 1)); 510 } 511 if (prev_address != 0 && 512 address >= prev_address && address < state.address_) { 513 return set_source_info(&state, info); 514 } else if (address == state.address_) { 515 found = true; 516 } 517 break; 518 } 519 520 case DW_LNE_define_file: { 521 /* Parameters start with the directly encoded zero-terminated 522 * file name. */ 523 state.set_file_info_ = INC_CPTR_T(Dwarf_STMTL_FileDesc, ex_op_ptr, 1); 524 assert(state.set_file_info_ != NULL); 525 if (state.set_file_info_ != NULL) { 526 ex_op_ptr = reinterpret_cast<const Elf_Byte*>(state.set_file_info_->process(NULL)); 527 } 528 break; 529 } 530 531 case DW_LNE_set_discriminator: { 532 Dwarf_Value discr_val; 533 /* One parameter: discriminator's ULEB128 value. */ 534 reinterpret_cast<const Dwarf_Leb128*>(ex_op_ptr + 1)->process_unsigned(&discr_val); 535 state.discriminator_ = discr_val.u32; 536 break; 537 } 538 539 default: 540 assert(0); 541 return false; 542 } 543 go += op_size.u32; 544 } else if (op < stmtl_header_.opcode_base) { 545 /* This is a standard opcode. */ 546 switch (op) { 547 case DW_LNS_copy: 548 /* No parameters. */ 549 state.basic_block_ = false; 550 state.prologue_end_ = false; 551 state.epilogue_begin_ = false; 552 break; 553 554 case DW_LNS_advance_pc: { 555 /* One parameter: ULEB128 value to add to the current address value 556 * in the state machine. */ 557 Dwarf_Value addr_add; 558 go = reinterpret_cast<const Elf_Byte*> 559 (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&addr_add)); 560 Elf_Xword prev_address = state.address_; 561 state.address_ += addr_add.u64; 562 if (prev_address != 0 && 563 address >= prev_address && address < state.address_) { 564 return set_source_info(&state, info); 565 } else if (address == state.address_) { 566 found = true; 567 } 568 break; 569 } 570 571 case DW_LNS_advance_line: { 572 /* One parameter: signed LEB128 value to add to the current line 573 * number in the state machine. */ 574 Dwarf_Value line_add; 575 go = reinterpret_cast<const Elf_Byte*> 576 (reinterpret_cast<const Dwarf_Leb128*>(go)->process_signed(&line_add)); 577 state.line_ += line_add.s32; 578 if (found) { 579 return set_source_info(&state, info); 580 } 581 break; 582 } 583 584 case DW_LNS_set_file: { 585 /* One parameter: ULEB128 value encoding current file number. */ 586 Dwarf_Value file_num; 587 go = reinterpret_cast<const Elf_Byte*> 588 (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&file_num)); 589 state.file_ = file_num.u32; 590 /* This operation should discard previously saved file information. */ 591 state.set_file_info_ = NULL; 592 break; 593 } 594 595 case DW_LNS_set_column: { 596 /* One parameter: ULEB128 value encoding current column number. */ 597 Dwarf_Value column_num; 598 go = reinterpret_cast<const Elf_Byte*> 599 (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&column_num)); 600 state.column_ = column_num.u32; 601 break; 602 } 603 604 case DW_LNS_negate_stmt: 605 /* No parameters. */ 606 state.is_stmt_ = !state.is_stmt_; 607 break; 608 609 case DW_LNS_set_basic_block: 610 /* No parameters. */ 611 state.basic_block_ = true; 612 break; 613 614 case DW_LNS_const_add_pc: { 615 Elf_Xword prev_address = state.address_; 616 /* No parameters. This operation does the same thing, as special 617 * opcode 255 would do to the current address. */ 618 Elf_Word adjusted = 619 static_cast<Elf_Word>(255) - stmtl_header_.opcode_base; 620 state.address_ += (adjusted / stmtl_header_.line_range) * 621 stmtl_header_.min_instruction_len; 622 if (prev_address != 0 && 623 address >= prev_address && address < state.address_) { 624 return set_source_info(&state, info); 625 } else if (address == state.address_) { 626 found = true; 627 } 628 break; 629 } 630 631 case DW_LNS_fixed_advance_pc: { 632 Elf_Xword prev_address = state.address_; 633 /* One parameter: directly encoded 16-bit value to add to the 634 * current address. */ 635 state.address_ += 636 elf_file()->pull_val(reinterpret_cast<const Elf_Half*>(go)); 637 if (prev_address != 0 && 638 address >= prev_address && address < state.address_) { 639 return set_source_info(&state, info); 640 } else if (address == state.address_) { 641 found = true; 642 } 643 go += sizeof(Elf_Half); 644 break; 645 } 646 647 case DW_LNS_set_prologue_end: 648 /* No parameters. */ 649 state.prologue_end_ = true; 650 break; 651 652 case DW_LNS_set_epilogue_begin: 653 /* No parameters. */ 654 state.epilogue_begin_ = true; 655 break; 656 657 case DW_LNS_set_isa: { 658 /* One parameter: ISA value encoded as ULEB128. */ 659 Dwarf_Value isa_val; 660 go = reinterpret_cast<const Elf_Byte*> 661 (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&isa_val)); 662 state.isa_ = isa_val.u32; 663 break; 664 } 665 666 default: 667 /* Unknown opcode. Just skip it. */ 668 for (Elf_Byte uleb = 0; 669 uleb < stmtl_header_.standard_opcode_lengths[op - 1]; uleb++) { 670 Dwarf_Value tmp; 671 go = reinterpret_cast<const Elf_Byte*> 672 (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&tmp)); 673 } 674 break; 675 } 676 } else { 677 Elf_Xword prev_address = state.address_; 678 /* This is a special opcode. */ 679 const Elf_Word adjusted = op - stmtl_header_.opcode_base; 680 /* Advance address. */ 681 state.address_ += (adjusted / stmtl_header_.line_range) * 682 stmtl_header_.min_instruction_len; 683 if (prev_address != 0 && 684 address >= prev_address && address < state.address_) { 685 return set_source_info(&state, info); 686 } 687 /* Advance line. */ 688 state.line_ += stmtl_header_.line_base + 689 (adjusted % stmtl_header_.line_range); 690 if (state.address_ == address) { 691 return set_source_info(&state, info); 692 } 693 /* Do the woodoo. */ 694 state.basic_block_ = false; 695 state.prologue_end_ = false; 696 state.epilogue_begin_ = false; 697 } 698 } 699 700 return false; 701 } 702 703 template <typename Dwarf_CUHdr, typename Dwarf_Off> 704 const Dwarf_STMTL_FileDesc* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::get_stmt_file_info( 705 Elf_Word index) { 706 /* Index must be 1-based. */ 707 if (index == 0) { 708 return NULL; 709 } 710 711 const Dwarf_STMTL_FileDesc* cur_desc = stmtl_header_.file_infos; 712 while (index != 1 && !cur_desc->is_last_entry()) { 713 cur_desc = cur_desc->process(NULL); 714 index--; 715 } 716 assert(!cur_desc->is_last_entry()); 717 return cur_desc->is_last_entry() ? NULL : cur_desc; 718 } 719 720 template <typename Dwarf_CUHdr, typename Dwarf_Off> 721 const char* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::get_stmt_dir_name( 722 Elf_Word dir_index) { 723 if (dir_index == 0) { 724 /* Requested is current compilation directory. */ 725 return comp_dir_path(); 726 } 727 if (dir_index > stmtl_header_.inc_dir_num) { 728 return NULL; 729 } 730 731 const char* cur_dir = stmtl_header_.include_directories; 732 while (dir_index != 1) { 733 cur_dir += strlen(cur_dir) + 1; 734 dir_index--; 735 } 736 return cur_dir; 737 } 738 739 template <typename Dwarf_CUHdr, typename Dwarf_Off> 740 bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::set_source_info( 741 const DwarfStateMachine* state, 742 Dwarf_AddressInfo* info) { 743 info->line_number = state->line_; 744 const Dwarf_STMTL_FileDesc* file_info = state->set_file_info_; 745 if (file_info == NULL) { 746 file_info = get_stmt_file_info(state->file_); 747 if (file_info == NULL) { 748 info->file_name = rel_cu_path(); 749 info->dir_name = comp_dir_path(); 750 return true; 751 } 752 } 753 info->file_name = file_info->get_file_name(); 754 const Elf_Word dir_index = file_info->get_dir_index(); 755 info->dir_name = get_stmt_dir_name(dir_index); 756 return true; 757 } 758 759