1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
// SPDX-License-Identifier: MPL-2.0
// (c) Hare authors <https://harelang.org>
use debug::image;
use errors;
use format::elf;
use io;
// Supported version of .debug_aranges decoder
def ARANGES_VERSION: u16 = 2;
// Returns the debug_info offset for the DIE that corresponds to this address,
// if known, or void if unknown.
export fn arange_lookup(
image: *image::image,
addr: uintptr,
) (u64 | void | errors::invalid) = {
const aranges = match (image::section_byname(image, ".debug_aranges")) {
case let sec: *elf::section64 =>
yield sec;
case null =>
return;
};
// Read all arange tables in this section
const rd = image::section_reader(image, aranges);
for (const rd => new_table_reader(&rd, true)!) {
match (arange_match(&rd, addr)) {
case void => void;
case let u: u64 =>
return u;
case io::error =>
return errors::invalid;
};
};
};
fn arange_match(rd: *table_reader, addr: uintptr) (u64 | void | io::error) = {
const ver = read_uhalf(rd)?;
const info_offset = read_secword(rd)?;
const asize = read_ubyte(rd)?;
const ssize = read_ubyte(rd)?;
assert(ver == ARANGES_VERSION, "debug::dwarf: unsupported .debug_ranges version");
assert(ssize == 0, "debug::dwarf: unsupported segmented target for .debug_aranges");
assert(asize == 8, "debug::dwarf: unsupported address size for .debug_aranges");
read_align(rd, asize * 2)?;
const au64 = addr: u64;
for (!read_iseof(rd)) {
const min = read_ulong(rd)?;
const length = read_ulong(rd)?;
if (min == 0 && length == 0) {
if (!read_iseof(rd)) {
return errors::invalid;
};
break;
};
const max = min + length;
if (min <= au64 && max > au64) {
return info_offset;
};
};
};
|