xref: /aosp_15_r20/external/elfutils/libdw/libdw_findcu.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
1*7304104dSAndroid Build Coastguard Worker /* Find CU for given offset.
2*7304104dSAndroid Build Coastguard Worker    Copyright (C) 2003-2010, 2014, 2016, 2017, 2018 Red Hat, Inc.
3*7304104dSAndroid Build Coastguard Worker    This file is part of elfutils.
4*7304104dSAndroid Build Coastguard Worker    Written by Ulrich Drepper <[email protected]>, 2003.
5*7304104dSAndroid Build Coastguard Worker 
6*7304104dSAndroid Build Coastguard Worker    This file is free software; you can redistribute it and/or modify
7*7304104dSAndroid Build Coastguard Worker    it under the terms of either
8*7304104dSAndroid Build Coastguard Worker 
9*7304104dSAndroid Build Coastguard Worker      * the GNU Lesser General Public License as published by the Free
10*7304104dSAndroid Build Coastguard Worker        Software Foundation; either version 3 of the License, or (at
11*7304104dSAndroid Build Coastguard Worker        your option) any later version
12*7304104dSAndroid Build Coastguard Worker 
13*7304104dSAndroid Build Coastguard Worker    or
14*7304104dSAndroid Build Coastguard Worker 
15*7304104dSAndroid Build Coastguard Worker      * the GNU General Public License as published by the Free
16*7304104dSAndroid Build Coastguard Worker        Software Foundation; either version 2 of the License, or (at
17*7304104dSAndroid Build Coastguard Worker        your option) any later version
18*7304104dSAndroid Build Coastguard Worker 
19*7304104dSAndroid Build Coastguard Worker    or both in parallel, as here.
20*7304104dSAndroid Build Coastguard Worker 
21*7304104dSAndroid Build Coastguard Worker    elfutils is distributed in the hope that it will be useful, but
22*7304104dSAndroid Build Coastguard Worker    WITHOUT ANY WARRANTY; without even the implied warranty of
23*7304104dSAndroid Build Coastguard Worker    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24*7304104dSAndroid Build Coastguard Worker    General Public License for more details.
25*7304104dSAndroid Build Coastguard Worker 
26*7304104dSAndroid Build Coastguard Worker    You should have received copies of the GNU General Public License and
27*7304104dSAndroid Build Coastguard Worker    the GNU Lesser General Public License along with this program.  If
28*7304104dSAndroid Build Coastguard Worker    not, see <http://www.gnu.org/licenses/>.  */
29*7304104dSAndroid Build Coastguard Worker 
30*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
31*7304104dSAndroid Build Coastguard Worker # include <config.h>
32*7304104dSAndroid Build Coastguard Worker #endif
33*7304104dSAndroid Build Coastguard Worker 
34*7304104dSAndroid Build Coastguard Worker #include <assert.h>
35*7304104dSAndroid Build Coastguard Worker #include <search.h>
36*7304104dSAndroid Build Coastguard Worker #include "libdwP.h"
37*7304104dSAndroid Build Coastguard Worker 
38*7304104dSAndroid Build Coastguard Worker static int
findcu_cb(const void * arg1,const void * arg2)39*7304104dSAndroid Build Coastguard Worker findcu_cb (const void *arg1, const void *arg2)
40*7304104dSAndroid Build Coastguard Worker {
41*7304104dSAndroid Build Coastguard Worker   struct Dwarf_CU *cu1 = (struct Dwarf_CU *) arg1;
42*7304104dSAndroid Build Coastguard Worker   struct Dwarf_CU *cu2 = (struct Dwarf_CU *) arg2;
43*7304104dSAndroid Build Coastguard Worker 
44*7304104dSAndroid Build Coastguard Worker   /* Find out which of the two arguments is the search value.  It has
45*7304104dSAndroid Build Coastguard Worker      end offset 0.  */
46*7304104dSAndroid Build Coastguard Worker   if (cu1->end == 0)
47*7304104dSAndroid Build Coastguard Worker     {
48*7304104dSAndroid Build Coastguard Worker       if (cu1->start < cu2->start)
49*7304104dSAndroid Build Coastguard Worker 	return -1;
50*7304104dSAndroid Build Coastguard Worker       if (cu1->start >= cu2->end)
51*7304104dSAndroid Build Coastguard Worker 	return 1;
52*7304104dSAndroid Build Coastguard Worker     }
53*7304104dSAndroid Build Coastguard Worker   else
54*7304104dSAndroid Build Coastguard Worker     {
55*7304104dSAndroid Build Coastguard Worker       if (cu2->start < cu1->start)
56*7304104dSAndroid Build Coastguard Worker 	return 1;
57*7304104dSAndroid Build Coastguard Worker       if (cu2->start >= cu1->end)
58*7304104dSAndroid Build Coastguard Worker 	return -1;
59*7304104dSAndroid Build Coastguard Worker     }
60*7304104dSAndroid Build Coastguard Worker 
61*7304104dSAndroid Build Coastguard Worker   return 0;
62*7304104dSAndroid Build Coastguard Worker }
63*7304104dSAndroid Build Coastguard Worker 
64*7304104dSAndroid Build Coastguard Worker int
__libdw_finddbg_cb(const void * arg1,const void * arg2)65*7304104dSAndroid Build Coastguard Worker __libdw_finddbg_cb (const void *arg1, const void *arg2)
66*7304104dSAndroid Build Coastguard Worker {
67*7304104dSAndroid Build Coastguard Worker   Dwarf *dbg1 = (Dwarf *) arg1;
68*7304104dSAndroid Build Coastguard Worker   Dwarf *dbg2 = (Dwarf *) arg2;
69*7304104dSAndroid Build Coastguard Worker 
70*7304104dSAndroid Build Coastguard Worker   Elf_Data *dbg1_data = dbg1->sectiondata[IDX_debug_info];
71*7304104dSAndroid Build Coastguard Worker   unsigned char *dbg1_start = dbg1_data->d_buf;
72*7304104dSAndroid Build Coastguard Worker   size_t dbg1_size = dbg1_data->d_size;
73*7304104dSAndroid Build Coastguard Worker 
74*7304104dSAndroid Build Coastguard Worker   Elf_Data *dbg2_data = dbg2->sectiondata[IDX_debug_info];
75*7304104dSAndroid Build Coastguard Worker   unsigned char *dbg2_start = dbg2_data->d_buf;
76*7304104dSAndroid Build Coastguard Worker   size_t dbg2_size = dbg2_data->d_size;
77*7304104dSAndroid Build Coastguard Worker 
78*7304104dSAndroid Build Coastguard Worker   /* Find out which of the two arguments is the search value.  It has
79*7304104dSAndroid Build Coastguard Worker      a size of 0.  */
80*7304104dSAndroid Build Coastguard Worker   if (dbg1_size == 0)
81*7304104dSAndroid Build Coastguard Worker     {
82*7304104dSAndroid Build Coastguard Worker       if (dbg1_start < dbg2_start)
83*7304104dSAndroid Build Coastguard Worker 	return -1;
84*7304104dSAndroid Build Coastguard Worker       if (dbg1_start >= dbg2_start + dbg2_size)
85*7304104dSAndroid Build Coastguard Worker 	return 1;
86*7304104dSAndroid Build Coastguard Worker     }
87*7304104dSAndroid Build Coastguard Worker   else
88*7304104dSAndroid Build Coastguard Worker     {
89*7304104dSAndroid Build Coastguard Worker       if (dbg2_start < dbg1_start)
90*7304104dSAndroid Build Coastguard Worker 	return 1;
91*7304104dSAndroid Build Coastguard Worker       if (dbg2_start >= dbg1_start + dbg1_size)
92*7304104dSAndroid Build Coastguard Worker 	return -1;
93*7304104dSAndroid Build Coastguard Worker     }
94*7304104dSAndroid Build Coastguard Worker 
95*7304104dSAndroid Build Coastguard Worker   return 0;
96*7304104dSAndroid Build Coastguard Worker }
97*7304104dSAndroid Build Coastguard Worker 
98*7304104dSAndroid Build Coastguard Worker struct Dwarf_CU *
99*7304104dSAndroid Build Coastguard Worker internal_function
__libdw_intern_next_unit(Dwarf * dbg,bool debug_types)100*7304104dSAndroid Build Coastguard Worker __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
101*7304104dSAndroid Build Coastguard Worker {
102*7304104dSAndroid Build Coastguard Worker   Dwarf_Off *const offsetp
103*7304104dSAndroid Build Coastguard Worker     = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
104*7304104dSAndroid Build Coastguard Worker   void **tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree;
105*7304104dSAndroid Build Coastguard Worker 
106*7304104dSAndroid Build Coastguard Worker   Dwarf_Off oldoff = *offsetp;
107*7304104dSAndroid Build Coastguard Worker   uint16_t version;
108*7304104dSAndroid Build Coastguard Worker   uint8_t unit_type;
109*7304104dSAndroid Build Coastguard Worker   uint8_t address_size;
110*7304104dSAndroid Build Coastguard Worker   uint8_t offset_size;
111*7304104dSAndroid Build Coastguard Worker   Dwarf_Off abbrev_offset;
112*7304104dSAndroid Build Coastguard Worker   uint64_t unit_id8;
113*7304104dSAndroid Build Coastguard Worker   Dwarf_Off subdie_offset;
114*7304104dSAndroid Build Coastguard Worker 
115*7304104dSAndroid Build Coastguard Worker   if (__libdw_next_unit (dbg, debug_types, oldoff, offsetp, NULL,
116*7304104dSAndroid Build Coastguard Worker 			 &version, &unit_type, &abbrev_offset,
117*7304104dSAndroid Build Coastguard Worker 			 &address_size, &offset_size,
118*7304104dSAndroid Build Coastguard Worker 			 &unit_id8, &subdie_offset) != 0)
119*7304104dSAndroid Build Coastguard Worker     /* No more entries.  */
120*7304104dSAndroid Build Coastguard Worker     return NULL;
121*7304104dSAndroid Build Coastguard Worker 
122*7304104dSAndroid Build Coastguard Worker   /* We only know how to handle the DWARF version 2 through 5 formats.
123*7304104dSAndroid Build Coastguard Worker      For v4 debug types we only handle version 4.  */
124*7304104dSAndroid Build Coastguard Worker   if (unlikely (version < 2) || unlikely (version > 5)
125*7304104dSAndroid Build Coastguard Worker       || (debug_types && unlikely (version != 4)))
126*7304104dSAndroid Build Coastguard Worker     {
127*7304104dSAndroid Build Coastguard Worker       __libdw_seterrno (DWARF_E_VERSION);
128*7304104dSAndroid Build Coastguard Worker       return NULL;
129*7304104dSAndroid Build Coastguard Worker     }
130*7304104dSAndroid Build Coastguard Worker 
131*7304104dSAndroid Build Coastguard Worker   /* We only handle 32 or 64 bit (4 or 8 byte) addresses and offsets.
132*7304104dSAndroid Build Coastguard Worker      Just assume we are dealing with 64bit in case the size is "unknown".
133*7304104dSAndroid Build Coastguard Worker      Too much code assumes if it isn't 4 then it is 8 (or the other way
134*7304104dSAndroid Build Coastguard Worker      around).  */
135*7304104dSAndroid Build Coastguard Worker   if (unlikely (address_size != 4 && address_size != 8))
136*7304104dSAndroid Build Coastguard Worker     address_size = 8;
137*7304104dSAndroid Build Coastguard Worker   if (unlikely (offset_size != 4 && offset_size != 8))
138*7304104dSAndroid Build Coastguard Worker     offset_size = 8;
139*7304104dSAndroid Build Coastguard Worker 
140*7304104dSAndroid Build Coastguard Worker   /* Invalid or truncated debug section data?  */
141*7304104dSAndroid Build Coastguard Worker   size_t sec_idx = debug_types ? IDX_debug_types : IDX_debug_info;
142*7304104dSAndroid Build Coastguard Worker   Elf_Data *data = dbg->sectiondata[sec_idx];
143*7304104dSAndroid Build Coastguard Worker   if (unlikely (*offsetp > data->d_size))
144*7304104dSAndroid Build Coastguard Worker     *offsetp = data->d_size;
145*7304104dSAndroid Build Coastguard Worker 
146*7304104dSAndroid Build Coastguard Worker   uint32_t dwp_row;
147*7304104dSAndroid Build Coastguard Worker   Dwarf_Off dwp_abbrev_offset;
148*7304104dSAndroid Build Coastguard Worker   if (__libdw_dwp_find_unit (dbg, debug_types, oldoff, version, unit_type,
149*7304104dSAndroid Build Coastguard Worker 			     unit_id8, &dwp_row, &dwp_abbrev_offset) != 0)
150*7304104dSAndroid Build Coastguard Worker     return NULL;
151*7304104dSAndroid Build Coastguard Worker   abbrev_offset += dwp_abbrev_offset;
152*7304104dSAndroid Build Coastguard Worker 
153*7304104dSAndroid Build Coastguard Worker   /* Create an entry for this CU.  */
154*7304104dSAndroid Build Coastguard Worker   struct Dwarf_CU *newp = libdw_typed_alloc (dbg, struct Dwarf_CU);
155*7304104dSAndroid Build Coastguard Worker 
156*7304104dSAndroid Build Coastguard Worker   newp->dbg = dbg;
157*7304104dSAndroid Build Coastguard Worker   newp->sec_idx = sec_idx;
158*7304104dSAndroid Build Coastguard Worker   newp->start = oldoff;
159*7304104dSAndroid Build Coastguard Worker   newp->end = *offsetp;
160*7304104dSAndroid Build Coastguard Worker   newp->dwp_row = dwp_row;
161*7304104dSAndroid Build Coastguard Worker   newp->address_size = address_size;
162*7304104dSAndroid Build Coastguard Worker   newp->offset_size = offset_size;
163*7304104dSAndroid Build Coastguard Worker   newp->version = version;
164*7304104dSAndroid Build Coastguard Worker   newp->unit_id8 = unit_id8;
165*7304104dSAndroid Build Coastguard Worker   newp->subdie_offset = subdie_offset;
166*7304104dSAndroid Build Coastguard Worker   Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41);
167*7304104dSAndroid Build Coastguard Worker   newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset;
168*7304104dSAndroid Build Coastguard Worker   newp->files = NULL;
169*7304104dSAndroid Build Coastguard Worker   newp->lines = NULL;
170*7304104dSAndroid Build Coastguard Worker   newp->locs = NULL;
171*7304104dSAndroid Build Coastguard Worker   newp->split = (Dwarf_CU *) -1;
172*7304104dSAndroid Build Coastguard Worker   newp->base_address = (Dwarf_Addr) -1;
173*7304104dSAndroid Build Coastguard Worker   newp->addr_base = (Dwarf_Off) -1;
174*7304104dSAndroid Build Coastguard Worker   newp->str_off_base = (Dwarf_Off) -1;
175*7304104dSAndroid Build Coastguard Worker   newp->ranges_base = (Dwarf_Off) -1;
176*7304104dSAndroid Build Coastguard Worker   newp->locs_base = (Dwarf_Off) -1;
177*7304104dSAndroid Build Coastguard Worker 
178*7304104dSAndroid Build Coastguard Worker   newp->startp = data->d_buf + newp->start;
179*7304104dSAndroid Build Coastguard Worker   newp->endp = data->d_buf + newp->end;
180*7304104dSAndroid Build Coastguard Worker 
181*7304104dSAndroid Build Coastguard Worker   /* v4 debug type units have version == 4 and unit_type == DW_UT_type.  */
182*7304104dSAndroid Build Coastguard Worker   if (debug_types)
183*7304104dSAndroid Build Coastguard Worker     newp->unit_type = DW_UT_type;
184*7304104dSAndroid Build Coastguard Worker   else if (version < 5)
185*7304104dSAndroid Build Coastguard Worker     {
186*7304104dSAndroid Build Coastguard Worker       /* This is a reasonable guess (and needed to get the CUDIE).  */
187*7304104dSAndroid Build Coastguard Worker       newp->unit_type = DW_UT_compile;
188*7304104dSAndroid Build Coastguard Worker 
189*7304104dSAndroid Build Coastguard Worker       /* But set it correctly from the actual CUDIE tag.  */
190*7304104dSAndroid Build Coastguard Worker       Dwarf_Die cudie = CUDIE (newp);
191*7304104dSAndroid Build Coastguard Worker       int tag = INTUSE(dwarf_tag) (&cudie);
192*7304104dSAndroid Build Coastguard Worker       if (tag == DW_TAG_compile_unit)
193*7304104dSAndroid Build Coastguard Worker 	{
194*7304104dSAndroid Build Coastguard Worker 	  Dwarf_Attribute dwo_id;
195*7304104dSAndroid Build Coastguard Worker 	  if (INTUSE(dwarf_attr) (&cudie, DW_AT_GNU_dwo_id, &dwo_id) != NULL)
196*7304104dSAndroid Build Coastguard Worker 	    {
197*7304104dSAndroid Build Coastguard Worker 	      Dwarf_Word id8;
198*7304104dSAndroid Build Coastguard Worker 	      if (INTUSE(dwarf_formudata) (&dwo_id, &id8) == 0)
199*7304104dSAndroid Build Coastguard Worker 		{
200*7304104dSAndroid Build Coastguard Worker 		  if (INTUSE(dwarf_haschildren) (&cudie) == 0
201*7304104dSAndroid Build Coastguard Worker 		      && INTUSE(dwarf_hasattr) (&cudie,
202*7304104dSAndroid Build Coastguard Worker 						DW_AT_GNU_dwo_name) == 1)
203*7304104dSAndroid Build Coastguard Worker 		    newp->unit_type = DW_UT_skeleton;
204*7304104dSAndroid Build Coastguard Worker 		  else
205*7304104dSAndroid Build Coastguard Worker 		    newp->unit_type = DW_UT_split_compile;
206*7304104dSAndroid Build Coastguard Worker 
207*7304104dSAndroid Build Coastguard Worker 		  newp->unit_id8 = id8;
208*7304104dSAndroid Build Coastguard Worker 		}
209*7304104dSAndroid Build Coastguard Worker 	    }
210*7304104dSAndroid Build Coastguard Worker 	}
211*7304104dSAndroid Build Coastguard Worker       else if (tag == DW_TAG_partial_unit)
212*7304104dSAndroid Build Coastguard Worker 	newp->unit_type = DW_UT_partial;
213*7304104dSAndroid Build Coastguard Worker       else if (tag == DW_TAG_type_unit)
214*7304104dSAndroid Build Coastguard Worker 	newp->unit_type = DW_UT_type;
215*7304104dSAndroid Build Coastguard Worker     }
216*7304104dSAndroid Build Coastguard Worker   else
217*7304104dSAndroid Build Coastguard Worker     newp->unit_type = unit_type;
218*7304104dSAndroid Build Coastguard Worker 
219*7304104dSAndroid Build Coastguard Worker   /* Store a reference to any type unit ids in the hash for quick lookup.  */
220*7304104dSAndroid Build Coastguard Worker   if (unit_type == DW_UT_type || unit_type == DW_UT_split_type)
221*7304104dSAndroid Build Coastguard Worker     Dwarf_Sig8_Hash_insert (&dbg->sig8_hash, unit_id8, newp);
222*7304104dSAndroid Build Coastguard Worker 
223*7304104dSAndroid Build Coastguard Worker   /* Add the new entry to the search tree.  */
224*7304104dSAndroid Build Coastguard Worker   if (tsearch (newp, tree, findcu_cb) == NULL)
225*7304104dSAndroid Build Coastguard Worker     {
226*7304104dSAndroid Build Coastguard Worker       /* Something went wrong.  Undo the operation.  */
227*7304104dSAndroid Build Coastguard Worker       *offsetp = oldoff;
228*7304104dSAndroid Build Coastguard Worker       __libdw_seterrno (DWARF_E_NOMEM);
229*7304104dSAndroid Build Coastguard Worker       return NULL;
230*7304104dSAndroid Build Coastguard Worker     }
231*7304104dSAndroid Build Coastguard Worker 
232*7304104dSAndroid Build Coastguard Worker   return newp;
233*7304104dSAndroid Build Coastguard Worker }
234*7304104dSAndroid Build Coastguard Worker 
235*7304104dSAndroid Build Coastguard Worker struct Dwarf_CU *
236*7304104dSAndroid Build Coastguard Worker internal_function
__libdw_findcu(Dwarf * dbg,Dwarf_Off start,bool v4_debug_types)237*7304104dSAndroid Build Coastguard Worker __libdw_findcu (Dwarf *dbg, Dwarf_Off start, bool v4_debug_types)
238*7304104dSAndroid Build Coastguard Worker {
239*7304104dSAndroid Build Coastguard Worker   void **tree = v4_debug_types ? &dbg->tu_tree : &dbg->cu_tree;
240*7304104dSAndroid Build Coastguard Worker   Dwarf_Off *next_offset
241*7304104dSAndroid Build Coastguard Worker     = v4_debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
242*7304104dSAndroid Build Coastguard Worker 
243*7304104dSAndroid Build Coastguard Worker   /* Maybe we already know that CU.  */
244*7304104dSAndroid Build Coastguard Worker   struct Dwarf_CU fake = { .start = start, .end = 0 };
245*7304104dSAndroid Build Coastguard Worker   struct Dwarf_CU **found = tfind (&fake, tree, findcu_cb);
246*7304104dSAndroid Build Coastguard Worker   if (found != NULL)
247*7304104dSAndroid Build Coastguard Worker     return *found;
248*7304104dSAndroid Build Coastguard Worker 
249*7304104dSAndroid Build Coastguard Worker   if (start < *next_offset)
250*7304104dSAndroid Build Coastguard Worker     {
251*7304104dSAndroid Build Coastguard Worker       __libdw_seterrno (DWARF_E_INVALID_DWARF);
252*7304104dSAndroid Build Coastguard Worker       return NULL;
253*7304104dSAndroid Build Coastguard Worker     }
254*7304104dSAndroid Build Coastguard Worker 
255*7304104dSAndroid Build Coastguard Worker   /* No.  Then read more CUs.  */
256*7304104dSAndroid Build Coastguard Worker   while (1)
257*7304104dSAndroid Build Coastguard Worker     {
258*7304104dSAndroid Build Coastguard Worker       struct Dwarf_CU *newp = __libdw_intern_next_unit (dbg, v4_debug_types);
259*7304104dSAndroid Build Coastguard Worker       if (newp == NULL)
260*7304104dSAndroid Build Coastguard Worker 	return NULL;
261*7304104dSAndroid Build Coastguard Worker 
262*7304104dSAndroid Build Coastguard Worker       /* Is this the one we are looking for?  */
263*7304104dSAndroid Build Coastguard Worker       if (start < *next_offset || start == newp->start)
264*7304104dSAndroid Build Coastguard Worker 	return newp;
265*7304104dSAndroid Build Coastguard Worker     }
266*7304104dSAndroid Build Coastguard Worker   /* NOTREACHED */
267*7304104dSAndroid Build Coastguard Worker }
268*7304104dSAndroid Build Coastguard Worker 
269*7304104dSAndroid Build Coastguard Worker struct Dwarf_CU *
270*7304104dSAndroid Build Coastguard Worker internal_function
__libdw_findcu_addr(Dwarf * dbg,void * addr)271*7304104dSAndroid Build Coastguard Worker __libdw_findcu_addr (Dwarf *dbg, void *addr)
272*7304104dSAndroid Build Coastguard Worker {
273*7304104dSAndroid Build Coastguard Worker   void **tree;
274*7304104dSAndroid Build Coastguard Worker   Dwarf_Off start;
275*7304104dSAndroid Build Coastguard Worker   if (addr >= dbg->sectiondata[IDX_debug_info]->d_buf
276*7304104dSAndroid Build Coastguard Worker       && addr < (dbg->sectiondata[IDX_debug_info]->d_buf
277*7304104dSAndroid Build Coastguard Worker 		 + dbg->sectiondata[IDX_debug_info]->d_size))
278*7304104dSAndroid Build Coastguard Worker     {
279*7304104dSAndroid Build Coastguard Worker       tree = &dbg->cu_tree;
280*7304104dSAndroid Build Coastguard Worker       start = addr - dbg->sectiondata[IDX_debug_info]->d_buf;
281*7304104dSAndroid Build Coastguard Worker     }
282*7304104dSAndroid Build Coastguard Worker   else if (dbg->sectiondata[IDX_debug_types] != NULL
283*7304104dSAndroid Build Coastguard Worker 	   && addr >= dbg->sectiondata[IDX_debug_types]->d_buf
284*7304104dSAndroid Build Coastguard Worker 	   && addr < (dbg->sectiondata[IDX_debug_types]->d_buf
285*7304104dSAndroid Build Coastguard Worker 		      + dbg->sectiondata[IDX_debug_types]->d_size))
286*7304104dSAndroid Build Coastguard Worker     {
287*7304104dSAndroid Build Coastguard Worker       tree = &dbg->tu_tree;
288*7304104dSAndroid Build Coastguard Worker       start = addr - dbg->sectiondata[IDX_debug_types]->d_buf;
289*7304104dSAndroid Build Coastguard Worker     }
290*7304104dSAndroid Build Coastguard Worker   else
291*7304104dSAndroid Build Coastguard Worker     return NULL;
292*7304104dSAndroid Build Coastguard Worker 
293*7304104dSAndroid Build Coastguard Worker   struct Dwarf_CU fake = { .start = start, .end = 0 };
294*7304104dSAndroid Build Coastguard Worker   struct Dwarf_CU **found = tfind (&fake, tree, findcu_cb);
295*7304104dSAndroid Build Coastguard Worker 
296*7304104dSAndroid Build Coastguard Worker   if (found != NULL)
297*7304104dSAndroid Build Coastguard Worker     return *found;
298*7304104dSAndroid Build Coastguard Worker 
299*7304104dSAndroid Build Coastguard Worker   return NULL;
300*7304104dSAndroid Build Coastguard Worker }
301*7304104dSAndroid Build Coastguard Worker 
302*7304104dSAndroid Build Coastguard Worker Dwarf *
303*7304104dSAndroid Build Coastguard Worker internal_function
__libdw_find_split_dbg_addr(Dwarf * dbg,void * addr)304*7304104dSAndroid Build Coastguard Worker __libdw_find_split_dbg_addr (Dwarf *dbg, void *addr)
305*7304104dSAndroid Build Coastguard Worker {
306*7304104dSAndroid Build Coastguard Worker   /* XXX Assumes split DWARF only has CUs in main IDX_debug_info.  */
307*7304104dSAndroid Build Coastguard Worker   Elf_Data fake_data = { .d_buf = addr, .d_size = 0 };
308*7304104dSAndroid Build Coastguard Worker   Dwarf fake = { .sectiondata[IDX_debug_info] = &fake_data };
309*7304104dSAndroid Build Coastguard Worker   Dwarf **found = tfind (&fake, &dbg->split_tree, __libdw_finddbg_cb);
310*7304104dSAndroid Build Coastguard Worker 
311*7304104dSAndroid Build Coastguard Worker   if (found != NULL)
312*7304104dSAndroid Build Coastguard Worker     return *found;
313*7304104dSAndroid Build Coastguard Worker 
314*7304104dSAndroid Build Coastguard Worker   return NULL;
315*7304104dSAndroid Build Coastguard Worker }
316