1 /*
2
3 Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of version 2.1 of the GNU Lesser General Public License
8 as published by the Free Software Foundation.
9
10 This program is distributed in the hope that it would be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 Further, this software is distributed without any warranty that it is
15 free of the rightful claim of any third person regarding infringement
16 or the like. Any license provided herein, whether implied or
17 otherwise, applies only to this software file. Patent licenses, if
18 any, provided herein do not apply to combinations of this program with
19 other software, or any other product whatsoever.
20
21 You should have received a copy of the GNU Lesser General Public
22 License along with this program; if not, write the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24 USA.
25
26 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27 Mountain View, CA 94043, or:
28
29 http://www.sgi.com
30
31 For further information regarding this notice, see:
32
33 http://oss.sgi.com/projects/GenInfo/NoticeExplan
34
35 */
36 /* The address of the Free Software Foundation is
37 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38 Boston, MA 02110-1301, USA.
39 SGI has moved from the Crittenden Lane address.
40 */
41
42
43
44
45 #include "config.h"
46 #include "dwarf_incl.h"
47 #include "dwarf_loc.h"
48 #include <stdio.h> /* for debugging only. */
49 #include <sys/types.h>
50
51 /*
52 Given a Dwarf_Block that represents a location expression,
53 this function returns a pointer to a Dwarf_Locdesc struct
54 that has its ld_cents field set to the number of location
55 operators in the block, and its ld_s field pointing to a
56 contiguous block of Dwarf_Loc structs. However, the
57 ld_lopc and ld_hipc values are uninitialized. Returns
58 NULL on error. This function assumes that the length of
59 the block is greater than 0. Zero length location expressions
60 to represent variables that have been optimized away are
61 handled in the calling function.
62 */
63 static Dwarf_Locdesc *
_dwarf_get_locdesc(Dwarf_Debug dbg,Dwarf_Block * loc_block,Dwarf_Half address_size,Dwarf_Addr lowpc,Dwarf_Addr highpc,Dwarf_Error * error)64 _dwarf_get_locdesc(Dwarf_Debug dbg,
65 Dwarf_Block * loc_block,
66 Dwarf_Half address_size,
67 Dwarf_Addr lowpc,
68 Dwarf_Addr highpc,
69 Dwarf_Error * error)
70 {
71 /* Size of the block containing the location expression. */
72 Dwarf_Unsigned loc_len = 0;
73
74 /* Sweeps the block containing the location expression. */
75 Dwarf_Small *loc_ptr = 0;
76
77 /* Current location operator. */
78 Dwarf_Small atom = 0;
79
80 /* Offset of current operator from start of block. */
81 Dwarf_Unsigned offset = 0;
82
83 /* Operands of current location operator. */
84 Dwarf_Unsigned operand1, operand2;
85
86 /* Used to chain the Dwarf_Loc_Chain_s structs. */
87 Dwarf_Loc_Chain curr_loc = NULL;
88 Dwarf_Loc_Chain prev_loc = NULL;
89 Dwarf_Loc_Chain head_loc = NULL;
90
91 /* Count of the number of location operators. */
92 Dwarf_Unsigned op_count = 0;
93
94 /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */
95 Dwarf_Loc *block_loc = 0;
96
97 /* Dwarf_Locdesc pointer to be returned. */
98 Dwarf_Locdesc *locdesc = 0;
99
100 Dwarf_Word leb128_length = 0;
101 Dwarf_Unsigned i = 0;
102
103 /* ***** BEGIN CODE ***** */
104
105 loc_len = loc_block->bl_len;
106 loc_ptr = loc_block->bl_data;
107
108 offset = 0;
109 op_count = 0;
110 while (offset < loc_len) {
111
112 operand1 = 0;
113 operand2 = 0;
114 op_count++;
115
116 atom = *(Dwarf_Small *) loc_ptr;
117 loc_ptr++;
118 offset++;
119
120 curr_loc =
121 (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN,
122 1);
123 if (curr_loc == NULL) {
124 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
125 return (NULL);
126 }
127 curr_loc->lc_offset = offset;
128 curr_loc->lc_atom = atom;
129 switch (atom) {
130
131 case DW_OP_reg0:
132 case DW_OP_reg1:
133 case DW_OP_reg2:
134 case DW_OP_reg3:
135 case DW_OP_reg4:
136 case DW_OP_reg5:
137 case DW_OP_reg6:
138 case DW_OP_reg7:
139 case DW_OP_reg8:
140 case DW_OP_reg9:
141 case DW_OP_reg10:
142 case DW_OP_reg11:
143 case DW_OP_reg12:
144 case DW_OP_reg13:
145 case DW_OP_reg14:
146 case DW_OP_reg15:
147 case DW_OP_reg16:
148 case DW_OP_reg17:
149 case DW_OP_reg18:
150 case DW_OP_reg19:
151 case DW_OP_reg20:
152 case DW_OP_reg21:
153 case DW_OP_reg22:
154 case DW_OP_reg23:
155 case DW_OP_reg24:
156 case DW_OP_reg25:
157 case DW_OP_reg26:
158 case DW_OP_reg27:
159 case DW_OP_reg28:
160 case DW_OP_reg29:
161 case DW_OP_reg30:
162 case DW_OP_reg31:
163 break;
164
165 case DW_OP_regx:
166 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
167 loc_ptr = loc_ptr + leb128_length;
168 offset = offset + leb128_length;
169 break;
170
171 case DW_OP_lit0:
172 case DW_OP_lit1:
173 case DW_OP_lit2:
174 case DW_OP_lit3:
175 case DW_OP_lit4:
176 case DW_OP_lit5:
177 case DW_OP_lit6:
178 case DW_OP_lit7:
179 case DW_OP_lit8:
180 case DW_OP_lit9:
181 case DW_OP_lit10:
182 case DW_OP_lit11:
183 case DW_OP_lit12:
184 case DW_OP_lit13:
185 case DW_OP_lit14:
186 case DW_OP_lit15:
187 case DW_OP_lit16:
188 case DW_OP_lit17:
189 case DW_OP_lit18:
190 case DW_OP_lit19:
191 case DW_OP_lit20:
192 case DW_OP_lit21:
193 case DW_OP_lit22:
194 case DW_OP_lit23:
195 case DW_OP_lit24:
196 case DW_OP_lit25:
197 case DW_OP_lit26:
198 case DW_OP_lit27:
199 case DW_OP_lit28:
200 case DW_OP_lit29:
201 case DW_OP_lit30:
202 case DW_OP_lit31:
203 operand1 = atom - DW_OP_lit0;
204 break;
205
206 case DW_OP_addr:
207 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned,
208 loc_ptr, address_size);
209 loc_ptr += address_size;
210 offset += address_size;
211 break;
212
213 case DW_OP_const1u:
214 operand1 = *(Dwarf_Small *) loc_ptr;
215 loc_ptr = loc_ptr + 1;
216 offset = offset + 1;
217 break;
218
219 case DW_OP_const1s:
220 operand1 = *(Dwarf_Sbyte *) loc_ptr;
221 SIGN_EXTEND(operand1,1);
222 loc_ptr = loc_ptr + 1;
223 offset = offset + 1;
224 break;
225
226 case DW_OP_const2u:
227 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
228 loc_ptr = loc_ptr + 2;
229 offset = offset + 2;
230 break;
231
232 case DW_OP_const2s:
233 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
234 SIGN_EXTEND(operand1,2);
235 loc_ptr = loc_ptr + 2;
236 offset = offset + 2;
237 break;
238
239 case DW_OP_const4u:
240 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
241 loc_ptr = loc_ptr + 4;
242 offset = offset + 4;
243 break;
244
245 case DW_OP_const4s:
246 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
247 SIGN_EXTEND(operand1,4);
248 loc_ptr = loc_ptr + 4;
249 offset = offset + 4;
250 break;
251
252 case DW_OP_const8u:
253 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
254 loc_ptr = loc_ptr + 8;
255 offset = offset + 8;
256 break;
257
258 case DW_OP_const8s:
259 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
260 loc_ptr = loc_ptr + 8;
261 offset = offset + 8;
262 break;
263
264 case DW_OP_constu:
265 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
266 loc_ptr = loc_ptr + leb128_length;
267 offset = offset + leb128_length;
268 break;
269
270 case DW_OP_consts:
271 operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
272 loc_ptr = loc_ptr + leb128_length;
273 offset = offset + leb128_length;
274 break;
275
276 case DW_OP_fbreg:
277 operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
278 loc_ptr = loc_ptr + leb128_length;
279 offset = offset + leb128_length;
280 break;
281
282 case DW_OP_breg0:
283 case DW_OP_breg1:
284 case DW_OP_breg2:
285 case DW_OP_breg3:
286 case DW_OP_breg4:
287 case DW_OP_breg5:
288 case DW_OP_breg6:
289 case DW_OP_breg7:
290 case DW_OP_breg8:
291 case DW_OP_breg9:
292 case DW_OP_breg10:
293 case DW_OP_breg11:
294 case DW_OP_breg12:
295 case DW_OP_breg13:
296 case DW_OP_breg14:
297 case DW_OP_breg15:
298 case DW_OP_breg16:
299 case DW_OP_breg17:
300 case DW_OP_breg18:
301 case DW_OP_breg19:
302 case DW_OP_breg20:
303 case DW_OP_breg21:
304 case DW_OP_breg22:
305 case DW_OP_breg23:
306 case DW_OP_breg24:
307 case DW_OP_breg25:
308 case DW_OP_breg26:
309 case DW_OP_breg27:
310 case DW_OP_breg28:
311 case DW_OP_breg29:
312 case DW_OP_breg30:
313 case DW_OP_breg31:
314 operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
315 loc_ptr = loc_ptr + leb128_length;
316 offset = offset + leb128_length;
317 break;
318
319 case DW_OP_bregx:
320 /* uleb reg num followed by sleb offset */
321 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
322 loc_ptr = loc_ptr + leb128_length;
323 offset = offset + leb128_length;
324
325 operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
326 loc_ptr = loc_ptr + leb128_length;
327 offset = offset + leb128_length;
328 break;
329
330 case DW_OP_dup:
331 case DW_OP_drop:
332 break;
333
334 case DW_OP_pick:
335 operand1 = *(Dwarf_Small *) loc_ptr;
336 loc_ptr = loc_ptr + 1;
337 offset = offset + 1;
338 break;
339
340 case DW_OP_over:
341 case DW_OP_swap:
342 case DW_OP_rot:
343 case DW_OP_deref:
344 break;
345
346 case DW_OP_deref_size:
347 operand1 = *(Dwarf_Small *) loc_ptr;
348 loc_ptr = loc_ptr + 1;
349 offset = offset + 1;
350 break;
351
352 case DW_OP_xderef:
353 break;
354
355 case DW_OP_xderef_size:
356 operand1 = *(Dwarf_Small *) loc_ptr;
357 loc_ptr = loc_ptr + 1;
358 offset = offset + 1;
359 break;
360
361 case DW_OP_abs:
362 case DW_OP_and:
363 case DW_OP_div:
364 case DW_OP_minus:
365 case DW_OP_mod:
366 case DW_OP_mul:
367 case DW_OP_neg:
368 case DW_OP_not:
369 case DW_OP_or:
370 case DW_OP_plus:
371 break;
372
373 case DW_OP_plus_uconst:
374 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
375 loc_ptr = loc_ptr + leb128_length;
376 offset = offset + leb128_length;
377 break;
378
379 case DW_OP_shl:
380 case DW_OP_shr:
381 case DW_OP_shra:
382 case DW_OP_xor:
383 break;
384
385 case DW_OP_le:
386 case DW_OP_ge:
387 case DW_OP_eq:
388 case DW_OP_lt:
389 case DW_OP_gt:
390 case DW_OP_ne:
391 break;
392
393 case DW_OP_skip:
394 case DW_OP_bra:
395 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
396 loc_ptr = loc_ptr + 2;
397 offset = offset + 2;
398 break;
399
400 case DW_OP_piece:
401 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
402 loc_ptr = loc_ptr + leb128_length;
403 offset = offset + leb128_length;
404 break;
405
406 case DW_OP_nop:
407 break;
408 case DW_OP_push_object_address: /* DWARF3 */
409 break;
410 case DW_OP_call2: /* DWARF3 */
411 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
412 loc_ptr = loc_ptr + 2;
413 offset = offset + 2;
414 break;
415
416 case DW_OP_call4: /* DWARF3 */
417 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
418 loc_ptr = loc_ptr + 4;
419 offset = offset + 4;
420 break;
421 case DW_OP_call_ref: /* DWARF3 */
422 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr,
423 dbg->de_length_size);
424 loc_ptr = loc_ptr + dbg->de_length_size;
425 offset = offset + dbg->de_length_size;
426 break;
427
428 case DW_OP_form_tls_address: /* DWARF3f */
429 break;
430 case DW_OP_call_frame_cfa: /* DWARF3f */
431 break;
432 case DW_OP_bit_piece: /* DWARF3f */
433 /* uleb size in bits followed by uleb offset in bits */
434 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
435 loc_ptr = loc_ptr + leb128_length;
436 offset = offset + leb128_length;
437
438 operand2 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
439 loc_ptr = loc_ptr + leb128_length;
440 offset = offset + leb128_length;
441 break;
442 case DW_OP_implicit_value: /* DWARF4 */
443 /* uleb length of value bytes followed by that
444 number of bytes of the value. */
445 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
446 loc_ptr = loc_ptr + leb128_length;
447 offset = offset + leb128_length;
448
449 /* Second operand is block of 'operand1' bytes of stuff. */
450 /* This using the second operand as a pointer
451 is quite ugly. */
452 /* This gets an ugly compiler warning. Sorry. */
453 operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr;
454 offset = offset + operand1;
455 loc_ptr = loc_ptr + operand1;
456 break;
457 case DW_OP_stack_value: /* DWARF4 */
458 break;
459
460
461 default:
462 _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
463 return (NULL);
464 }
465
466
467 curr_loc->lc_number = operand1;
468 curr_loc->lc_number2 = operand2;
469
470 if (head_loc == NULL)
471 head_loc = prev_loc = curr_loc;
472 else {
473 prev_loc->lc_next = curr_loc;
474 prev_loc = curr_loc;
475 }
476 }
477
478 block_loc =
479 (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count);
480 if (block_loc == NULL) {
481 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
482 return (NULL);
483 }
484
485 curr_loc = head_loc;
486 for (i = 0; i < op_count; i++) {
487 (block_loc + i)->lr_atom = curr_loc->lc_atom;
488 (block_loc + i)->lr_number = curr_loc->lc_number;
489 (block_loc + i)->lr_number2 = curr_loc->lc_number2;
490 (block_loc + i)->lr_offset = curr_loc->lc_offset;
491
492 prev_loc = curr_loc;
493 curr_loc = curr_loc->lc_next;
494 dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
495 }
496
497 locdesc =
498 (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
499 if (locdesc == NULL) {
500 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
501 return (NULL);
502 }
503
504 locdesc->ld_cents = op_count;
505 locdesc->ld_s = block_loc;
506 locdesc->ld_from_loclist = loc_block->bl_from_loclist;
507 locdesc->ld_section_offset = loc_block->bl_section_offset;
508 locdesc->ld_lopc = lowpc;
509 locdesc->ld_hipc = highpc;
510
511 return (locdesc);
512 }
513
514 /* Using a loclist offset to get the in-memory
515 address of .debug_loc data to read, returns the loclist
516 'header' info in return_block.
517 */
518
519 #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
520
521 static int
_dwarf_read_loc_section(Dwarf_Debug dbg,Dwarf_Block * return_block,Dwarf_Addr * lowpc,Dwarf_Addr * hipc,Dwarf_Off sec_offset,Dwarf_Half address_size,Dwarf_Error * error)522 _dwarf_read_loc_section(Dwarf_Debug dbg,
523 Dwarf_Block * return_block,
524 Dwarf_Addr * lowpc, Dwarf_Addr * hipc,
525 Dwarf_Off sec_offset,
526 Dwarf_Half address_size,
527 Dwarf_Error * error)
528 {
529 Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset;
530
531 Dwarf_Addr start_addr = 0;
532 Dwarf_Addr end_addr = 0;
533 Dwarf_Half exprblock_size = 0;
534 Dwarf_Unsigned exprblock_off =
535 2 * address_size + sizeof(Dwarf_Half);
536
537 if (sec_offset >= dbg->de_debug_loc.dss_size) {
538 /* We're at the end. No more present. */
539 return DW_DLV_NO_ENTRY;
540 }
541
542 /* If it goes past end, error */
543 if (exprblock_off > dbg->de_debug_loc.dss_size) {
544 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
545 return DW_DLV_ERROR;
546 }
547
548 READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size);
549 READ_UNALIGNED(dbg, end_addr, Dwarf_Addr,
550 beg + address_size, address_size);
551 if (start_addr == 0 && end_addr == 0) {
552 /* If start_addr and end_addr are 0, it's the end and no
553 exprblock_size field follows. */
554 exprblock_size = 0;
555 exprblock_off -= sizeof(Dwarf_Half);
556 } else if (start_addr == MAX_ADDR) {
557 /* end address is a base address, no exprblock_size field here
558 either */
559 exprblock_size = 0;
560 exprblock_off -= sizeof(Dwarf_Half);
561 } else {
562
563 READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half,
564 beg + 2 * address_size, sizeof(Dwarf_Half));
565 /* exprblock_size can be zero, means no expression */
566 if ((exprblock_off + exprblock_size) > dbg->de_debug_loc.dss_size) {
567 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
568 return DW_DLV_ERROR;
569 }
570 }
571 #undef MAX_ADDR
572 *lowpc = start_addr;
573 *hipc = end_addr;
574
575 return_block->bl_len = exprblock_size;
576 return_block->bl_from_loclist = 1;
577 return_block->bl_data = beg + exprblock_off;
578 return_block->bl_section_offset =
579 ((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc.dss_data;
580
581 return DW_DLV_OK;
582
583 }
584 static int
_dwarf_get_loclist_count(Dwarf_Debug dbg,Dwarf_Off loclist_offset,Dwarf_Half address_size,int * loclist_count,Dwarf_Error * error)585 _dwarf_get_loclist_count(Dwarf_Debug dbg,
586 Dwarf_Off loclist_offset,
587 Dwarf_Half address_size,
588 int *loclist_count, Dwarf_Error * error)
589 {
590 int count = 0;
591 Dwarf_Off offset = loclist_offset;
592
593
594 for (;;) {
595 Dwarf_Block b;
596 Dwarf_Addr lowpc;
597 Dwarf_Addr highpc;
598 int res = _dwarf_read_loc_section(dbg, &b,
599 &lowpc, &highpc,
600 offset, address_size,error);
601
602 if (res != DW_DLV_OK) {
603 return res;
604 }
605 offset = b.bl_len + b.bl_section_offset;
606 if (lowpc == 0 && highpc == 0) {
607 break;
608 }
609 count++;
610 }
611 *loclist_count = count;
612 return DW_DLV_OK;
613 }
614
615 /* Helper routine to avoid code duplication.
616 */
617 static int
_dwarf_setup_loc(Dwarf_Attribute attr,Dwarf_Debug * dbg_ret,Dwarf_CU_Context * cucontext_ret,Dwarf_Half * form_ret,Dwarf_Error * error)618 _dwarf_setup_loc(Dwarf_Attribute attr,
619 Dwarf_Debug * dbg_ret,
620 Dwarf_CU_Context *cucontext_ret,
621 Dwarf_Half * form_ret, Dwarf_Error * error)
622 {
623 Dwarf_Debug dbg = 0;
624 Dwarf_Half form = 0;
625 int blkres = DW_DLV_ERROR;
626
627 if (attr == NULL) {
628 _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
629 return (DW_DLV_ERROR);
630 }
631 if (attr->ar_cu_context == NULL) {
632 _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
633 return (DW_DLV_ERROR);
634 }
635 *cucontext_ret = attr->ar_cu_context;
636
637 dbg = attr->ar_cu_context->cc_dbg;
638 if (dbg == NULL) {
639 _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
640 return (DW_DLV_ERROR);
641 }
642 *dbg_ret = dbg;
643 blkres = dwarf_whatform(attr, &form, error);
644 if (blkres != DW_DLV_OK) {
645 _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
646 return blkres;
647 }
648 *form_ret = form;
649 return DW_DLV_OK;
650 }
651
652 /* Helper routine to avoid code duplication.
653 */
654 static int
_dwarf_get_loclist_header_start(Dwarf_Debug dbg,Dwarf_Attribute attr,Dwarf_Unsigned * loclist_offset,Dwarf_Error * error)655 _dwarf_get_loclist_header_start(Dwarf_Debug dbg,
656 Dwarf_Attribute attr,
657 Dwarf_Unsigned * loclist_offset,
658 Dwarf_Error * error)
659 {
660 int blkres = dwarf_formudata(attr, loclist_offset, error);
661 if (blkres != DW_DLV_OK) {
662 return (blkres);
663 }
664
665 if (!dbg->de_debug_loc.dss_data) {
666 int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
667 if (secload != DW_DLV_OK) {
668 return secload;
669 }
670 }
671 return DW_DLV_OK;
672 }
673
674 /* When llbuf (see dwarf_loclist_n) is partially set up
675 and an error is encountered, tear it down as it
676 won't be used.
677 */
678 static void
_dwarf_cleanup_llbuf(Dwarf_Debug dbg,Dwarf_Locdesc ** llbuf,int count)679 _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count)
680 {
681 int i;
682 for (i = 0; i < count; ++i) {
683 dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
684 dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
685 }
686 dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
687 }
688
689 /*
690 Handles simple location entries and loclists.
691 Returns all the Locdesc's thru llbuf.
692
693 */
694 int
dwarf_loclist_n(Dwarf_Attribute attr,Dwarf_Locdesc *** llbuf_out,Dwarf_Signed * listlen_out,Dwarf_Error * error)695 dwarf_loclist_n(Dwarf_Attribute attr,
696 Dwarf_Locdesc *** llbuf_out,
697 Dwarf_Signed * listlen_out, Dwarf_Error * error)
698 {
699 Dwarf_Debug dbg;
700
701 /*
702 Dwarf_Attribute that describes the DW_AT_location in die, if
703 present. */
704 Dwarf_Attribute loc_attr = attr;
705
706 /* Dwarf_Block that describes a single location expression. */
707 Dwarf_Block loc_block;
708
709 /* A pointer to the current Dwarf_Locdesc read. */
710 Dwarf_Locdesc *locdesc = 0;
711
712 Dwarf_Half form = 0;
713 Dwarf_Addr lowpc = 0;
714 Dwarf_Addr highpc = 0;
715 Dwarf_Signed listlen = 0;
716 Dwarf_Locdesc **llbuf = 0;
717 Dwarf_CU_Context cucontext = 0;
718 unsigned address_size = 0;
719
720 int blkres = DW_DLV_ERROR;
721 int setup_res = DW_DLV_ERROR;
722
723 /* ***** BEGIN CODE ***** */
724 setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
725 if (setup_res != DW_DLV_OK) {
726 return setup_res;
727 }
728 address_size = cucontext->cc_address_size;
729 /* If this is a form_block then it's a location expression. If it's
730 DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
731 if (((cucontext->cc_version_stamp == CURRENT_VERSION_STAMP ||
732 cucontext->cc_version_stamp == CURRENT_VERSION_STAMP3) &&
733 (form == DW_FORM_data4 || form == DW_FORM_data8)) ||
734 (cucontext->cc_version_stamp == CURRENT_VERSION_STAMP4 &&
735 form == DW_FORM_sec_offset))
736 {
737
738
739 /* A reference to .debug_loc, with an offset in .debug_loc of a
740 loclist */
741 Dwarf_Unsigned loclist_offset = 0;
742 int off_res = DW_DLV_ERROR;
743 int count_res = DW_DLV_ERROR;
744 int loclist_count;
745 int lli;
746
747 off_res = _dwarf_get_loclist_header_start(dbg,
748 attr, &loclist_offset,
749 error);
750 if (off_res != DW_DLV_OK) {
751 return off_res;
752 }
753 count_res = _dwarf_get_loclist_count(dbg, loclist_offset,
754 address_size,
755 &loclist_count, error);
756 listlen = loclist_count;
757 if (count_res != DW_DLV_OK) {
758 return count_res;
759 }
760 if (loclist_count == 0) {
761 return DW_DLV_NO_ENTRY;
762 }
763
764 llbuf = (Dwarf_Locdesc **)
765 _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
766 if (!llbuf) {
767 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
768 return (DW_DLV_ERROR);
769 }
770
771 for (lli = 0; lli < loclist_count; ++lli) {
772 blkres = _dwarf_read_loc_section(dbg, &loc_block,
773 &lowpc,
774 &highpc,
775 loclist_offset,
776 address_size,
777 error);
778 if (blkres != DW_DLV_OK) {
779 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
780 return (blkres);
781 }
782 locdesc = _dwarf_get_locdesc(dbg, &loc_block,
783 address_size,
784 lowpc, highpc, error);
785 if (locdesc == NULL) {
786 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
787 /* low level error already set: let it be passed back */
788 return (DW_DLV_ERROR);
789 }
790 llbuf[lli] = locdesc;
791
792 /* Now get to next loclist entry offset. */
793 loclist_offset = loc_block.bl_section_offset +
794 loc_block.bl_len;
795 }
796
797
798 } else {
799 Dwarf_Block *tblock = 0;
800
801 blkres = dwarf_formblock(loc_attr, &tblock, error);
802 if (blkres != DW_DLV_OK) {
803 return (blkres);
804 }
805 loc_block = *tblock;
806 /* We copied tblock contents to the stack var, so can dealloc
807 tblock now. Avoids leaks. */
808 dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
809 listlen = 1; /* One by definition of a location entry. */
810 lowpc = 0; /* HACK */
811 highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
812
813 /* An empty location description (block length 0) means the
814 code generator emitted no variable, the variable was not
815 generated, it was unused or perhaps never tested after being
816 set. Dwarf2, section 2.4.1 In other words, it is not an
817 error, and we don't test for block length 0 specially here. */
818 locdesc = _dwarf_get_locdesc(dbg, &loc_block,
819 address_size,
820 lowpc, highpc, error);
821 if (locdesc == NULL) {
822 /* low level error already set: let it be passed back */
823 return (DW_DLV_ERROR);
824 }
825 llbuf = (Dwarf_Locdesc **)
826 _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
827 if (!llbuf) {
828 /* Free the locdesc we allocated but won't use. */
829 dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
830 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
831 return (DW_DLV_ERROR);
832 }
833 llbuf[0] = locdesc;
834 }
835
836 *llbuf_out = llbuf;
837 *listlen_out = listlen;
838 return (DW_DLV_OK);
839 }
840
841
842 /*
843 Handles only a location expression.
844 If called on a loclist, just returns one of those.
845 Cannot not handle a real loclist.
846 It returns the location expression as a loclist with
847 a single entry.
848 See dwarf_loclist_n() which handles any number
849 of location list entries.
850
851 This is the original definition, and it simply
852 does not work for loclists. Kept for compatibility.
853 */
854 int
dwarf_loclist(Dwarf_Attribute attr,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)855 dwarf_loclist(Dwarf_Attribute attr,
856 Dwarf_Locdesc ** llbuf,
857 Dwarf_Signed * listlen, Dwarf_Error * error)
858 {
859 Dwarf_Debug dbg;
860
861 /* Dwarf_Attribute that describes the DW_AT_location in die, if
862 present. */
863 Dwarf_Attribute loc_attr = attr;
864
865 /* Dwarf_Block that describes a single location expression. */
866 Dwarf_Block loc_block;
867
868 /* A pointer to the current Dwarf_Locdesc read. */
869 Dwarf_Locdesc *locdesc = 0;
870
871 Dwarf_Half form = 0;
872 Dwarf_Addr lowpc = 0;
873 Dwarf_Addr highpc = 0;
874 Dwarf_CU_Context cucontext = 0;
875 unsigned address_size = 0;
876
877 int blkres = DW_DLV_ERROR;
878 int setup_res = DW_DLV_ERROR;
879
880 /* ***** BEGIN CODE ***** */
881 setup_res = _dwarf_setup_loc(attr, &dbg, &cucontext, &form, error);
882 if (setup_res != DW_DLV_OK) {
883 return setup_res;
884 }
885 address_size = cucontext->cc_address_size;
886 /* If this is a form_block then it's a location expression. If it's
887 DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
888 if (((cucontext->cc_version_stamp == CURRENT_VERSION_STAMP ||
889 cucontext->cc_version_stamp == CURRENT_VERSION_STAMP3) &&
890 (form == DW_FORM_data4 || form == DW_FORM_data8)) ||
891 (cucontext->cc_version_stamp == CURRENT_VERSION_STAMP4 &&
892 form == DW_FORM_sec_offset))
893 {
894
895 /* A reference to .debug_loc, with an offset in .debug_loc of a
896 loclist */
897 Dwarf_Unsigned loclist_offset = 0;
898 int off_res = DW_DLV_ERROR;
899
900 off_res = _dwarf_get_loclist_header_start(dbg,
901 attr, &loclist_offset,
902 error);
903 if (off_res != DW_DLV_OK) {
904 return off_res;
905 }
906
907 /* With dwarf_loclist, just read a single entry */
908 blkres = _dwarf_read_loc_section(dbg, &loc_block,
909 &lowpc,
910 &highpc,
911 loclist_offset,
912 address_size,
913 error);
914 if (blkres != DW_DLV_OK) {
915 return (blkres);
916 }
917 } else {
918 Dwarf_Block *tblock = 0;
919
920 blkres = dwarf_formblock(loc_attr, &tblock, error);
921 if (blkres != DW_DLV_OK) {
922 return (blkres);
923 }
924 loc_block = *tblock;
925 /* We copied tblock contents to the stack var, so can dealloc
926 tblock now. Avoids leaks. */
927 dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
928 lowpc = 0; /* HACK */
929 highpc = (Dwarf_Unsigned) (-1LL); /* HACK */
930 }
931
932 /* An empty location description (block length 0) means the code
933 generator emitted no variable, the variable was not generated,
934 it was unused or perhaps never tested after being set. Dwarf2,
935 section 2.4.1 In other words, it is not an error, and we don't
936 test for block length 0 specially here.
937 See *dwarf_loclist_n() which handles the general case, this case
938 handles only a single location expression. */
939 locdesc = _dwarf_get_locdesc(dbg, &loc_block,
940 address_size,
941 lowpc, highpc, error);
942 if (locdesc == NULL) {
943 /* low level error already set: let it be passed back */
944 return (DW_DLV_ERROR);
945 }
946
947 *llbuf = locdesc;
948 *listlen = 1;
949 return (DW_DLV_OK);
950 }
951
952
953
954 /*
955 Handles only a location expression.
956 It returns the location expression as a loclist with
957 a single entry.
958
959 Usable to access dwarf expressions from any source, but
960 specifically from
961 DW_CFA_def_cfa_expression
962 DW_CFA_expression
963 DW_CFA_val_expression
964
965 expression_in must point to a valid dwarf expression
966 set of bytes of length expression_length. Not
967 a DW_FORM_block*, just the expression bytes.
968
969 If the address_size != de_pointer_size this will not work
970 right. FIXME.
971 */
972 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)973 dwarf_loclist_from_expr(Dwarf_Debug dbg,
974 Dwarf_Ptr expression_in,
975 Dwarf_Unsigned expression_length,
976 Dwarf_Locdesc ** llbuf,
977 Dwarf_Signed * listlen, Dwarf_Error * error)
978 {
979 int res = 0;
980 Dwarf_Half addr_size = dbg->de_pointer_size;
981 res = dwarf_loclist_from_expr_a(dbg,expression_in,
982 expression_length, addr_size,llbuf,listlen,error);
983 return res;
984 }
985 /* New April 27 2009. Adding addr_size argument for the rare
986 * cases where an object has CUs with a different address_size. */
987 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)988 dwarf_loclist_from_expr_a(Dwarf_Debug dbg,
989 Dwarf_Ptr expression_in,
990 Dwarf_Unsigned expression_length,
991 Dwarf_Half addr_size,
992 Dwarf_Locdesc ** llbuf,
993 Dwarf_Signed * listlen, Dwarf_Error * error)
994 {
995 /* Dwarf_Block that describes a single location expression. */
996 Dwarf_Block loc_block;
997
998 /* A pointer to the current Dwarf_Locdesc read. */
999 Dwarf_Locdesc *locdesc = 0;
1000 Dwarf_Addr lowpc = 0;
1001 Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL);
1002
1003 memset(&loc_block,0,sizeof(loc_block));
1004 loc_block.bl_len = expression_length;
1005 loc_block.bl_data = expression_in;
1006 loc_block.bl_from_loclist = 0; /* Not from loclist. */
1007 loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
1008
1009 /* An empty location description (block length 0) means the code
1010 generator emitted no variable, the variable was not generated,
1011 it was unused or perhaps never tested after being set. Dwarf2,
1012 section 2.4.1 In other words, it is not an error, and we don't
1013 test for block length 0 specially here. */
1014 locdesc = _dwarf_get_locdesc(dbg, &loc_block,
1015 addr_size,lowpc, highpc, error);
1016 if (locdesc == NULL) {
1017 /* low level error already set: let it be passed back */
1018 return (DW_DLV_ERROR);
1019 }
1020
1021 *llbuf = locdesc;
1022 *listlen = 1;
1023 return (DW_DLV_OK);
1024 }
1025
1026 /* Usable to read a single loclist or to read a block of them
1027 or to read an entire section's loclists.
1028
1029 It's broken because it's not safe to read a loclist entry
1030 when we do not know the address size (in any object where
1031 address size can vary by compilation unit).
1032 */
1033
1034 /*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)1035 dwarf_get_loclist_entry(Dwarf_Debug dbg,
1036 Dwarf_Unsigned offset,
1037 Dwarf_Addr * hipc_offset,
1038 Dwarf_Addr * lopc_offset,
1039 Dwarf_Ptr * data,
1040 Dwarf_Unsigned * entry_len,
1041 Dwarf_Unsigned * next_entry,
1042 Dwarf_Error * error)
1043 {
1044 Dwarf_Block b;
1045 Dwarf_Addr lowpc = 0;
1046 Dwarf_Addr highpc = 0;
1047 Dwarf_Half address_size = 0;
1048 int res = DW_DLV_ERROR;
1049
1050 if (!dbg->de_debug_loc.dss_data) {
1051 int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error);
1052 if (secload != DW_DLV_OK) {
1053 return secload;
1054 }
1055 }
1056
1057 /* FIXME: address_size is not necessarily the same in every frame. */
1058 address_size = dbg->de_pointer_size;
1059 res = _dwarf_read_loc_section(dbg,
1060 &b, &lowpc, &highpc, offset,
1061 address_size,error);
1062 if (res != DW_DLV_OK) {
1063 return res;
1064 }
1065 *hipc_offset = highpc;
1066 *lopc_offset = lowpc;
1067 *entry_len = b.bl_len;
1068 *data = b.bl_data;
1069 *next_entry = b.bl_len + b.bl_section_offset;
1070 return DW_DLV_OK;
1071 }
1072
1073
1074