1.\" Copyright (c) 2011 Kai Wang
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $Id: dwarf_get_ranges.3 3182 2015-04-10 16:08:10Z emaste $
26.\"
27.Dd November 9, 2011
28.Os
29.Dt DWARF_GET_RANGES 3
30.Sh NAME
31.Nm dwarf_get_ranges
32.Nd retrieve non-contiguous address ranges
33.Sh LIBRARY
34.Lb libdwarf
35.Sh SYNOPSIS
36.In libdwarf.h
37.Ft int
38.Fo dwarf_get_ranges
39.Fa "Dwarf_Debug dbg"
40.Fa "Dwarf_Off offset"
41.Fa "Dwarf_Ranges **ranges"
42.Fa "Dwarf_Signed *cnt"
43.Fa "Dwarf_Unsigned *byte_cnt"
44.Fa "Dwarf_Error *err"
45.Fc
46.Ft int
47.Fo dwarf_get_ranges_a
48.Fa "Dwarf_Debug dbg"
49.Fa "Dwarf_Off offset"
50.Fa "Dwarf_Die die"
51.Fa "Dwarf_Ranges **ranges"
52.Fa "Dwarf_Signed *cnt"
53.Fa "Dwarf_Unsigned *byte_cnt"
54.Fa "Dwarf_Error *err"
55.Fc
56.Sh DESCRIPTION
57Function
58.Fn dwarf_get_ranges
59retrieves information about the non-contiguous address ranges associated
60with a DWARF debugging information entry.
61Information about address ranges is returned as an array of
62descriptors of type
63.Vt Dwarf_Ranges ,
64with each
65.Vt Dwarf_Ranges
66descriptor describing one address range entry.
67.Pp
68Argument
69.Ar dbg
70should reference a DWARF debug context allocated using
71.Xr dwarf_init 3 .
72.Pp
73Argument
74.Ar offset
75is an offset, relative to the
76.Dq ".debug_ranges"
77section, to the start of the desired list of address ranges.
78The offset of an address ranges list is indicated by the
79.Dv DW_AT_ranges
80attribute of a debugging information entry.
81.Pp
82Argument
83.Ar die
84(function
85.Fn dwarf_get_ranges_a
86only) is ignored in this implementation; see the section
87.Sx "Compatibility Notes"
88below.
89.Pp
90Argument
91.Ar ranges
92should point to a location that will be set to a pointer to an array
93of
94.Vt Dwarf_Ranges
95descriptors.
96.Pp
97Argument
98.Ar cnt
99should point to a location that will be set to the number of entries
100returned.
101If argument
102.Ar byte_cnt
103is not NULL, it will be set to the number of bytes occupied by the
104returned entries in the
105.Dq ".debug_ranges"
106section.
107.Pp
108If argument
109.Ar err
110is not NULL, it will be used to store error information in case
111of an error.
112.Pp
113.Vt Dwarf_Ranges
114descriptors are defined in the header file
115.In libdwarf.h ,
116and consists of the following fields:
117.Bl -tag -width ".Va dwr_addr1"
118.It Va dwr_addr1
119The first address offset, whose meaning depends on the type of the
120entry.
121.It Va dwr_addr2
122The second address offset, whose meaning depends on the type of the
123entry.
124.It Va dwr_type
125The type of this address range entry:
126.Bl -tag -width ".Dv DW_RANGES_ENTRY" -compact
127.It Dv DW_RANGES_ENTRY
128A range list entry.
129For this type of entry, the fields
130.Va dwr_addr1
131and
132.Va dwr_addr2
133hold the beginning and ending offsets of the address range, respectively.
134.It Dv DW_RANGES_ADDRESS_SELECTION
135A base address selection entry.
136For this type of entry, the field
137.Va dwr_addr1
138is the value of the largest representable address offset, and
139.Va dwr_addr2
140is a base address for the beginning and ending address offsets of
141subsequent address range entries in the list.
142.It Dv DW_RANGES_END
143An end of list mark.
144Both
145.Va dwr_addr1
146and
147.Va dwr_addr2
148are set to 0.
149.El
150.El
151.Ss Memory Management
152The memory area used for the array of
153.Vt Dwarf_Ranges
154descriptors returned in argument
155.Ar ranges
156is owned by the
157.Lb libdwarf .
158The application should not attempt to directly free this pointer.
159Portable code should instead use
160.Fn dwarf_ranges_dealloc
161to indicate that the memory may be freed.
162.Sh COMPATIBILITY
163Function
164.Fn dwarf_get_ranges_a
165is identical to
166.Fn dwarf_get_ranges ,
167except that it requires one additional argument
168.Ar die
169denoting the debugging information entry associated with
170the address range list.
171In this implementation of the
172.Lb libdwarf ,
173the argument
174.Ar die
175is ignored, and function
176.Fn dwarf_get_ranges_a
177is only provided for compatibility with other implementations of the
178DWARF(3) API.
179.Sh RETURN VALUES
180These functions
181return
182.Dv DW_DLV_OK
183when they succeed.
184They return
185.Dv DW_DLV_NO_ENTRY
186if there is no address range list at the specified offset
187.Ar offset .
188In case of an error, they return
189.Dv DW_DLV_ERROR
190and set the argument
191.Ar err .
192.Sh ERRORS
193These function can fail with:
194.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY"
195.It Bq Er DW_DLE_ARGUMENT
196One of the arguments
197.Ar dbg ,
198.Ar ranges
199or
200.Ar cnt
201was NULL.
202.It Bq Er DW_DLE_NO_ENTRY
203There is no address range list at the specified offset
204.Ar offset .
205.El
206.Sh EXAMPLE
207To retrieve the address range list associated with a debugging
208information entry, use:
209.Bd -literal -offset indent
210Dwarf_Debug dbg;
211Dwarf_Die die;
212Dwarf_Error de;
213Dwarf_Addr base;
214Dwarf_Attribute *attr_list;
215Dwarf_Ranges *ranges;
216Dwarf_Signed cnt;
217Dwarf_Unsigned off, attr_count, bytecnt;
218int i, j;
219
220if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) !=
221    DW_DLV_OK)
222	errx(EXIT_FAILURE, "dwarf_attrlist failed: %s",
223	    dwarf_errmsg(de));
224
225for (i = 0; (Dwarf_Unsigned) i < attr_count; i++) {
226	if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) {
227		warnx("dwarf_whatattr failed: %s",
228		    dwarf_errmsg(de));
229		continue;
230	}
231	if (attr != DW_AT_ranges)
232		continue;
233	if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) {
234		warnx("dwarf_formudata failed: %s",
235		    dwarf_errmsg(de));
236		continue;
237	}
238	if (dwarf_get_ranges(dbg, (Dwarf_Off) off, &ranges, &cnt,
239	    &bytecnt, &de) != DW_DLV_OK)
240		continue;
241	for (j = 0; j < cnt; j++) {
242		if (ranges[j].dwr_type == DW_RANGES_END)
243			break;
244		else if (ranges[j].dwr_type ==
245		    DW_RANGES_ADDRESS_SELECTION)
246			base = ranges[j].dwr_addr2;
247		else {
248			/*
249			 * DW_RANGES_ENTRY entry.
250			 * .. Use dwr_addr1 and dwr_addr2 ..
251			 */
252		}
253	}
254}
255.Ed
256.Sh SEE ALSO
257.Xr dwarf 3 ,
258.Xr dwarf_ranges_dealloc 3
259