xref: /titanic_54/usr/src/lib/libdwarf/common/dwarf_ranges.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
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