Index: include/llvm/DebugInfo/DWARF/DWARFDebugLine.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -163,6 +163,9 @@ struct LineTable { LineTable(); + // Represents an invalid row + const uint32_t UnknownRowIndex = UINT32_MAX; + void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); } @@ -171,7 +174,7 @@ } // Returns the index of the row with file/line info for a given address, - // or -1 if there is no such row. + // or UnknownRowIndex if there is no such row. uint32_t lookupAddress(uint64_t address) const; bool lookupAddressRange(uint64_t address, uint64_t size, @@ -203,6 +206,10 @@ typedef SequenceVector::const_iterator SequenceIter; RowVector Rows; SequenceVector Sequences; + + private: + uint32_t findRowInSeq(const DWARFDebugLine::Sequence &seq, + uint64_t address) const; }; const LineTable *getLineTable(uint32_t offset) const; Index: lib/DebugInfo/DWARF/DWARFDebugLine.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -522,10 +522,36 @@ return end_offset; } +uint32_t +DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &seq, + uint64_t address) const { + if (!seq.containsPC(address)) + return UnknownRowIndex; + // Search for instruction address in the rows describing the sequence. + // Rows are stored in a vector, so we may use arithmetical operations with + // iterators. + DWARFDebugLine::Row row; + row.Address = address; + RowIter first_row = Rows.begin() + seq.FirstRowIndex; + RowIter last_row = Rows.begin() + seq.LastRowIndex; + LineTable::RowIter row_pos = std::lower_bound( + first_row, last_row, row, DWARFDebugLine::Row::orderByAddress); + if (row_pos == last_row) { + return seq.LastRowIndex - 1; + } + uint32_t index = seq.FirstRowIndex + (row_pos - first_row); + if (row_pos->Address > address) { + if (row_pos == first_row) + return UnknownRowIndex; + else + index--; + } + return index; +} + uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const { - uint32_t unknown_index = UINT32_MAX; if (Sequences.empty()) - return unknown_index; + return UnknownRowIndex; // First, find an instruction sequence containing the given address. DWARFDebugLine::Sequence sequence; sequence.LowPC = address; @@ -540,31 +566,10 @@ found_seq = *seq_pos; } else { if (seq_pos == first_seq) - return unknown_index; + return UnknownRowIndex; found_seq = *(seq_pos - 1); } - if (!found_seq.containsPC(address)) - return unknown_index; - // Search for instruction address in the rows describing the sequence. - // Rows are stored in a vector, so we may use arithmetical operations with - // iterators. - DWARFDebugLine::Row row; - row.Address = address; - RowIter first_row = Rows.begin() + found_seq.FirstRowIndex; - RowIter last_row = Rows.begin() + found_seq.LastRowIndex; - RowIter row_pos = std::lower_bound(first_row, last_row, row, - DWARFDebugLine::Row::orderByAddress); - if (row_pos == last_row) { - return found_seq.LastRowIndex - 1; - } - uint32_t index = found_seq.FirstRowIndex + (row_pos - first_row); - if (row_pos->Address > address) { - if (row_pos == first_row) - return unknown_index; - else - index--; - } - return index; + return findRowInSeq(found_seq, address); } bool DWARFDebugLine::LineTable::lookupAddressRange( @@ -593,45 +598,21 @@ // index we just calculated while (seq_pos != last_seq && seq_pos->LowPC < end_addr) { - DWARFDebugLine::Sequence cur_seq = *seq_pos; - uint32_t first_row_index; - uint32_t last_row_index; - if (seq_pos == start_pos) { - // For the first sequence, we need to find which row in the sequence is the - // first in our range. Rows are stored in a vector, so we may use - // arithmetical operations with iterators. - DWARFDebugLine::Row row; - row.Address = address; - RowIter first_row = Rows.begin() + cur_seq.FirstRowIndex; - RowIter last_row = Rows.begin() + cur_seq.LastRowIndex; - RowIter row_pos = std::upper_bound(first_row, last_row, row, - DWARFDebugLine::Row::orderByAddress); - // The 'row_pos' iterator references the first row that is greater than - // our start address. Unless that's the first row, we want to start at - // the row before that. - first_row_index = cur_seq.FirstRowIndex + (row_pos - first_row); - if (row_pos != first_row) - --first_row_index; - } else - first_row_index = cur_seq.FirstRowIndex; - - // For the last sequence in our range, we need to figure out the last row in - // range. For all other sequences we can go to the end of the sequence. - if (cur_seq.HighPC > end_addr) { - DWARFDebugLine::Row row; - row.Address = end_addr; - RowIter first_row = Rows.begin() + cur_seq.FirstRowIndex; - RowIter last_row = Rows.begin() + cur_seq.LastRowIndex; - RowIter row_pos = std::upper_bound(first_row, last_row, row, - DWARFDebugLine::Row::orderByAddress); - // The 'row_pos' iterator references the first row that is greater than - // our end address. The row before that is the last row we want. - last_row_index = cur_seq.FirstRowIndex + (row_pos - first_row) - 1; - } else - // Contrary to what you might expect, DWARFDebugLine::SequenceLastRowIndex - // isn't a valid index within the current sequence. It's that plus one. + const DWARFDebugLine::Sequence &cur_seq = *seq_pos; + // For the first sequence, we need to find which row in the sequence is the + // first in our range. + uint32_t first_row_index = cur_seq.FirstRowIndex; + if (seq_pos == start_pos) + first_row_index = findRowInSeq(cur_seq, address); + + // Figure out the last row in the range. + uint32_t last_row_index = findRowInSeq(cur_seq, end_addr - 1); + if (last_row_index == UnknownRowIndex) last_row_index = cur_seq.LastRowIndex - 1; + assert(first_row_index != UnknownRowIndex); + assert(last_row_index != UnknownRowIndex); + for (uint32_t i = first_row_index; i <= last_row_index; ++i) { result.push_back(i); } Index: test/DebugInfo/debuglineinfo-macho.test =================================================================== --- test/DebugInfo/debuglineinfo-macho.test +++ test/DebugInfo/debuglineinfo-macho.test @@ -3,3 +3,39 @@ RUN: llvm-dwarfdump %p/Inputs/test-multiple-macho.o | FileCheck %s CHECK-NOT: error: failed to compute relocation: X86_64_RELOC_UNSIGNED + +# Check that relocations get applied correctly +RUN: llvm-rtdyld -printobjline %p/Inputs/test-simple-macho.o \ +RUN: | FileCheck %s -check-prefix TEST_SIMPLE +RUN: llvm-rtdyld -printline %p/Inputs/test-simple-macho.o \ +RUN: | FileCheck %s -check-prefix TEST_SIMPLE +RUN: llvm-rtdyld -printobjline %p/Inputs/test-multiple-macho.o \ +RUN: | FileCheck %s -check-prefix TEST_MULTIPLE +RUN: llvm-rtdyld -printline %p/Inputs/test-multiple-macho.o \ +RUN: | FileCheck %s -check-prefix TEST_MULTIPLE + +TEST_SIMPLE: Function: _foo, Size = 11 +TEST_SIMPLE-NEXT: Line info @ 0: simple.c, line:1 +TEST_SIMPLE-NEXT: Line info @ 7: simple.c, line:2 +TEST_SIMPLE-NOT: Line info @ 11: simple.c, line:2 + +TEST_MULTIPLE: Function: _bar, Size = 48 +TEST_MULTIPLE-NEXT: Line info @ 0: multiple.c, line:5 +TEST_MULTIPLE-NEXT: Line info @ 7: multiple.c, line:6 +TEST_MULTIPLE-NEXT: Line info @ 16: multiple.c, line:9 +TEST_MULTIPLE-NEXT: Line info @ 21: multiple.c, line:9 +TEST_MULTIPLE-NEXT: Line info @ 26: multiple.c, line:7 +TEST_MULTIPLE-NEXT: Line info @ 33: multiple.c, line:10 +TEST_MULTIPLE-NOT: Line info @ 48: multiple.c, line:12 +TEST_MULTIPLE-NEXT: Function: _foo, Size = 16 +TEST_MULTIPLE-NEXT: Line info @ 0: multiple.c, line:1 +TEST_MULTIPLE-NEXT: Line info @ 7: multiple.c, line:2 +TEST_MULTIPLE-NOT: Line info @ 16: multiple.c, line:5 +TEST_MULTIPLE-NEXT: Function: _fubar, Size = 46 +TEST_MULTIPLE-NEXT: Line info @ 0: multiple.c, line:12 +TEST_MULTIPLE-NEXT: Line info @ 7: multiple.c, line:13 +TEST_MULTIPLE-NEXT: Line info @ 12: multiple.c, line:17 +TEST_MULTIPLE-NEXT: Line info @ 25: multiple.c, line:15 +TEST_MULTIPLE-NEXT: Line info @ 34: multiple.c, line:19 +TEST_MULTIPLE-NEXT: Line info @ 41: multiple.c, line:21 +TEST_MULTIPLE-NOT: Line info @ 46: multiple.c, line:21 Index: test/DebugInfo/debuglineinfo.test =================================================================== --- test/DebugInfo/debuglineinfo.test +++ test/DebugInfo/debuglineinfo.test @@ -18,7 +18,6 @@ TEST_INLINE-NEXT: Function: _Z3foov, Size = 3 TEST_INLINE-NEXT: Line info @ 0: test-inline.cpp, line:28 TEST_INLINE-NEXT: Line info @ 2: test-inline.cpp, line:29 -TEST_INLINE-NEXT: Line info @ 3: test-inline.cpp, line:29 TEST_INLINE-NEXT: Function: main, Size = 146 TEST_INLINE-NEXT: Line info @ 0: test-inline.cpp, line:39 TEST_INLINE-NEXT: Line info @ 21: test-inline.cpp, line:41 @@ -29,7 +28,6 @@ TEST_INLINE-NEXT: Line info @ 95: test-inline.cpp, line:46 TEST_INLINE-NEXT: Line info @ 114: test-inline.cpp, line:48 TEST_INLINE-NEXT: Line info @ 141: test-inline.cpp, line:49 -TEST_INLINE-NEXT: Line info @ 146: test-inline.cpp, line:49 ; This test checks the case where all code is in a single section. TEST_PARAMETERS: Function: _Z15test_parametersPfPA2_dR11char_structPPitm, Size = 170 @@ -49,5 +47,4 @@ TEST_PARAMETERS-NEXT: Line info @ 95: test-parameters.cpp, line:46 TEST_PARAMETERS-NEXT: Line info @ 114: test-parameters.cpp, line:48 TEST_PARAMETERS-NEXT: Line info @ 141: test-parameters.cpp, line:49 -TEST_PARAMETERS-NEXT: Line info @ 146: test-parameters.cpp, line:49