DWARF_GET_RANGES(3)
π DWARF_GET_RANGES(3) π
okay bestie, welcome to the Library Functions Manual corner of the group chat. todayβs main character is dwarf_get_ranges, and weβre getting into non-contiguous address ranges. stay with me, itβs gonna slay.
β¨ NAME β¨
dwarf_get_ranges β retrieve non-contiguous address ranges
π LIBRARY π
DWARF Access Library (libdwarf, -ldwarf)
π¦ SYNOPSIS π¦
#include <libdwarf.h>
int
dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_Off offset,
Dwarf_Ranges **ranges, Dwarf_Signed *cnt, Dwarf_Unsigned *byte_cnt,
Dwarf_Error *err);
int
dwarf_get_ranges_a(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die die,
Dwarf_Ranges **ranges, Dwarf_Signed *cnt, Dwarf_Unsigned *byte_cnt,
Dwarf_Error *err);
π DESCRIPTION π
okay so dwarf_get_ranges() pulls the info about the non-contiguous address ranges attached to a DWARF debugging information entry. the address-range info comes back as an array of descriptors of type Dwarf_Ranges, and each Dwarf_Ranges descriptor describes one address range entry. iconic, honestly.
Hereβs the argument tea, one by one:
dbgβ should reference a DWARF debug context allocated usingdwarf_init(3). no randomdbg, got it?offsetβ an offset, relative to the.debug_rangessection, to the start of the desired list of address ranges. the offset of an address ranges list is indicated by theDW_AT_rangesattribute of a debugging information entry. follow the little breadcrumb, bestie.dieβ functiondwarf_get_ranges_a()only. in this implementation it is ignored; see the section βCompatibility Notesβ below. yes, ignored. weβll circle back.rangesβ should point to a location that will be set to a pointer to an array ofDwarf_Rangesdescriptors. so itβs like, pointer to a pointer situation, but make it DWARF.cntβ should point to a location that will be set to the number of entries returned. if argumentbyte_cntis notNULL, it will be set to the number of bytes occupied by the returned entries in the.debug_rangessection. numbers are coming back, periodt.errβ if argumenterris notNULL, it will be used to store error information in case of an error. error gossip gets stored there.
Dwarf_Ranges descriptors are defined in the header file <libdwarf.h>, and consists of the following fields:
dwr_addr1β the first address offset, whose meaning depends on the type of the entry.dwr_addr2β the second address offset, whose meaning depends on the type of the entry.dwr_typeβ the type of this address range entry:DW_RANGES_ENTRYβ a range list entry. for this type of entry, the fieldsdwr_addr1anddwr_addr2hold the beginning and ending offsets of the address range, respectively. beginning and ending, cute little range sandwich.DW_RANGES_ADDRESS_SELECTIONβ a base address selection entry. for this type of entry, the fielddwr_addr1is the value of the largest representable address offset, anddwr_addr2is a base address for the beginning and ending address offsets of subsequent address range entries in the list. big address energy.DW_RANGES_ENDβ an end of list mark. bothdwr_addr1anddwr_addr2are set to0. the end, literally.
π§ Memory Management π§
bestie, listen: the memory area used for the array of Dwarf_Ranges descriptors returned in argument ranges is owned by the DWARF Access Library (libdwarf, -ldwarf). the application should not attempt to directly free this pointer. do not just free() it, okay? thatβs not the move.
portable code should instead use dwarf_ranges_dealloc() to indicate that the memory may be freed. thatβs the polite, portable way to do it.
π RETURN VALUES π
these functions return DW_DLV_OK when they succeed. yay
they return DW_DLV_NO_ENTRY if there is no address range list at the specified offset offset. nothing there, no entries, moving on
in case of an error, they return DW_DLV_ERROR and set the argument err. error era
π EXAMPLES π
to retrieve the address range list associated with a debugging information entry, use:
Dwarf_Debug dbg;
Dwarf_Die die;
Dwarf_Error de;
Dwarf_Addr base;
Dwarf_Attribute *attr_list;
Dwarf_Ranges *ranges;
Dwarf_Signed cnt;
Dwarf_Unsigned off, attr_count, bytecnt;
int i, j;
if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) !=
DW_DLV_OK)
errx(EXIT_FAILURE, "dwarf_attrlist failed: %s",
dwarf_errmsg(de));
for (i = 0; (Dwarf_Unsigned) i < attr_count; i++) {
if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) {
warnx("dwarf_whatattr failed: %s",
dwarf_errmsg(de));
continue;
}
if (attr != DW_AT_ranges)
continue;
if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) {
warnx("dwarf_formudata failed: %s",
dwarf_errmsg(de));
continue;
}
if (dwarf_get_ranges(dbg, (Dwarf_Off) off, &ranges, &cnt,
&bytecnt, &de) != DW_DLV_OK)
continue;
for (j = 0; j < cnt; j++) {
if (ranges[j].dwr_type == DW_RANGES_END)
break;
else if (ranges[j].dwr_type ==
DW_RANGES_ADDRESS_SELECTION)
base = ranges[j].dwr_addr2;
else {
/*
* DW_RANGES_ENTRY entry.
* .. Use dwr_addr1 and dwr_addr2 ..
*/
}
}
}
π COMPATIBILITY π
function dwarf_get_ranges_a() is identical to dwarf_get_ranges(), except that it requires one additional argument die denoting the debugging information entry associated with the address range list.
in this implementation of the DWARF Access Library (libdwarf, -ldwarf), the argument die is ignored, and function dwarf_get_ranges_a() is only provided for compatibility with other implementations of the DWARF(3) API. so itβs there for the other girls, but this implementation is not using it.
π ERRORS π
these functions can fail with:
[DW_DLE_ARGUMENT]β one of the argumentsdbg,rangesorcntwasNULL. null moment, not cute[DW_DLE_NO_ENTRY]β there is no address range list at the specifiedoffsetoffset. empty list energy
π₯ SEE ALSO π₯
dwarf(3), dwarf_ranges_dealloc(3)
and thatβs the whole DWARF ranges situation, bestie β¨ source/version: Debian Β· date: November 9, 2011 Β· mwah π
π¦ where this page comes from
- freebsd 14.5: base 14.5
- freebsd 15.1: base 15.1
- nixpkgs unstable: libdwarf 15.0.0
- Copyright (c) 2011 Kai Wang
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms