xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_loc.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1 /*
2   Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved.
4   Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved.
5 
6   This program is free software; you can redistribute it
7   and/or modify it under the terms of version 2.1 of the
8   GNU Lesser General Public License as published by the Free
9   Software Foundation.
10 
11   This program is distributed in the hope that it would be
12   useful, but WITHOUT ANY WARRANTY; without even the implied
13   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14   PURPOSE.
15 
16   Further, this software is distributed without any warranty
17   that it is free of the rightful claim of any third person
18   regarding infringement or the like.  Any license provided
19   herein, whether implied or otherwise, applies only to this
20   software file.  Patent licenses, if any, provided herein
21   do not apply to combinations of this program with other
22   software, or any other product whatsoever.
23 
24   You should have received a copy of the GNU Lesser General
25   Public License along with this program; if not, write the
26   Free Software Foundation, Inc., 51 Franklin Street - Fifth
27   Floor, Boston MA 02110-1301, USA.
28 
29 */
30 
31 #include "config.h"
32 #include <stdio.h> /* for debugging only. */
33 #ifdef HAVE_STDINT_H
34 #include <stdint.h> /* For uintptr_t */
35 #endif /* HAVE_STDINT_H */
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h> /* For uintptr_t */
38 #endif /* HAVE_STDLIB_H */
39 #include "dwarf_incl.h"
40 #include "dwarf_alloc.h"
41 #include "dwarf_error.h"
42 #include "dwarf_util.h"
43 #include "dwarf_loc.h"
44 #include "dwarfstring.h"
45 
46 #define TRUE 1
47 #define FALSE 0
48 
49 static int _dwarf_read_loc_section_dwo(Dwarf_Debug dbg,
50    Dwarf_Block_c * return_block,
51    Dwarf_Addr * lowpc,
52    Dwarf_Addr * highpc,
53    Dwarf_Bool * at_end,
54    Dwarf_Half * lle_op,
55    Dwarf_Off    sec_offset,
56    Dwarf_Half   address_size,
57    Dwarf_Half   lkind,
58    Dwarf_Error *error);
59 
60 
61 static void
_dwarf_lkind_name(unsigned lkind,dwarfstring * m)62 _dwarf_lkind_name(unsigned lkind, dwarfstring *m)
63 {
64     switch(lkind) {
65     case DW_LKIND_expression:
66         dwarfstring_append(m,"DW_LKIND_expression");
67         return;
68     case DW_LKIND_loclist:
69         dwarfstring_append(m,"DW_LKIND_loclist");
70         return;
71     case DW_LKIND_GNU_exp_list:
72         dwarfstring_append(m,"DW_LKIND_GNU_exp_list");
73         return;
74     case DW_LKIND_loclists:
75         dwarfstring_append(m,"DW_LKIND_loclists");
76         return;
77     case DW_LKIND_unknown:
78         dwarfstring_append(m,"DW_LKIND_unknown");
79         return;
80     }
81     dwarfstring_append_printf_u(m,
82         "<DW_LKIND location kind is unknown and has value %u>.",
83         lkind);
84 }
85 
86 
87 static int
determine_location_lkind(unsigned int version,unsigned int form,UNUSEDARG unsigned int attribute,Dwarf_Bool is_dwo)88 determine_location_lkind(unsigned int version,
89     unsigned int form,
90     UNUSEDARG unsigned int attribute,
91     Dwarf_Bool is_dwo)
92 {
93     switch(form) {
94     case DW_FORM_exprloc: /* only defined for
95         DW_CFA_def_cfa_expression */
96     case DW_FORM_block:
97     case DW_FORM_block1:
98     case DW_FORM_block2:
99     case DW_FORM_block4:
100         return DW_LKIND_expression;
101         break;
102     case DW_FORM_data4:
103     case DW_FORM_data8:
104         if (version > 1 && version < 4) {
105             return DW_LKIND_loclist;
106         }
107         break;
108     case DW_FORM_sec_offset:
109         if (version == 5 ) {
110             return DW_LKIND_loclists;
111         }
112         if (version == 4 &&  is_dwo  ) {
113             return DW_LKIND_GNU_exp_list;
114         }
115         return DW_LKIND_loclist;
116         break;
117     case DW_FORM_loclistx:
118         if (version == 5 ) {
119             return DW_LKIND_loclists;
120         }
121         break;
122     default:
123         break;
124     }
125     return DW_LKIND_unknown;
126 }
127 
128 static void
_dwarf_free_op_chain(Dwarf_Debug dbg,Dwarf_Loc_Chain headloc)129 _dwarf_free_op_chain(Dwarf_Debug dbg,
130     Dwarf_Loc_Chain headloc)
131 {
132     Dwarf_Loc_Chain cur = headloc;
133 
134     while (cur) {
135         Dwarf_Loc_Chain next = cur->lc_next;
136         dwarf_dealloc(dbg, cur, DW_DLA_LOC_CHAIN);
137         cur = next;
138     }
139 }
140 /*  Given a Dwarf_Block that represents a location expression,
141     this function returns a pointer to a Dwarf_Locdesc struct
142     that has its ld_cents field set to the number of location
143     operators in the block, and its ld_s field pointing to a
144     contiguous block of Dwarf_Loc structs.  However, the
145     ld_lopc and ld_hipc values are uninitialized.  Returns
146     DW_DLV_ERROR on error.
147 
148     Created for DWARF2 this really does not work well
149     as later DWARF needs the newer interface.
150     You want Dwarf_Locdesc_c opaque struct, not what this
151     function provides.
152 
153     This function assumes that the length of
154     the block is greater than 0.  Zero length location expressions
155     to represent variables that have been optimized away are
156     handled in the calling function.
157 
158     address_size, offset_size, and version_stamp are
159     per-CU, not per-object or per dbg.
160     We cannot use dbg directly to get those values.
161 
162     Use for DWARF 2,3,4 only to avoid updating to
163     later interfaces. Not for experimental
164     dwarf4 dwo either.
165     Better to switch to a newer interface.
166 */
167 static int
_dwarf_get_locdesc(Dwarf_Debug dbg,Dwarf_Block_c * loc_block,Dwarf_Half address_size,Dwarf_Half offset_size,Dwarf_Small version_stamp,Dwarf_Addr lowpc,Dwarf_Addr highpc,Dwarf_Small * section_end,Dwarf_Locdesc ** locdesc_out,Dwarf_Error * error)168 _dwarf_get_locdesc(Dwarf_Debug dbg,
169     Dwarf_Block_c * loc_block,
170     Dwarf_Half address_size,
171     Dwarf_Half offset_size,
172     Dwarf_Small version_stamp,
173     Dwarf_Addr lowpc,
174     Dwarf_Addr highpc,
175     Dwarf_Small * section_end,
176     Dwarf_Locdesc ** locdesc_out,
177     Dwarf_Error * error)
178 {
179     /* Offset of current operator from start of block. */
180     Dwarf_Unsigned offset = 0;
181 
182     /* Used to chain the Dwarf_Loc_Chain_s structs. */
183     Dwarf_Loc_Chain new_loc = NULL;
184     Dwarf_Loc_Chain prev_loc = NULL;
185     Dwarf_Loc_Chain head_loc = NULL;
186     /* Count of the number of location operators. */
187     Dwarf_Unsigned op_count = 0;
188 
189     /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */
190     Dwarf_Loc *block_loc = 0;
191 
192     /* Dwarf_Locdesc pointer to be returned. */
193     Dwarf_Locdesc *locdesc = 0;
194 
195     Dwarf_Unsigned i = 0;
196     int res = 0;
197 
198     /* ***** BEGIN CODE ***** */
199 
200     offset = 0;
201     op_count = 0;
202 
203 
204     res = _dwarf_loc_block_sanity_check(dbg,loc_block,error);
205     if (res != DW_DLV_OK) {
206         return res;
207     }
208 
209     /* OLD loop getting Loc operators. No DWARF5 */
210     while (offset <= loc_block->bl_len) {
211         Dwarf_Unsigned nextoffset = 0;
212         struct Dwarf_Loc_Expr_Op_s temp_loc;
213 
214         res = _dwarf_read_loc_expr_op(dbg,loc_block,
215             op_count,
216             version_stamp,
217             offset_size,
218             address_size,
219             offset,
220             section_end,
221             &nextoffset,
222             &temp_loc,
223             error);
224         if (res == DW_DLV_ERROR) {
225             _dwarf_free_op_chain(dbg, head_loc);
226             return res;
227         }
228         if (res == DW_DLV_NO_ENTRY) {
229             /* Normal end. */
230             break;
231         }
232         op_count++;
233         new_loc =
234             (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg,
235             DW_DLA_LOC_CHAIN, 1);
236         if (new_loc == NULL) {
237             dwarfstring m;
238 
239             _dwarf_free_op_chain(dbg, head_loc);
240             dwarfstring_constructor(&m);
241             dwarfstring_append_printf_u(&m,
242                 " DW_DLE_ALLOC_FAIL: out of memory"
243                 "  allocating location"
244                 " expression operator chain entry %u.",
245                 op_count);
246             _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
247                 dwarfstring_string(&m));
248             dwarfstring_destructor(&m);
249             return DW_DLV_ERROR;
250         }
251 
252         /* Copying only the fields needed by DWARF 2,3,4 */
253         new_loc->lc_atom    = temp_loc.lr_atom;
254         new_loc->lc_opnumber= temp_loc.lr_opnumber;
255         new_loc->lc_number  = temp_loc.lr_number;
256         new_loc->lc_number2 = temp_loc.lr_number2;
257         new_loc->lc_number3 = temp_loc.lr_number3;
258         new_loc->lc_raw1  = temp_loc.lr_raw1;
259         new_loc->lc_raw2  = temp_loc.lr_raw2;
260         new_loc->lc_raw3  = temp_loc.lr_raw3;
261         new_loc->lc_offset  = temp_loc.lr_offset;
262         offset = nextoffset;
263 
264         if (head_loc == NULL)
265             head_loc = prev_loc = new_loc;
266         else {
267             prev_loc->lc_next = new_loc;
268             prev_loc = new_loc;
269         }
270     }
271 
272     block_loc =
273         (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK,
274         op_count);
275     if (block_loc == NULL) {
276         _dwarf_free_op_chain(dbg, head_loc);
277         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
278         return DW_DLV_ERROR;
279     }
280 
281     new_loc = head_loc;
282     for (i = 0; i < op_count; i++) {
283         /*  Copying only the fields needed by DWARF 2,3,4
284             the struct is public and must never be changed. */
285         (block_loc + i)->lr_atom = new_loc->lc_atom;
286         (block_loc + i)->lr_number = new_loc->lc_number;
287         (block_loc + i)->lr_number2 = new_loc->lc_number2;
288         (block_loc + i)->lr_offset = new_loc->lc_offset;
289         prev_loc = new_loc;
290         new_loc = prev_loc->lc_next;
291         dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
292     }
293 
294     locdesc =
295         (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
296     if (locdesc == NULL) {
297         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
298         return DW_DLV_ERROR;
299     }
300 
301     locdesc->ld_cents = op_count;
302     locdesc->ld_s = block_loc;
303     locdesc->ld_section_offset = loc_block->bl_section_offset;
304     locdesc->ld_lopc = lowpc;
305     locdesc->ld_hipc = highpc;
306     locdesc->ld_from_loclist = 1;
307     *locdesc_out = locdesc;
308     return DW_DLV_OK;
309 }
310 
311 /*  Using a loclist offset to get the in-memory
312     address of .debug_loc data to read, returns the loclist
313     'header' info in return_block.
314 */
315 
316 #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
317 
318 
319 static int
_dwarf_read_loc_section(Dwarf_Debug dbg,Dwarf_Block_c * return_block,Dwarf_Addr * lowpc,Dwarf_Addr * hipc,Dwarf_Half * lle_val,Dwarf_Off sec_offset,Dwarf_Half address_size,UNUSEDARG unsigned lkind,Dwarf_Error * error)320 _dwarf_read_loc_section(Dwarf_Debug dbg,
321     Dwarf_Block_c * return_block,
322     Dwarf_Addr    * lowpc,
323     Dwarf_Addr    * hipc,
324     Dwarf_Half    * lle_val,
325     Dwarf_Off       sec_offset,
326     Dwarf_Half      address_size,
327     UNUSEDARG unsigned   lkind,
328     Dwarf_Error   * error)
329 {
330     Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset;
331     Dwarf_Small *loc_section_end =
332         dbg->de_debug_loc.dss_data + dbg->de_debug_loc.dss_size;
333 
334     /*  start_addr and end_addr are actually offsets
335         of the applicable base address of the CU.
336         They are address-size. */
337     Dwarf_Addr start_addr = 0;
338     Dwarf_Addr end_addr = 0;
339     Dwarf_Half exprblock_size = 0;
340     Dwarf_Unsigned exprblock_off =
341         2 * address_size + DWARF_HALF_SIZE;
342 
343     if (sec_offset >= dbg->de_debug_loc.dss_size) {
344         /* We're at the end. No more present. */
345         return DW_DLV_NO_ENTRY;
346     }
347 
348     /* If it goes past end, error */
349     if (exprblock_off > dbg->de_debug_loc.dss_size) {
350         _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
351         return DW_DLV_ERROR;
352     }
353 
354 
355     READ_UNALIGNED_CK(dbg, start_addr, Dwarf_Addr, beg, address_size,
356         error,loc_section_end);
357     READ_UNALIGNED_CK(dbg, end_addr, Dwarf_Addr,
358         beg + address_size, address_size,
359         error,loc_section_end);
360     if (start_addr == 0 && end_addr == 0) {
361         /*  If start_addr and end_addr are 0, it's the end and no
362             exprblock_size field follows. */
363         exprblock_size = 0;
364         exprblock_off -= DWARF_HALF_SIZE;
365         *lle_val = DW_LLE_end_of_list;
366     } else if (start_addr == MAX_ADDR) {
367         /*  End address is a base address, no exprblock_size field here
368             either */
369         exprblock_size = 0;
370         exprblock_off -=  DWARF_HALF_SIZE;
371         *lle_val = DW_LLE_base_address;
372     } else {
373         /*  Here we note the address and length of the
374             expression operators, DW_OP_reg0 etc */
375         READ_UNALIGNED_CK(dbg, exprblock_size, Dwarf_Half,
376             beg + 2 * address_size, DWARF_HALF_SIZE,
377             error,loc_section_end);
378         /* exprblock_size can be zero, means no expression */
379         if ( exprblock_size >= dbg->de_debug_loc.dss_size) {
380             _dwarf_error(dbg, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
381             return DW_DLV_ERROR;
382         }
383         if ((sec_offset +exprblock_off + exprblock_size) >
384             dbg->de_debug_loc.dss_size) {
385             _dwarf_error(dbg, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
386             return DW_DLV_ERROR;
387         }
388         *lle_val = DW_LLE_start_end;
389     }
390     *lowpc = start_addr;
391     *hipc = end_addr;
392 
393     return_block->bl_len = exprblock_size;
394     return_block->bl_kind = DW_LKIND_loclist;
395     return_block->bl_data = beg + exprblock_off;
396     return_block->bl_section_offset =
397         ((Dwarf_Small *) return_block->bl_data) -
398         dbg->de_debug_loc.dss_data;
399     return DW_DLV_OK;
400 }
401 
402 static int
_dwarf_get_loclist_lle_count_dwo(Dwarf_Debug dbg,Dwarf_Off loclist_offset,Dwarf_Half address_size,unsigned lkind,int * loclist_count,Dwarf_Error * error)403 _dwarf_get_loclist_lle_count_dwo(Dwarf_Debug dbg,
404     Dwarf_Off loclist_offset,
405     Dwarf_Half address_size,
406     unsigned lkind,
407     int *loclist_count,
408     Dwarf_Error * error)
409 {
410     int count = 0;
411     Dwarf_Off offset = loclist_offset;
412 
413     for (;;) {
414         Dwarf_Block_c b;
415         Dwarf_Bool at_end = FALSE;
416         Dwarf_Addr lowpc = 0;
417         Dwarf_Addr highpc = 0;
418         Dwarf_Half lle_op = 0;
419         int res = _dwarf_read_loc_section_dwo(dbg, &b,
420             &lowpc,
421             &highpc,
422             &at_end,
423             &lle_op,
424             offset,
425             address_size,
426             lkind,
427             error);
428         if (res != DW_DLV_OK) {
429             return res;
430         }
431         if (at_end) {
432             count++;
433             break;
434         }
435         offset = b.bl_len + b.bl_section_offset;
436         count++;
437     }
438     *loclist_count = count;
439     return DW_DLV_OK;
440 }
441 
442 static int
_dwarf_get_loclist_lle_count(Dwarf_Debug dbg,Dwarf_Off loclist_offset,Dwarf_Half address_size,unsigned lkind,int * loclist_count,Dwarf_Error * error)443 _dwarf_get_loclist_lle_count(Dwarf_Debug dbg,
444     Dwarf_Off loclist_offset,
445     Dwarf_Half address_size,
446     unsigned lkind,
447     int *loclist_count,
448     Dwarf_Error * error)
449 {
450     int count = 0;
451     Dwarf_Off offset = loclist_offset;
452 
453 
454     for (;;) {
455         Dwarf_Block_c b;
456         Dwarf_Addr lowpc = 0;
457         Dwarf_Addr highpc = 0;
458         Dwarf_Half lle_val = 0;
459 
460         int res = _dwarf_read_loc_section(dbg, &b,
461             &lowpc, &highpc,
462             &lle_val,
463             offset, address_size,lkind,error);
464         if (res != DW_DLV_OK) {
465             return res;
466         }
467         offset = b.bl_len + b.bl_section_offset;
468         if (lowpc == 0 && highpc == 0) {
469             break;
470         }
471         count++;
472     }
473     *loclist_count = count;
474     return DW_DLV_OK;
475 }
476 
477 /* Helper routine to avoid code duplication.
478 */
479 static int
_dwarf_setup_loc(Dwarf_Attribute attr,Dwarf_Debug * dbg_ret,Dwarf_CU_Context * cucontext_ret,Dwarf_Half * form_ret,Dwarf_Error * error)480 _dwarf_setup_loc(Dwarf_Attribute attr,
481     Dwarf_Debug *     dbg_ret,
482     Dwarf_CU_Context *cucontext_ret,
483     Dwarf_Half       *form_ret,
484     Dwarf_Error      *error)
485 {
486     Dwarf_Debug dbg = 0;
487     Dwarf_Half form = 0;
488     int blkres = DW_DLV_ERROR;
489 
490     if (!attr) {
491         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
492         return (DW_DLV_ERROR);
493     }
494     if (attr->ar_cu_context == NULL) {
495         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
496         return (DW_DLV_ERROR);
497     }
498     *cucontext_ret = attr->ar_cu_context;
499 
500     dbg = attr->ar_cu_context->cc_dbg;
501     if (dbg == NULL) {
502         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
503         return (DW_DLV_ERROR);
504     }
505     *dbg_ret = dbg;
506     blkres = dwarf_whatform(attr, &form, error);
507     if (blkres != DW_DLV_OK) {
508         _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
509         return blkres;
510     }
511     *form_ret = form;
512     return DW_DLV_OK;
513 }
514 
515 /* Helper routine  to avoid code duplication.
516 */
517 static int
_dwarf_get_loclist_header_start(Dwarf_Debug dbg,Dwarf_Attribute attr,Dwarf_Unsigned * loclist_offset_out,Dwarf_Error * error)518 _dwarf_get_loclist_header_start(Dwarf_Debug dbg,
519     Dwarf_Attribute attr,
520     Dwarf_Unsigned * loclist_offset_out,
521     Dwarf_Error * error)
522 {
523     Dwarf_Unsigned loc_sec_size = 0;
524     Dwarf_Unsigned loclist_offset = 0;
525 
526     int blkres = dwarf_global_formref(attr, &loclist_offset, error);
527     if (blkres != DW_DLV_OK) {
528         return blkres;
529     }
530     if (!dbg->de_debug_loc.dss_data) {
531         int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
532         if (secload != DW_DLV_OK) {
533             return secload;
534         }
535         if (!dbg->de_debug_loc.dss_size) {
536             return (DW_DLV_NO_ENTRY);
537         }
538     }
539     loc_sec_size = dbg->de_debug_loc.dss_size;
540     if (loclist_offset >= loc_sec_size) {
541         _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD);
542         return DW_DLV_ERROR;
543     }
544 
545     {
546         int fisres = 0;
547         Dwarf_Unsigned fissoff = 0;
548         Dwarf_Unsigned size = 0;
549         fisres = _dwarf_get_fission_addition_die(attr->ar_die,
550             DW_SECT_LOCLISTS,
551             &fissoff, &size,error);
552         if(fisres != DW_DLV_OK) {
553             return fisres;
554         }
555         if (fissoff >= loc_sec_size) {
556             _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD);
557             return DW_DLV_ERROR;
558         }
559         loclist_offset += fissoff;
560         if  (loclist_offset >= loc_sec_size) {
561             _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD);
562             return DW_DLV_ERROR;
563         }
564     }
565     *loclist_offset_out = loclist_offset;
566     return DW_DLV_OK;
567 }
568 
569 /* When llbuf (see dwarf_loclist_n) is partially set up
570    and an error is encountered, tear it down as it
571    won't be used.
572 */
573 static void
_dwarf_cleanup_llbuf(Dwarf_Debug dbg,Dwarf_Locdesc ** llbuf,int count)574 _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count)
575 {
576     int i;
577     for (i = 0; i < count; ++i) {
578         dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
579         dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
580     }
581     dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
582 }
583 
584 static int
context_is_cu_not_tu(Dwarf_CU_Context context,Dwarf_Bool * r)585 context_is_cu_not_tu(Dwarf_CU_Context context,
586     Dwarf_Bool *r)
587 {
588     int ut = context->cc_unit_type;
589 
590     if (ut == DW_UT_type || ut == DW_UT_split_type ) {
591         *r =FALSE;
592         return DW_DLV_OK;
593     }
594     *r = TRUE;
595     return DW_DLV_OK;
596 }
597 
598 /*  Handles simple location entries and loclists.
599     Returns all the Locdesc's thru llbuf.
600 
601     Will not work properly for DWARF5 and may not
602     work for some recent versions of gcc or llvm emitting
603     DWARF4 with location extensions.
604 
605     Does not work for .debug_loc.dwo
606 */
607 int
dwarf_loclist_n(Dwarf_Attribute attr,Dwarf_Locdesc *** llbuf_out,Dwarf_Signed * listlen_out,Dwarf_Error * error)608 dwarf_loclist_n(Dwarf_Attribute attr,
609     Dwarf_Locdesc *** llbuf_out,
610     Dwarf_Signed * listlen_out, Dwarf_Error * error)
611 {
612     Dwarf_Debug dbg = 0;
613 
614     /*  Dwarf_Attribute that describes the DW_AT_location in die, if
615         present. */
616     Dwarf_Attribute loc_attr = attr;
617 
618     /* Dwarf_Block that describes a single location expression. */
619     Dwarf_Block_c loc_block;
620 
621     /* A pointer to the current Dwarf_Locdesc read. */
622     Dwarf_Locdesc *locdesc = 0;
623 
624     Dwarf_Half form = 0;
625     Dwarf_Addr lowpc = 0;
626     Dwarf_Addr highpc = 0;
627     Dwarf_Signed listlen = 0;
628     Dwarf_Locdesc **llbuf = 0;
629     Dwarf_CU_Context cucontext = 0;
630     unsigned address_size = 0;
631     int cuvstamp = 0;
632     Dwarf_Bool is_cu = FALSE;
633     Dwarf_Half attrnum = 0;
634     int is_dwo = FALSE;
635     unsigned lkind = 0;
636 
637     int blkres = DW_DLV_ERROR;
638     int setup_res = DW_DLV_ERROR;
639     Dwarf_Small * info_section_end = 0;
640 
641     /* ***** BEGIN CODE ***** */
642     setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
643     if (setup_res != DW_DLV_OK) {
644         return setup_res;
645     }
646     info_section_end = _dwarf_calculate_info_section_end_ptr(cucontext);
647     cuvstamp = cucontext->cc_version_stamp;
648     address_size = cucontext->cc_address_size;
649     /*  If this is a form_block then it's a location expression. If it's
650         DW_FORM_data4 or DW_FORM_data8  in DWARF2 or DWARF3
651         (or in DWARF4 or 5 a DW_FORM_sec_offset) it's a loclist offset */
652     if (cuvstamp == DW_CU_VERSION5) {
653         /* Use a newer interface. */
654         _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR);
655         return (DW_DLV_ERROR);
656     }
657     attrnum = attr->ar_attribute;
658     lkind =  determine_location_lkind(cuvstamp,form, attrnum, is_dwo);
659     if (lkind == DW_LKIND_unknown ||
660         lkind == DW_LKIND_GNU_exp_list ||
661         lkind == DW_LKIND_loclists ) {
662         /*  We cannot handle this here. */
663         _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR);
664         return (DW_DLV_ERROR);
665     }
666 
667     if (lkind == DW_LKIND_loclist ) {
668         /*  A reference to .debug_loc, with an offset in .debug_loc of a
669             loclist */
670         Dwarf_Small *loc_section_end = 0;
671         Dwarf_Unsigned loclist_offset = 0;
672         int off_res  = DW_DLV_ERROR;
673         int count_res = DW_DLV_ERROR;
674         int loclist_count = 0;
675         int lli = 0;
676 
677         setup_res = context_is_cu_not_tu(cucontext,&is_cu);
678         if(setup_res != DW_DLV_OK) {
679             return setup_res;
680         }
681 
682         off_res = _dwarf_get_loclist_header_start(dbg,
683             attr, &loclist_offset, error);
684         if (off_res != DW_DLV_OK) {
685             return off_res;
686         }
687         count_res = _dwarf_get_loclist_lle_count(dbg, loclist_offset,
688             address_size,lkind, &loclist_count, error);
689         listlen = loclist_count;
690         if (count_res != DW_DLV_OK) {
691             return count_res;
692         }
693         if (loclist_count == 0) {
694             return DW_DLV_NO_ENTRY;
695         }
696 
697         llbuf = (Dwarf_Locdesc **)
698             _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
699         if (!llbuf) {
700             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
701             return (DW_DLV_ERROR);
702         }
703 
704         for (lli = 0; lli < loclist_count; ++lli) {
705             int lres = 0;
706             Dwarf_Half ll_op = 0;
707 
708             blkres = _dwarf_read_loc_section(dbg,
709                 &loc_block,
710                 &lowpc,
711                 &highpc,
712                 &ll_op,
713                 loclist_offset,
714                 address_size,lkind,
715                 error);
716             if (blkres != DW_DLV_OK) {
717                 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
718                 return (blkres);
719             }
720             loc_section_end = dbg->de_debug_loc.dss_data+
721                 dbg->de_debug_loc.dss_size;
722             lres = _dwarf_get_locdesc(dbg,
723                 &loc_block,
724                 address_size,
725                 cucontext->cc_length_size,
726                 cucontext->cc_version_stamp,
727                 lowpc, highpc,
728                 loc_section_end,
729                 &locdesc,
730                 error);
731             if (lres != DW_DLV_OK) {
732                 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
733                 /* low level error already set: let it be passed back */
734                 return lres;
735             }
736             llbuf[lli] = locdesc;
737 
738             /* Now get to next loclist entry offset. */
739             loclist_offset = loc_block.bl_section_offset +
740                 loc_block.bl_len;
741         }
742     } else { /* DW_LKIND_expression */
743         if( form == DW_FORM_exprloc) {
744             blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len,
745                 &loc_block.bl_data,error);
746             if(blkres != DW_DLV_OK) {
747                 return blkres;
748             }
749             loc_block.bl_kind = lkind;
750             loc_block.bl_section_offset  =
751                 (char *)loc_block.bl_data -
752                 (char *)dbg->de_debug_info.dss_data;
753         } else {
754             Dwarf_Block *tblock = 0;
755             blkres = dwarf_formblock(loc_attr, &tblock, error);
756             if (blkres != DW_DLV_OK) {
757                 return (blkres);
758             }
759             loc_block.bl_len = tblock->bl_len;
760             loc_block.bl_data = tblock->bl_data;
761             loc_block.bl_kind = lkind;
762             loc_block.bl_section_offset = tblock->bl_section_offset;
763             loc_block.bl_locdesc_offset = 0; /* not relevent */
764             /*  We copied tblock contents to the stack var,
765                 so can dealloc
766                 tblock now.  Avoids leaks. */
767             dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
768         }
769         listlen = 1; /* One by definition of a location entry. */
770         lowpc = 0;   /* HACK, but with bl_kind we do not need */
771         highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
772 
773         /*  An empty location description (block length 0) means the
774             code generator emitted no variable, the variable was not
775             generated, it was unused or perhaps never tested
776             after being set.
777             Dwarf2, section 2.4.1 In other words, it is not an
778             error, and we don't test for block length 0
779             specially here. */
780         blkres = _dwarf_get_locdesc(dbg, &loc_block,
781             address_size,
782             cucontext->cc_length_size,
783             cucontext->cc_version_stamp,
784             lowpc, highpc,
785             info_section_end,
786             &locdesc,
787             error);
788         if (blkres != DW_DLV_OK) {
789             /* low level error already set: let it be passed back */
790             return blkres;
791         }
792         llbuf = (Dwarf_Locdesc **)
793             _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
794         if (!llbuf) {
795             /* Free the locdesc we allocated but won't use. */
796             dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
797             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
798             return (DW_DLV_ERROR);
799         }
800         llbuf[0] = locdesc;
801     }
802 
803     *llbuf_out = llbuf;
804     *listlen_out = listlen;
805     return (DW_DLV_OK);
806 }
807 
808 /*  Handles only a location expression.
809     If called on a loclist, just returns one of those.
810     Cannot not handle a real loclist.
811     It returns the location expression as a loclist with
812     a single entry.
813     See dwarf_loclist_n() which handles any number
814     of location list entries.
815 
816     This is the original definition, and it simply
817     does not work for loclists.
818     Nor does it work on DWARF4 nor on some
819     versions of gcc generating DWARF4.
820     Kept for compatibility.
821 */
822 int
dwarf_loclist(Dwarf_Attribute attr,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)823 dwarf_loclist(Dwarf_Attribute attr,
824     Dwarf_Locdesc ** llbuf,
825     Dwarf_Signed * listlen, Dwarf_Error * error)
826 {
827     Dwarf_Debug dbg = 0;
828 
829     /*  Dwarf_Attribute that describes the DW_AT_location in die, if
830         present. */
831     Dwarf_Attribute loc_attr = attr;
832 
833     /*  Dwarf_Block that describes a single location expression. */
834     Dwarf_Block_c loc_block;
835 
836     /*  A pointer to the current Dwarf_Locdesc read. */
837     Dwarf_Locdesc *locdesc = 0;
838     int is_dwo             = FALSE;
839     Dwarf_Small *info_section_end = 0;
840     Dwarf_Half form        = 0;
841     Dwarf_Addr lowpc       = 0;
842     Dwarf_Addr highpc      = 0;
843     Dwarf_CU_Context cucontext = 0;
844     unsigned address_size  = 0;
845     unsigned lkind         = 0;
846     int blkres             = DW_DLV_ERROR;
847     int setup_res          = DW_DLV_ERROR;
848     int cuvstamp           = 0;
849     unsigned attrnum       = 0;
850 
851     /* ***** BEGIN CODE ***** */
852     setup_res = _dwarf_setup_loc(attr, &dbg, &cucontext, &form, error);
853     if (setup_res != DW_DLV_OK) {
854         return setup_res;
855     }
856     info_section_end = _dwarf_calculate_info_section_end_ptr(cucontext);
857     memset(&loc_block,0,sizeof(loc_block));
858     cuvstamp = cucontext->cc_version_stamp;
859     address_size = cucontext->cc_address_size;
860     attrnum = attr->ar_attribute;
861     lkind =  determine_location_lkind(cuvstamp,form, attrnum, is_dwo);
862     if (lkind == DW_LKIND_unknown ||
863         lkind == DW_LKIND_GNU_exp_list ||
864         lkind == DW_LKIND_loclists ) {
865         /*  We cannot handle this here. */
866         _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR);
867         return (DW_DLV_ERROR);
868     }
869 
870     /*  If this is a form_block then it's a location expression. If it's
871         DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
872     if (lkind == DW_LKIND_loclist) {
873         /*  A reference to .debug_loc, with an offset in .debug_loc of a
874             loclist. */
875         Dwarf_Unsigned loclist_offset = 0;
876         int off_res = DW_DLV_ERROR;
877         Dwarf_Half  ll_op = 0;
878 
879         off_res = _dwarf_get_loclist_header_start(dbg,
880             attr, &loclist_offset,
881             error);
882         if (off_res != DW_DLV_OK) {
883             return off_res;
884         }
885 
886         /* With dwarf_loclist, just read a single entry */
887         blkres = _dwarf_read_loc_section(dbg, &loc_block,
888             &lowpc,
889             &highpc,
890             &ll_op,
891             loclist_offset,
892             address_size,
893             lkind,
894             error);
895         if (blkres != DW_DLV_OK) {
896             return (blkres);
897         }
898     } else { /* DW_LKIND_expression */
899         if( form == DW_FORM_exprloc) {
900             blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len,
901                 &loc_block.bl_data,error);
902             if(blkres != DW_DLV_OK) {
903                 return blkres;
904             }
905             loc_block.bl_kind = lkind;
906             loc_block.bl_section_offset  =
907                 (char *)loc_block.bl_data -
908                 (char *)dbg->de_debug_info.dss_data;
909         } else {
910             Dwarf_Block *tblock = 0;
911 
912             /* If DWARF5 this will surely fail, get an error. */
913             blkres = dwarf_formblock(loc_attr, &tblock, error);
914             if (blkres != DW_DLV_OK) {
915                 return (blkres);
916             }
917             loc_block.bl_len = tblock->bl_len;
918             loc_block.bl_data = tblock->bl_data;
919             loc_block.bl_kind = tblock->bl_from_loclist;
920             /* ASSERT: lkind == loc_block.bl_kind  */
921             loc_block.bl_section_offset = tblock->bl_section_offset;
922             /*  We copied tblock contents to the stack
923                 var, so can dealloc tblock now.
924                 Avoids leaks. */
925             dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
926         }
927         /*  Because we set bl_kind we don't really
928             need this hack any more */
929         lowpc = 0;              /* HACK */
930         highpc = (Dwarf_Unsigned) (-1LL);       /* HACK */
931     }
932 
933     /*  An empty location description (block length 0) means
934         the code
935         generator emitted no variable, the variable was not
936         generated, it was unused or perhaps never tested after
937         being set. Dwarf2, section 2.4.1 In other words,
938         it is not an error, and we don't test for block
939         length 0 specially here.  See *dwarf_loclist_n()
940         which handles the general case, this case handles
941         only a single location expression.  */
942     blkres = _dwarf_get_locdesc(dbg, &loc_block,
943         address_size, cucontext->cc_length_size,
944         cucontext->cc_version_stamp, lowpc, highpc,
945         info_section_end, &locdesc, error);
946     if (blkres != DW_DLV_OK) {
947         /* low level error already set: let it be passed back
948         */ return blkres;
949     }
950 
951     *llbuf = locdesc;
952     *listlen = 1;
953     return (DW_DLV_OK);
954 }
955 
956 
957 
958 /*  Handles only a location expression.
959     It returns the location expression as a loclist with
960     a single entry.
961 
962     Usable to access dwarf expressions from any source, but
963     specifically from
964         DW_CFA_def_cfa_expression
965         DW_CFA_expression
966         DW_CFA_val_expression
967 
968     expression_in must point to a valid dwarf expression
969     set of bytes of length expression_length. Not
970     a DW_FORM_block*, just the expression bytes.
971 
972     If the address_size != de_pointer_size this will not work
973     right.
974     See dwarf_loclist_from_expr_b() for a better interface.
975 */
976 int
dwarf_loclist_from_expr(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)977 dwarf_loclist_from_expr(Dwarf_Debug dbg,
978     Dwarf_Ptr expression_in,
979     Dwarf_Unsigned expression_length,
980     Dwarf_Locdesc ** llbuf,
981     Dwarf_Signed * listlen, Dwarf_Error * error)
982 {
983     int res = 0;
984     Dwarf_Half addr_size =  dbg->de_pointer_size;
985     res = dwarf_loclist_from_expr_a(dbg,expression_in,
986         expression_length, addr_size,llbuf,listlen,error);
987     return res;
988 }
989 
990 /*  New April 27 2009. Adding addr_size argument for the rare
991     cases where an object has CUs with a different address_size.
992 
993     As of 2012 we have yet another version, dwarf_loclist_from_expr_b()
994     with the version_stamp and offset size (length size) passed in.
995 */
996 int
dwarf_loclist_from_expr_a(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Half addr_size,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)997 dwarf_loclist_from_expr_a(Dwarf_Debug dbg,
998     Dwarf_Ptr expression_in,
999     Dwarf_Unsigned expression_length,
1000     Dwarf_Half addr_size,
1001     Dwarf_Locdesc ** llbuf,
1002     Dwarf_Signed * listlen,
1003     Dwarf_Error * error)
1004 {
1005     int res;
1006     Dwarf_Debug_InfoTypes info_reading = &dbg->de_info_reading;
1007     Dwarf_CU_Context current_cu_context =
1008         info_reading->de_cu_context;
1009     Dwarf_Small version_stamp =  DW_CU_VERSION2;
1010     Dwarf_Half offset_size = dbg->de_length_size;
1011 
1012     if (current_cu_context) {
1013         /*  This is ugly. It is not necessarily right. Due to
1014             oddity in DW_OP_GNU_implicit_pointer, see its
1015             implementation above.
1016             For correctness, use dwarf_loclist_from_expr_b()
1017             instead of dwarf_loclist_from_expr_a(). */
1018         version_stamp = current_cu_context->cc_version_stamp;
1019         offset_size = current_cu_context->cc_length_size;
1020         if (version_stamp < 2) {
1021             /* This is probably totally silly.  */
1022             version_stamp = DW_CU_VERSION2;
1023         }
1024     }
1025     res = dwarf_loclist_from_expr_b(dbg,
1026         expression_in,
1027         expression_length,
1028         addr_size,
1029         offset_size,
1030         version_stamp, /* CU context DWARF version */
1031         llbuf,
1032         listlen,
1033         error);
1034     return res;
1035 }
1036 /*  New November 13 2012. Adding
1037     DWARF version number argument.
1038 */
1039 int
dwarf_loclist_from_expr_b(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Half addr_size,Dwarf_Half offset_size,Dwarf_Small dwarf_version,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)1040 dwarf_loclist_from_expr_b(Dwarf_Debug dbg,
1041     Dwarf_Ptr expression_in,
1042     Dwarf_Unsigned expression_length,
1043     Dwarf_Half addr_size,
1044     Dwarf_Half offset_size,
1045     Dwarf_Small dwarf_version,
1046     Dwarf_Locdesc ** llbuf,
1047     Dwarf_Signed * listlen,
1048     Dwarf_Error * error)
1049 {
1050     /* Dwarf_Block that describes a single location expression. */
1051     Dwarf_Block_c loc_block;
1052 
1053     /* A pointer to the current Dwarf_Locdesc read. */
1054     Dwarf_Locdesc *locdesc = 0;
1055     Dwarf_Addr lowpc = 0;
1056     Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL);
1057     Dwarf_Small version_stamp = dwarf_version;
1058     int res = 0;
1059     /* We do not know what the end is in this interface. */
1060     Dwarf_Small *section_start = 0;
1061     Dwarf_Unsigned section_size = 0;
1062     Dwarf_Small *section_end = 0;
1063     const char *section_name = 0;
1064 
1065     res = _dwarf_what_section_are_we(dbg,
1066         expression_in,&section_name,&section_start,
1067         &section_size,&section_end,error);
1068     if (res != DW_DLV_OK) {
1069         _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN);
1070         return DW_DLV_ERROR;
1071     }
1072 
1073     memset(&loc_block,0,sizeof(loc_block));
1074     loc_block.bl_len = expression_length;
1075     loc_block.bl_data = expression_in;
1076     loc_block.bl_kind = DW_LKIND_expression;
1077     loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
1078 
1079     /* An empty location description (block length 0) means the code
1080     generator emitted no variable, the variable was not generated,
1081     it was unused or perhaps never tested after being set. Dwarf2,
1082     section 2.4.1 In other words, it is not an error, and we don't
1083     test for block length 0 specially here.  */
1084     /* We need the DWARF version to get a locdesc! */
1085     res = _dwarf_get_locdesc(dbg, &loc_block,
1086         addr_size,
1087         offset_size,
1088         version_stamp,
1089         lowpc, highpc,
1090         section_end,
1091         &locdesc,
1092         error);
1093     if (res != DW_DLV_OK) {
1094         /* low level error already set: let it be passed back */
1095         return res;
1096     }
1097 
1098     *llbuf = locdesc;
1099     *listlen = 1;
1100     return DW_DLV_OK;
1101 }
1102 
1103 /* Usable to read a single loclist or to read a block of them
1104    or to read an entire section's loclists.
1105 
1106    It's BROKEN because it's not safe to read a loclist entry
1107    when we do not know the address size (in any object where
1108    address size can vary by compilation unit).
1109 
1110    It also does not recognize split dwarf or DWARF4
1111    or DWARF5 adequately.
1112 
1113    Use get_locdesc_entry_c() instead.
1114 */
1115 /*ARGSUSED*/ int
dwarf_get_loclist_entry(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Addr * hipc_offset,Dwarf_Addr * lopc_offset,Dwarf_Ptr * data,Dwarf_Unsigned * entry_len,Dwarf_Unsigned * next_entry,Dwarf_Error * error)1116 dwarf_get_loclist_entry(Dwarf_Debug dbg,
1117     Dwarf_Unsigned offset,
1118     Dwarf_Addr * hipc_offset,
1119     Dwarf_Addr * lopc_offset,
1120     Dwarf_Ptr * data,
1121     Dwarf_Unsigned * entry_len,
1122     Dwarf_Unsigned * next_entry,
1123     Dwarf_Error * error)
1124 {
1125     Dwarf_Block_c b;
1126     Dwarf_Addr lowpc = 0;
1127     Dwarf_Addr highpc = 0;
1128     Dwarf_Half address_size = 0;
1129     int res = DW_DLV_ERROR;
1130     Dwarf_Half ll_op = 0;
1131 
1132     if (!dbg->de_debug_loc.dss_data) {
1133         int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
1134         if (secload != DW_DLV_OK) {
1135             return secload;
1136         }
1137     }
1138 
1139     /*  FIXME: DO NOT USE the call. address_size is not necessarily
1140         the same in every frame. */
1141     address_size = dbg->de_pointer_size;
1142     res = _dwarf_read_loc_section(dbg,
1143         &b, &lowpc, &highpc,
1144         &ll_op,offset,
1145         address_size,DW_LKIND_loclist,error);
1146     if (res != DW_DLV_OK) {
1147         return res;
1148     }
1149     *hipc_offset = highpc;
1150     *lopc_offset = lowpc;
1151     *entry_len = b.bl_len;
1152     *data = b.bl_data;
1153     *next_entry = b.bl_len + b.bl_section_offset;
1154     return DW_DLV_OK;
1155 }
1156 
1157 /* ============== the October 2015 interfaces. */
1158 int
_dwarf_loc_block_sanity_check(Dwarf_Debug dbg,Dwarf_Block_c * loc_block,Dwarf_Error * error)1159 _dwarf_loc_block_sanity_check(Dwarf_Debug dbg,
1160     Dwarf_Block_c *loc_block,Dwarf_Error* error)
1161 {
1162     unsigned lkind = loc_block->bl_kind;
1163     if (lkind == DW_LKIND_loclist) {
1164         Dwarf_Small *loc_ptr = 0;
1165         Dwarf_Unsigned loc_len = 0;
1166         Dwarf_Small *end_ptr = 0;
1167 
1168         loc_ptr = loc_block->bl_data;
1169         loc_len = loc_block->bl_len;
1170         end_ptr =  dbg->de_debug_loc.dss_size +
1171             dbg->de_debug_loc.dss_data;
1172         if ((loc_ptr +loc_len) > end_ptr) {
1173             dwarfstring m;
1174 
1175             dwarfstring_constructor(&m);
1176             dwarfstring_append(&m,
1177                 "DW_DLE_DEBUG_LOC_SECTION_SHORT kind: ");
1178             _dwarf_lkind_name(lkind, &m);
1179             _dwarf_error_string(dbg,error,
1180                 DW_DLE_DEBUG_LOC_SECTION_SHORT,
1181                 dwarfstring_string(&m));
1182             dwarfstring_destructor(&m);
1183             return DW_DLV_ERROR;
1184         }
1185         return DW_DLV_OK;
1186     }
1187     if (lkind == DW_LKIND_loclists) {
1188         Dwarf_Small *loc_ptr = 0;
1189         Dwarf_Unsigned loc_len = 0;
1190         Dwarf_Small *end_ptr = 0;
1191 
1192         loc_ptr = loc_block->bl_data;
1193         loc_len = loc_block->bl_len;
1194         end_ptr =  dbg->de_debug_loclists.dss_size +
1195             dbg->de_debug_loclists.dss_data;
1196         if ((loc_ptr +loc_len) > end_ptr) {
1197             dwarfstring m;
1198 
1199             dwarfstring_constructor(&m);
1200             dwarfstring_append(&m,
1201                 "DW_DLE_DEBUG_LOC_SECTION_SHORT "
1202                 "(the .debug_loclists section is short), kind: ");
1203             _dwarf_lkind_name(lkind, &m);
1204             _dwarf_error_string(dbg,error,
1205                 DW_DLE_DEBUG_LOC_SECTION_SHORT,
1206                 dwarfstring_string(&m));
1207             dwarfstring_destructor(&m);
1208             return DW_DLV_ERROR;
1209         }
1210     }
1211     return DW_DLV_OK;
1212 }
1213 
1214 /*  Sets locdesc operator list information in locdesc.
1215     Sets the locdesc values (rawlow, rawhigh etc).
1216     This synthesizes the ld_lle_value of the locdesc
1217     if it's not already provided.
1218     Not passing in locdesc pointer, the locdesc_index suffices
1219     to index to the relevant locdesc pointer.
1220     See also dwarf_loclists.c: build_array_of_lle*/
1221 int
_dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg,Dwarf_Unsigned locdesc_index,Dwarf_Loc_Head_c loc_head,Dwarf_Block_c * loc_block,Dwarf_Half address_size,Dwarf_Half offset_size,Dwarf_Small version_stamp,Dwarf_Addr lowpc,Dwarf_Addr highpc,Dwarf_Half lle_op,Dwarf_Error * error)1222 _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg,
1223     Dwarf_Unsigned locdesc_index,
1224     Dwarf_Loc_Head_c loc_head,
1225     Dwarf_Block_c * loc_block,
1226     Dwarf_Half address_size,
1227     Dwarf_Half offset_size,
1228     Dwarf_Small version_stamp,
1229     Dwarf_Addr lowpc,
1230     Dwarf_Addr highpc,
1231     Dwarf_Half lle_op,
1232     Dwarf_Error * error)
1233 {
1234     /* Offset of current operator from start of block. */
1235     Dwarf_Unsigned offset = 0;
1236 
1237     /*  Chain the  DW_OPerator structs. */
1238     Dwarf_Loc_Chain new_loc = NULL;
1239     Dwarf_Loc_Chain prev_loc = NULL;
1240     Dwarf_Loc_Chain head_loc = NULL;
1241 
1242     Dwarf_Unsigned  op_count = 0;
1243 
1244     /*  Contiguous block of Dwarf_Loc_Expr_Op_s
1245         for Dwarf_Locdesc. */
1246     Dwarf_Loc_Expr_Op block_loc = 0;
1247 
1248     Dwarf_Locdesc_c locdesc = loc_head->ll_locdesc + locdesc_index;
1249     Dwarf_Unsigned  i = 0;
1250     int             res = 0;
1251     Dwarf_Small    *section_start = 0;
1252     Dwarf_Unsigned  section_size = 0;
1253     Dwarf_Small    *section_end = 0;
1254     const char     *section_name = 0;
1255     Dwarf_Small    *blockdataptr = 0;
1256     unsigned lkind = loc_head->ll_kind;
1257 
1258     /* ***** BEGIN CODE ***** */
1259     blockdataptr = loc_block->bl_data;
1260     if (!blockdataptr || !loc_block->bl_len) {
1261         /*  an empty block has no operations so
1262             no section or tests need be done.. */
1263     } else {
1264         res = _dwarf_what_section_are_we(dbg,
1265             blockdataptr,&section_name,&section_start,
1266             &section_size,&section_end,error);
1267         if (res != DW_DLV_OK) {
1268             _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN);
1269             return DW_DLV_ERROR;
1270         }
1271         res = _dwarf_loc_block_sanity_check(dbg,loc_block,error);
1272         if (res != DW_DLV_OK) {
1273             return res;
1274         }
1275     }
1276     /* New loop getting Loc operators. Non DWO */
1277     while (offset <= loc_block->bl_len) {
1278         Dwarf_Unsigned nextoffset = 0;
1279         struct Dwarf_Loc_Expr_Op_s temp_loc;
1280 
1281         /*  This call is ok even if bl_data NULL and bl_len 0 */
1282         res = _dwarf_read_loc_expr_op(dbg,loc_block,
1283             op_count,
1284             version_stamp,
1285             offset_size,
1286             address_size,
1287             offset,
1288             section_end,
1289             &nextoffset,
1290             &temp_loc,
1291             error);
1292         if (res == DW_DLV_ERROR) {
1293             return res;
1294         }
1295         if (res == DW_DLV_NO_ENTRY) {
1296             /*  Normal end.
1297                 Also the end for an empty loc_block.  */
1298             break;
1299         }
1300         op_count++;
1301         new_loc =
1302             (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN, 1);
1303         if (new_loc == NULL) {
1304             _dwarf_free_op_chain(dbg,head_loc);
1305             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1306             return DW_DLV_ERROR;
1307         }
1308 
1309         /* Copying all the fields. DWARF 2,3,4,5. */
1310         new_loc->lc_atom    = temp_loc.lr_atom;
1311         new_loc->lc_opnumber= temp_loc.lr_opnumber;
1312         new_loc->lc_raw1    = temp_loc.lr_number;
1313         new_loc->lc_raw2    = temp_loc.lr_number2;
1314         new_loc->lc_raw3    = temp_loc.lr_number3;
1315         new_loc->lc_number  = temp_loc.lr_number;
1316         new_loc->lc_number2 = temp_loc.lr_number2;
1317         new_loc->lc_number3 = temp_loc.lr_number3;
1318         new_loc->lc_offset  = temp_loc.lr_offset;
1319         if (head_loc == NULL)
1320             head_loc = prev_loc = new_loc;
1321         else {
1322             prev_loc->lc_next = new_loc;
1323             prev_loc = new_loc;
1324         }
1325         offset = nextoffset;
1326     }
1327     block_loc =
1328         (Dwarf_Loc_Expr_Op ) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK_C,
1329         op_count);
1330     new_loc = head_loc;
1331     if (block_loc == NULL) {
1332         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1333         for (i = 0; i < op_count; i++) {
1334             prev_loc = new_loc;
1335             new_loc = prev_loc->lc_next;
1336             dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
1337         }
1338         return DW_DLV_ERROR;
1339     }
1340 
1341     /* op_count could be zero. */
1342     new_loc = head_loc;
1343     for (i = 0; i < op_count; i++) {
1344         /* Copying only the fields needed by DWARF 2,3,4 */
1345         (block_loc + i)->lr_atom = new_loc->lc_atom;
1346         (block_loc + i)->lr_raw1 = new_loc->lc_raw1;
1347         (block_loc + i)->lr_raw2 = new_loc->lc_raw2;
1348         (block_loc + i)->lr_raw3 = new_loc->lc_raw3;
1349         (block_loc + i)->lr_number = new_loc->lc_number;
1350         (block_loc + i)->lr_number2 = new_loc->lc_number2;
1351         (block_loc + i)->lr_number3 = new_loc->lc_number3;
1352         (block_loc + i)->lr_offset = new_loc->lc_offset;
1353         (block_loc + i)->lr_opnumber = new_loc->lc_opnumber;
1354         prev_loc = new_loc;
1355         new_loc = prev_loc->lc_next;
1356         dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
1357     }
1358     /*  Synthesizing the DW_LLE values for the old loclist
1359         versions. */
1360     if (loc_head->ll_kind == DW_LKIND_loclist) {
1361         /*  Meaningless for a DW_LKIND_expression */
1362         if(highpc == 0 && lowpc == 0) {
1363             locdesc->ld_lle_value =  DW_LLE_end_of_list;
1364         } else if(lowpc == MAX_ADDR) {
1365             locdesc->ld_lle_value = DW_LLE_base_address;
1366         } else {
1367             locdesc->ld_lle_value = DW_LLE_offset_pair;
1368         }
1369     } else  if (DW_LKIND_GNU_exp_list){
1370         /* DW_LKIND_GNU_exp_list */
1371         locdesc->ld_lle_value = lle_op;
1372     }
1373     locdesc->ld_cents = op_count;
1374     locdesc->ld_s = block_loc;
1375     locdesc->ld_kind = lkind;
1376     locdesc->ld_section_offset = loc_block->bl_section_offset;
1377     locdesc->ld_locdesc_offset = loc_block->bl_locdesc_offset;
1378     locdesc->ld_rawlow = lowpc;
1379     locdesc->ld_rawhigh = highpc;
1380     /*  Leaving the cooked values zero. Filled in later. */
1381     /*  We have not yet looked for debug_addr, so we'll
1382         set it as not-missing. */
1383     locdesc->ld_index_failed = FALSE;
1384     return DW_DLV_OK;
1385 }
1386 
1387 
1388 /* Non-standard DWARF4 dwo loclist */
1389 static int
_dwarf_read_loc_section_dwo(Dwarf_Debug dbg,Dwarf_Block_c * return_block,Dwarf_Addr * lowpc,Dwarf_Addr * highpc,Dwarf_Bool * at_end,Dwarf_Half * lle_op,Dwarf_Off sec_offset,Dwarf_Half address_size,Dwarf_Half lkind,Dwarf_Error * error)1390 _dwarf_read_loc_section_dwo(Dwarf_Debug dbg,
1391     Dwarf_Block_c * return_block,
1392     Dwarf_Addr * lowpc,
1393     Dwarf_Addr * highpc,
1394     Dwarf_Bool *at_end,
1395     Dwarf_Half * lle_op,
1396     Dwarf_Off sec_offset,
1397     Dwarf_Half address_size,
1398     Dwarf_Half lkind,
1399     Dwarf_Error * error)
1400 {
1401     Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset;
1402     Dwarf_Small *locptr = 0;
1403     Dwarf_Small llecode = 0;
1404     Dwarf_Unsigned expr_offset  = sec_offset;
1405     Dwarf_Byte_Ptr section_end = dbg->de_debug_loc.dss_data
1406         + dbg->de_debug_loc.dss_size;
1407 
1408     if (sec_offset >= dbg->de_debug_loc.dss_size) {
1409         /* We're at the end. No more present. */
1410         return DW_DLV_NO_ENTRY;
1411     }
1412     memset(return_block,0,sizeof(*return_block));
1413 
1414     /* not the same as non-split loclist, but still a list. */
1415     return_block->bl_kind = lkind;
1416 
1417     /* This is non-standard  GNU Dwarf4 loclist */
1418     return_block->bl_locdesc_offset = sec_offset;
1419     llecode = *beg;
1420     locptr = beg +1;
1421     expr_offset++;
1422     switch(llecode) {
1423     case DW_LLEX_end_of_list_entry:
1424         *at_end = TRUE;
1425         return_block->bl_section_offset = expr_offset;
1426         expr_offset++;
1427         break;
1428     case DW_LLEX_base_address_selection_entry: {
1429         Dwarf_Unsigned addr_index = 0;
1430 
1431         DECODE_LEB128_UWORD_CK(locptr,addr_index,
1432             dbg,error,section_end);
1433         return_block->bl_section_offset = expr_offset;
1434         /* So this behaves much like non-dwo loclist */
1435         *lowpc=MAX_ADDR;
1436         *highpc=addr_index;
1437         }
1438         break;
1439     case DW_LLEX_start_end_entry: {
1440         Dwarf_Unsigned addr_indexs = 0;
1441         Dwarf_Unsigned addr_indexe= 0;
1442         Dwarf_Unsigned exprlen = 0;
1443         Dwarf_Unsigned leb128_length = 0;
1444 
1445         DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexs,
1446             leb128_length,
1447             dbg,error,section_end);
1448         expr_offset += leb128_length;
1449 
1450         DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexe,
1451             leb128_length,
1452             dbg,error,section_end);
1453         expr_offset +=leb128_length;
1454 
1455         *lowpc=addr_indexs;
1456         *highpc=addr_indexe;
1457 
1458         READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr,
1459             DWARF_HALF_SIZE,
1460             error,section_end);
1461         locptr += DWARF_HALF_SIZE;
1462         expr_offset += DWARF_HALF_SIZE;
1463 
1464         return_block->bl_len = exprlen;
1465         return_block->bl_data = locptr;
1466         return_block->bl_section_offset = expr_offset;
1467 
1468         expr_offset += exprlen;
1469         if (expr_offset > dbg->de_debug_loc.dss_size) {
1470 
1471             _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
1472             return DW_DLV_ERROR;
1473         }
1474         }
1475         break;
1476     case DW_LLEX_start_length_entry: {
1477         Dwarf_Unsigned addr_index = 0;
1478         Dwarf_Unsigned  range_length = 0;
1479         Dwarf_Unsigned exprlen = 0;
1480         Dwarf_Unsigned leb128_length = 0;
1481 
1482         DECODE_LEB128_UWORD_LEN_CK(locptr,addr_index,
1483             leb128_length,
1484             dbg,error,section_end);
1485         expr_offset +=leb128_length;
1486 
1487         READ_UNALIGNED_CK(dbg, range_length, Dwarf_Unsigned, locptr,
1488             DWARF_32BIT_SIZE,
1489             error,section_end);
1490         locptr += DWARF_32BIT_SIZE;
1491         expr_offset += DWARF_32BIT_SIZE;
1492 
1493         READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr,
1494             DWARF_HALF_SIZE,
1495             error,section_end);
1496         locptr += DWARF_HALF_SIZE;
1497         expr_offset += DWARF_HALF_SIZE;
1498 
1499         *lowpc = addr_index;
1500         *highpc = range_length;
1501         return_block->bl_len = exprlen;
1502         return_block->bl_data = locptr;
1503         return_block->bl_section_offset = expr_offset;
1504         /* exprblock_size can be zero, means no expression */
1505 
1506         expr_offset += exprlen;
1507         if (expr_offset > dbg->de_debug_loc.dss_size) {
1508             _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
1509             return DW_DLV_ERROR;
1510         }
1511         }
1512         break;
1513     case DW_LLEX_offset_pair_entry: {
1514         Dwarf_Unsigned  startoffset = 0;
1515         Dwarf_Unsigned  endoffset = 0;
1516         Dwarf_Unsigned exprlen = 0;
1517 
1518         READ_UNALIGNED_CK(dbg, startoffset,
1519             Dwarf_Unsigned, locptr,
1520             DWARF_32BIT_SIZE,
1521             error,section_end);
1522         locptr += DWARF_32BIT_SIZE;
1523         expr_offset += DWARF_32BIT_SIZE;
1524 
1525         READ_UNALIGNED_CK(dbg, endoffset,
1526             Dwarf_Unsigned, locptr,
1527             DWARF_32BIT_SIZE,
1528             error,section_end);
1529         locptr += DWARF_32BIT_SIZE;
1530         expr_offset +=  DWARF_32BIT_SIZE;
1531         *lowpc= startoffset;
1532         *highpc = endoffset;
1533 
1534         READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr,
1535             DWARF_HALF_SIZE,
1536             error,section_end);
1537         locptr += DWARF_HALF_SIZE;
1538         expr_offset += DWARF_HALF_SIZE;
1539 
1540         return_block->bl_len = exprlen;
1541         return_block->bl_data = locptr;
1542         return_block->bl_section_offset = expr_offset;
1543 
1544         expr_offset += exprlen;
1545         if (expr_offset > dbg->de_debug_loc.dss_size) {
1546             _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
1547             return DW_DLV_ERROR;
1548         }
1549         }
1550         break;
1551     default:
1552         _dwarf_error(dbg,error,DW_DLE_LLE_CODE_UNKNOWN);
1553         return DW_DLV_ERROR;
1554     }
1555     *lle_op = llecode;
1556     return DW_DLV_OK;
1557 }
1558 
1559 
1560 int
dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c ll_header,unsigned int * kind,UNUSEDARG Dwarf_Error * error)1561 dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c ll_header,
1562     unsigned int * kind,
1563     UNUSEDARG Dwarf_Error  * error)
1564 {
1565     *kind = ll_header->ll_kind;
1566     return DW_DLV_OK;
1567 }
1568 
1569 static int
_dwarf_original_loclist_build(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Attribute attr,Dwarf_Error * error)1570 _dwarf_original_loclist_build(Dwarf_Debug dbg,
1571     Dwarf_Loc_Head_c llhead,
1572     Dwarf_Attribute attr,
1573     Dwarf_Error *error)
1574 {
1575     Dwarf_Unsigned loclist_offset = 0;
1576     int off_res  = DW_DLV_ERROR;
1577     int count_res = DW_DLV_ERROR;
1578     int loclist_count = 0;
1579     Dwarf_Unsigned lli = 0;
1580     unsigned lkind = llhead->ll_kind;
1581     unsigned address_size = llhead->ll_address_size;
1582     Dwarf_Unsigned listlen = 0;
1583     Dwarf_Locdesc_c llbuf = 0;
1584     Dwarf_CU_Context cucontext;
1585 
1586     off_res = _dwarf_get_loclist_header_start(dbg,
1587         attr, &loclist_offset, error);
1588     if (off_res != DW_DLV_OK) {
1589         return off_res;
1590     }
1591 #if 0
1592     res = dwarf_global_formref(attr,&loclist_offset,error);
1593     if (res != DW_DLV_OK) {
1594         return res;
1595     }
1596 #endif
1597 
1598     if (lkind == DW_LKIND_GNU_exp_list) {
1599         count_res = _dwarf_get_loclist_lle_count_dwo(dbg,
1600             loclist_offset,
1601             address_size,
1602             llhead->ll_kind,
1603             &loclist_count,
1604             error);
1605     } else {
1606         count_res = _dwarf_get_loclist_lle_count(dbg,
1607             loclist_offset, address_size,
1608             llhead->ll_kind,
1609             &loclist_count,
1610             error);
1611     }
1612     if (count_res != DW_DLV_OK) {
1613         return count_res;
1614     }
1615     if (loclist_count == 0) {
1616         return DW_DLV_NO_ENTRY;
1617     }
1618 
1619     listlen = loclist_count;
1620     llbuf = (Dwarf_Locdesc_c)
1621         _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen);
1622     if (!llbuf) {
1623         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1624         return (DW_DLV_ERROR);
1625     }
1626     llhead->ll_locdesc = llbuf;
1627     llhead->ll_locdesc_count = listlen;
1628     cucontext = llhead->ll_context;
1629     llhead->ll_llearea_offset = loclist_offset;
1630 
1631         /* New get loc ops */
1632     for (lli = 0; lli < listlen; ++lli) {
1633         int lres = 0;
1634         Dwarf_Half lle_op = 0;
1635         Dwarf_Bool at_end = 0;
1636         Dwarf_Block_c loc_block;
1637         Dwarf_Unsigned lowpc = 0;
1638         Dwarf_Unsigned highpc = 0;
1639         int blkres = 0;
1640 
1641         memset(&loc_block,0,sizeof(loc_block));
1642         if( lkind == DW_LKIND_GNU_exp_list) {
1643             blkres = _dwarf_read_loc_section_dwo(dbg,
1644                 &loc_block,
1645                 &lowpc, &highpc,
1646                 &at_end, &lle_op,
1647                 loclist_offset,
1648                 address_size,
1649                 lkind,
1650                 error);
1651         } else {
1652             blkres = _dwarf_read_loc_section(dbg,
1653                 &loc_block,
1654                 &lowpc, &highpc,
1655                 &lle_op,
1656                 loclist_offset,
1657                 address_size,
1658                 lkind,
1659                 error);
1660         }
1661         if (blkres != DW_DLV_OK) {
1662             return blkres;
1663         }
1664         /* Fills in the locdesc and its operators list at index lli */
1665         lres = _dwarf_fill_in_locdesc_op_c(dbg,
1666             lli,
1667             llhead,
1668             &loc_block,
1669             address_size,
1670             cucontext->cc_length_size,
1671             cucontext->cc_version_stamp,
1672             lowpc,
1673             highpc,
1674             lle_op,
1675             error);
1676         if (lres != DW_DLV_OK) {
1677             return lres;
1678         }
1679         /* Now get to next loclist entry offset. */
1680         loclist_offset = loc_block.bl_section_offset +
1681             loc_block.bl_len;
1682     }
1683     return DW_DLV_OK;
1684 }
1685 
1686 static int
_dwarf_original_expression_build(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Attribute attr,Dwarf_Error * error)1687 _dwarf_original_expression_build(Dwarf_Debug dbg,
1688     Dwarf_Loc_Head_c llhead,
1689     Dwarf_Attribute attr,
1690     Dwarf_Error *error)
1691 {
1692 
1693     Dwarf_Block_c loc_blockc;
1694     Dwarf_Unsigned lowpc = 0;
1695     Dwarf_Unsigned highpc = 0;
1696     unsigned form = llhead->ll_attrform;
1697     int blkres = 0;
1698     Dwarf_Locdesc_c llbuf = 0;
1699     unsigned listlen = 1;
1700     Dwarf_CU_Context cucontext = llhead->ll_context;
1701 
1702     memset(&loc_blockc,0,sizeof(loc_blockc));
1703     if( form == DW_FORM_exprloc) {
1704         blkres = dwarf_formexprloc(attr,&loc_blockc.bl_len,
1705             &loc_blockc.bl_data,error);
1706         if(blkres != DW_DLV_OK) {
1707             dwarf_loc_head_c_dealloc(llhead);
1708             return blkres;
1709         }
1710         loc_blockc.bl_kind = llhead->ll_kind;
1711         loc_blockc.bl_section_offset  =
1712             (char *)loc_blockc.bl_data -
1713             (char *)dbg->de_debug_info.dss_data;
1714         loc_blockc.bl_locdesc_offset = 0; /* not relevant */
1715     } else {
1716         Dwarf_Block loc_block;
1717 
1718         memset(&loc_block,0,sizeof(loc_block));
1719         blkres = _dwarf_formblock_internal(dbg,attr,
1720             llhead->ll_context,
1721             &loc_block,
1722             error);
1723         if (blkres != DW_DLV_OK) {
1724             return blkres;
1725         }
1726         loc_blockc.bl_len = loc_block.bl_len;
1727         loc_blockc.bl_data = loc_block.bl_data;
1728         loc_blockc.bl_kind = llhead->ll_kind;
1729         loc_blockc.bl_section_offset = loc_block.bl_section_offset;
1730         loc_blockc.bl_locdesc_offset = 0; /* not relevant */
1731     }
1732     /*  This hack ensures that the Locdesc_c
1733         is marked DW_LLE_start_end. But really unncessary
1734         as we are marked as the correct ll_kind */
1735     lowpc = 0;   /* HACK */
1736     highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
1737 
1738     llbuf = (Dwarf_Locdesc_c)
1739         _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen);
1740     if (!llbuf) {
1741         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1742         return (DW_DLV_ERROR);
1743     }
1744     llhead->ll_locdesc = llbuf;
1745     /* One by definition of a location entry. */
1746     llhead->ll_locdesc_count = listlen;
1747 
1748     /*  An empty location description (block length 0)
1749         means the code generator emitted no variable,
1750         the variable was not generated, it was unused
1751         or perhaps never tested after being set. Dwarf2,
1752         section 2.4.1 In other words, it is not an error,
1753         and we don't test for block length 0 specially here.  */
1754 
1755     /* Fills in the locdesc and its operators list at index 0 */
1756     blkres = _dwarf_fill_in_locdesc_op_c(dbg,
1757         0, /* fake locdesc is index 0 */
1758         llhead,
1759         &loc_blockc,
1760         llhead->ll_address_size,
1761         cucontext->cc_length_size,
1762         cucontext->cc_version_stamp,
1763         lowpc, highpc,
1764         0,
1765         error);
1766     if (blkres != DW_DLV_OK) {
1767         /* low level error already set: let it be passed back */
1768         return blkres;
1769     }
1770     return DW_DLV_OK;
1771 }
1772 
1773 /*  Following the original loclist definition the low
1774     value is all one bits, the high value is the base
1775     address. */
1776 static int
cook_original_loclist_contents(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Error * error)1777 cook_original_loclist_contents(Dwarf_Debug dbg,
1778     Dwarf_Loc_Head_c llhead,
1779     Dwarf_Error *error)
1780 {
1781     Dwarf_Unsigned baseaddress = llhead->ll_cu_base_address;
1782     Dwarf_Unsigned count = llhead->ll_locdesc_count;
1783     Dwarf_Unsigned i = 0;
1784 
1785     for ( i = 0 ; i < count; ++i) {
1786         Dwarf_Locdesc_c  llc = 0;
1787 
1788         llc = llhead->ll_locdesc +i;
1789         switch(llc->ld_lle_value) {
1790         case DW_LLE_end_of_list: {
1791             /* nothing to do */
1792             break;
1793             }
1794         case DW_LLE_base_address: {
1795             llc->ld_lopc =  llc->ld_rawhigh;
1796             llc->ld_highpc =  llc->ld_rawhigh;
1797             baseaddress =  llc->ld_rawhigh;
1798             break;
1799             }
1800         case DW_LLE_offset_pair: {
1801             llc->ld_lopc = llc->ld_rawlow + baseaddress;
1802             llc->ld_highpc = llc->ld_rawhigh + baseaddress;
1803             break;
1804             }
1805         default: {
1806             dwarfstring m;
1807 
1808             dwarfstring_constructor(&m);
1809             dwarfstring_append_printf_u(&m,
1810                 "DW_DLE_LOCLISTS_ERROR: improper synthesized LLE code "
1811                 "of 0x%x is unknown. In standard DWARF3/4 loclist",
1812                 llc->ld_lle_value);
1813             _dwarf_error_string(dbg,error,
1814                 DW_DLE_LOCLISTS_ERROR,
1815                 dwarfstring_string(&m));
1816             dwarfstring_destructor(&m);
1817             return DW_DLV_ERROR;
1818             }
1819         }
1820     }
1821     return DW_DLV_OK;
1822 }
1823 
1824 static int
cook_gnu_loclist_contents(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Error * error)1825 cook_gnu_loclist_contents(Dwarf_Debug dbg,
1826     Dwarf_Loc_Head_c llhead,
1827     Dwarf_Error *error)
1828 {
1829     Dwarf_Unsigned baseaddress = llhead->ll_cu_base_address;
1830     Dwarf_Unsigned count = llhead->ll_locdesc_count;
1831     Dwarf_Unsigned i = 0;
1832     Dwarf_CU_Context cucontext = llhead->ll_context;
1833     int res = 0;
1834 
1835     for (i = 0 ; i < count ; ++i) {
1836         Dwarf_Locdesc_c  llc = 0;
1837 
1838         llc = llhead->ll_locdesc +i;
1839         switch(llc->ld_lle_value) {
1840         case DW_LLEX_base_address_selection_entry:{
1841             Dwarf_Addr targaddr = 0;
1842             res = _dwarf_extract_address_from_debug_addr(dbg,
1843                 cucontext,llc->ld_rawhigh,&targaddr,error);
1844             if (res != DW_DLV_OK) {
1845                 llc->ld_index_failed = TRUE;
1846                 llc->ld_lopc = 0;
1847                 llc->ld_highpc = 0;
1848                 if (res == DW_DLV_ERROR) {
1849                     dwarf_dealloc_error(dbg, *error);
1850                     *error = 0;
1851                 }
1852             } else {
1853                 llc->ld_lopc = targaddr;
1854                 llc->ld_highpc = targaddr;
1855             }
1856             break;
1857             }
1858         case DW_LLEX_end_of_list_entry:{
1859             /* Nothing to do. */
1860             break;
1861             }
1862         case DW_LLEX_start_length_entry:{
1863             Dwarf_Addr targaddr = 0;
1864             res = _dwarf_extract_address_from_debug_addr(dbg,
1865                 cucontext,llc->ld_rawlow,&targaddr,error);
1866             if (res != DW_DLV_OK) {
1867                 llc->ld_index_failed = TRUE;
1868                 llc->ld_lopc = 0;
1869                 if (res == DW_DLV_ERROR) {
1870                     dwarf_dealloc_error(dbg, *error);
1871                     *error = 0;
1872                 }
1873             } else {
1874                 llc->ld_lopc = targaddr;
1875                 llc->ld_highpc = llc->ld_lopc +llc->ld_rawhigh;
1876             }
1877             break;
1878             }
1879         case DW_LLEX_offset_pair_entry:{
1880             llc->ld_lopc = llc->ld_rawlow + baseaddress;
1881             llc->ld_highpc = llc->ld_rawhigh + baseaddress;
1882             break;
1883             }
1884         case DW_LLEX_start_end_entry:{
1885             Dwarf_Addr targaddr = 0;
1886             res = _dwarf_extract_address_from_debug_addr(dbg,
1887                 cucontext,llc->ld_rawlow,&targaddr,error);
1888             if (res != DW_DLV_OK) {
1889                 llc->ld_index_failed = TRUE;
1890                 llc->ld_lopc = 0;
1891                 if (res == DW_DLV_ERROR) {
1892                     dwarf_dealloc_error(dbg, *error);
1893                     *error = 0;
1894                 }
1895             } else {
1896                 llc->ld_lopc = targaddr;
1897             }
1898             res = _dwarf_extract_address_from_debug_addr(dbg,
1899                 cucontext,llc->ld_rawhigh,&targaddr,error);
1900             if (res != DW_DLV_OK) {
1901                 llc->ld_index_failed = TRUE;
1902                 llc->ld_highpc = 0;
1903                 if (res == DW_DLV_ERROR) {
1904                     dwarf_dealloc_error(dbg, *error);
1905                     *error = 0;
1906                 }
1907             } else {
1908                 llc->ld_highpc = targaddr;
1909             }
1910 
1911 
1912             break;
1913             }
1914         default:{
1915             dwarfstring m;
1916 
1917             dwarfstring_constructor(&m);
1918             dwarfstring_append_printf_u(&m,
1919                 "DW_DLE_LOCLISTS_ERROR: improper LLEX code "
1920                 "of 0x%x is unknown. GNU LLEX dwo loclists error",
1921                 llc->ld_lle_value);
1922             _dwarf_error_string(dbg,error,
1923                 DW_DLE_LOCLISTS_ERROR,
1924                 dwarfstring_string(&m));
1925             dwarfstring_destructor(&m);
1926             return DW_DLV_ERROR;
1927 
1928             break;
1929             }
1930         }
1931     }
1932     return DW_DLV_OK;
1933 }
1934 
1935 
1936 /* DWARF5 */
1937 static int
cook_loclists_contents(Dwarf_Debug dbg,Dwarf_Loc_Head_c llhead,Dwarf_Error * error)1938 cook_loclists_contents(Dwarf_Debug dbg,
1939     Dwarf_Loc_Head_c llhead,
1940     Dwarf_Error *error)
1941 {
1942     Dwarf_Unsigned baseaddress = llhead->ll_cu_base_address;
1943     Dwarf_Unsigned count = llhead->ll_locdesc_count;
1944     Dwarf_Unsigned i = 0;
1945     Dwarf_CU_Context cucontext = llhead->ll_context;
1946     int res = 0;
1947 
1948     for (i = 0 ; i < count ; ++i) {
1949         Dwarf_Locdesc_c  llc = 0;
1950 
1951         llc = llhead->ll_locdesc +i;
1952         switch(llc->ld_lle_value) {
1953         case DW_LLE_base_addressx: {
1954             Dwarf_Addr targaddr = 0;
1955             res = _dwarf_extract_address_from_debug_addr(dbg,
1956                 cucontext,llc->ld_rawlow,&targaddr,error);
1957             if (res != DW_DLV_OK) {
1958                 llc->ld_index_failed = TRUE;
1959                 llc->ld_lopc = 0;
1960                 if (res == DW_DLV_ERROR) {
1961                     dwarf_dealloc_error(dbg, *error);
1962                     *error = 0;
1963                 }
1964             } else {
1965                 llc->ld_lopc = targaddr;
1966             }
1967             break;
1968         }
1969         case DW_LLE_startx_endx:{
1970             /* two indexes into debug_addr */
1971             Dwarf_Addr targaddr = 0;
1972             res = _dwarf_extract_address_from_debug_addr(dbg,
1973                 cucontext,llc->ld_rawlow,&targaddr,error);
1974             if (res != DW_DLV_OK) {
1975                 llc->ld_index_failed = TRUE;
1976                 llc->ld_lopc = 0;
1977                 if (res == DW_DLV_ERROR) {
1978                     dwarf_dealloc_error(dbg, *error);
1979                     *error = 0;
1980                 }
1981             } else {
1982                 llc->ld_lopc = targaddr;
1983             }
1984             res = _dwarf_extract_address_from_debug_addr(dbg,
1985                 cucontext,llc->ld_rawhigh,&targaddr,error);
1986             if (res != DW_DLV_OK) {
1987                 llc->ld_index_failed = TRUE;
1988                 llc->ld_highpc = 0;
1989                 if (res == DW_DLV_ERROR) {
1990                     dwarf_dealloc_error(dbg, *error);
1991                     *error = 0;
1992                 }
1993             } else {
1994                 llc->ld_highpc = targaddr;
1995             }
1996             break;
1997         }
1998         case DW_LLE_startx_length:{
1999             /* one index to debug_addr other a length */
2000             Dwarf_Addr targaddr = 0;
2001             res = _dwarf_extract_address_from_debug_addr(dbg,
2002                 cucontext,llc->ld_rawlow,&targaddr,error);
2003             if (res != DW_DLV_OK) {
2004                 llc->ld_index_failed = TRUE;
2005                 llc->ld_lopc = 0;
2006                 if (res == DW_DLV_ERROR) {
2007                     dwarf_dealloc_error(dbg, *error);
2008                     *error = 0;
2009                 }
2010             } else {
2011                 llc->ld_lopc = targaddr;
2012                 llc->ld_highpc = targaddr + llc->ld_rawhigh;
2013             }
2014             break;
2015         }
2016         case DW_LLE_offset_pair:{
2017             /*offsets of the current base address*/
2018             llc->ld_lopc = llc->ld_rawlow +baseaddress;
2019             llc->ld_highpc = llc->ld_rawhigh +baseaddress;
2020             break;
2021         }
2022         case DW_LLE_default_location:{
2023             /*  nothing to do here, just has a counted
2024                 location description */
2025             break;
2026         }
2027         case DW_LLE_base_address:{
2028             llc->ld_lopc = llc->ld_rawlow;
2029             llc->ld_highpc = llc->ld_rawlow;
2030             baseaddress = llc->ld_rawlow;
2031             break;
2032         }
2033         case DW_LLE_start_end:{
2034             llc->ld_lopc = llc->ld_rawlow;
2035             llc->ld_highpc = llc->ld_rawhigh;
2036             break;
2037         }
2038         case DW_LLE_start_length:{
2039             llc->ld_lopc = llc->ld_rawlow;
2040             llc->ld_highpc = llc->ld_rawlow + llc->ld_rawhigh;
2041             break;
2042         }
2043         case DW_LLE_end_of_list:{
2044             /* do nothing */
2045             break;
2046         }
2047         default: {
2048             dwarfstring m;
2049 
2050             dwarfstring_constructor(&m);
2051             dwarfstring_append_printf_u(&m,
2052                 "DW_DLE_LOCLISTS_ERROR: improper DW_LLE code "
2053                 "of 0x%x is unknown. DWARF5 loclists error",
2054                 llc->ld_lle_value);
2055             _dwarf_error_string(dbg,error,
2056                 DW_DLE_LOCLISTS_ERROR,
2057                 dwarfstring_string(&m));
2058             dwarfstring_destructor(&m);
2059             return DW_DLV_ERROR;
2060         }
2061         }
2062     }
2063     return DW_DLV_OK;
2064 }
2065 
2066 /*  New October 2015
2067     This interface requires the use of interface functions
2068     to get data from Dwarf_Locdesc_c.  The structures
2069     are not visible to callers. */
2070 int
dwarf_get_loclist_c(Dwarf_Attribute attr,Dwarf_Loc_Head_c * ll_header_out,Dwarf_Unsigned * listlen_out,Dwarf_Error * error)2071 dwarf_get_loclist_c(Dwarf_Attribute attr,
2072     Dwarf_Loc_Head_c * ll_header_out,
2073     Dwarf_Unsigned   * listlen_out,
2074     Dwarf_Error      * error)
2075 {
2076     Dwarf_Debug dbg;
2077     Dwarf_Half form          = 0;
2078     Dwarf_Loc_Head_c llhead  = 0;
2079     Dwarf_CU_Context cucontext = 0;
2080     unsigned address_size    = 0;
2081     int cuversionstamp       = 0;
2082     Dwarf_Bool is_cu         = FALSE;
2083     Dwarf_Unsigned attrnum   = 0;
2084     Dwarf_Bool is_dwo        = 0;
2085     int setup_res            = DW_DLV_ERROR;
2086     int lkind                = 0;
2087 
2088     /* ***** BEGIN CODE ***** */
2089     setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
2090     if (setup_res != DW_DLV_OK) {
2091         return setup_res;
2092     }
2093     attrnum = attr->ar_attribute;
2094     cuversionstamp = cucontext->cc_version_stamp;
2095     address_size = cucontext->cc_address_size;
2096     is_dwo = cucontext->cc_is_dwo;
2097     lkind = determine_location_lkind(cuversionstamp,
2098         form, attrnum, is_dwo);
2099     if (lkind == DW_LKIND_unknown) {
2100         dwarfstring m;
2101         const char * formname = "<unknownform>";
2102         const char * attrname = "<unknown attribute>";
2103 
2104         dwarfstring_constructor(&m);
2105         dwarf_get_FORM_name(form,&formname);
2106         dwarf_get_AT_name(attrnum,&attrname);
2107         dwarfstring_append_printf_u(&m,
2108             "DW_DLE_LOC_EXPR_BAD: For Compilation Unit "
2109             "version %u",cuversionstamp);
2110         dwarfstring_append_printf_u(&m,
2111             ", attribute 0x%x (",attrnum);
2112         dwarfstring_append(&m,(char *)attrname);
2113         dwarfstring_append_printf_u(&m,
2114             ") form 0x%x (",form);
2115         dwarfstring_append(&m,(char *)formname);
2116         if (is_dwo) {
2117             dwarfstring_append(&m,") (the CU is a .dwo) ");
2118         } else {
2119             dwarfstring_append(&m,") (the CU is not a .dwo) ");
2120         }
2121         dwarfstring_append(&m," we don't undrstand the location");
2122         _dwarf_error_string(dbg,error,DW_DLE_LOC_EXPR_BAD,
2123             dwarfstring_string(&m));
2124         dwarfstring_destructor(&m);
2125         return DW_DLV_ERROR;
2126     }
2127     /*  Doing this early (first) to avoid repeating the alloc code
2128         for each type  */
2129     llhead = (Dwarf_Loc_Head_c)
2130         _dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1);
2131     if (!llhead) {
2132         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
2133         return (DW_DLV_ERROR);
2134     }
2135     llhead->ll_cuversion = cuversionstamp;
2136     llhead->ll_kind = lkind;
2137     llhead->ll_attrnum = attrnum;
2138     llhead->ll_attrform = form;
2139     llhead->ll_dbg = dbg;
2140     llhead->ll_address_size = address_size;
2141     llhead->ll_offset_size = cucontext->cc_length_size;
2142     llhead->ll_context = cucontext;
2143 
2144     llhead->ll_at_loclists_base_present =
2145         cucontext->cc_loclists_base_present;
2146     llhead->ll_at_loclists_base =  cucontext->cc_loclists_base;
2147     llhead->ll_cu_base_address_present = cucontext->cc_low_pc_present;
2148     llhead->ll_cu_base_address = cucontext->cc_low_pc;
2149     llhead->ll_cu_addr_base = cucontext->cc_addr_base;
2150     llhead->ll_cu_addr_base_present = cucontext->cc_addr_base_present;
2151 
2152     if (lkind == DW_LKIND_loclist ||
2153         lkind == DW_LKIND_GNU_exp_list) {
2154         int ores = 0;
2155         /* Here we have a loclist to deal with. */
2156         ores = context_is_cu_not_tu(cucontext,&is_cu);
2157         if(ores != DW_DLV_OK) {
2158             dwarf_loc_head_c_dealloc(llhead);
2159             return setup_res;
2160         }
2161         ores = _dwarf_original_loclist_build(dbg,
2162             llhead, attr, error);
2163         if (ores != DW_DLV_OK) {
2164             dwarf_loc_head_c_dealloc(llhead);
2165             return ores;
2166         }
2167         if (lkind == DW_LKIND_loclist) {
2168             ores = cook_original_loclist_contents(dbg,llhead,error);
2169         } else {
2170             ores = cook_gnu_loclist_contents(dbg,llhead,error);
2171         }
2172         if (ores != DW_DLV_OK) {
2173             dwarf_loc_head_c_dealloc(llhead);
2174             return ores;
2175         }
2176     } else if (lkind == DW_LKIND_expression) {
2177         /* DWARF2,3,4,5 */
2178         int eres = 0;
2179         eres = _dwarf_original_expression_build(dbg,
2180             llhead, attr, error);
2181         if (eres != DW_DLV_OK) {
2182             dwarf_loc_head_c_dealloc(llhead);
2183             return eres;
2184         }
2185     } else if (lkind == DW_LKIND_loclists) {
2186         /* DWARF5! */
2187         int leres = 0;
2188 
2189         leres = _dwarf_loclists_fill_in_lle_head(dbg,
2190             attr,llhead,error);
2191         if (leres != DW_DLV_OK) {
2192             dwarf_loc_head_c_dealloc(llhead);
2193             return leres;
2194         }
2195         leres = cook_loclists_contents(dbg,llhead,error);
2196         if (leres != DW_DLV_OK) {
2197             dwarf_loc_head_c_dealloc(llhead);
2198             return leres;
2199         }
2200     } /* ASSERT else impossible */
2201     *ll_header_out = llhead;
2202     *listlen_out = llhead->ll_locdesc_count;
2203     return DW_DLV_OK;
2204 }
2205 
2206 /*  An interface giving us no cu context!
2207     This is not going to be quite right. */
2208 int
dwarf_loclist_from_expr_c(Dwarf_Debug dbg,Dwarf_Ptr expression_in,Dwarf_Unsigned expression_length,Dwarf_Half address_size,Dwarf_Half offset_size,Dwarf_Small dwarf_version,Dwarf_Loc_Head_c * loc_head,Dwarf_Unsigned * listlen,Dwarf_Error * error)2209 dwarf_loclist_from_expr_c(Dwarf_Debug dbg,
2210     Dwarf_Ptr expression_in,
2211     Dwarf_Unsigned expression_length,
2212     Dwarf_Half address_size,
2213     Dwarf_Half offset_size,
2214     Dwarf_Small dwarf_version,
2215     Dwarf_Loc_Head_c *loc_head,
2216     Dwarf_Unsigned * listlen,
2217     Dwarf_Error * error)
2218 {
2219     /* Dwarf_Block that describes a single location expression. */
2220     Dwarf_Block_c loc_block;
2221     Dwarf_Loc_Head_c llhead = 0;
2222     Dwarf_Locdesc_c llbuf = 0;
2223     int local_listlen = 1;
2224     Dwarf_Addr lowpc = 0;
2225     Dwarf_Addr highpc = MAX_ADDR;
2226     Dwarf_Small version_stamp = dwarf_version;
2227     int res = 0;
2228 
2229     llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg,
2230         DW_DLA_LOC_HEAD_C, 1);
2231     if (!llhead) {
2232         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
2233         return (DW_DLV_ERROR);
2234     }
2235     memset(&loc_block,0,sizeof(loc_block));
2236     loc_block.bl_len = expression_length;
2237     loc_block.bl_data = expression_in;
2238     loc_block.bl_kind = DW_LKIND_expression; /* Not from loclist. */
2239     loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
2240     loc_block.bl_locdesc_offset = 0; /* Fake. Not meaningful. */
2241     llbuf = (Dwarf_Locdesc_c)
2242         _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, local_listlen);
2243     if (!llbuf) {
2244         dwarf_loc_head_c_dealloc(llhead);
2245         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
2246         return (DW_DLV_ERROR);
2247     }
2248     llhead->ll_locdesc = llbuf;
2249     llhead->ll_locdesc_count = local_listlen;
2250     llhead->ll_context = 0; /* Not available! */
2251     llhead->ll_dbg = dbg;
2252     llhead->ll_kind = DW_LKIND_expression;
2253 
2254     /*  An empty location description (block length 0)
2255         means the code generator emitted no variable,
2256         the variable was not generated,
2257         it was unused or perhaps never tested
2258         after being set. Dwarf2,
2259         section 2.4.1 In other words, it is not
2260         an error, and we don't
2261         test for block length 0 specially here.  */
2262 
2263     /* Fills in the locdesc and its operators list at index 0 */
2264     res = _dwarf_fill_in_locdesc_op_c(dbg,
2265         0,
2266         llhead,
2267         &loc_block,
2268         address_size,
2269         offset_size,
2270         version_stamp,
2271         lowpc,
2272         highpc,
2273         DW_LKIND_expression,
2274         error);
2275     if (res != DW_DLV_OK) {
2276         /* low level error already set: let it be passed back */
2277         dwarf_loc_head_c_dealloc(llhead);
2278         return (DW_DLV_ERROR);
2279     }
2280     *loc_head = llhead;
2281     *listlen = local_listlen;
2282     return (DW_DLV_OK);
2283 }
2284 
2285 
2286 /*  New June 2020. */
2287 int
dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head,Dwarf_Unsigned index,Dwarf_Small * lle_value_out,Dwarf_Unsigned * rawval1,Dwarf_Unsigned * rawval2,Dwarf_Bool * debug_addr_unavailable,Dwarf_Addr * lowpc_out,Dwarf_Addr * hipc_out,Dwarf_Unsigned * loclist_expr_op_count_out,Dwarf_Locdesc_c * locdesc_entry_out,Dwarf_Small * loclist_source_out,Dwarf_Unsigned * expression_offset_out,Dwarf_Unsigned * locdesc_offset_out,Dwarf_Error * error)2288 dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head,
2289    Dwarf_Unsigned   index,
2290    Dwarf_Small    * lle_value_out,
2291    Dwarf_Unsigned * rawval1,
2292    Dwarf_Unsigned * rawval2,
2293    Dwarf_Bool     * debug_addr_unavailable,
2294    Dwarf_Addr     * lowpc_out, /* 'cooked' value */
2295    Dwarf_Addr     * hipc_out, /* 'cooked' value */
2296    Dwarf_Unsigned * loclist_expr_op_count_out,
2297    /* Returns pointer to the specific locdesc of the index; */
2298    Dwarf_Locdesc_c* locdesc_entry_out,
2299    Dwarf_Small    * loclist_source_out, /* 0,1, or 2 */
2300    Dwarf_Unsigned * expression_offset_out,
2301    Dwarf_Unsigned * locdesc_offset_out,
2302    Dwarf_Error    * error)
2303 {
2304     Dwarf_Locdesc_c descs_base =  0;
2305     Dwarf_Locdesc_c desc =  0;
2306     Dwarf_Unsigned desc_count = 0;
2307     Dwarf_Debug dbg;
2308 
2309     desc_count = loclist_head->ll_locdesc_count;
2310     descs_base  = loclist_head->ll_locdesc;
2311     dbg = loclist_head->ll_dbg;
2312     if (index >= desc_count) {
2313         _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR);
2314         return (DW_DLV_ERROR);
2315     }
2316     desc = descs_base + index;
2317     *lle_value_out = desc->ld_lle_value;
2318     *rawval1 = desc->ld_rawlow;
2319     *rawval2 = desc->ld_rawhigh;
2320     *lowpc_out = desc->ld_lopc;
2321     *hipc_out = desc->ld_highpc;
2322     *debug_addr_unavailable = desc->ld_index_failed;
2323     *loclist_expr_op_count_out = desc->ld_cents;
2324     *locdesc_entry_out = desc;
2325     *loclist_source_out = desc->ld_kind;
2326     *expression_offset_out = desc->ld_section_offset;
2327     *locdesc_offset_out = desc->ld_locdesc_offset;
2328     return DW_DLV_OK;
2329 }
2330 int
dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c loclist_head,Dwarf_Unsigned index,Dwarf_Small * lle_value_out,Dwarf_Addr * lowpc_out,Dwarf_Addr * hipc_out,Dwarf_Unsigned * loclist_count_out,Dwarf_Locdesc_c * locdesc_entry_out,Dwarf_Small * loclist_source_out,Dwarf_Unsigned * expression_offset_out,Dwarf_Unsigned * locdesc_offset_out,Dwarf_Error * error)2331 dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c loclist_head,
2332     Dwarf_Unsigned   index,
2333     Dwarf_Small    * lle_value_out,
2334     Dwarf_Addr     * lowpc_out,
2335     Dwarf_Addr     * hipc_out,
2336     Dwarf_Unsigned * loclist_count_out,
2337 
2338     /* Returns pointer to the specific locdesc of the index; */
2339     Dwarf_Locdesc_c* locdesc_entry_out,
2340     Dwarf_Small    * loclist_source_out, /* 0,1, or 2 */
2341     Dwarf_Unsigned * expression_offset_out,
2342     Dwarf_Unsigned * locdesc_offset_out,
2343     Dwarf_Error    * error)
2344 {
2345     int res = 0;
2346     Dwarf_Unsigned cookedlow = 0;
2347     Dwarf_Unsigned cookedhigh = 0;
2348     Dwarf_Bool debug_addr_unavailable = FALSE;
2349 
2350     res = dwarf_get_locdesc_entry_d(loclist_head,
2351         index,lle_value_out,
2352         lowpc_out,hipc_out,
2353         &debug_addr_unavailable,
2354         &cookedlow,&cookedhigh,
2355         loclist_count_out,
2356         locdesc_entry_out,
2357         loclist_source_out,
2358         expression_offset_out,
2359         locdesc_offset_out,
2360         error);
2361     return res;
2362 }
2363 
2364 
2365 int
dwarf_get_location_op_value_d(Dwarf_Locdesc_c locdesc,Dwarf_Unsigned index,Dwarf_Small * atom_out,Dwarf_Unsigned * operand1,Dwarf_Unsigned * operand2,Dwarf_Unsigned * operand3,Dwarf_Unsigned * rawop1,Dwarf_Unsigned * rawop2,Dwarf_Unsigned * rawop3,Dwarf_Unsigned * offset_for_branch,Dwarf_Error * error)2366 dwarf_get_location_op_value_d(Dwarf_Locdesc_c locdesc,
2367     Dwarf_Unsigned   index,
2368     Dwarf_Small    * atom_out,
2369     Dwarf_Unsigned * operand1,
2370     Dwarf_Unsigned * operand2,
2371     Dwarf_Unsigned * operand3,
2372     Dwarf_Unsigned * rawop1,
2373     Dwarf_Unsigned * rawop2,
2374     Dwarf_Unsigned * rawop3,
2375     Dwarf_Unsigned * offset_for_branch,
2376     Dwarf_Error*     error)
2377 {
2378     Dwarf_Loc_Expr_Op op = 0;
2379     Dwarf_Unsigned max = locdesc->ld_cents;
2380 
2381     if(index >= max) {
2382         Dwarf_Debug dbg = locdesc->ld_loclist_head->ll_dbg;
2383         _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR);
2384         return (DW_DLV_ERROR);
2385     }
2386     op = locdesc->ld_s + index;
2387     *atom_out = op->lr_atom;
2388     *operand1 = op->lr_number;
2389     *operand2 = op->lr_number2;
2390     *operand3 = op->lr_number3;
2391     *rawop1 = op->lr_raw1;
2392     *rawop2 = op->lr_raw2;
2393     *rawop3 = op->lr_raw3;
2394     *offset_for_branch = op->lr_offset;
2395     return DW_DLV_OK;
2396 }
2397 
2398 
2399 int
dwarf_get_location_op_value_c(Dwarf_Locdesc_c locdesc,Dwarf_Unsigned index,Dwarf_Small * atom_out,Dwarf_Unsigned * operand1,Dwarf_Unsigned * operand2,Dwarf_Unsigned * operand3,Dwarf_Unsigned * offset_for_branch,Dwarf_Error * error)2400 dwarf_get_location_op_value_c(Dwarf_Locdesc_c locdesc,
2401     Dwarf_Unsigned   index,
2402     Dwarf_Small    * atom_out,
2403     Dwarf_Unsigned * operand1,
2404     Dwarf_Unsigned * operand2,
2405     Dwarf_Unsigned * operand3,
2406     Dwarf_Unsigned * offset_for_branch,
2407     Dwarf_Error*     error)
2408 {
2409     Dwarf_Unsigned raw1 = 0;
2410     Dwarf_Unsigned raw2 = 0;
2411     Dwarf_Unsigned raw3 = 0;
2412     int res = 0;
2413 
2414     res = dwarf_get_location_op_value_d(locdesc,
2415         index,atom_out,
2416         operand1,operand2,operand3,
2417         &raw1,&raw2,&raw3,
2418         offset_for_branch,
2419         error);
2420     return res;
2421 }
2422 
2423 void
dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head)2424 dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head)
2425 {
2426     Dwarf_Debug dbg = loclist_head->ll_dbg;
2427     _dwarf_free_loclists_head(loclist_head);
2428     dwarf_dealloc(dbg,loclist_head,DW_DLA_LOC_HEAD_C);
2429 }
2430 /* ============== End of the October 2015 interfaces. */
2431