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