1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi
3*7fd79137SRobert Mustacchi Copyright (C) 2008-2010 David Anderson. All Rights Reserved.
4*7fd79137SRobert Mustacchi
5*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it
6*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License
7*7fd79137SRobert Mustacchi as published by the Free Software Foundation.
8*7fd79137SRobert Mustacchi
9*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but
10*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of
11*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*7fd79137SRobert Mustacchi
13*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is
14*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement
15*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or
16*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if
17*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with
18*7fd79137SRobert Mustacchi other software, or any other product whatsoever.
19*7fd79137SRobert Mustacchi
20*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public
21*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software
22*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23*7fd79137SRobert Mustacchi USA.
24*7fd79137SRobert Mustacchi
25*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
26*7fd79137SRobert Mustacchi Mountain View, CA 94043, or:
27*7fd79137SRobert Mustacchi
28*7fd79137SRobert Mustacchi http://www.sgi.com
29*7fd79137SRobert Mustacchi
30*7fd79137SRobert Mustacchi For further information regarding this notice, see:
31*7fd79137SRobert Mustacchi
32*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan
33*7fd79137SRobert Mustacchi
34*7fd79137SRobert Mustacchi */
35*7fd79137SRobert Mustacchi /* The address of the Free Software Foundation is
36*7fd79137SRobert Mustacchi Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
37*7fd79137SRobert Mustacchi Boston, MA 02110-1301, USA.
38*7fd79137SRobert Mustacchi SGI has moved from the Crittenden Lane address.
39*7fd79137SRobert Mustacchi */
40*7fd79137SRobert Mustacchi
41*7fd79137SRobert Mustacchi
42*7fd79137SRobert Mustacchi
43*7fd79137SRobert Mustacchi #include "config.h"
44*7fd79137SRobert Mustacchi #include <stdlib.h>
45*7fd79137SRobert Mustacchi #include "dwarf_incl.h"
46*7fd79137SRobert Mustacchi
47*7fd79137SRobert Mustacchi struct ranges_entry {
48*7fd79137SRobert Mustacchi struct ranges_entry *next;
49*7fd79137SRobert Mustacchi Dwarf_Ranges cur;
50*7fd79137SRobert Mustacchi };
51*7fd79137SRobert Mustacchi
52*7fd79137SRobert Mustacchi
53*7fd79137SRobert Mustacchi #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
dwarf_get_ranges_a(Dwarf_Debug dbg,Dwarf_Off rangesoffset,Dwarf_Die die,Dwarf_Ranges ** rangesbuf,Dwarf_Signed * listlen,Dwarf_Unsigned * bytecount,Dwarf_Error * error)54*7fd79137SRobert Mustacchi int dwarf_get_ranges_a(Dwarf_Debug dbg,
55*7fd79137SRobert Mustacchi Dwarf_Off rangesoffset,
56*7fd79137SRobert Mustacchi Dwarf_Die die,
57*7fd79137SRobert Mustacchi Dwarf_Ranges ** rangesbuf,
58*7fd79137SRobert Mustacchi Dwarf_Signed * listlen,
59*7fd79137SRobert Mustacchi Dwarf_Unsigned * bytecount,
60*7fd79137SRobert Mustacchi Dwarf_Error * error)
61*7fd79137SRobert Mustacchi {
62*7fd79137SRobert Mustacchi Dwarf_Small *rangeptr = 0;
63*7fd79137SRobert Mustacchi Dwarf_Small *beginrangeptr = 0;
64*7fd79137SRobert Mustacchi Dwarf_Small *section_end = 0;
65*7fd79137SRobert Mustacchi unsigned entry_count = 0;
66*7fd79137SRobert Mustacchi struct ranges_entry *base = 0;
67*7fd79137SRobert Mustacchi struct ranges_entry *last = 0;
68*7fd79137SRobert Mustacchi struct ranges_entry *curre = 0;
69*7fd79137SRobert Mustacchi Dwarf_Ranges * ranges_data_out = 0;
70*7fd79137SRobert Mustacchi unsigned copyindex = 0;
71*7fd79137SRobert Mustacchi Dwarf_Half address_size = 0;
72*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR;
73*7fd79137SRobert Mustacchi
74*7fd79137SRobert Mustacchi res = _dwarf_load_section(dbg, &dbg->de_debug_ranges,error);
75*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
76*7fd79137SRobert Mustacchi return res;
77*7fd79137SRobert Mustacchi }
78*7fd79137SRobert Mustacchi if(rangesoffset >= dbg->de_debug_ranges.dss_size) {
79*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD);
80*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
81*7fd79137SRobert Mustacchi
82*7fd79137SRobert Mustacchi }
83*7fd79137SRobert Mustacchi address_size = _dwarf_get_address_size(dbg, die);
84*7fd79137SRobert Mustacchi section_end = dbg->de_debug_ranges.dss_data +
85*7fd79137SRobert Mustacchi dbg->de_debug_ranges.dss_size;
86*7fd79137SRobert Mustacchi rangeptr = dbg->de_debug_ranges.dss_data + rangesoffset;
87*7fd79137SRobert Mustacchi beginrangeptr = rangeptr;
88*7fd79137SRobert Mustacchi
89*7fd79137SRobert Mustacchi for(;;) {
90*7fd79137SRobert Mustacchi struct ranges_entry * re = calloc(sizeof(struct ranges_entry),1);
91*7fd79137SRobert Mustacchi if(!re) {
92*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM);
93*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
94*7fd79137SRobert Mustacchi }
95*7fd79137SRobert Mustacchi if(rangeptr >= section_end) {
96*7fd79137SRobert Mustacchi return (DW_DLV_NO_ENTRY);
97*7fd79137SRobert Mustacchi }
98*7fd79137SRobert Mustacchi if((rangeptr + (2*address_size)) > section_end) {
99*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD);
100*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
101*7fd79137SRobert Mustacchi }
102*7fd79137SRobert Mustacchi entry_count++;
103*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg,re->cur.dwr_addr1,
104*7fd79137SRobert Mustacchi Dwarf_Addr, rangeptr,
105*7fd79137SRobert Mustacchi address_size);
106*7fd79137SRobert Mustacchi rangeptr += address_size;
107*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg,re->cur.dwr_addr2 ,
108*7fd79137SRobert Mustacchi Dwarf_Addr, rangeptr,
109*7fd79137SRobert Mustacchi address_size);
110*7fd79137SRobert Mustacchi rangeptr += address_size;
111*7fd79137SRobert Mustacchi if(!base) {
112*7fd79137SRobert Mustacchi base = re;
113*7fd79137SRobert Mustacchi last = re;
114*7fd79137SRobert Mustacchi } else {
115*7fd79137SRobert Mustacchi last->next = re;
116*7fd79137SRobert Mustacchi last = re;
117*7fd79137SRobert Mustacchi }
118*7fd79137SRobert Mustacchi if(re->cur.dwr_addr1 == 0 && re->cur.dwr_addr2 == 0) {
119*7fd79137SRobert Mustacchi re->cur.dwr_type = DW_RANGES_END;
120*7fd79137SRobert Mustacchi break;
121*7fd79137SRobert Mustacchi } else if ( re->cur.dwr_addr1 == MAX_ADDR) {
122*7fd79137SRobert Mustacchi re->cur.dwr_type = DW_RANGES_ADDRESS_SELECTION;
123*7fd79137SRobert Mustacchi } else {
124*7fd79137SRobert Mustacchi re->cur.dwr_type = DW_RANGES_ENTRY;
125*7fd79137SRobert Mustacchi }
126*7fd79137SRobert Mustacchi }
127*7fd79137SRobert Mustacchi
128*7fd79137SRobert Mustacchi ranges_data_out = (Dwarf_Ranges *)
129*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg,DW_DLA_RANGES,entry_count);
130*7fd79137SRobert Mustacchi if(!ranges_data_out) {
131*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM);
132*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
133*7fd79137SRobert Mustacchi }
134*7fd79137SRobert Mustacchi curre = base;
135*7fd79137SRobert Mustacchi *rangesbuf = ranges_data_out;
136*7fd79137SRobert Mustacchi *listlen = entry_count;
137*7fd79137SRobert Mustacchi for( copyindex = 0; curre && (copyindex < entry_count);
138*7fd79137SRobert Mustacchi ++copyindex,++ranges_data_out) {
139*7fd79137SRobert Mustacchi
140*7fd79137SRobert Mustacchi struct ranges_entry *r = curre;
141*7fd79137SRobert Mustacchi *ranges_data_out = curre->cur;
142*7fd79137SRobert Mustacchi curre = curre->next;
143*7fd79137SRobert Mustacchi free(r);
144*7fd79137SRobert Mustacchi }
145*7fd79137SRobert Mustacchi /* Callers will often not care about the bytes used. */
146*7fd79137SRobert Mustacchi if(bytecount) {
147*7fd79137SRobert Mustacchi *bytecount = rangeptr - beginrangeptr;
148*7fd79137SRobert Mustacchi }
149*7fd79137SRobert Mustacchi return DW_DLV_OK;
150*7fd79137SRobert Mustacchi }
dwarf_get_ranges(Dwarf_Debug dbg,Dwarf_Off rangesoffset,Dwarf_Ranges ** rangesbuf,Dwarf_Signed * listlen,Dwarf_Unsigned * bytecount,Dwarf_Error * error)151*7fd79137SRobert Mustacchi int dwarf_get_ranges(Dwarf_Debug dbg,
152*7fd79137SRobert Mustacchi Dwarf_Off rangesoffset,
153*7fd79137SRobert Mustacchi Dwarf_Ranges ** rangesbuf,
154*7fd79137SRobert Mustacchi Dwarf_Signed * listlen,
155*7fd79137SRobert Mustacchi Dwarf_Unsigned * bytecount,
156*7fd79137SRobert Mustacchi Dwarf_Error * error)
157*7fd79137SRobert Mustacchi {
158*7fd79137SRobert Mustacchi Dwarf_Die die = 0;
159*7fd79137SRobert Mustacchi int res = dwarf_get_ranges_a(dbg,rangesoffset,die,
160*7fd79137SRobert Mustacchi rangesbuf,listlen,bytecount,error);
161*7fd79137SRobert Mustacchi return res;
162*7fd79137SRobert Mustacchi }
163*7fd79137SRobert Mustacchi
164*7fd79137SRobert Mustacchi void
dwarf_ranges_dealloc(Dwarf_Debug dbg,Dwarf_Ranges * rangesbuf,Dwarf_Signed rangecount)165*7fd79137SRobert Mustacchi dwarf_ranges_dealloc(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf,
166*7fd79137SRobert Mustacchi Dwarf_Signed rangecount)
167*7fd79137SRobert Mustacchi {
168*7fd79137SRobert Mustacchi dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES);
169*7fd79137SRobert Mustacchi
170*7fd79137SRobert Mustacchi }
171*7fd79137SRobert Mustacchi
172