1*4d9fdb46SRobert Mustacchi /*
2*4d9fdb46SRobert Mustacchi   Copyright (C) 2014-2019 David Anderson. All Rights Reserved.
3*4d9fdb46SRobert Mustacchi 
4*4d9fdb46SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
5*4d9fdb46SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
6*4d9fdb46SRobert Mustacchi   as published by the Free Software Foundation.
7*4d9fdb46SRobert Mustacchi 
8*4d9fdb46SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
9*4d9fdb46SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
10*4d9fdb46SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11*4d9fdb46SRobert Mustacchi 
12*4d9fdb46SRobert Mustacchi   Further, this software is distributed without any warranty that it is
13*4d9fdb46SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
14*4d9fdb46SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
15*4d9fdb46SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
16*4d9fdb46SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
17*4d9fdb46SRobert Mustacchi   other software, or any other product whatsoever.
18*4d9fdb46SRobert Mustacchi 
19*4d9fdb46SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
20*4d9fdb46SRobert Mustacchi   License along with this program; if not, write the Free Software
21*4d9fdb46SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
22*4d9fdb46SRobert Mustacchi   USA.
23*4d9fdb46SRobert Mustacchi 
24*4d9fdb46SRobert Mustacchi */
25*4d9fdb46SRobert Mustacchi 
26*4d9fdb46SRobert Mustacchi /*  The file and functions have  'xu' because
27*4d9fdb46SRobert Mustacchi     the .debug_cu_index and .debug_tu_index
28*4d9fdb46SRobert Mustacchi     sections have the same layout and this deals with both.
29*4d9fdb46SRobert Mustacchi 
30*4d9fdb46SRobert Mustacchi     This is DebugFission, part of DWARF5.
31*4d9fdb46SRobert Mustacchi 
32*4d9fdb46SRobert Mustacchi     It allows fast section access in a .dwp object file
33*4d9fdb46SRobert Mustacchi     with debug-information to locate offsets
34*4d9fdb46SRobert Mustacchi     within and between sections.
35*4d9fdb46SRobert Mustacchi 
36*4d9fdb46SRobert Mustacchi     See the DWARF5 Standard: section 7.3.5 and
37*4d9fdb46SRobert Mustacchi     examples in Appendix F.3.
38*4d9fdb46SRobert Mustacchi 
39*4d9fdb46SRobert Mustacchi     A note about the index field from the index table.
40*4d9fdb46SRobert Mustacchi     See DWARF5 7.5.3.5.
41*4d9fdb46SRobert Mustacchi     The index table array index values are [1,S)
42*4d9fdb46SRobert Mustacchi     These value ae used to call functions requestiong
43*4d9fdb46SRobert Mustacchi     values from the offset table and size table.
44*4d9fdb46SRobert Mustacchi 
45*4d9fdb46SRobert Mustacchi     Inside the code in this file we subtract 1 and use
46*4d9fdb46SRobert Mustacchi     0 origin as that is how we arranged the
47*4d9fdb46SRobert Mustacchi     table access here.
48*4d9fdb46SRobert Mustacchi     A zero in the index table is an unused signature
49*4d9fdb46SRobert Mustacchi     table signature and unused index.
50*4d9fdb46SRobert Mustacchi 
51*4d9fdb46SRobert Mustacchi     By subtracting one and arranging things properly
52*4d9fdb46SRobert Mustacchi     in the offset table and size table we can refer
53*4d9fdb46SRobert Mustacchi     to the tables in an identical simple fashion
54*4d9fdb46SRobert Mustacchi     These tables are thus U rows and N columns.
55*4d9fdb46SRobert Mustacchi     Technically the Offset table physically
56*4d9fdb46SRobert Mustacchi     row zero is a separate set of numbers translating
57*4d9fdb46SRobert Mustacchi     the column number to a DW_SECT* value
58*4d9fdb46SRobert Mustacchi     so callers can request specific bases(offsets)
59*4d9fdb46SRobert Mustacchi     and sizes from the offset and size tables.
60*4d9fdb46SRobert Mustacchi     But we change things a little internally so both
61*4d9fdb46SRobert Mustacchi     tables look zero-origin.
62*4d9fdb46SRobert Mustacchi */
63*4d9fdb46SRobert Mustacchi #include "config.h"
64*4d9fdb46SRobert Mustacchi #include <stdio.h>
65*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
66*4d9fdb46SRobert Mustacchi #include <stdlib.h>
67*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
68*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
69*4d9fdb46SRobert Mustacchi #include "dwarf_alloc.h"
70*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
71*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
72*4d9fdb46SRobert Mustacchi #include "dwarf_xu_index.h"
73*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
74*4d9fdb46SRobert Mustacchi 
75*4d9fdb46SRobert Mustacchi #define  HASHSIGNATURELEN 8
76*4d9fdb46SRobert Mustacchi #define  LEN32BIT   4
77*4d9fdb46SRobert Mustacchi 
78*4d9fdb46SRobert Mustacchi #define TRUE 1
79*4d9fdb46SRobert Mustacchi #define FALSE 0
80*4d9fdb46SRobert Mustacchi 
81*4d9fdb46SRobert Mustacchi /* The following actually assumes (as used here)
82*4d9fdb46SRobert Mustacchi     that t is 8 bytes (integer) while s is
83*4d9fdb46SRobert Mustacchi     also 8 bytes (Dwarf_Sig8 struct). */
84*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
85*4d9fdb46SRobert Mustacchi #define ASNAR(t,s,l)                   \
86*4d9fdb46SRobert Mustacchi     do {                                    \
87*4d9fdb46SRobert Mustacchi         unsigned tbyte = sizeof(t) - l;     \
88*4d9fdb46SRobert Mustacchi         if (sizeof(t) < l) {                \
89*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg,error,DW_DLE_XU_HASH_INDEX_ERROR); \
90*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;             \
91*4d9fdb46SRobert Mustacchi         }                                   \
92*4d9fdb46SRobert Mustacchi         t = 0;                              \
93*4d9fdb46SRobert Mustacchi         dbg->de_copy_word(((char *)&t)+tbyte ,&s[0],l);\
94*4d9fdb46SRobert Mustacchi     } while (0)
95*4d9fdb46SRobert Mustacchi #else /* LITTLE ENDIAN */
96*4d9fdb46SRobert Mustacchi #define ASNAR(t,s,l)                 \
97*4d9fdb46SRobert Mustacchi     do {                                \
98*4d9fdb46SRobert Mustacchi         t = 0;                          \
99*4d9fdb46SRobert Mustacchi         if (sizeof(t) < l) {            \
100*4d9fdb46SRobert Mustacchi             _dwarf_error(dbg,error,DW_DLE_XU_HASH_INDEX_ERROR); \
101*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;         \
102*4d9fdb46SRobert Mustacchi         }                               \
103*4d9fdb46SRobert Mustacchi         dbg->de_copy_word(&t,&s[0],l);  \
104*4d9fdb46SRobert Mustacchi     } while (0)
105*4d9fdb46SRobert Mustacchi #endif /* end LITTLE- BIG-ENDIAN */
106*4d9fdb46SRobert Mustacchi 
107*4d9fdb46SRobert Mustacchi /* zerohashkey used as all-zero-bits for comparison. */
108*4d9fdb46SRobert Mustacchi static const Dwarf_Sig8 zerohashkey;
109*4d9fdb46SRobert Mustacchi 
110*4d9fdb46SRobert Mustacchi #if 0
111*4d9fdb46SRobert Mustacchi static void
112*4d9fdb46SRobert Mustacchi dump_bytes(char * msg,Dwarf_Small * start, long len)
113*4d9fdb46SRobert Mustacchi {
114*4d9fdb46SRobert Mustacchi     Dwarf_Small *end = start + len;
115*4d9fdb46SRobert Mustacchi     Dwarf_Small *cur = start;
116*4d9fdb46SRobert Mustacchi 
117*4d9fdb46SRobert Mustacchi     printf("%s ",msg);
118*4d9fdb46SRobert Mustacchi     for (; cur < end; cur++) {
119*4d9fdb46SRobert Mustacchi         printf("%02x ", *cur);
120*4d9fdb46SRobert Mustacchi     }
121*4d9fdb46SRobert Mustacchi     printf("\n");
122*4d9fdb46SRobert Mustacchi }
123*4d9fdb46SRobert Mustacchi #endif
124*4d9fdb46SRobert Mustacchi 
125*4d9fdb46SRobert Mustacchi /*  Precondition: headerline_offset + N*32 is within
126*4d9fdb46SRobert Mustacchi     the section. */
127*4d9fdb46SRobert Mustacchi static int
fill_in_offsets_headerline(Dwarf_Debug dbg,Dwarf_Xu_Index_Header xuhdr,Dwarf_Unsigned headerline_offset,Dwarf_Unsigned num_sects,Dwarf_Error * err)128*4d9fdb46SRobert Mustacchi fill_in_offsets_headerline(Dwarf_Debug dbg,
129*4d9fdb46SRobert Mustacchi     Dwarf_Xu_Index_Header xuhdr,
130*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned headerline_offset,
131*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned num_sects,
132*4d9fdb46SRobert Mustacchi     Dwarf_Error *err)
133*4d9fdb46SRobert Mustacchi {
134*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_start = xuhdr->gx_section_data;
135*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_end = xuhdr->gx_section_data+
136*4d9fdb46SRobert Mustacchi         xuhdr->gx_section_length;
137*4d9fdb46SRobert Mustacchi     Dwarf_Small *data = 0;
138*4d9fdb46SRobert Mustacchi     unsigned i = 0;
139*4d9fdb46SRobert Mustacchi 
140*4d9fdb46SRobert Mustacchi     data = section_start +headerline_offset;
141*4d9fdb46SRobert Mustacchi     for( ; i < num_sects ; ++i) {
142*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned v = 0;
143*4d9fdb46SRobert Mustacchi 
144*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg,v, Dwarf_Unsigned,
145*4d9fdb46SRobert Mustacchi             data,LEN32BIT,
146*4d9fdb46SRobert Mustacchi             err,section_end);
147*4d9fdb46SRobert Mustacchi         data += LEN32BIT;
148*4d9fdb46SRobert Mustacchi         if (v > DW_SECT_RNGLISTS) {
149*4d9fdb46SRobert Mustacchi             dwarfstring s;
150*4d9fdb46SRobert Mustacchi 
151*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&s);
152*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&s,
153*4d9fdb46SRobert Mustacchi                 "ERROR: DW_DLE_XU_NAME_COL_ERROR  The "
154*4d9fdb46SRobert Mustacchi                 "section number of %u ",v);
155*4d9fdb46SRobert Mustacchi             dwarfstring_append(&s," is too high. "
156*4d9fdb46SRobert Mustacchi                 "There sections 1-8 are listed in "
157*4d9fdb46SRobert Mustacchi                 "DWARF5 table 7.1.");
158*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
159*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&s));
160*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&s);
161*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
162*4d9fdb46SRobert Mustacchi         }
163*4d9fdb46SRobert Mustacchi         xuhdr->gx_section_id[i] = v;
164*4d9fdb46SRobert Mustacchi     }
165*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
166*4d9fdb46SRobert Mustacchi }
167*4d9fdb46SRobert Mustacchi 
168*4d9fdb46SRobert Mustacchi 
169*4d9fdb46SRobert Mustacchi /*  Read in a cu or tu section and
170*4d9fdb46SRobert Mustacchi     return overview information.
171*4d9fdb46SRobert Mustacchi 
172*4d9fdb46SRobert Mustacchi     For libdwarf-internal lookups
173*4d9fdb46SRobert Mustacchi     dwarf_init*() calls
174*4d9fdb46SRobert Mustacchi     dwarf_get_xu_index_header() when
175*4d9fdb46SRobert Mustacchi     the object file is opened and
176*4d9fdb46SRobert Mustacchi     dwarf_xu_header_free() is called
177*4d9fdb46SRobert Mustacchi     by dwarf_finish(), there is
178*4d9fdb46SRobert Mustacchi     no need for users to do this.
179*4d9fdb46SRobert Mustacchi 
180*4d9fdb46SRobert Mustacchi     If one wants to call the various
181*4d9fdb46SRobert Mustacchi     tu/cu functions oneself (possibly to print the
182*4d9fdb46SRobert Mustacchi     .debug_cu_index or .debug_tu_index sections).
183*4d9fdb46SRobert Mustacchi     then you will need to call dwarf_get_xu_index_header()
184*4d9fdb46SRobert Mustacchi     and eventually dwarf_xu_header_free().
185*4d9fdb46SRobert Mustacchi 
186*4d9fdb46SRobert Mustacchi     The libdwarf-internal data is kept in Dwarf_Debug
187*4d9fdb46SRobert Mustacchi     fields de_cu_hashindex_data/de_tu_hashindex_data.
188*4d9fdb46SRobert Mustacchi */
189*4d9fdb46SRobert Mustacchi int
dwarf_get_xu_index_header(Dwarf_Debug dbg,const char * section_type,Dwarf_Xu_Index_Header * xuptr,Dwarf_Unsigned * version,Dwarf_Unsigned * number_of_columns,Dwarf_Unsigned * number_of_CUs,Dwarf_Unsigned * number_of_slots,const char ** section_name,Dwarf_Error * error)190*4d9fdb46SRobert Mustacchi dwarf_get_xu_index_header(Dwarf_Debug dbg,
191*4d9fdb46SRobert Mustacchi     /* Pass in section_type "tu" or "cu" */
192*4d9fdb46SRobert Mustacchi     const char *     section_type,
193*4d9fdb46SRobert Mustacchi     Dwarf_Xu_Index_Header * xuptr,
194*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * version,
195*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * number_of_columns, /* L section count.*/
196*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * number_of_CUs,     /* U unit count    */
197*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * number_of_slots,   /* S slot count    */
198*4d9fdb46SRobert Mustacchi     /*  Standard says S > U DWARF5 sec 7.3.5.3 */
199*4d9fdb46SRobert Mustacchi     const char    ** section_name,
200*4d9fdb46SRobert Mustacchi     Dwarf_Error    * error)
201*4d9fdb46SRobert Mustacchi {
202*4d9fdb46SRobert Mustacchi     Dwarf_Xu_Index_Header indexptr = 0;
203*4d9fdb46SRobert Mustacchi     int res = DW_DLV_ERROR;
204*4d9fdb46SRobert Mustacchi     struct Dwarf_Section_s *sect = 0;
205*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned local_version = 0;
206*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned num_secs  = 0;
207*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned num_CUs  = 0;
208*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned num_slots  = 0;
209*4d9fdb46SRobert Mustacchi     Dwarf_Small *data = 0;
210*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned tables_end_offset = 0;
211*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned hash_tab_offset = 0;
212*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned indexes_tab_offset = 0;
213*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned section_offsets_tab_offset = 0;
214*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned section_offsets_headerline_offset = 0;
215*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned section_sizes_tab_offset = 0;
216*4d9fdb46SRobert Mustacchi     unsigned datalen32 = LEN32BIT;
217*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_end = 0;
218*4d9fdb46SRobert Mustacchi 
219*4d9fdb46SRobert Mustacchi     if (!strcmp(section_type,"cu") ) {
220*4d9fdb46SRobert Mustacchi         sect = &dbg->de_debug_cu_index;
221*4d9fdb46SRobert Mustacchi     } else if (!strcmp(section_type,"tu") ) {
222*4d9fdb46SRobert Mustacchi         sect = &dbg->de_debug_tu_index;
223*4d9fdb46SRobert Mustacchi     } else {
224*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_XU_TYPE_ARG_ERROR);
225*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
226*4d9fdb46SRobert Mustacchi     }
227*4d9fdb46SRobert Mustacchi     if (!sect->dss_size) {
228*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
229*4d9fdb46SRobert Mustacchi     }
230*4d9fdb46SRobert Mustacchi     if (!sect->dss_data) {
231*4d9fdb46SRobert Mustacchi         res = _dwarf_load_section(dbg, sect,error);
232*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
233*4d9fdb46SRobert Mustacchi             return res;
234*4d9fdb46SRobert Mustacchi         }
235*4d9fdb46SRobert Mustacchi     }
236*4d9fdb46SRobert Mustacchi 
237*4d9fdb46SRobert Mustacchi     data = sect->dss_data;
238*4d9fdb46SRobert Mustacchi     section_end = data + sect->dss_size;
239*4d9fdb46SRobert Mustacchi 
240*4d9fdb46SRobert Mustacchi     if (sect->dss_size < (4*datalen32) ) {
241*4d9fdb46SRobert Mustacchi         dwarfstring m;
242*4d9fdb46SRobert Mustacchi 
243*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
244*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_s(&m,
245*4d9fdb46SRobert Mustacchi             "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
246*4d9fdb46SRobert Mustacchi             "The size of the %s ",(char *)section_type);
247*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
248*4d9fdb46SRobert Mustacchi             " is just %u bytes, much to small to be "
249*4d9fdb46SRobert Mustacchi             " a correct section",sect->dss_size);
250*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
251*4d9fdb46SRobert Mustacchi             DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
252*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
253*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
254*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
255*4d9fdb46SRobert Mustacchi     }
256*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,local_version, Dwarf_Unsigned,
257*4d9fdb46SRobert Mustacchi         data,datalen32,
258*4d9fdb46SRobert Mustacchi         error,section_end);
259*4d9fdb46SRobert Mustacchi     data += datalen32;
260*4d9fdb46SRobert Mustacchi 
261*4d9fdb46SRobert Mustacchi     /* reading N */
262*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,num_secs, Dwarf_Unsigned,
263*4d9fdb46SRobert Mustacchi         data,datalen32,
264*4d9fdb46SRobert Mustacchi         error,section_end);
265*4d9fdb46SRobert Mustacchi     data += datalen32;
266*4d9fdb46SRobert Mustacchi     /* reading U */
267*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,num_CUs, Dwarf_Unsigned,
268*4d9fdb46SRobert Mustacchi         data,datalen32,
269*4d9fdb46SRobert Mustacchi         error,section_end);
270*4d9fdb46SRobert Mustacchi     data += datalen32;
271*4d9fdb46SRobert Mustacchi     /* reading S */
272*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,num_slots, Dwarf_Unsigned,
273*4d9fdb46SRobert Mustacchi         data,datalen32,
274*4d9fdb46SRobert Mustacchi         error,section_end);
275*4d9fdb46SRobert Mustacchi     hash_tab_offset = datalen32*4;
276*4d9fdb46SRobert Mustacchi     indexes_tab_offset = hash_tab_offset +
277*4d9fdb46SRobert Mustacchi         (num_slots * HASHSIGNATURELEN);
278*4d9fdb46SRobert Mustacchi     /*  Look for corrupt section data. */
279*4d9fdb46SRobert Mustacchi     if (num_slots > sect->dss_size) {
280*4d9fdb46SRobert Mustacchi         dwarfstring m;
281*4d9fdb46SRobert Mustacchi 
282*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
283*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_s(&m,
284*4d9fdb46SRobert Mustacchi             "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
285*4d9fdb46SRobert Mustacchi             "The size of the %s ",(char *)section_type);
286*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
287*4d9fdb46SRobert Mustacchi             " is just %u bytes,",sect->dss_size);
288*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
289*4d9fdb46SRobert Mustacchi             "while the number of slots (S) is %u. "
290*4d9fdb46SRobert Mustacchi             "which is clearly wrong",num_slots );
291*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
292*4d9fdb46SRobert Mustacchi             DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
293*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
294*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
295*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
296*4d9fdb46SRobert Mustacchi     }
297*4d9fdb46SRobert Mustacchi     if ( (4*num_slots) > sect->dss_size) {
298*4d9fdb46SRobert Mustacchi         dwarfstring m;
299*4d9fdb46SRobert Mustacchi 
300*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
301*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_s(&m,
302*4d9fdb46SRobert Mustacchi             "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
303*4d9fdb46SRobert Mustacchi             "The size of the %s ",(char *)section_type);
304*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
305*4d9fdb46SRobert Mustacchi             " is just %u bytes,",sect->dss_size);
306*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
307*4d9fdb46SRobert Mustacchi             "while the number of slots bytes (S) is at least %u. "
308*4d9fdb46SRobert Mustacchi             "which is clearly wrong",num_slots*4);
309*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
310*4d9fdb46SRobert Mustacchi             DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
311*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
312*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
313*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
314*4d9fdb46SRobert Mustacchi     }
315*4d9fdb46SRobert Mustacchi 
316*4d9fdb46SRobert Mustacchi     /*  This offset is to  1 row of N columns, each 32bit. */
317*4d9fdb46SRobert Mustacchi     section_offsets_headerline_offset = indexes_tab_offset +
318*4d9fdb46SRobert Mustacchi         (num_slots *datalen32);
319*4d9fdb46SRobert Mustacchi     /*  Now we can make the real table part index normally.
320*4d9fdb46SRobert Mustacchi         This offset is to  U row of N columns, each 32bit. */
321*4d9fdb46SRobert Mustacchi     section_offsets_tab_offset = section_offsets_headerline_offset
322*4d9fdb46SRobert Mustacchi         + (num_secs*datalen32);
323*4d9fdb46SRobert Mustacchi     if ( num_secs > sect->dss_size) {
324*4d9fdb46SRobert Mustacchi         dwarfstring m;
325*4d9fdb46SRobert Mustacchi 
326*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
327*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_s(&m,
328*4d9fdb46SRobert Mustacchi             "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
329*4d9fdb46SRobert Mustacchi             "The size of the %s ",(char *)section_type);
330*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
331*4d9fdb46SRobert Mustacchi             " is just %u bytes,",sect->dss_size);
332*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
333*4d9fdb46SRobert Mustacchi             "while the number of sections/columns (S) is %u. "
334*4d9fdb46SRobert Mustacchi             "which is clearly wrong",num_secs );
335*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
336*4d9fdb46SRobert Mustacchi             DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
337*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
338*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
339*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
340*4d9fdb46SRobert Mustacchi     }
341*4d9fdb46SRobert Mustacchi     if ( (datalen32*num_secs) > sect->dss_size) {
342*4d9fdb46SRobert Mustacchi         dwarfstring m;
343*4d9fdb46SRobert Mustacchi 
344*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
345*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_s(&m,
346*4d9fdb46SRobert Mustacchi             "DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
347*4d9fdb46SRobert Mustacchi             "The size of the %s ",(char *)section_type);
348*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
349*4d9fdb46SRobert Mustacchi             " is just %u bytes,",sect->dss_size);
350*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,
351*4d9fdb46SRobert Mustacchi             "while the number of sections/columns bytes (S)"
352*4d9fdb46SRobert Mustacchi             " is at least %u. "
353*4d9fdb46SRobert Mustacchi             "which is clearly wrong",num_secs*4);
354*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
355*4d9fdb46SRobert Mustacchi             DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
356*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
357*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
358*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
359*4d9fdb46SRobert Mustacchi     }
360*4d9fdb46SRobert Mustacchi     section_sizes_tab_offset = section_offsets_tab_offset +
361*4d9fdb46SRobert Mustacchi         (num_CUs *num_secs* datalen32) ;
362*4d9fdb46SRobert Mustacchi     tables_end_offset = section_sizes_tab_offset +
363*4d9fdb46SRobert Mustacchi         (num_CUs * num_secs * datalen32);
364*4d9fdb46SRobert Mustacchi     if ( tables_end_offset > sect->dss_size) {
365*4d9fdb46SRobert Mustacchi         /* Something is badly wrong here. */
366*4d9fdb46SRobert Mustacchi         dwarfstring m;
367*4d9fdb46SRobert Mustacchi 
368*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&m);
369*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,"ERROR: "
370*4d9fdb46SRobert Mustacchi             "DW_DLE_ERRONEOUS_XU_INDEX_SECTION as the end offset "
371*4d9fdb46SRobert Mustacchi             "0x%lx is greater than ",tables_end_offset);
372*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&m,"the section size "
373*4d9fdb46SRobert Mustacchi             "0x%lx.",sect->dss_size);
374*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error,
375*4d9fdb46SRobert Mustacchi             DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
376*4d9fdb46SRobert Mustacchi             dwarfstring_string(&m));
377*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&m);
378*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
379*4d9fdb46SRobert Mustacchi     }
380*4d9fdb46SRobert Mustacchi     indexptr = (Dwarf_Xu_Index_Header)
381*4d9fdb46SRobert Mustacchi         _dwarf_get_alloc(dbg,DW_DLA_XU_INDEX,1);
382*4d9fdb46SRobert Mustacchi     if (indexptr == NULL) {
383*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
384*4d9fdb46SRobert Mustacchi         return (DW_DLV_ERROR);
385*4d9fdb46SRobert Mustacchi     }
386*4d9fdb46SRobert Mustacchi     /*  Only "cu" or "tu" allowed, that is checked above.
387*4d9fdb46SRobert Mustacchi         But for safety we just copy the allowed bytes*/
388*4d9fdb46SRobert Mustacchi     indexptr->gx_type[0] = section_type[0];
389*4d9fdb46SRobert Mustacchi     indexptr->gx_type[1] = section_type[1];
390*4d9fdb46SRobert Mustacchi     indexptr->gx_type[2] = 0;
391*4d9fdb46SRobert Mustacchi     indexptr->gx_dbg = dbg;
392*4d9fdb46SRobert Mustacchi     indexptr->gx_section_length = sect->dss_size;
393*4d9fdb46SRobert Mustacchi     indexptr->gx_section_data   = sect->dss_data;
394*4d9fdb46SRobert Mustacchi     indexptr->gx_section_name   = sect->dss_name;
395*4d9fdb46SRobert Mustacchi     indexptr->gx_version        = local_version;
396*4d9fdb46SRobert Mustacchi     indexptr->gx_column_count_sections = num_secs;
397*4d9fdb46SRobert Mustacchi     indexptr->gx_units_in_index = num_CUs;
398*4d9fdb46SRobert Mustacchi     indexptr->gx_slots_in_hash  = num_slots;
399*4d9fdb46SRobert Mustacchi     indexptr->gx_hash_table_offset  =  hash_tab_offset;
400*4d9fdb46SRobert Mustacchi     indexptr->gx_index_table_offset = indexes_tab_offset;
401*4d9fdb46SRobert Mustacchi     indexptr->gx_section_offsets_headerline_offset=
402*4d9fdb46SRobert Mustacchi         section_offsets_headerline_offset;
403*4d9fdb46SRobert Mustacchi     indexptr->gx_section_offsets_offset= section_offsets_tab_offset;
404*4d9fdb46SRobert Mustacchi     indexptr->gx_section_sizes_offset  = section_sizes_tab_offset;
405*4d9fdb46SRobert Mustacchi     res = fill_in_offsets_headerline(dbg,indexptr,
406*4d9fdb46SRobert Mustacchi         section_offsets_headerline_offset,
407*4d9fdb46SRobert Mustacchi         num_secs,error);
408*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
409*4d9fdb46SRobert Mustacchi         return res;
410*4d9fdb46SRobert Mustacchi     }
411*4d9fdb46SRobert Mustacchi     *xuptr             =     indexptr;
412*4d9fdb46SRobert Mustacchi     *version           = indexptr->gx_version;
413*4d9fdb46SRobert Mustacchi     *number_of_columns = indexptr->gx_column_count_sections;
414*4d9fdb46SRobert Mustacchi     *number_of_CUs     = indexptr->gx_units_in_index;
415*4d9fdb46SRobert Mustacchi     *number_of_slots   = indexptr->gx_slots_in_hash;
416*4d9fdb46SRobert Mustacchi     *section_name      = indexptr->gx_section_name;
417*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
418*4d9fdb46SRobert Mustacchi }
419*4d9fdb46SRobert Mustacchi 
420*4d9fdb46SRobert Mustacchi 
421*4d9fdb46SRobert Mustacchi 
dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header xuhdr,const char ** typename,const char ** sectionname,UNUSEDARG Dwarf_Error * err)422*4d9fdb46SRobert Mustacchi int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header xuhdr,
423*4d9fdb46SRobert Mustacchi     /*  the function returns a pointer to
424*4d9fdb46SRobert Mustacchi         the immutable string "tu" or "cu" via
425*4d9fdb46SRobert Mustacchi         this arg. Do not free.  */
426*4d9fdb46SRobert Mustacchi     const char ** typename,
427*4d9fdb46SRobert Mustacchi     /*  the function returns a pointer to
428*4d9fdb46SRobert Mustacchi         the immutable section name. Do not free.
429*4d9fdb46SRobert Mustacchi         .debug_cu_index or .debug_tu_index */
430*4d9fdb46SRobert Mustacchi     const char ** sectionname,
431*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Error * err)
432*4d9fdb46SRobert Mustacchi {
433*4d9fdb46SRobert Mustacchi     *typename    = &xuhdr->gx_type[0];
434*4d9fdb46SRobert Mustacchi     *sectionname = xuhdr->gx_section_name;
435*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
436*4d9fdb46SRobert Mustacchi }
437*4d9fdb46SRobert Mustacchi 
438*4d9fdb46SRobert Mustacchi /*  Index values 0 to S-1 are valid. */
dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header xuhdr,Dwarf_Unsigned index,Dwarf_Sig8 * hash_value,Dwarf_Unsigned * index_to_sections,Dwarf_Error * err)439*4d9fdb46SRobert Mustacchi int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header xuhdr,
440*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned    index,
441*4d9fdb46SRobert Mustacchi     /* returns the hash value. 64 bits. */
442*4d9fdb46SRobert Mustacchi     Dwarf_Sig8     *  hash_value,
443*4d9fdb46SRobert Mustacchi 
444*4d9fdb46SRobert Mustacchi     /* returns the index into rows of offset/size tables. */
445*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *  index_to_sections,
446*4d9fdb46SRobert Mustacchi     Dwarf_Error *     err)
447*4d9fdb46SRobert Mustacchi {
448*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = xuhdr->gx_dbg;
449*4d9fdb46SRobert Mustacchi     Dwarf_Small *hashtab = xuhdr->gx_section_data +
450*4d9fdb46SRobert Mustacchi         xuhdr->gx_hash_table_offset;
451*4d9fdb46SRobert Mustacchi     Dwarf_Small *indextab = xuhdr->gx_section_data +
452*4d9fdb46SRobert Mustacchi         xuhdr->gx_index_table_offset;
453*4d9fdb46SRobert Mustacchi     Dwarf_Small *indexentry = 0;
454*4d9fdb46SRobert Mustacchi     Dwarf_Small *hashentry = 0;
455*4d9fdb46SRobert Mustacchi     Dwarf_Sig8 hashval;
456*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned indexval = 0;
457*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_end = xuhdr->gx_section_data +
458*4d9fdb46SRobert Mustacchi         xuhdr->gx_section_length;
459*4d9fdb46SRobert Mustacchi 
460*4d9fdb46SRobert Mustacchi     hashval  = zerohashkey;
461*4d9fdb46SRobert Mustacchi     if (xuhdr->gx_slots_in_hash > 0) {
462*4d9fdb46SRobert Mustacchi         if (index >= xuhdr->gx_slots_in_hash) {
463*4d9fdb46SRobert Mustacchi             dwarfstring m;
464*4d9fdb46SRobert Mustacchi 
465*4d9fdb46SRobert Mustacchi             dwarfstring_constructor(&m);
466*4d9fdb46SRobert Mustacchi             dwarfstring_append_printf_u(&m,
467*4d9fdb46SRobert Mustacchi                 "DW_DLE_XU_HASH_ROW_ERROR the index passed in, "
468*4d9fdb46SRobert Mustacchi                 " %u, is greater than the number of slots "
469*4d9fdb46SRobert Mustacchi                 " in the hash table.",index);
470*4d9fdb46SRobert Mustacchi             _dwarf_error_string(dbg, err,  DW_DLE_XU_HASH_ROW_ERROR,
471*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&m));
472*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&m);
473*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
474*4d9fdb46SRobert Mustacchi         }
475*4d9fdb46SRobert Mustacchi         hashentry = hashtab + (index * HASHSIGNATURELEN);
476*4d9fdb46SRobert Mustacchi         memcpy(&hashval,hashentry,sizeof(hashval));
477*4d9fdb46SRobert Mustacchi     } else {
478*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, err,  DW_DLE_XU_HASH_ROW_ERROR,
479*4d9fdb46SRobert Mustacchi             "DW_DLE_XU_HASH_ROW_ERROR the number of slots is zero"
480*4d9fdb46SRobert Mustacchi             " which seems wrong.");
481*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
482*4d9fdb46SRobert Mustacchi     }
483*4d9fdb46SRobert Mustacchi 
484*4d9fdb46SRobert Mustacchi     indexentry = indextab + (index * LEN32BIT);
485*4d9fdb46SRobert Mustacchi     memcpy(hash_value,&hashval,sizeof(hashval));
486*4d9fdb46SRobert Mustacchi     READ_UNALIGNED_CK(dbg,indexval,Dwarf_Unsigned, indexentry,
487*4d9fdb46SRobert Mustacchi         LEN32BIT,
488*4d9fdb46SRobert Mustacchi         err,section_end);
489*4d9fdb46SRobert Mustacchi     indexentry += LEN32BIT;
490*4d9fdb46SRobert Mustacchi     if (indexval > xuhdr->gx_units_in_index) {
491*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, err,  DW_DLE_XU_HASH_INDEX_ERROR);
492*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
493*4d9fdb46SRobert Mustacchi     }
494*4d9fdb46SRobert Mustacchi 
495*4d9fdb46SRobert Mustacchi     *index_to_sections = indexval;
496*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
497*4d9fdb46SRobert Mustacchi }
498*4d9fdb46SRobert Mustacchi 
499*4d9fdb46SRobert Mustacchi 
500*4d9fdb46SRobert Mustacchi static const char * dwp_secnames[] = {
501*4d9fdb46SRobert Mustacchi "No name for zero",
502*4d9fdb46SRobert Mustacchi "DW_SECT_INFO"        /* 1 */ /*".debug_info.dwo"*/,
503*4d9fdb46SRobert Mustacchi "DW_SECT_TYPES"       /* 2 */ /*".debug_types.dwo"*/,
504*4d9fdb46SRobert Mustacchi "DW_SECT_ABBREV"      /* 3 */ /*".debug_abbrev.dwo"*/,
505*4d9fdb46SRobert Mustacchi "DW_SECT_LINE"        /* 4 */ /*".debug_line.dwo"*/,
506*4d9fdb46SRobert Mustacchi "DW_SECT_LOC"         /* 5 */ /*".debug_loc.dwo"*/,
507*4d9fdb46SRobert Mustacchi "DW_SECT_STR_OFFSETS" /* 6 */ /*".debug_str_offsets.dwo"*/,
508*4d9fdb46SRobert Mustacchi "DW_SECT_MACRO"       /* 7 */ /*".debug_macro.dwo"*/,
509*4d9fdb46SRobert Mustacchi "DW_SECT_RNGLISTS"       /* 8 */ /*".debug_rnglists.dwo"*/,
510*4d9fdb46SRobert Mustacchi "No name > 8",
511*4d9fdb46SRobert Mustacchi };
512*4d9fdb46SRobert Mustacchi 
513*4d9fdb46SRobert Mustacchi /*  Row 0 of the Table of Section Offsets,
514*4d9fdb46SRobert Mustacchi     columns 0 to L-1,  are the section id's,
515*4d9fdb46SRobert Mustacchi     and names, such as DW_SECT_INFO (ie, 1)  */
516*4d9fdb46SRobert Mustacchi int
dwarf_get_xu_section_names(Dwarf_Xu_Index_Header xuhdr,Dwarf_Unsigned column_index,Dwarf_Unsigned * number,const char ** name,Dwarf_Error * err)517*4d9fdb46SRobert Mustacchi dwarf_get_xu_section_names(Dwarf_Xu_Index_Header xuhdr,
518*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned  column_index,
519*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned* number,
520*4d9fdb46SRobert Mustacchi     const char **   name,
521*4d9fdb46SRobert Mustacchi     Dwarf_Error *   err)
522*4d9fdb46SRobert Mustacchi {
523*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned sec_num = 0;
524*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = xuhdr->gx_dbg;
525*4d9fdb46SRobert Mustacchi 
526*4d9fdb46SRobert Mustacchi     if( column_index >= xuhdr->gx_column_count_sections) {
527*4d9fdb46SRobert Mustacchi         dwarfstring s;
528*4d9fdb46SRobert Mustacchi 
529*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&s);
530*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s,
531*4d9fdb46SRobert Mustacchi             "ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
532*4d9fdb46SRobert Mustacchi             "column index of %u ",column_index);
533*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s," is too high. "
534*4d9fdb46SRobert Mustacchi             "There are %u sections.",
535*4d9fdb46SRobert Mustacchi             xuhdr->gx_column_count_sections);
536*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
537*4d9fdb46SRobert Mustacchi             dwarfstring_string(&s));
538*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&s);
539*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
540*4d9fdb46SRobert Mustacchi     }
541*4d9fdb46SRobert Mustacchi     sec_num = xuhdr->gx_section_id[column_index];
542*4d9fdb46SRobert Mustacchi     if (sec_num < 1) {
543*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
544*4d9fdb46SRobert Mustacchi     }
545*4d9fdb46SRobert Mustacchi     *number = sec_num;
546*4d9fdb46SRobert Mustacchi     *name =  dwp_secnames[sec_num];
547*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
548*4d9fdb46SRobert Mustacchi }
549*4d9fdb46SRobert Mustacchi 
550*4d9fdb46SRobert Mustacchi 
551*4d9fdb46SRobert Mustacchi /*  Rows 0 to U-1
552*4d9fdb46SRobert Mustacchi     col 0 to L-1
553*4d9fdb46SRobert Mustacchi     are section offset and length values from
554*4d9fdb46SRobert Mustacchi     the Table of Section Offsets and Table of Section Sizes.
555*4d9fdb46SRobert Mustacchi     The formally the table of section offsets is a header
556*4d9fdb46SRobert Mustacchi     line of the section offsets we subtract 1 from
557*4d9fdb46SRobert Mustacchi     the incoming irow_index as our tables are
558*4d9fdb46SRobert Mustacchi     now zero origin. */
559*4d9fdb46SRobert Mustacchi int
dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header xuhdr,Dwarf_Unsigned irow_index,Dwarf_Unsigned column_index,Dwarf_Unsigned * sec_offset,Dwarf_Unsigned * sec_size,Dwarf_Error * err)560*4d9fdb46SRobert Mustacchi dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header xuhdr,
561*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned  irow_index,
562*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned  column_index,
563*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned* sec_offset,
564*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned* sec_size,
565*4d9fdb46SRobert Mustacchi     Dwarf_Error *   err)
566*4d9fdb46SRobert Mustacchi {
567*4d9fdb46SRobert Mustacchi     /* We use zero origin in the arrays, Users see
568*4d9fdb46SRobert Mustacchi         one origin from the hash table. */
569*4d9fdb46SRobert Mustacchi     Dwarf_Debug dbg = xuhdr->gx_dbg;
570*4d9fdb46SRobert Mustacchi     /* get to base of tables first. */
571*4d9fdb46SRobert Mustacchi     Dwarf_Small *offsetrow =  xuhdr->gx_section_offsets_offset +
572*4d9fdb46SRobert Mustacchi         xuhdr->gx_section_data;
573*4d9fdb46SRobert Mustacchi     Dwarf_Small *sizerow =  xuhdr->gx_section_sizes_offset +
574*4d9fdb46SRobert Mustacchi         xuhdr->gx_section_data;
575*4d9fdb46SRobert Mustacchi     Dwarf_Small *offsetentry = 0;
576*4d9fdb46SRobert Mustacchi     Dwarf_Small *sizeentry =  0;
577*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset = 0;
578*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size = 0;
579*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned column_count = xuhdr->gx_column_count_sections;
580*4d9fdb46SRobert Mustacchi     Dwarf_Small *section_end = xuhdr->gx_section_data +
581*4d9fdb46SRobert Mustacchi         xuhdr->gx_section_length;
582*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned row_index = irow_index-1;
583*4d9fdb46SRobert Mustacchi 
584*4d9fdb46SRobert Mustacchi     if(!irow_index) {
585*4d9fdb46SRobert Mustacchi         dwarfstring s;
586*4d9fdb46SRobert Mustacchi 
587*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&s);
588*4d9fdb46SRobert Mustacchi         dwarfstring_append(&s,
589*4d9fdb46SRobert Mustacchi             "ERROR: DW_DLE_ERRONEOUS_XU_INDEX_SECTION "
590*4d9fdb46SRobert Mustacchi             "The row index passed to dwarf_get_xu_section_offset() "
591*4d9fdb46SRobert Mustacchi             "is zero, which is not a valid row in "
592*4d9fdb46SRobert Mustacchi             " the offset-table or the size table as we think"
593*4d9fdb46SRobert Mustacchi             " of them as 1-origin.");
594*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
595*4d9fdb46SRobert Mustacchi             dwarfstring_string(&s));
596*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&s);
597*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
598*4d9fdb46SRobert Mustacchi     }
599*4d9fdb46SRobert Mustacchi     if( row_index >= xuhdr->gx_units_in_index) {
600*4d9fdb46SRobert Mustacchi         dwarfstring s;
601*4d9fdb46SRobert Mustacchi 
602*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&s);
603*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s,
604*4d9fdb46SRobert Mustacchi             "ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
605*4d9fdb46SRobert Mustacchi             "row index of %u ",row_index);
606*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s," is too high. "
607*4d9fdb46SRobert Mustacchi             "Valid units must be < %u ",xuhdr->gx_units_in_index);
608*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
609*4d9fdb46SRobert Mustacchi             dwarfstring_string(&s));
610*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&s);
611*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
612*4d9fdb46SRobert Mustacchi     }
613*4d9fdb46SRobert Mustacchi 
614*4d9fdb46SRobert Mustacchi     if( column_index >=  xuhdr->gx_column_count_sections) {
615*4d9fdb46SRobert Mustacchi         dwarfstring s;
616*4d9fdb46SRobert Mustacchi 
617*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&s);
618*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s,
619*4d9fdb46SRobert Mustacchi             "ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
620*4d9fdb46SRobert Mustacchi             "column index of %u ",column_index);
621*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s," is too high. "
622*4d9fdb46SRobert Mustacchi             "Valid column indexes  must be < %u ",
623*4d9fdb46SRobert Mustacchi             xuhdr->gx_column_count_sections);
624*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
625*4d9fdb46SRobert Mustacchi             dwarfstring_string(&s));
626*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&s);
627*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
628*4d9fdb46SRobert Mustacchi     }
629*4d9fdb46SRobert Mustacchi     /*  As noted above we have hidden the extra initial
630*4d9fdb46SRobert Mustacchi         row from the offsets table so it is just
631*4d9fdb46SRobert Mustacchi         0 to U-1. */
632*4d9fdb46SRobert Mustacchi     offsetrow = offsetrow + (row_index*column_count * LEN32BIT);
633*4d9fdb46SRobert Mustacchi     offsetentry = offsetrow + (column_index *  LEN32BIT);
634*4d9fdb46SRobert Mustacchi 
635*4d9fdb46SRobert Mustacchi     sizerow = sizerow + (row_index*column_count * LEN32BIT);
636*4d9fdb46SRobert Mustacchi     sizeentry = sizerow + (column_index *  LEN32BIT);
637*4d9fdb46SRobert Mustacchi 
638*4d9fdb46SRobert Mustacchi     {
639*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg,offset,Dwarf_Unsigned,
640*4d9fdb46SRobert Mustacchi             offsetentry,
641*4d9fdb46SRobert Mustacchi             LEN32BIT,err,section_end);
642*4d9fdb46SRobert Mustacchi         offsetentry += LEN32BIT;
643*4d9fdb46SRobert Mustacchi 
644*4d9fdb46SRobert Mustacchi         READ_UNALIGNED_CK(dbg,size,Dwarf_Unsigned,
645*4d9fdb46SRobert Mustacchi             sizeentry,
646*4d9fdb46SRobert Mustacchi             LEN32BIT,err,section_end);
647*4d9fdb46SRobert Mustacchi         sizeentry += LEN32BIT;
648*4d9fdb46SRobert Mustacchi     }
649*4d9fdb46SRobert Mustacchi     *sec_offset = offset;
650*4d9fdb46SRobert Mustacchi     *sec_size =  size;
651*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
652*4d9fdb46SRobert Mustacchi }
653*4d9fdb46SRobert Mustacchi 
654*4d9fdb46SRobert Mustacchi 
655*4d9fdb46SRobert Mustacchi static int
_dwarf_search_fission_for_key(UNUSEDARG Dwarf_Debug dbg,Dwarf_Xu_Index_Header xuhdr,Dwarf_Sig8 * key_in,Dwarf_Unsigned * percu_index_out,Dwarf_Error * error)656*4d9fdb46SRobert Mustacchi _dwarf_search_fission_for_key(UNUSEDARG Dwarf_Debug dbg,
657*4d9fdb46SRobert Mustacchi     Dwarf_Xu_Index_Header xuhdr,
658*4d9fdb46SRobert Mustacchi     Dwarf_Sig8 *key_in,
659*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * percu_index_out,
660*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
661*4d9fdb46SRobert Mustacchi {
662*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned key = 0;
663*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned primary_hash = 0;
664*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned hashprime = 0;
665*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned slots =  xuhdr->gx_slots_in_hash;
666*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned mask = slots -1;
667*4d9fdb46SRobert Mustacchi     Dwarf_Sig8 hashentry_key;
668*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned percu_index = 0;
669*4d9fdb46SRobert Mustacchi 
670*4d9fdb46SRobert Mustacchi     hashentry_key = zerohashkey;
671*4d9fdb46SRobert Mustacchi     /*  Look for corrupt section data. */
672*4d9fdb46SRobert Mustacchi     if (slots > xuhdr->gx_section_length) {
673*4d9fdb46SRobert Mustacchi         dwarfstring s;
674*4d9fdb46SRobert Mustacchi 
675*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&s);
676*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s,
677*4d9fdb46SRobert Mustacchi             "ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
678*4d9fdb46SRobert Mustacchi             "slots count of %u ",slots);
679*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s," is too high. "
680*4d9fdb46SRobert Mustacchi             "given the section length of %u\n",
681*4d9fdb46SRobert Mustacchi             xuhdr->gx_section_length);
682*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error, DW_DLE_XU_NAME_COL_ERROR,
683*4d9fdb46SRobert Mustacchi             dwarfstring_string(&s));
684*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&s);
685*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
686*4d9fdb46SRobert Mustacchi     }
687*4d9fdb46SRobert Mustacchi     if ( (4*slots) > xuhdr->gx_section_length) {
688*4d9fdb46SRobert Mustacchi         dwarfstring s;
689*4d9fdb46SRobert Mustacchi 
690*4d9fdb46SRobert Mustacchi         dwarfstring_constructor(&s);
691*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s,
692*4d9fdb46SRobert Mustacchi             "ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
693*4d9fdb46SRobert Mustacchi             "slots count *4 of %u ",slots*4);
694*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&s," is too high. "
695*4d9fdb46SRobert Mustacchi             "given the section length of %u\n",
696*4d9fdb46SRobert Mustacchi             xuhdr->gx_section_length);
697*4d9fdb46SRobert Mustacchi         _dwarf_error_string(dbg, error, DW_DLE_XU_NAME_COL_ERROR,
698*4d9fdb46SRobert Mustacchi             dwarfstring_string(&s));
699*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&s);
700*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
701*4d9fdb46SRobert Mustacchi     }
702*4d9fdb46SRobert Mustacchi     if (sizeof (key) != sizeof(key_in)) {
703*4d9fdb46SRobert Mustacchi         /* The hash won't work right in this case */
704*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_XU_HASH_ROW_ERROR);
705*4d9fdb46SRobert Mustacchi     }
706*4d9fdb46SRobert Mustacchi     ASNAR(key,key_in,sizeof(*key_in));
707*4d9fdb46SRobert Mustacchi     primary_hash = key & mask;
708*4d9fdb46SRobert Mustacchi     hashprime =  (((key >>32) &mask) |1);
709*4d9fdb46SRobert Mustacchi     while (1) {
710*4d9fdb46SRobert Mustacchi         int res = 0;
711*4d9fdb46SRobert Mustacchi 
712*4d9fdb46SRobert Mustacchi         res = dwarf_get_xu_hash_entry(xuhdr,
713*4d9fdb46SRobert Mustacchi             primary_hash,&hashentry_key,
714*4d9fdb46SRobert Mustacchi             &percu_index,error);
715*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
716*4d9fdb46SRobert Mustacchi             return res;
717*4d9fdb46SRobert Mustacchi         }
718*4d9fdb46SRobert Mustacchi         if (percu_index == 0 &&
719*4d9fdb46SRobert Mustacchi             !memcmp(&hashentry_key,&zerohashkey,sizeof(Dwarf_Sig8))) {
720*4d9fdb46SRobert Mustacchi             return DW_DLV_NO_ENTRY;
721*4d9fdb46SRobert Mustacchi         }
722*4d9fdb46SRobert Mustacchi         if (!memcmp(key_in,&hashentry_key,sizeof(Dwarf_Sig8))) {
723*4d9fdb46SRobert Mustacchi             /* FOUND */
724*4d9fdb46SRobert Mustacchi             *percu_index_out = percu_index;
725*4d9fdb46SRobert Mustacchi             return  DW_DLV_OK;
726*4d9fdb46SRobert Mustacchi         }
727*4d9fdb46SRobert Mustacchi         primary_hash = (primary_hash + hashprime) % slots;
728*4d9fdb46SRobert Mustacchi     }
729*4d9fdb46SRobert Mustacchi     /* ASSERT: Cannot get here. */
730*4d9fdb46SRobert Mustacchi     return DW_DLV_NO_ENTRY;
731*4d9fdb46SRobert Mustacchi }
732*4d9fdb46SRobert Mustacchi 
733*4d9fdb46SRobert Mustacchi /* Slow. Consider tsearch. */
734*4d9fdb46SRobert Mustacchi /* For type units and for CUs. */
735*4d9fdb46SRobert Mustacchi /* We're finding an index entry refers
736*4d9fdb46SRobert Mustacchi    to a global offset in some CU
737*4d9fdb46SRobert Mustacchi    and hence is unique in the target. */
738*4d9fdb46SRobert Mustacchi static int
_dwarf_search_fission_for_offset(Dwarf_Debug dbg,Dwarf_Xu_Index_Header xuhdr,Dwarf_Unsigned offset,Dwarf_Unsigned dfp_sect_num,Dwarf_Unsigned * percu_index_out,Dwarf_Sig8 * key_out,Dwarf_Error * error)739*4d9fdb46SRobert Mustacchi _dwarf_search_fission_for_offset(Dwarf_Debug dbg,
740*4d9fdb46SRobert Mustacchi     Dwarf_Xu_Index_Header xuhdr,
741*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
742*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned dfp_sect_num, /* DW_SECT_INFO or TYPES */
743*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * percu_index_out,
744*4d9fdb46SRobert Mustacchi     Dwarf_Sig8 * key_out,
745*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
746*4d9fdb46SRobert Mustacchi {
747*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
748*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned m = 0;
749*4d9fdb46SRobert Mustacchi     int secnum_index = -1;  /* N index */
750*4d9fdb46SRobert Mustacchi     int res = 0;
751*4d9fdb46SRobert Mustacchi 
752*4d9fdb46SRobert Mustacchi     for ( i = 0; i< xuhdr->gx_column_count_sections; i++) {
753*4d9fdb46SRobert Mustacchi         /*  We could put the secnums array into xuhdr
754*4d9fdb46SRobert Mustacchi             if looping here is too slow. */
755*4d9fdb46SRobert Mustacchi         const char *name = 0;
756*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned num = 0;
757*4d9fdb46SRobert Mustacchi         res = dwarf_get_xu_section_names(xuhdr,i,&num,&name,error);
758*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
759*4d9fdb46SRobert Mustacchi             return res;
760*4d9fdb46SRobert Mustacchi         }
761*4d9fdb46SRobert Mustacchi         if (num == dfp_sect_num) {
762*4d9fdb46SRobert Mustacchi             secnum_index = i;
763*4d9fdb46SRobert Mustacchi             break;
764*4d9fdb46SRobert Mustacchi         }
765*4d9fdb46SRobert Mustacchi     }
766*4d9fdb46SRobert Mustacchi     if (secnum_index == -1) {
767*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,DW_DLE_FISSION_SECNUM_ERR);
768*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
769*4d9fdb46SRobert Mustacchi     }
770*4d9fdb46SRobert Mustacchi     for ( m = 0; m < xuhdr->gx_slots_in_hash; ++m) {
771*4d9fdb46SRobert Mustacchi         Dwarf_Sig8 hash;
772*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned indexn = 0;
773*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned sec_offset = 0;
774*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned sec_size = 0;
775*4d9fdb46SRobert Mustacchi 
776*4d9fdb46SRobert Mustacchi         res = dwarf_get_xu_hash_entry(xuhdr,m,&hash,&indexn,error);
777*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
778*4d9fdb46SRobert Mustacchi             return res;
779*4d9fdb46SRobert Mustacchi         }
780*4d9fdb46SRobert Mustacchi         if (indexn == 0 &&
781*4d9fdb46SRobert Mustacchi             !memcmp(&hash,&zerohashkey,sizeof(Dwarf_Sig8))) {
782*4d9fdb46SRobert Mustacchi             /* Empty slot. */
783*4d9fdb46SRobert Mustacchi             continue;
784*4d9fdb46SRobert Mustacchi         }
785*4d9fdb46SRobert Mustacchi 
786*4d9fdb46SRobert Mustacchi         res = dwarf_get_xu_section_offset(xuhdr,
787*4d9fdb46SRobert Mustacchi             indexn,secnum_index,&sec_offset,&sec_size,error);
788*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
789*4d9fdb46SRobert Mustacchi             return res;
790*4d9fdb46SRobert Mustacchi         }
791*4d9fdb46SRobert Mustacchi         if (sec_offset != offset) {
792*4d9fdb46SRobert Mustacchi             continue;
793*4d9fdb46SRobert Mustacchi         }
794*4d9fdb46SRobert Mustacchi         *percu_index_out = indexn;
795*4d9fdb46SRobert Mustacchi         *key_out = hash;
796*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
797*4d9fdb46SRobert Mustacchi     }
798*4d9fdb46SRobert Mustacchi     return DW_DLV_NO_ENTRY;
799*4d9fdb46SRobert Mustacchi }
800*4d9fdb46SRobert Mustacchi 
801*4d9fdb46SRobert Mustacchi static int
_dwarf_get_xuhdr(Dwarf_Debug dbg,const char * sigtype,Dwarf_Xu_Index_Header * xuout,Dwarf_Error * error)802*4d9fdb46SRobert Mustacchi _dwarf_get_xuhdr(Dwarf_Debug dbg,
803*4d9fdb46SRobert Mustacchi    const char *sigtype,
804*4d9fdb46SRobert Mustacchi    Dwarf_Xu_Index_Header *xuout,
805*4d9fdb46SRobert Mustacchi    Dwarf_Error *error)
806*4d9fdb46SRobert Mustacchi {
807*4d9fdb46SRobert Mustacchi    if (!strcmp(sigtype,"tu")) {
808*4d9fdb46SRobert Mustacchi         if (!dbg->de_tu_hashindex_data) {
809*4d9fdb46SRobert Mustacchi             return DW_DLV_NO_ENTRY;
810*4d9fdb46SRobert Mustacchi         }
811*4d9fdb46SRobert Mustacchi         *xuout = dbg->de_tu_hashindex_data;
812*4d9fdb46SRobert Mustacchi     } else if (!strcmp(sigtype,"cu")) {
813*4d9fdb46SRobert Mustacchi         if (!dbg->de_cu_hashindex_data) {
814*4d9fdb46SRobert Mustacchi             return DW_DLV_NO_ENTRY;
815*4d9fdb46SRobert Mustacchi         }
816*4d9fdb46SRobert Mustacchi         *xuout = dbg->de_cu_hashindex_data;
817*4d9fdb46SRobert Mustacchi     } else {
818*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,DW_DLE_SIG_TYPE_WRONG_STRING);
819*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
820*4d9fdb46SRobert Mustacchi     }
821*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
822*4d9fdb46SRobert Mustacchi 
823*4d9fdb46SRobert Mustacchi }
824*4d9fdb46SRobert Mustacchi 
825*4d9fdb46SRobert Mustacchi static int
transform_xu_to_dfp(Dwarf_Xu_Index_Header xuhdr,Dwarf_Unsigned percu_index,Dwarf_Sig8 * key,const char * sig_type,Dwarf_Debug_Fission_Per_CU * percu_out,Dwarf_Error * error)826*4d9fdb46SRobert Mustacchi transform_xu_to_dfp(Dwarf_Xu_Index_Header xuhdr,
827*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned percu_index,
828*4d9fdb46SRobert Mustacchi     Dwarf_Sig8 *key,
829*4d9fdb46SRobert Mustacchi     const char *sig_type,
830*4d9fdb46SRobert Mustacchi     Dwarf_Debug_Fission_Per_CU *  percu_out,
831*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
832*4d9fdb46SRobert Mustacchi {
833*4d9fdb46SRobert Mustacchi     unsigned i = 0;
834*4d9fdb46SRobert Mustacchi     unsigned l = 0;
835*4d9fdb46SRobert Mustacchi     unsigned n = 1;
836*4d9fdb46SRobert Mustacchi     unsigned max_cols = xuhdr->gx_column_count_sections;  /* L */
837*4d9fdb46SRobert Mustacchi     unsigned secnums[DW_FISSION_SECT_COUNT];
838*4d9fdb46SRobert Mustacchi     int res;
839*4d9fdb46SRobert Mustacchi     for ( i = 0; i< max_cols; i++) {
840*4d9fdb46SRobert Mustacchi         /*  We could put the secnums array into xuhdr
841*4d9fdb46SRobert Mustacchi             if recreating it is too slow. */
842*4d9fdb46SRobert Mustacchi         const char *name = 0;
843*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned num = 0;
844*4d9fdb46SRobert Mustacchi         res = dwarf_get_xu_section_names(xuhdr,i,&num,&name,error);
845*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
846*4d9fdb46SRobert Mustacchi             return res;
847*4d9fdb46SRobert Mustacchi         }
848*4d9fdb46SRobert Mustacchi         secnums[i] = num;
849*4d9fdb46SRobert Mustacchi     }
850*4d9fdb46SRobert Mustacchi     n = percu_index;
851*4d9fdb46SRobert Mustacchi     for(l = 0; l < max_cols; ++l) {  /* L */
852*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned sec_off = 0;
853*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned sec_size = 0;
854*4d9fdb46SRobert Mustacchi         unsigned l_as_sect = secnums[l];
855*4d9fdb46SRobert Mustacchi         res = dwarf_get_xu_section_offset(xuhdr,n,l,
856*4d9fdb46SRobert Mustacchi             &sec_off,&sec_size,error);
857*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
858*4d9fdb46SRobert Mustacchi             return res;
859*4d9fdb46SRobert Mustacchi         }
860*4d9fdb46SRobert Mustacchi         percu_out->pcu_offset[l_as_sect] = sec_off;
861*4d9fdb46SRobert Mustacchi         percu_out->pcu_size[l_as_sect] = sec_size;
862*4d9fdb46SRobert Mustacchi     }
863*4d9fdb46SRobert Mustacchi     percu_out->pcu_type = sig_type;
864*4d9fdb46SRobert Mustacchi     percu_out->pcu_index = percu_index;
865*4d9fdb46SRobert Mustacchi     percu_out->pcu_hash = *key;
866*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
867*4d9fdb46SRobert Mustacchi }
868*4d9fdb46SRobert Mustacchi 
869*4d9fdb46SRobert Mustacchi /*  This should only be called for a CU, never a TU.
870*4d9fdb46SRobert Mustacchi     For a TU the type hash is known while reading
871*4d9fdb46SRobert Mustacchi     the TU Header.  Not so for a CU. */
872*4d9fdb46SRobert Mustacchi int
_dwarf_get_debugfission_for_offset(Dwarf_Debug dbg,Dwarf_Off offset_wanted,const char * key_type,struct Dwarf_Debug_Fission_Per_CU_s * percu_out,Dwarf_Error * error)873*4d9fdb46SRobert Mustacchi _dwarf_get_debugfission_for_offset(Dwarf_Debug dbg,
874*4d9fdb46SRobert Mustacchi     Dwarf_Off    offset_wanted,
875*4d9fdb46SRobert Mustacchi     const char * key_type, /*  "cu" or "tu" */
876*4d9fdb46SRobert Mustacchi     struct Dwarf_Debug_Fission_Per_CU_s *  percu_out,
877*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
878*4d9fdb46SRobert Mustacchi {
879*4d9fdb46SRobert Mustacchi     Dwarf_Xu_Index_Header xuhdr = 0;
880*4d9fdb46SRobert Mustacchi     int sres = 0;
881*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned percu_index = 0;
882*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned sect_index_base = 0;
883*4d9fdb46SRobert Mustacchi     Dwarf_Sig8 key;
884*4d9fdb46SRobert Mustacchi 
885*4d9fdb46SRobert Mustacchi     sect_index_base = DW_SECT_INFO;
886*4d9fdb46SRobert Mustacchi     key = zerohashkey;
887*4d9fdb46SRobert Mustacchi     sres = _dwarf_get_xuhdr(dbg,key_type, &xuhdr,error);
888*4d9fdb46SRobert Mustacchi     if (sres != DW_DLV_OK) {
889*4d9fdb46SRobert Mustacchi         return sres;
890*4d9fdb46SRobert Mustacchi     }
891*4d9fdb46SRobert Mustacchi     sres = _dwarf_search_fission_for_offset(dbg,
892*4d9fdb46SRobert Mustacchi         xuhdr,offset_wanted, sect_index_base, &percu_index,
893*4d9fdb46SRobert Mustacchi         &key,
894*4d9fdb46SRobert Mustacchi         error);
895*4d9fdb46SRobert Mustacchi     if (sres != DW_DLV_OK) {
896*4d9fdb46SRobert Mustacchi         return sres;
897*4d9fdb46SRobert Mustacchi     }
898*4d9fdb46SRobert Mustacchi     sres = transform_xu_to_dfp(xuhdr,percu_index,&key,
899*4d9fdb46SRobert Mustacchi         key_type,percu_out, error);
900*4d9fdb46SRobert Mustacchi     return sres;
901*4d9fdb46SRobert Mustacchi 
902*4d9fdb46SRobert Mustacchi }
903*4d9fdb46SRobert Mustacchi int
dwarf_get_debugfission_for_key(Dwarf_Debug dbg,Dwarf_Sig8 * key,const char * key_type,Dwarf_Debug_Fission_Per_CU * percu_out,Dwarf_Error * error)904*4d9fdb46SRobert Mustacchi dwarf_get_debugfission_for_key(Dwarf_Debug dbg,
905*4d9fdb46SRobert Mustacchi     Dwarf_Sig8 *  key  /* pointer to hash signature */,
906*4d9fdb46SRobert Mustacchi     const char * key_type  /*  "cu" or "tu" */,
907*4d9fdb46SRobert Mustacchi     Dwarf_Debug_Fission_Per_CU *  percu_out,
908*4d9fdb46SRobert Mustacchi     Dwarf_Error *  error )
909*4d9fdb46SRobert Mustacchi {
910*4d9fdb46SRobert Mustacchi     int sres = 0;
911*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned percu_index = 0;
912*4d9fdb46SRobert Mustacchi     Dwarf_Xu_Index_Header xuhdr = 0;
913*4d9fdb46SRobert Mustacchi 
914*4d9fdb46SRobert Mustacchi     sres = _dwarf_load_debug_info(dbg,error);
915*4d9fdb46SRobert Mustacchi     if (sres == DW_DLV_ERROR) {
916*4d9fdb46SRobert Mustacchi         return sres;
917*4d9fdb46SRobert Mustacchi     }
918*4d9fdb46SRobert Mustacchi     sres = _dwarf_load_debug_types(dbg,error);
919*4d9fdb46SRobert Mustacchi     if (sres == DW_DLV_ERROR) {
920*4d9fdb46SRobert Mustacchi         return sres;
921*4d9fdb46SRobert Mustacchi     }
922*4d9fdb46SRobert Mustacchi     /*  Returns already existing xuhdr */
923*4d9fdb46SRobert Mustacchi     sres = _dwarf_get_xuhdr(dbg,key_type, &xuhdr,error);
924*4d9fdb46SRobert Mustacchi     if (sres != DW_DLV_OK) {
925*4d9fdb46SRobert Mustacchi         return sres;
926*4d9fdb46SRobert Mustacchi     }
927*4d9fdb46SRobert Mustacchi     /*  Search in that xu data. */
928*4d9fdb46SRobert Mustacchi     sres = _dwarf_search_fission_for_key(dbg,
929*4d9fdb46SRobert Mustacchi         xuhdr,key,&percu_index,error);
930*4d9fdb46SRobert Mustacchi     if (sres != DW_DLV_OK) {
931*4d9fdb46SRobert Mustacchi         return sres;
932*4d9fdb46SRobert Mustacchi     }
933*4d9fdb46SRobert Mustacchi     sres = transform_xu_to_dfp(xuhdr,percu_index,key,
934*4d9fdb46SRobert Mustacchi         key_type,percu_out,error);
935*4d9fdb46SRobert Mustacchi     return sres;
936*4d9fdb46SRobert Mustacchi }
937*4d9fdb46SRobert Mustacchi 
938*4d9fdb46SRobert Mustacchi void
dwarf_xu_header_free(Dwarf_Xu_Index_Header indexptr)939*4d9fdb46SRobert Mustacchi dwarf_xu_header_free(Dwarf_Xu_Index_Header indexptr)
940*4d9fdb46SRobert Mustacchi {
941*4d9fdb46SRobert Mustacchi     if(indexptr) {
942*4d9fdb46SRobert Mustacchi         Dwarf_Debug dbg = indexptr->gx_dbg;
943*4d9fdb46SRobert Mustacchi         dwarf_dealloc(dbg,indexptr,DW_DLA_XU_INDEX);
944*4d9fdb46SRobert Mustacchi     }
945*4d9fdb46SRobert Mustacchi }
946