DwarfLinesResolve
Description
Find the entry covering vaddr (file-relative virtual address). The match is the row with the greatest address <= vaddr whose sequence has not ended; if vaddr falls past the last row of every sequence, returns NULL.
Success
Returns a pointer to the matching entry inside self->entries. Valid until DwarfLinesDeinit.
Failure
Returns NULL when no row covers vaddr.
Usage example (Cross-references)
Usage examples (Cross-references)
const DwarfLineEntry *de = NULL;
if (cache_entry->dwarf_ok) {
de = DwarfLinesResolve(&cache_entry->dwarf, file_relative);
}
if (!de && cache_entry->has_sidecar) { }
if (cache_entry->sidecar_dwarf_ok) {
de = DwarfLinesResolve(&cache_entry->sidecar_dwarf, file_relative);
}
}- In
Dwarf.c:670:
// ---------------------------------------------------------------------------
const DwarfLineEntry *DwarfLinesResolve(const DwarfLines *self, u64 vaddr) {
if (!self || VecLen(&self->entries) == 0)
return NULL;- In
Dwarf.Mut.c:234:
bool ok = built;
if (built) {
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x3000);
// Out-of-range file -> no file string (NULL), not a bogus pointer.
ok = ok && e && e->file == NULL;- In
Dwarf.Mut.c:305:
bool ok = built;
if (built) {
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x3300);
// file present, but dir index 0 -> dir must be NULL, not pool+42.
ok = ok && e && e->file && ZstrFindSubstring(e->file, "only.c") != NULL;- In
Dwarf.c:72:
bool ok = false;
if (built) {
const DwarfLineEntry *e = DwarfLinesResolve(&lines, file_relative);
if (e && e->file && ZstrFindSubstring(e->file, "Dwarf.c") != NULL && e->line > 0) {
ok = true;- In
Dwarf.c:589:
// Address 0x2000 -> source.c:10
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "source.c") != NULL && e->line == 10;- In
Dwarf.c:593:
// An address inside the first row's range still maps to line 10.
e = DwarfLinesResolve(&lines, 0x2004);
ok = ok && e && e->line == 10;- In
Dwarf.c:597:
// Address 0x2008 -> source.c:20
e = DwarfLinesResolve(&lines, 0x2008);
ok = ok && e && e->line == 20;- In
Dwarf.c:601:
// Below the first row's address -> unresolved.
ok = ok && DwarfLinesResolve(&lines, 0x1000) == NULL;
// At/after the end_sequence boundary -> unresolved.
- In
Dwarf.c:604:
// At/after the end_sequence boundary -> unresolved.
ok = ok && DwarfLinesResolve(&lines, 0x2010) == NULL;
DwarfLinesDeinit(&lines);- In
Dwarf.c:1120:
bool ok = true;
// The special opcode emitted a row at 0x3002, line 95.
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0x3002);
ok = ok && e && e->line == 95 && e->address == 0x3002;
// Just below 0x3002 there is no covering row (only the special-opcode
- In
Dwarf.c:1124:
// Just below 0x3002 there is no covering row (only the special-opcode
// row exists before end_sequence), so a lower address misses.
ok = ok && DwarfLinesResolve(&fx.lines, 0x3001) == NULL;
// The file is source.c (default file 1).
ok = ok && e && e->file && ZstrFindSubstring(e->file, "source.c") != NULL;- In
Dwarf.c:1155:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0x5001);
ok = ok && e && e->line == 51 && e->address == 0x5001;
ok = ok && DwarfLinesResolve(&fx.lines, 0x5000) == NULL;- In
Dwarf.c:1157:
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0x5001);
ok = ok && e && e->line == 51 && e->address == 0x5001;
ok = ok && DwarfLinesResolve(&fx.lines, 0x5000) == NULL;
lines_fixture_close(&fx);
return ok;- In
Dwarf.c:1189:
bool ok = true;
// Row landed at 0x7000 + 17 = 0x7011.
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0x7011);
ok = ok && e && e->address == 0x7011 && e->line == 42;
// 255-13=242 (sub_to_add mutation -> 268, /14 = 19 -> addr 0x7013) and
- In
Dwarf.c:1194:
// div_to_mul (242*14 huge -> saturates to u64 max) both move the row off
// 0x7011. Pin that nothing covers an address just below 0x7011.
ok = ok && DwarfLinesResolve(&fx.lines, 0x7010) == NULL;
lines_fixture_close(&fx);
return ok;- In
Dwarf.c:1230:
bool ok = true;
// A row must exist at 0x9000 with line 75 (special opcode 13 emitted it).
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0x9000);
ok = ok && e && e->address == 0x9000 && e->line == 75;
lines_fixture_close(&fx);- In
Dwarf.c:1261:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0xB000);
ok = ok && e && e->file;
// Must be "other.c" (file 2), and NOT "source.c". `st.file = f` mutated
- In
Dwarf.c:1291:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0xB800);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "source.c") != NULL;
lines_fixture_close(&fx);- In
Dwarf.c:1320:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0xD000);
ok = ok && e && e->column == 37;
lines_fixture_close(&fx);- In
Dwarf.c:1353:
bool ok = true;
const DwarfLineEntry *e0 = DwarfLinesResolve(&fx.lines, 0xF000);
ok = ok && e0 && e0->is_stmt == true;
const DwarfLineEntry *e1 = DwarfLinesResolve(&fx.lines, 0xF010);- In
Dwarf.c:1355:
const DwarfLineEntry *e0 = DwarfLinesResolve(&fx.lines, 0xF000);
ok = ok && e0 && e0->is_stmt == true;
const DwarfLineEntry *e1 = DwarfLinesResolve(&fx.lines, 0xF010);
ok = ok && e1 && e1->is_stmt == false;
lines_fixture_close(&fx);- In
Dwarf.c:1400:
bool ok = true;
const DwarfLineEntry *e1 = DwarfLinesResolve(&fx.lines, 0x11000);
ok = ok && e1 && e1->line == 500;
// Second sequence's row: line must be 7 (clean reset), not 506.
- In
Dwarf.c:1403:
ok = ok && e1 && e1->line == 500;
// Second sequence's row: line must be 7 (clean reset), not 506.
const DwarfLineEntry *e2 = DwarfLinesResolve(&fx.lines, 0x12000);
ok = ok && e2 && e2->line == 7;
lines_fixture_close(&fx);- In
Dwarf.c:1433:
bool ok = true;
// The real row resolves.
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0x13000);
ok = ok && e && e->line == 10;
// An address inside [0x13000, 0x13020) still maps to the real row.
- In
Dwarf.c:1436:
ok = ok && e && e->line == 10;
// An address inside [0x13000, 0x13020) still maps to the real row.
e = DwarfLinesResolve(&fx.lines, 0x13010);
ok = ok && e && e->line == 10;
// At/after the end_sequence boundary -> unresolved (closing row is not a
- In
Dwarf.c:1441:
// lookup target). If end_sequence were set to false, the closing row at
// 0x13020 would resolve instead of returning NULL.
ok = ok && DwarfLinesResolve(&fx.lines, 0x13020) == NULL;
lines_fixture_close(&fx);
return ok;- In
Dwarf.c:1476:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0x00150000u);
// 4-byte decode must reconstruct the full address 0x150000 and emit the
// row there. A broken == 4 branch / wrong decode / address = const moves
- In
Dwarf.c:1481:
// the row off 0x150000.
ok = ok && e && e->address == 0x00150000u && e->line == 34;
ok = ok && DwarfLinesResolve(&fx.lines, 0x0014ffffu) == NULL;
lines_fixture_close(&fx);
return ok;- In
Dwarf.c:1535:
// malformed record must not have produced a second resolvable row at
// an out-of-range address derived from over-read bytes.
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x17000);
// The only acceptable success is: either no rows, or the single safe
// row, with end correctly bounded.
- In
Dwarf.c:1579:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&fx.lines, 0x18000);
ok = ok && e && e->address == 0x18000 && e->line == 22;
lines_fixture_close(&fx);- In
Dwarf.c:1625:
if (built) {
// First row at 0x5000, line 42.
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x5000);
ok = ok && e && e->line == 42;
// The byte right before the fixed advance still maps to row 1.
- In
Dwarf.c:1628:
ok = ok && e && e->line == 42;
// The byte right before the fixed advance still maps to row 1.
e = DwarfLinesResolve(&lines, 0x5122);
ok = ok && e && e->address == 0x5000 && e->line == 42;
// Exactly at the fixed-advanced address: distinct second row.
- In
Dwarf.c:1631:
ok = ok && e && e->address == 0x5000 && e->line == 42;
// Exactly at the fixed-advanced address: distinct second row.
e = DwarfLinesResolve(&lines, 0x5123);
ok = ok && e && e->address == 0x5123 && e->line == 42;
DwarfLinesDeinit(&lines);- In
Dwarf.c:1662:
bool ok = built;
if (built) {
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x8000 + 0x7abc);
ok = ok && e && e->address == 0x8000 + 0x7abc;
// Just below the second row -> still the first row.
- In
Dwarf.c:1665:
ok = ok && e && e->address == 0x8000 + 0x7abc;
// Just below the second row -> still the first row.
e = DwarfLinesResolve(&lines, 0x8000 + 0x7abc - 1);
ok = ok && e && e->address == 0x8000;
DwarfLinesDeinit(&lines);- In
Dwarf.c:1708:
if (built) {
// The special opcode emitted exactly one real row at 0x6002:14.
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x6002);
ok = ok && e && e->address == 0x6002 && e->line == 14;
// Below the emitted address -> nothing (no row at/below 0x6002
- In
Dwarf.c:1712:
// Below the emitted address -> nothing (no row at/below 0x6002
// other than the one we emitted; 0x6001 < 0x6002).
ok = ok && DwarfLinesResolve(&lines, 0x6001) == NULL;
// The file string came through.
ok = ok && e->file && ZstrFindSubstring(e->file, "source.c") != NULL;- In
Dwarf.c:1745:
if (built) {
// First special opcode: same address (addr_adv 0), line 42.
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x7000);
ok = ok && e && e->address == 0x7000 && e->line == 42;
// Second special opcode: address advanced by 3, line 48.
- In
Dwarf.c:1748:
ok = ok && e && e->address == 0x7000 && e->line == 42;
// Second special opcode: address advanced by 3, line 48.
e = DwarfLinesResolve(&lines, 0x7003);
ok = ok && e && e->address == 0x7003 && e->line == 48;
DwarfLinesDeinit(&lines);- In
Dwarf.c:1783:
}
ok = ok && real_rows >= 1;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x9002);
ok = ok && e && e->address == 0x9002;
DwarfLinesDeinit(&lines);- In
Dwarf.c:1828:
bool ok = built;
if (built) {
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0xA000);
ok = ok && e && e->address == 0xA000 && e->line == 7;
DwarfLinesDeinit(&lines);- In
Dwarf.c:1977:
bool ok = built;
if (built) {
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0xB000);
ok = ok && e && e->address == 0xB000 && e->line == 5;
DwarfLinesDeinit(&lines);- In
Dwarf.c:2026:
bool ok = built;
if (built) {
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0xC000);
ok = ok && e && e->address == 0xC000 && e->line == 3;
DwarfLinesDeinit(&lines);- In
Dwarf.c:2063:
bool ok = built;
if (built) {
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0xD000);
ok = ok && e && e->address == 0xD000 && e->line == 10;
e = DwarfLinesResolve(&lines, 0xE000);- In
Dwarf.c:2065:
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0xD000);
ok = ok && e && e->address == 0xD000 && e->line == 10;
e = DwarfLinesResolve(&lines, 0xE000);
ok = ok && e && e->address == 0xE000 && e->line == 50;
// The gap between sequences (after seq 1's end_sequence at 0xD000,
- In
Dwarf.c:2069:
// The gap between sequences (after seq 1's end_sequence at 0xD000,
// before seq 2) does not resolve to seq 1.
ok = ok && DwarfLinesResolve(&lines, 0xCFFF) == NULL;
DwarfLinesDeinit(&lines);
}- In
Dwarf.c:2141:
ok = ok && VecLen(&lines.entries) == 3;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
ok = ok && e && e->dir && ZstrFindSubstring(e->dir, "real_dir") != NULL;- In
Dwarf.c:2148:
// Inside the first row's [0x2000, 0x2008) span -> still line 10.
e = DwarfLinesResolve(&lines, 0x2004);
ok = ok && e && e->line == 10;- In
Dwarf.c:2152:
// 0x2008 -> line 20, same file/dir.
e = DwarfLinesResolve(&lines, 0x2008);
ok = ok && e && e->line == 20;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;- In
Dwarf.c:2158:
// Below the first address and at/after end_sequence -> unresolved.
ok = ok && DwarfLinesResolve(&lines, 0x1fff) == NULL;
ok = ok && DwarfLinesResolve(&lines, 0x2010) == NULL;- In
Dwarf.c:2159:
// Below the first address and at/after end_sequence -> unresolved.
ok = ok && DwarfLinesResolve(&lines, 0x1fff) == NULL;
ok = ok && DwarfLinesResolve(&lines, 0x2010) == NULL;
DwarfLinesDeinit(&lines);- In
Dwarf.c:2207:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x3000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "first.c") != NULL;
ok = ok && e && e->line == 7;- In
Dwarf.c:2262:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x5001);
ok = ok && e && e->address == 0x5001;
ok = ok && e && e->line == 3;- In
Dwarf.c:2266:
ok = ok && e && e->line == 3;
// Below the emitted row's address -> unresolved.
ok = ok && DwarfLinesResolve(&lines, 0x5000) == NULL;
DwarfLinesDeinit(&lines);- In
Dwarf.c:2336:
// Sequence 1: 0x6000 -> second.c:100
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x6000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;
ok = ok && e && e->line == 100;- In
Dwarf.c:2342:
// Sequence 2: 0x7000 -> first.c:5 (only correct if reset restored
// file=1 and line=1 between sequences).
e = DwarfLinesResolve(&lines, 0x7000);
ok = ok && e && e->file && ZstrFindSubstring(e->file, "first.c") != NULL;
ok = ok && e && e->line == 5;- In
Dwarf.c:2347:
// The gap between sequences (0x6008 .. 0x7000) is unresolved.
ok = ok && DwarfLinesResolve(&lines, 0x6800) == NULL;
DwarfLinesDeinit(&lines);- In
Dwarf.c:2433:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x8000);
ok = ok && e && e->line == 4;
ok = ok && e && e->is_stmt == false;- In
Dwarf.c:2478:
ok = ok && VecLen(&lines.entries) >= 2;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->file && ZstrCompare(e->file, "source.c") == 0 && e->line == 10;- In
Dwarf.c:2481:
ok = ok && e && e->file && ZstrCompare(e->file, "source.c") == 0 && e->line == 10;
e = DwarfLinesResolve(&lines, 0x2008);
ok = ok && e && e->file && ZstrCompare(e->file, "source.c") == 0 && e->line == 20;- In
Dwarf.c:2592:
if (built) {
// Exact hit on the first row's address.
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->line == 10;
// Strictly inside the first row's [0x2000, 0x2008) span -> line 10.
- In
Dwarf.c:2595:
ok = ok && e && e->line == 10;
// Strictly inside the first row's [0x2000, 0x2008) span -> line 10.
e = DwarfLinesResolve(&lines, 0x2004);
ok = ok && e && e->line == 10;
// Exact hit on the second row's address.
- In
Dwarf.c:2598:
ok = ok && e && e->line == 10;
// Exact hit on the second row's address.
e = DwarfLinesResolve(&lines, 0x2008);
ok = ok && e && e->line == 20;
// Strictly inside the second row's [0x2008, 0x2010) span -> line 20.
- In
Dwarf.c:2601:
ok = ok && e && e->line == 20;
// Strictly inside the second row's [0x2008, 0x2010) span -> line 20.
e = DwarfLinesResolve(&lines, 0x200f);
ok = ok && e && e->line == 20;
// Strictly below the first address -> no row.
- In
Dwarf.c:2604:
ok = ok && e && e->line == 20;
// Strictly below the first address -> no row.
ok = ok && DwarfLinesResolve(&lines, 0x1fff) == NULL;
// At the end_sequence boundary (exclusive upper) -> no row.
ok = ok && DwarfLinesResolve(&lines, 0x2010) == NULL;- In
Dwarf.c:2606:
ok = ok && DwarfLinesResolve(&lines, 0x1fff) == NULL;
// At the end_sequence boundary (exclusive upper) -> no row.
ok = ok && DwarfLinesResolve(&lines, 0x2010) == NULL;
// Above the last sequence -> no row.
ok = ok && DwarfLinesResolve(&lines, 0x3000) == NULL;- In
Dwarf.c:2608:
ok = ok && DwarfLinesResolve(&lines, 0x2010) == NULL;
// Above the last sequence -> no row.
ok = ok && DwarfLinesResolve(&lines, 0x3000) == NULL;
DwarfLinesDeinit(&lines);- In
Dwarf.c:2648:
// Sanity: the file/dir tables really populated (otherwise the
// CuStrings vectors never allocate and the leak is unobservable).
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->file && ZstrCompare(e->file, "source.c") == 0;
DwarfLinesDeinit(&lines);- In
Dwarf.c:2694:
// The pool must really hold the "source.c" string so its buffer
// is a distinct live allocation the deinit has to release.
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->file && ZstrCompare(e->file, "source.c") == 0;
// After the build there must be live allocations to release.
- In
Dwarf.c:2760:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x2000);
ok = ok && e && e->line == 10;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;- In
Dwarf.c:2813:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x4000);
// Only an exact table-skip places the program at the SET_ADDRESS opcode,
// so the row exists at 0x4000 with line 42 and file "first.c".
- In
Dwarf.c:2872:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x4400);
ok = ok && e && e->address == 0x4400 && e->line == 22;
ok = ok && e && e->file && ZstrFindSubstring(e->file, "second.c") != NULL;- In
Dwarf.c:2978:
bool ok = true;
const DwarfLineEntry *e = DwarfLinesResolve(&lines, 0x6000);
ok = ok && e && e->address == 0x6000 && e->line == 10;
Last updated on