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