LLVM API Documentation
00001 //===-- DWARFDebugLine.cpp ------------------------------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "DWARFDebugLine.h" 00011 #include "llvm/Support/Dwarf.h" 00012 #include "llvm/Support/Format.h" 00013 #include "llvm/Support/Path.h" 00014 #include "llvm/Support/raw_ostream.h" 00015 #include <algorithm> 00016 using namespace llvm; 00017 using namespace dwarf; 00018 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; 00019 00020 DWARFDebugLine::Prologue::Prologue() { 00021 clear(); 00022 } 00023 00024 void DWARFDebugLine::Prologue::clear() { 00025 TotalLength = Version = PrologueLength = 0; 00026 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0; 00027 OpcodeBase = 0; 00028 StandardOpcodeLengths.clear(); 00029 IncludeDirectories.clear(); 00030 FileNames.clear(); 00031 } 00032 00033 void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { 00034 OS << "Line table prologue:\n" 00035 << format(" total_length: 0x%8.8x\n", TotalLength) 00036 << format(" version: %u\n", Version) 00037 << format(" prologue_length: 0x%8.8x\n", PrologueLength) 00038 << format(" min_inst_length: %u\n", MinInstLength) 00039 << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst) 00040 << format(" default_is_stmt: %u\n", DefaultIsStmt) 00041 << format(" line_base: %i\n", LineBase) 00042 << format(" line_range: %u\n", LineRange) 00043 << format(" opcode_base: %u\n", OpcodeBase); 00044 00045 for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i) 00046 OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i+1), 00047 StandardOpcodeLengths[i]); 00048 00049 if (!IncludeDirectories.empty()) 00050 for (uint32_t i = 0; i < IncludeDirectories.size(); ++i) 00051 OS << format("include_directories[%3u] = '", i+1) 00052 << IncludeDirectories[i] << "'\n"; 00053 00054 if (!FileNames.empty()) { 00055 OS << " Dir Mod Time File Len File Name\n" 00056 << " ---- ---------- ---------- -----------" 00057 "----------------\n"; 00058 for (uint32_t i = 0; i < FileNames.size(); ++i) { 00059 const FileNameEntry& fileEntry = FileNames[i]; 00060 OS << format("file_names[%3u] %4" PRIu64 " ", i+1, fileEntry.DirIdx) 00061 << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", 00062 fileEntry.ModTime, fileEntry.Length) 00063 << fileEntry.Name << '\n'; 00064 } 00065 } 00066 } 00067 00068 bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data, 00069 uint32_t *offset_ptr) { 00070 const uint32_t prologue_offset = *offset_ptr; 00071 00072 clear(); 00073 TotalLength = debug_line_data.getU32(offset_ptr); 00074 Version = debug_line_data.getU16(offset_ptr); 00075 if (Version < 2) 00076 return false; 00077 00078 PrologueLength = debug_line_data.getU32(offset_ptr); 00079 const uint32_t end_prologue_offset = PrologueLength + *offset_ptr; 00080 MinInstLength = debug_line_data.getU8(offset_ptr); 00081 if (Version >= 4) 00082 MaxOpsPerInst = debug_line_data.getU8(offset_ptr); 00083 DefaultIsStmt = debug_line_data.getU8(offset_ptr); 00084 LineBase = debug_line_data.getU8(offset_ptr); 00085 LineRange = debug_line_data.getU8(offset_ptr); 00086 OpcodeBase = debug_line_data.getU8(offset_ptr); 00087 00088 StandardOpcodeLengths.reserve(OpcodeBase - 1); 00089 for (uint32_t i = 1; i < OpcodeBase; ++i) { 00090 uint8_t op_len = debug_line_data.getU8(offset_ptr); 00091 StandardOpcodeLengths.push_back(op_len); 00092 } 00093 00094 while (*offset_ptr < end_prologue_offset) { 00095 const char *s = debug_line_data.getCStr(offset_ptr); 00096 if (s && s[0]) 00097 IncludeDirectories.push_back(s); 00098 else 00099 break; 00100 } 00101 00102 while (*offset_ptr < end_prologue_offset) { 00103 const char *name = debug_line_data.getCStr(offset_ptr); 00104 if (name && name[0]) { 00105 FileNameEntry fileEntry; 00106 fileEntry.Name = name; 00107 fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); 00108 fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); 00109 fileEntry.Length = debug_line_data.getULEB128(offset_ptr); 00110 FileNames.push_back(fileEntry); 00111 } else { 00112 break; 00113 } 00114 } 00115 00116 if (*offset_ptr != end_prologue_offset) { 00117 fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should" 00118 " have ended at 0x%8.8x but it ended at 0x%8.8x\n", 00119 prologue_offset, end_prologue_offset, *offset_ptr); 00120 return false; 00121 } 00122 return true; 00123 } 00124 00125 DWARFDebugLine::Row::Row(bool default_is_stmt) { 00126 reset(default_is_stmt); 00127 } 00128 00129 void DWARFDebugLine::Row::postAppend() { 00130 BasicBlock = false; 00131 PrologueEnd = false; 00132 EpilogueBegin = false; 00133 } 00134 00135 void DWARFDebugLine::Row::reset(bool default_is_stmt) { 00136 Address = 0; 00137 Line = 1; 00138 Column = 0; 00139 File = 1; 00140 Isa = 0; 00141 Discriminator = 0; 00142 IsStmt = default_is_stmt; 00143 BasicBlock = false; 00144 EndSequence = false; 00145 PrologueEnd = false; 00146 EpilogueBegin = false; 00147 } 00148 00149 void DWARFDebugLine::Row::dump(raw_ostream &OS) const { 00150 OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column) 00151 << format(" %6u %3u %13u ", File, Isa, Discriminator) 00152 << (IsStmt ? " is_stmt" : "") 00153 << (BasicBlock ? " basic_block" : "") 00154 << (PrologueEnd ? " prologue_end" : "") 00155 << (EpilogueBegin ? " epilogue_begin" : "") 00156 << (EndSequence ? " end_sequence" : "") 00157 << '\n'; 00158 } 00159 00160 DWARFDebugLine::Sequence::Sequence() { 00161 reset(); 00162 } 00163 00164 void DWARFDebugLine::Sequence::reset() { 00165 LowPC = 0; 00166 HighPC = 0; 00167 FirstRowIndex = 0; 00168 LastRowIndex = 0; 00169 Empty = true; 00170 } 00171 00172 DWARFDebugLine::LineTable::LineTable() { 00173 clear(); 00174 } 00175 00176 void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { 00177 Prologue.dump(OS); 00178 OS << '\n'; 00179 00180 if (!Rows.empty()) { 00181 OS << "Address Line Column File ISA Discriminator Flags\n" 00182 << "------------------ ------ ------ ------ --- ------------- " 00183 "-------------\n"; 00184 for (const Row &R : Rows) { 00185 R.dump(OS); 00186 } 00187 } 00188 } 00189 00190 void DWARFDebugLine::LineTable::clear() { 00191 Prologue.clear(); 00192 Rows.clear(); 00193 Sequences.clear(); 00194 } 00195 00196 DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT) 00197 : LineTable(LT), RowNumber(0) { 00198 resetRowAndSequence(); 00199 } 00200 00201 void DWARFDebugLine::ParsingState::resetRowAndSequence() { 00202 Row.reset(LineTable->Prologue.DefaultIsStmt); 00203 Sequence.reset(); 00204 } 00205 00206 void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t offset) { 00207 if (Sequence.Empty) { 00208 // Record the beginning of instruction sequence. 00209 Sequence.Empty = false; 00210 Sequence.LowPC = Row.Address; 00211 Sequence.FirstRowIndex = RowNumber; 00212 } 00213 ++RowNumber; 00214 LineTable->appendRow(Row); 00215 if (Row.EndSequence) { 00216 // Record the end of instruction sequence. 00217 Sequence.HighPC = Row.Address; 00218 Sequence.LastRowIndex = RowNumber; 00219 if (Sequence.isValid()) 00220 LineTable->appendSequence(Sequence); 00221 Sequence.reset(); 00222 } 00223 Row.postAppend(); 00224 } 00225 00226 const DWARFDebugLine::LineTable * 00227 DWARFDebugLine::getLineTable(uint32_t offset) const { 00228 LineTableConstIter pos = LineTableMap.find(offset); 00229 if (pos != LineTableMap.end()) 00230 return &pos->second; 00231 return nullptr; 00232 } 00233 00234 const DWARFDebugLine::LineTable * 00235 DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data, 00236 uint32_t offset) { 00237 std::pair<LineTableIter, bool> pos = 00238 LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable())); 00239 LineTable *LT = &pos.first->second; 00240 if (pos.second) { 00241 if (!LT->parse(debug_line_data, RelocMap, &offset)) 00242 return nullptr; 00243 } 00244 return LT; 00245 } 00246 00247 bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data, 00248 const RelocAddrMap *RMap, 00249 uint32_t *offset_ptr) { 00250 const uint32_t debug_line_offset = *offset_ptr; 00251 00252 clear(); 00253 00254 if (!Prologue.parse(debug_line_data, offset_ptr)) { 00255 // Restore our offset and return false to indicate failure! 00256 *offset_ptr = debug_line_offset; 00257 return false; 00258 } 00259 00260 const uint32_t end_offset = debug_line_offset + Prologue.TotalLength + 00261 sizeof(Prologue.TotalLength); 00262 00263 ParsingState State(this); 00264 00265 while (*offset_ptr < end_offset) { 00266 uint8_t opcode = debug_line_data.getU8(offset_ptr); 00267 00268 if (opcode == 0) { 00269 // Extended Opcodes always start with a zero opcode followed by 00270 // a uleb128 length so you can skip ones you don't know about 00271 uint32_t ext_offset = *offset_ptr; 00272 uint64_t len = debug_line_data.getULEB128(offset_ptr); 00273 uint32_t arg_size = len - (*offset_ptr - ext_offset); 00274 00275 uint8_t sub_opcode = debug_line_data.getU8(offset_ptr); 00276 switch (sub_opcode) { 00277 case DW_LNE_end_sequence: 00278 // Set the end_sequence register of the state machine to true and 00279 // append a row to the matrix using the current values of the 00280 // state-machine registers. Then reset the registers to the initial 00281 // values specified above. Every statement program sequence must end 00282 // with a DW_LNE_end_sequence instruction which creates a row whose 00283 // address is that of the byte after the last target machine instruction 00284 // of the sequence. 00285 State.Row.EndSequence = true; 00286 State.appendRowToMatrix(*offset_ptr); 00287 State.resetRowAndSequence(); 00288 break; 00289 00290 case DW_LNE_set_address: 00291 // Takes a single relocatable address as an operand. The size of the 00292 // operand is the size appropriate to hold an address on the target 00293 // machine. Set the address register to the value given by the 00294 // relocatable address. All of the other statement program opcodes 00295 // that affect the address register add a delta to it. This instruction 00296 // stores a relocatable value into it instead. 00297 { 00298 // If this address is in our relocation map, apply the relocation. 00299 RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr); 00300 if (AI != RMap->end()) { 00301 const std::pair<uint8_t, int64_t> &R = AI->second; 00302 State.Row.Address = 00303 debug_line_data.getAddress(offset_ptr) + R.second; 00304 } else 00305 State.Row.Address = debug_line_data.getAddress(offset_ptr); 00306 } 00307 break; 00308 00309 case DW_LNE_define_file: 00310 // Takes 4 arguments. The first is a null terminated string containing 00311 // a source file name. The second is an unsigned LEB128 number 00312 // representing the directory index of the directory in which the file 00313 // was found. The third is an unsigned LEB128 number representing the 00314 // time of last modification of the file. The fourth is an unsigned 00315 // LEB128 number representing the length in bytes of the file. The time 00316 // and length fields may contain LEB128(0) if the information is not 00317 // available. 00318 // 00319 // The directory index represents an entry in the include_directories 00320 // section of the statement program prologue. The index is LEB128(0) 00321 // if the file was found in the current directory of the compilation, 00322 // LEB128(1) if it was found in the first directory in the 00323 // include_directories section, and so on. The directory index is 00324 // ignored for file names that represent full path names. 00325 // 00326 // The files are numbered, starting at 1, in the order in which they 00327 // appear; the names in the prologue come before names defined by 00328 // the DW_LNE_define_file instruction. These numbers are used in the 00329 // the file register of the state machine. 00330 { 00331 FileNameEntry fileEntry; 00332 fileEntry.Name = debug_line_data.getCStr(offset_ptr); 00333 fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); 00334 fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); 00335 fileEntry.Length = debug_line_data.getULEB128(offset_ptr); 00336 Prologue.FileNames.push_back(fileEntry); 00337 } 00338 break; 00339 00340 case DW_LNE_set_discriminator: 00341 State.Row.Discriminator = debug_line_data.getULEB128(offset_ptr); 00342 break; 00343 00344 default: 00345 // Length doesn't include the zero opcode byte or the length itself, but 00346 // it does include the sub_opcode, so we have to adjust for that below 00347 (*offset_ptr) += arg_size; 00348 break; 00349 } 00350 } else if (opcode < Prologue.OpcodeBase) { 00351 switch (opcode) { 00352 // Standard Opcodes 00353 case DW_LNS_copy: 00354 // Takes no arguments. Append a row to the matrix using the 00355 // current values of the state-machine registers. Then set 00356 // the basic_block register to false. 00357 State.appendRowToMatrix(*offset_ptr); 00358 break; 00359 00360 case DW_LNS_advance_pc: 00361 // Takes a single unsigned LEB128 operand, multiplies it by the 00362 // min_inst_length field of the prologue, and adds the 00363 // result to the address register of the state machine. 00364 State.Row.Address += 00365 debug_line_data.getULEB128(offset_ptr) * Prologue.MinInstLength; 00366 break; 00367 00368 case DW_LNS_advance_line: 00369 // Takes a single signed LEB128 operand and adds that value to 00370 // the line register of the state machine. 00371 State.Row.Line += debug_line_data.getSLEB128(offset_ptr); 00372 break; 00373 00374 case DW_LNS_set_file: 00375 // Takes a single unsigned LEB128 operand and stores it in the file 00376 // register of the state machine. 00377 State.Row.File = debug_line_data.getULEB128(offset_ptr); 00378 break; 00379 00380 case DW_LNS_set_column: 00381 // Takes a single unsigned LEB128 operand and stores it in the 00382 // column register of the state machine. 00383 State.Row.Column = debug_line_data.getULEB128(offset_ptr); 00384 break; 00385 00386 case DW_LNS_negate_stmt: 00387 // Takes no arguments. Set the is_stmt register of the state 00388 // machine to the logical negation of its current value. 00389 State.Row.IsStmt = !State.Row.IsStmt; 00390 break; 00391 00392 case DW_LNS_set_basic_block: 00393 // Takes no arguments. Set the basic_block register of the 00394 // state machine to true 00395 State.Row.BasicBlock = true; 00396 break; 00397 00398 case DW_LNS_const_add_pc: 00399 // Takes no arguments. Add to the address register of the state 00400 // machine the address increment value corresponding to special 00401 // opcode 255. The motivation for DW_LNS_const_add_pc is this: 00402 // when the statement program needs to advance the address by a 00403 // small amount, it can use a single special opcode, which occupies 00404 // a single byte. When it needs to advance the address by up to 00405 // twice the range of the last special opcode, it can use 00406 // DW_LNS_const_add_pc followed by a special opcode, for a total 00407 // of two bytes. Only if it needs to advance the address by more 00408 // than twice that range will it need to use both DW_LNS_advance_pc 00409 // and a special opcode, requiring three or more bytes. 00410 { 00411 uint8_t adjust_opcode = 255 - Prologue.OpcodeBase; 00412 uint64_t addr_offset = 00413 (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength; 00414 State.Row.Address += addr_offset; 00415 } 00416 break; 00417 00418 case DW_LNS_fixed_advance_pc: 00419 // Takes a single uhalf operand. Add to the address register of 00420 // the state machine the value of the (unencoded) operand. This 00421 // is the only extended opcode that takes an argument that is not 00422 // a variable length number. The motivation for DW_LNS_fixed_advance_pc 00423 // is this: existing assemblers cannot emit DW_LNS_advance_pc or 00424 // special opcodes because they cannot encode LEB128 numbers or 00425 // judge when the computation of a special opcode overflows and 00426 // requires the use of DW_LNS_advance_pc. Such assemblers, however, 00427 // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. 00428 State.Row.Address += debug_line_data.getU16(offset_ptr); 00429 break; 00430 00431 case DW_LNS_set_prologue_end: 00432 // Takes no arguments. Set the prologue_end register of the 00433 // state machine to true 00434 State.Row.PrologueEnd = true; 00435 break; 00436 00437 case DW_LNS_set_epilogue_begin: 00438 // Takes no arguments. Set the basic_block register of the 00439 // state machine to true 00440 State.Row.EpilogueBegin = true; 00441 break; 00442 00443 case DW_LNS_set_isa: 00444 // Takes a single unsigned LEB128 operand and stores it in the 00445 // column register of the state machine. 00446 State.Row.Isa = debug_line_data.getULEB128(offset_ptr); 00447 break; 00448 00449 default: 00450 // Handle any unknown standard opcodes here. We know the lengths 00451 // of such opcodes because they are specified in the prologue 00452 // as a multiple of LEB128 operands for each opcode. 00453 { 00454 assert(opcode - 1U < Prologue.StandardOpcodeLengths.size()); 00455 uint8_t opcode_length = Prologue.StandardOpcodeLengths[opcode - 1]; 00456 for (uint8_t i = 0; i < opcode_length; ++i) 00457 debug_line_data.getULEB128(offset_ptr); 00458 } 00459 break; 00460 } 00461 } else { 00462 // Special Opcodes 00463 00464 // A special opcode value is chosen based on the amount that needs 00465 // to be added to the line and address registers. The maximum line 00466 // increment for a special opcode is the value of the line_base 00467 // field in the header, plus the value of the line_range field, 00468 // minus 1 (line base + line range - 1). If the desired line 00469 // increment is greater than the maximum line increment, a standard 00470 // opcode must be used instead of a special opcode. The "address 00471 // advance" is calculated by dividing the desired address increment 00472 // by the minimum_instruction_length field from the header. The 00473 // special opcode is then calculated using the following formula: 00474 // 00475 // opcode = (desired line increment - line_base) + 00476 // (line_range * address advance) + opcode_base 00477 // 00478 // If the resulting opcode is greater than 255, a standard opcode 00479 // must be used instead. 00480 // 00481 // To decode a special opcode, subtract the opcode_base from the 00482 // opcode itself to give the adjusted opcode. The amount to 00483 // increment the address register is the result of the adjusted 00484 // opcode divided by the line_range multiplied by the 00485 // minimum_instruction_length field from the header. That is: 00486 // 00487 // address increment = (adjusted opcode / line_range) * 00488 // minimum_instruction_length 00489 // 00490 // The amount to increment the line register is the line_base plus 00491 // the result of the adjusted opcode modulo the line_range. That is: 00492 // 00493 // line increment = line_base + (adjusted opcode % line_range) 00494 00495 uint8_t adjust_opcode = opcode - Prologue.OpcodeBase; 00496 uint64_t addr_offset = 00497 (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength; 00498 int32_t line_offset = 00499 Prologue.LineBase + (adjust_opcode % Prologue.LineRange); 00500 State.Row.Line += line_offset; 00501 State.Row.Address += addr_offset; 00502 State.appendRowToMatrix(*offset_ptr); 00503 } 00504 } 00505 00506 if (!State.Sequence.Empty) { 00507 fprintf(stderr, "warning: last sequence in debug line table is not" 00508 "terminated!\n"); 00509 } 00510 00511 // Sort all sequences so that address lookup will work faster. 00512 if (!Sequences.empty()) { 00513 std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC); 00514 // Note: actually, instruction address ranges of sequences should not 00515 // overlap (in shared objects and executables). If they do, the address 00516 // lookup would still work, though, but result would be ambiguous. 00517 // We don't report warning in this case. For example, 00518 // sometimes .so compiled from multiple object files contains a few 00519 // rudimentary sequences for address ranges [0x0, 0xsomething). 00520 } 00521 00522 return end_offset; 00523 } 00524 00525 uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { 00526 uint32_t unknown_index = UINT32_MAX; 00527 if (Sequences.empty()) 00528 return unknown_index; 00529 // First, find an instruction sequence containing the given address. 00530 DWARFDebugLine::Sequence sequence; 00531 sequence.LowPC = address; 00532 SequenceIter first_seq = Sequences.begin(); 00533 SequenceIter last_seq = Sequences.end(); 00534 SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence, 00535 DWARFDebugLine::Sequence::orderByLowPC); 00536 DWARFDebugLine::Sequence found_seq; 00537 if (seq_pos == last_seq) { 00538 found_seq = Sequences.back(); 00539 } else if (seq_pos->LowPC == address) { 00540 found_seq = *seq_pos; 00541 } else { 00542 if (seq_pos == first_seq) 00543 return unknown_index; 00544 found_seq = *(seq_pos - 1); 00545 } 00546 if (!found_seq.containsPC(address)) 00547 return unknown_index; 00548 // Search for instruction address in the rows describing the sequence. 00549 // Rows are stored in a vector, so we may use arithmetical operations with 00550 // iterators. 00551 DWARFDebugLine::Row row; 00552 row.Address = address; 00553 RowIter first_row = Rows.begin() + found_seq.FirstRowIndex; 00554 RowIter last_row = Rows.begin() + found_seq.LastRowIndex; 00555 RowIter row_pos = std::lower_bound(first_row, last_row, row, 00556 DWARFDebugLine::Row::orderByAddress); 00557 if (row_pos == last_row) { 00558 return found_seq.LastRowIndex - 1; 00559 } 00560 uint32_t index = found_seq.FirstRowIndex + (row_pos - first_row); 00561 if (row_pos->Address > address) { 00562 if (row_pos == first_row) 00563 return unknown_index; 00564 else 00565 index--; 00566 } 00567 return index; 00568 } 00569 00570 bool DWARFDebugLine::LineTable::lookupAddressRange( 00571 uint64_t address, uint64_t size, std::vector<uint32_t> &result) const { 00572 if (Sequences.empty()) 00573 return false; 00574 uint64_t end_addr = address + size; 00575 // First, find an instruction sequence containing the given address. 00576 DWARFDebugLine::Sequence sequence; 00577 sequence.LowPC = address; 00578 SequenceIter first_seq = Sequences.begin(); 00579 SequenceIter last_seq = Sequences.end(); 00580 SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence, 00581 DWARFDebugLine::Sequence::orderByLowPC); 00582 if (seq_pos == last_seq || seq_pos->LowPC != address) { 00583 if (seq_pos == first_seq) 00584 return false; 00585 seq_pos--; 00586 } 00587 if (!seq_pos->containsPC(address)) 00588 return false; 00589 00590 SequenceIter start_pos = seq_pos; 00591 00592 // Add the rows from the first sequence to the vector, starting with the 00593 // index we just calculated 00594 00595 while (seq_pos != last_seq && seq_pos->LowPC < end_addr) { 00596 DWARFDebugLine::Sequence cur_seq = *seq_pos; 00597 uint32_t first_row_index; 00598 uint32_t last_row_index; 00599 if (seq_pos == start_pos) { 00600 // For the first sequence, we need to find which row in the sequence is the 00601 // first in our range. Rows are stored in a vector, so we may use 00602 // arithmetical operations with iterators. 00603 DWARFDebugLine::Row row; 00604 row.Address = address; 00605 RowIter first_row = Rows.begin() + cur_seq.FirstRowIndex; 00606 RowIter last_row = Rows.begin() + cur_seq.LastRowIndex; 00607 RowIter row_pos = std::upper_bound(first_row, last_row, row, 00608 DWARFDebugLine::Row::orderByAddress); 00609 // The 'row_pos' iterator references the first row that is greater than 00610 // our start address. Unless that's the first row, we want to start at 00611 // the row before that. 00612 first_row_index = cur_seq.FirstRowIndex + (row_pos - first_row); 00613 if (row_pos != first_row) 00614 --first_row_index; 00615 } else 00616 first_row_index = cur_seq.FirstRowIndex; 00617 00618 // For the last sequence in our range, we need to figure out the last row in 00619 // range. For all other sequences we can go to the end of the sequence. 00620 if (cur_seq.HighPC > end_addr) { 00621 DWARFDebugLine::Row row; 00622 row.Address = end_addr; 00623 RowIter first_row = Rows.begin() + cur_seq.FirstRowIndex; 00624 RowIter last_row = Rows.begin() + cur_seq.LastRowIndex; 00625 RowIter row_pos = std::upper_bound(first_row, last_row, row, 00626 DWARFDebugLine::Row::orderByAddress); 00627 // The 'row_pos' iterator references the first row that is greater than 00628 // our end address. The row before that is the last row we want. 00629 last_row_index = cur_seq.FirstRowIndex + (row_pos - first_row) - 1; 00630 } else 00631 // Contrary to what you might expect, DWARFDebugLine::SequenceLastRowIndex 00632 // isn't a valid index within the current sequence. It's that plus one. 00633 last_row_index = cur_seq.LastRowIndex - 1; 00634 00635 for (uint32_t i = first_row_index; i <= last_row_index; ++i) { 00636 result.push_back(i); 00637 } 00638 00639 ++seq_pos; 00640 } 00641 00642 return true; 00643 } 00644 00645 bool 00646 DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, 00647 FileLineInfoKind Kind, 00648 std::string &Result) const { 00649 if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() || 00650 Kind == FileLineInfoKind::None) 00651 return false; 00652 const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; 00653 const char *FileName = Entry.Name; 00654 if (Kind != FileLineInfoKind::AbsoluteFilePath || 00655 sys::path::is_absolute(FileName)) { 00656 Result = FileName; 00657 return true; 00658 } 00659 SmallString<16> FilePath; 00660 uint64_t IncludeDirIndex = Entry.DirIdx; 00661 // Be defensive about the contents of Entry. 00662 if (IncludeDirIndex > 0 && 00663 IncludeDirIndex <= Prologue.IncludeDirectories.size()) { 00664 const char *IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]; 00665 sys::path::append(FilePath, IncludeDir); 00666 } 00667 sys::path::append(FilePath, FileName); 00668 Result = FilePath.str(); 00669 return true; 00670 }