1 /*
2
3 Copyright (C) 2000-2006 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
46 #include "config.h"
47 #include "dwarf_incl.h"
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <sys/types.h>
51 #include "dwarf_frame.h"
52 #include "dwarf_arange.h" /* Using Arange as a way to build a
53 list */
54
55 #define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg ) \
56 do { \
57 if ((fde) == NULL) { \
58 _dwarf_error(NULL, error, DW_DLE_FDE_NULL); \
59 return (DW_DLV_ERROR); \
60 } \
61 (dbg)= (fde)->fd_dbg; \
62 if ((dbg) == NULL) { \
63 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\
64 return (DW_DLV_ERROR); \
65 } } while (0)
66
67
68 #define MIN(a,b) (((a) < (b))? a:b)
69
70 static void _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
71 int last_reg_num,
72 int initial_value);
73 static int dwarf_initialize_fde_table(Dwarf_Debug dbg,
74 struct Dwarf_Frame_s *fde_table,
75 unsigned table_real_data_size,
76 Dwarf_Error * error);
77 static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table);
78
79 #if 0
80 /* Only used for debugging libdwarf. */
81 static void dump_frame_rule(char *msg,
82 struct Dwarf_Reg_Rule_s *reg_rule);
83 #endif
84
85
86
87 /*
88 This function is the heart of the debug_frame stuff. Don't even
89 think of reading this without reading both the Libdwarf and
90 consumer API carefully first. This function basically executes
91 frame instructions contained in a Cie or an Fde, but does in a
92 number of different ways depending on the information sought.
93 Start_instr_ptr points to the first byte of the frame instruction
94 stream, and final_instr_ptr to the to the first byte after the
95 last.
96
97 The offsets returned in the frame instructions are factored. That
98 is they need to be multiplied by either the code_alignment_factor
99 or the data_alignment_factor, as appropriate to obtain the actual
100 offset. This makes it possible to expand an instruction stream
101 without the corresponding Cie. However, when an Fde frame instr
102 sequence is being expanded there must be a valid Cie with a pointer
103 to an initial table row.
104
105
106 If successful, returns DW_DLV_OK
107 And sets returned_count thru the pointer
108 if make_instr is true.
109 If make_instr is false returned_count
110 should NOT be used by the caller (returned_count
111 is set to 0 thru the pointer by this routine...)
112 If unsuccessful, returns DW_DLV_ERROR
113 and sets returned_error to the error code
114
115 It does not do a whole lot of input validation being a private
116 function. Please make sure inputs are valid.
117
118 (1) If make_instr is true, it makes a list of pointers to
119 Dwarf_Frame_Op structures containing the frame instructions
120 executed. A pointer to this list is returned in ret_frame_instr.
121 Make_instr is true only when a list of frame instructions is to be
122 returned. In this case since we are not interested in the contents
123 of the table, the input Cie can be NULL. This is the only case
124 where the inpute Cie can be NULL.
125
126 (2) If search_pc is true, frame instructions are executed till
127 either a location is reached that is greater than the search_pc_val
128 provided, or all instructions are executed. At this point the
129 last row of the table generated is returned in a structure.
130 A pointer to this structure is supplied in table.
131
132 (3) This function is also used to create the initial table row
133 defined by a Cie. In this case, the Dwarf_Cie pointer cie, is
134 NULL. For an FDE, however, cie points to the associated Cie.
135
136 make_instr - make list of frame instr? 0/1
137 ret_frame_instr - Ptr to list of ptrs to frame instrs
138 search_pc - Search for a pc value? 0/1
139 search_pc_val - Search for this pc value
140 initial_loc - Initial code location value.
141 start_instr_ptr - Ptr to start of frame instrs.
142 final_instr_ptr - Ptr just past frame instrs.
143 table - Ptr to struct with last row.
144 cie - Ptr to Cie used by the Fde.
145 Different cies may have distinct address-sizes, so the cie
146 is used, not de_pointer_size.
147
148 */
149
150 int
_dwarf_exec_frame_instr(Dwarf_Bool make_instr,Dwarf_Frame_Op ** ret_frame_instr,Dwarf_Bool search_pc,Dwarf_Addr search_pc_val,Dwarf_Addr initial_loc,Dwarf_Small * start_instr_ptr,Dwarf_Small * final_instr_ptr,Dwarf_Frame table,Dwarf_Cie cie,Dwarf_Debug dbg,Dwarf_Half reg_num_of_cfa,Dwarf_Sword * returned_count,int * returned_error)151 _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
152 Dwarf_Frame_Op ** ret_frame_instr,
153 Dwarf_Bool search_pc,
154 Dwarf_Addr search_pc_val,
155 Dwarf_Addr initial_loc,
156 Dwarf_Small * start_instr_ptr,
157 Dwarf_Small * final_instr_ptr,
158 Dwarf_Frame table,
159 Dwarf_Cie cie,
160 Dwarf_Debug dbg,
161 Dwarf_Half reg_num_of_cfa,
162 Dwarf_Sword * returned_count,
163 int *returned_error)
164 {
165 #define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg) \
166 do { \
167 if ((macreg) >= (machigh_reg) || (macreg) < 0) { \
168 SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \
169 } \
170 } /*CONSTCOND */ while(0)
171 #define SIMPLE_ERROR_RETURN(code) \
172 free(localregtab); \
173 *returned_error = code; \
174 return DW_DLV_ERROR
175
176 /* Sweeps the frame instructions. */
177 Dwarf_Small *instr_ptr;
178
179 /* Register numbers not limited to just 255, thus not using
180 Dwarf_Small. */
181 typedef int reg_num_type;
182
183 Dwarf_Unsigned factored_N_value;
184 Dwarf_Signed signed_factored_N_value;
185 Dwarf_Addr current_loc = initial_loc; /* code location/
186 pc-value
187 corresponding to the
188 frame instructions.
189 Starts at zero when
190 the caller has no
191 value to pass in. */
192
193 /* Must be min de_pointer_size bytes and must be at least sizeof
194 Dwarf_ufixed */
195 Dwarf_Unsigned adv_loc = 0;
196
197 int reg_count = dbg->de_frame_reg_rules_entry_count;
198 struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count,
199 sizeof(struct
200 Dwarf_Reg_Rule_s));
201
202 struct Dwarf_Reg_Rule_s cfa_reg;
203
204
205 /* This is used to end executing frame instructions. */
206 /* Becomes true when search_pc is true and current_loc */
207 /* is greater than search_pc_val. */
208 Dwarf_Bool search_over = false;
209
210 /* Used by the DW_FRAME_advance_loc instr */
211 /* to hold the increment in pc value. */
212 Dwarf_Addr adv_pc;
213
214 /* Contains the length in bytes of */
215 /* an leb128 encoded number. */
216 Dwarf_Word leb128_length;
217
218 Dwarf_Half address_size = (cie)? cie->ci_address_size:
219 dbg->de_pointer_size;
220
221 /* Counts the number of frame instructions executed. */
222 Dwarf_Word instr_count = 0;
223
224 /*
225 These contain the current fields of the current frame
226 instruction. */
227 Dwarf_Small fp_base_op = 0;
228 Dwarf_Small fp_extended_op;
229 reg_num_type fp_register;
230
231 /* The value in fp_offset may be signed, though we call it
232 unsigned. This works ok for 2-s complement arithmetic. */
233 Dwarf_Unsigned fp_offset;
234 Dwarf_Off fp_instr_offset;
235
236 /*
237 Stack_table points to the row (Dwarf_Frame ie) being pushed or
238 popped by a remember or restore instruction. Top_stack points to
239 the top of the stack of rows. */
240 Dwarf_Frame stack_table = NULL;
241 Dwarf_Frame top_stack = NULL;
242
243 /*
244 These are used only when make_instr is true. Curr_instr is a
245 pointer to the current frame instruction executed.
246 Curr_instr_ptr, head_instr_list, and curr_instr_list are used to
247 form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is
248 used to deallocate the structs used to form the chain.
249 Head_instr_block points to a contiguous list of pointers to the
250 Dwarf_Frame_Op structs executed. */
251 Dwarf_Frame_Op *curr_instr;
252 Dwarf_Chain curr_instr_item, dealloc_instr_item;
253 Dwarf_Chain head_instr_chain = NULL;
254 Dwarf_Chain tail_instr_chain = NULL;
255 Dwarf_Frame_Op *head_instr_block;
256
257 /*
258 These are the alignment_factors taken from the Cie provided.
259 When no input Cie is provided they are set to 1, because only
260 factored offsets are required. */
261 Dwarf_Sword code_alignment_factor = 1;
262 Dwarf_Sword data_alignment_factor = 1;
263
264 /*
265 This flag indicates when an actual alignment factor is needed.
266 So if a frame instruction that computes an offset using an
267 alignment factor is encountered when this flag is set, an error
268 is returned because the Cie did not have a valid augmentation. */
269 Dwarf_Bool need_augmentation = false;
270
271 Dwarf_Word i;
272
273 /* Initialize first row from associated Cie. Using temp regs
274 explicity */
275
276 if (localregtab == 0) {
277 SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL);
278 }
279 {
280 struct Dwarf_Reg_Rule_s *t1reg = localregtab;
281 struct Dwarf_Reg_Rule_s *t1end = t1reg + reg_count;
282
283 if (cie != NULL && cie->ci_initial_table != NULL) {
284 struct Dwarf_Reg_Rule_s *t2reg =
285 cie->ci_initial_table->fr_reg;
286
287 if (reg_count != cie->ci_initial_table->fr_reg_count) {
288 /* Should never happen, it makes no sense to have the
289 table sizes change. There is no real allowance for
290 the set of registers to change dynamically in a
291 single Dwarf_Debug (except the size can be set near
292 initial Dwarf_Debug creation time). */
293 SIMPLE_ERROR_RETURN
294 (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH);
295 }
296
297 for (; t1reg < t1end; t1reg++, t2reg++) {
298 *t1reg = *t2reg;
299 }
300 cfa_reg = cie->ci_initial_table->fr_cfa_rule;
301 } else {
302 _dwarf_init_regrule_table(t1reg,
303 reg_count,
304 dbg->de_frame_rule_initial_value);
305 _dwarf_init_regrule_table(&cfa_reg, 1,
306 dbg->de_frame_rule_initial_value);
307 }
308 }
309
310 /*
311 The idea here is that the code_alignment_factor and
312 data_alignment_factor which are needed for certain instructions
313 are valid only when the Cie has a proper augmentation string. So
314 if the augmentation is not right, only Frame instruction can be
315 read. */
316 if (cie != NULL && cie->ci_augmentation != NULL) {
317 code_alignment_factor = cie->ci_code_alignment_factor;
318 data_alignment_factor = cie->ci_data_alignment_factor;
319 } else {
320 need_augmentation = !make_instr;
321 }
322
323 instr_ptr = start_instr_ptr;
324 while ((instr_ptr < final_instr_ptr) && (!search_over)) {
325 Dwarf_Small instr = 0;
326 Dwarf_Small opcode = 0;
327 reg_num_type reg_no = 0;
328
329 fp_instr_offset = instr_ptr - start_instr_ptr;
330 instr = *(Dwarf_Small *) instr_ptr;
331 instr_ptr += sizeof(Dwarf_Small);
332
333 fp_base_op = (instr & 0xc0) >> 6;
334 if ((instr & 0xc0) == 0x00) {
335 opcode = instr; /* is really extended op */
336 fp_extended_op = (instr & (~(0xc0))) & 0xff;
337 } else {
338 opcode = instr & 0xc0; /* is base op */
339 fp_extended_op = 0;
340 }
341
342 fp_register = 0;
343 fp_offset = 0;
344 switch (opcode) {
345 case DW_CFA_advance_loc:
346 {
347 /* base op */
348 fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
349
350 if (need_augmentation) {
351 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
352 }
353 adv_pc = adv_pc * code_alignment_factor;
354
355 search_over = search_pc &&
356 (current_loc + adv_pc > search_pc_val);
357 /* If gone past pc needed, retain old pc. */
358 if (!search_over) {
359 current_loc = current_loc + adv_pc;
360 }
361 break;
362 }
363
364 case DW_CFA_offset:
365 { /* base op */
366 reg_no =
367 (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK);
368 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
369
370 factored_N_value =
371 _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
372 instr_ptr = instr_ptr + leb128_length;
373
374 fp_register = reg_no;
375 fp_offset = factored_N_value;
376
377 if (need_augmentation) {
378 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
379 }
380
381 localregtab[reg_no].ru_is_off = 1;
382 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
383 localregtab[reg_no].ru_register = reg_num_of_cfa;
384 localregtab[reg_no].ru_offset_or_block_len =
385 factored_N_value * data_alignment_factor;
386
387 break;
388 }
389
390 case DW_CFA_restore:
391 { /* base op */
392 reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
393 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
394
395 fp_register = reg_no;
396
397 if (cie != NULL && cie->ci_initial_table != NULL)
398 localregtab[reg_no] =
399 cie->ci_initial_table->fr_reg[reg_no];
400 else if (!make_instr) {
401 SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT);
402 }
403
404 break;
405 }
406 case DW_CFA_set_loc:
407 {
408 Dwarf_Addr new_loc = 0;
409
410 READ_UNALIGNED(dbg, new_loc, Dwarf_Addr,
411 instr_ptr, address_size);
412 instr_ptr += address_size;
413 if (new_loc != 0 && current_loc != 0) {
414 /* Pre-relocation or before current_loc is set the
415 test comparing new_loc and current_loc makes no
416 sense. Testing for non-zero (above) is a way
417 (fallible) to check that current_loc, new_loc
418 are already relocated. */
419 if (new_loc <= current_loc) {
420 /* Within a frame, address must increase.
421 Seemingly it has not. Seems to be an error. */
422
423 SIMPLE_ERROR_RETURN
424 (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
425 }
426 }
427
428 search_over = search_pc && (new_loc > search_pc_val);
429
430 /* If gone past pc needed, retain old pc. */
431 if (!search_over) {
432 current_loc = new_loc;
433 }
434 fp_offset = new_loc;
435 break;
436 }
437
438 case DW_CFA_advance_loc1:
439 {
440 fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr;
441 instr_ptr += sizeof(Dwarf_Small);
442
443 if (need_augmentation) {
444 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
445 }
446 adv_loc *= code_alignment_factor;
447
448 search_over = search_pc &&
449 (current_loc + adv_loc > search_pc_val);
450
451 /* If gone past pc needed, retain old pc. */
452 if (!search_over) {
453 current_loc = current_loc + adv_loc;
454 }
455 break;
456 }
457
458 case DW_CFA_advance_loc2:
459 {
460 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
461 instr_ptr, sizeof(Dwarf_Half));
462 instr_ptr += sizeof(Dwarf_Half);
463 fp_offset = adv_loc;
464
465 if (need_augmentation) {
466 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
467 }
468 adv_loc *= code_alignment_factor;
469
470 search_over = search_pc &&
471 (current_loc + adv_loc > search_pc_val);
472
473 /* If gone past pc needed, retain old pc. */
474 if (!search_over) {
475 current_loc = current_loc + adv_loc;
476 }
477 break;
478 }
479
480 case DW_CFA_advance_loc4:
481 {
482 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
483 instr_ptr, sizeof(Dwarf_ufixed));
484 instr_ptr += sizeof(Dwarf_ufixed);
485 fp_offset = adv_loc;
486
487 if (need_augmentation) {
488 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
489 }
490 adv_loc *= code_alignment_factor;
491
492 search_over = search_pc &&
493 (current_loc + adv_loc > search_pc_val);
494
495 /* If gone past pc needed, retain old pc. */
496 if (!search_over) {
497 current_loc = current_loc + adv_loc;
498 }
499 break;
500 }
501
502 case DW_CFA_offset_extended:
503 {
504 Dwarf_Unsigned lreg;
505
506 DECODE_LEB128_UWORD(instr_ptr, lreg);
507 reg_no = (reg_num_type) lreg;
508 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);;
509 factored_N_value =
510 _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
511 instr_ptr += leb128_length;
512
513 if (need_augmentation) {
514 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
515 }
516 localregtab[reg_no].ru_is_off = 1;
517 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
518 localregtab[reg_no].ru_register = reg_num_of_cfa;
519 localregtab[reg_no].ru_offset_or_block_len = factored_N_value *
520 data_alignment_factor;
521
522 fp_register = reg_no;
523 fp_offset = factored_N_value;
524 break;
525 }
526
527 case DW_CFA_restore_extended:
528 {
529 Dwarf_Unsigned lreg;
530
531 DECODE_LEB128_UWORD(instr_ptr, lreg);
532 reg_no = (reg_num_type) lreg;
533
534 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
535
536 if (cie != NULL && cie->ci_initial_table != NULL) {
537 localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
538 } else {
539 if (!make_instr) {
540 SIMPLE_ERROR_RETURN
541 (DW_DLE_DF_MAKE_INSTR_NO_INIT);
542 }
543 }
544
545 fp_register = reg_no;
546 break;
547 }
548
549 case DW_CFA_undefined:
550 {
551 Dwarf_Unsigned lreg;
552
553 DECODE_LEB128_UWORD(instr_ptr, lreg);
554 reg_no = (reg_num_type) lreg;
555 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
556
557 localregtab[reg_no].ru_is_off = 0;
558 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
559 localregtab[reg_no].ru_register =
560 dbg->de_frame_undefined_value_number;
561 localregtab[reg_no].ru_offset_or_block_len = 0;
562
563 fp_register = reg_no;
564 break;
565 }
566
567 case DW_CFA_same_value:
568 {
569 Dwarf_Unsigned lreg;
570
571 DECODE_LEB128_UWORD(instr_ptr, lreg);
572 reg_no = (reg_num_type) lreg;
573 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
574
575 localregtab[reg_no].ru_is_off = 0;
576 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
577 localregtab[reg_no].ru_register =
578 dbg->de_frame_same_value_number;
579 localregtab[reg_no].ru_offset_or_block_len = 0;
580 fp_register = reg_no;
581 break;
582 }
583
584 case DW_CFA_register:
585 {
586 Dwarf_Unsigned lreg;
587 reg_num_type reg_noA = 0;
588 reg_num_type reg_noB = 0;
589
590 DECODE_LEB128_UWORD(instr_ptr, lreg);
591 reg_noA = (reg_num_type) lreg;
592
593 ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count);
594
595 DECODE_LEB128_UWORD(instr_ptr, lreg);
596 reg_noB = (reg_num_type) lreg;
597
598 if (reg_noB > reg_count) {
599 SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH);
600 }
601
602
603 localregtab[reg_noA].ru_is_off = 0;
604 localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET;
605 localregtab[reg_noA].ru_register = reg_noB;
606 localregtab[reg_noA].ru_offset_or_block_len = 0;
607
608 fp_register = reg_noA;
609 fp_offset = reg_noB;
610 break;
611 }
612
613 case DW_CFA_remember_state:
614 {
615 stack_table = (Dwarf_Frame)
616 _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
617 if (stack_table == NULL) {
618 SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
619 }
620
621 for (i = 0; i < reg_count; i++)
622 stack_table->fr_reg[i] = localregtab[i];
623 stack_table->fr_cfa_rule = cfa_reg;
624
625 if (top_stack != NULL)
626 stack_table->fr_next = top_stack;
627 top_stack = stack_table;
628
629 break;
630 }
631
632 case DW_CFA_restore_state:
633 {
634 if (top_stack == NULL) {
635 SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK);
636 }
637 stack_table = top_stack;
638 top_stack = stack_table->fr_next;
639
640 for (i = 0; i < reg_count; i++)
641 localregtab[i] = stack_table->fr_reg[i];
642 cfa_reg = stack_table->fr_cfa_rule;
643
644 dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
645 break;
646 }
647
648 case DW_CFA_def_cfa:
649 {
650 Dwarf_Unsigned lreg;
651
652 DECODE_LEB128_UWORD(instr_ptr, lreg);
653 reg_no = (reg_num_type) lreg;
654
655 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
656
657 factored_N_value =
658 _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
659 instr_ptr += leb128_length;
660
661 if (need_augmentation) {
662 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
663 }
664 cfa_reg.ru_is_off = 1;
665 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
666 cfa_reg.ru_register = reg_no;
667 cfa_reg.ru_offset_or_block_len = factored_N_value;
668
669 fp_register = reg_no;
670 fp_offset = factored_N_value;
671 break;
672 }
673
674 case DW_CFA_def_cfa_register:
675 {
676 Dwarf_Unsigned lreg;
677
678 DECODE_LEB128_UWORD(instr_ptr, lreg);
679 reg_no = (reg_num_type) lreg;
680 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
681
682 cfa_reg.ru_register = reg_no;
683 /* Do NOT set ru_offset_or_block_len or ru_is_off here.
684 See dwarf2/3 spec. */
685 fp_register = reg_no;
686 break;
687 }
688
689 case DW_CFA_def_cfa_offset:
690 {
691 factored_N_value =
692 _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
693 instr_ptr += leb128_length;
694
695 if (need_augmentation) {
696 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
697 }
698 /* Do set ru_is_off here, as here factored_N_value
699 counts. */
700 cfa_reg.ru_is_off = 1;
701 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
702 cfa_reg.ru_offset_or_block_len = factored_N_value;
703
704 fp_offset = factored_N_value;
705 break;
706 }
707 case DW_CFA_nop:
708 {
709 break;
710 }
711 /* DWARF3 ops begin here. */
712 case DW_CFA_def_cfa_expression:
713 {
714 /* A single DW_FORM_block representing a dwarf
715 expression. The form block establishes the way to
716 compute the CFA. */
717 Dwarf_Unsigned block_len = 0;
718
719 DECODE_LEB128_UWORD(instr_ptr, block_len);
720 cfa_reg.ru_is_off = 0; /* arbitrary */
721 cfa_reg.ru_value_type = DW_EXPR_EXPRESSION;
722 cfa_reg.ru_offset_or_block_len = block_len;
723 cfa_reg.ru_block = instr_ptr;
724 fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
725 instr_ptr += block_len;
726 }
727 break;
728 case DW_CFA_expression:
729 {
730 /* An unsigned leb128 value is the first operand (a
731 register number). The second operand is single
732 DW_FORM_block representing a dwarf expression. The
733 evaluator pushes the CFA on the evaluation stack
734 then evaluates the expression to compute the value
735 of the register contents. */
736 Dwarf_Unsigned lreg = 0;
737 Dwarf_Unsigned block_len = 0;
738
739 DECODE_LEB128_UWORD(instr_ptr, lreg);
740 reg_no = (reg_num_type) lreg;
741 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
742 DECODE_LEB128_UWORD(instr_ptr, block_len);
743 localregtab[lreg].ru_is_off = 0; /* arbitrary */
744 localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION;
745 localregtab[lreg].ru_offset_or_block_len = block_len;
746 localregtab[lreg].ru_block = instr_ptr;
747 fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
748 fp_register = reg_no;
749 instr_ptr += block_len;
750 }
751 break;
752 case DW_CFA_offset_extended_sf:
753 {
754 /* The first operand is an unsigned leb128 register
755 number. The second is a signed factored offset.
756 Identical to DW_CFA_offset_extended except the
757 secondoperand is signed */
758 Dwarf_Unsigned lreg;
759
760 DECODE_LEB128_UWORD(instr_ptr, lreg);
761 reg_no = (reg_num_type) lreg;
762 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
763 signed_factored_N_value =
764 _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
765 instr_ptr += leb128_length;
766
767 if (need_augmentation) {
768 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
769 }
770 localregtab[reg_no].ru_is_off = 1;
771 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
772 localregtab[reg_no].ru_register = reg_num_of_cfa;
773 localregtab[reg_no].ru_offset_or_block_len =
774 signed_factored_N_value * data_alignment_factor;
775
776 fp_register = reg_no;
777 fp_offset = signed_factored_N_value;
778 }
779 break;
780 case DW_CFA_def_cfa_sf:
781 {
782 /* The first operand is an unsigned leb128 register
783 number. The second is a signed leb128 factored
784 offset. Identical to DW_CFA_def_cfa except that the
785 second operand is signed and factored. */
786 Dwarf_Unsigned lreg;
787
788 DECODE_LEB128_UWORD(instr_ptr, lreg);
789 reg_no = (reg_num_type) lreg;
790 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
791
792 signed_factored_N_value =
793 _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
794 instr_ptr += leb128_length;
795
796 if (need_augmentation) {
797 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
798 }
799 cfa_reg.ru_is_off = 1;
800 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
801 cfa_reg.ru_register = reg_no;
802 cfa_reg.ru_offset_or_block_len =
803 signed_factored_N_value * data_alignment_factor;
804
805 fp_register = reg_no;
806 fp_offset = signed_factored_N_value;
807 }
808 break;
809 case DW_CFA_def_cfa_offset_sf:
810 {
811 /* The operand is a signed leb128 operand representing
812 a factored offset. Identical to
813 DW_CFA_def_cfa_offset excep the operand is signed
814 and factored. */
815
816 signed_factored_N_value =
817 _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
818 instr_ptr += leb128_length;
819
820 if (need_augmentation) {
821 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
822 }
823 /* Do set ru_is_off here, as here factored_N_value
824 counts. */
825 cfa_reg.ru_is_off = 1;
826 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
827 cfa_reg.ru_offset_or_block_len =
828 signed_factored_N_value * data_alignment_factor;
829
830 fp_offset = signed_factored_N_value;
831 }
832 break;
833 case DW_CFA_val_offset:
834 {
835 /* The first operand is an unsigned leb128 register
836 number. The second is a factored unsigned offset.
837 Makes the register be a val_offset(N) rule with N =
838 factored_offset*data_alignment_factor. */
839
840 Dwarf_Unsigned lreg;
841
842 DECODE_LEB128_UWORD(instr_ptr, lreg);
843 reg_no = (reg_num_type) lreg;
844
845 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
846
847 factored_N_value =
848 _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
849 instr_ptr += leb128_length;
850
851 if (need_augmentation) {
852 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
853 }
854 /* Do set ru_is_off here, as here factored_N_value
855 counts. */
856 localregtab[reg_no].ru_is_off = 1;
857 localregtab[reg_no].ru_register = reg_num_of_cfa;
858 localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
859 localregtab[reg_no].ru_offset_or_block_len =
860 factored_N_value * data_alignment_factor;
861
862 fp_offset = factored_N_value;
863 break;
864 }
865 case DW_CFA_val_offset_sf:
866 {
867 /* The first operand is an unsigned leb128 register
868 number. The second is a factored signed offset.
869 Makes the register be a val_offset(N) rule with N =
870 factored_offset*data_alignment_factor. */
871 Dwarf_Unsigned lreg;
872
873 DECODE_LEB128_UWORD(instr_ptr, lreg);
874 reg_no = (reg_num_type) lreg;
875
876 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
877 signed_factored_N_value =
878 _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
879 instr_ptr += leb128_length;
880
881 if (need_augmentation) {
882 SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
883 }
884 /* Do set ru_is_off here, as here factored_N_value
885 counts. */
886 localregtab[reg_no].ru_is_off = 1;
887 localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
888 localregtab[reg_no].ru_offset_or_block_len =
889 signed_factored_N_value * data_alignment_factor;
890
891 fp_offset = signed_factored_N_value;
892
893 }
894 break;
895 case DW_CFA_val_expression:
896 {
897 /* The first operand is an unsigned leb128 register
898 number. The second is a DW_FORM_block representing a
899 DWARF expression. The rule for the register number
900 becomes a val_expression(E) rule. */
901 Dwarf_Unsigned lreg = 0;
902 Dwarf_Unsigned block_len = 0;
903
904 DECODE_LEB128_UWORD(instr_ptr, lreg);
905 reg_no = (reg_num_type) lreg;
906 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
907 DECODE_LEB128_UWORD(instr_ptr, block_len);
908 localregtab[lreg].ru_is_off = 0; /* arbitrary */
909 localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION;
910 localregtab[lreg].ru_offset_or_block_len = block_len;
911 localregtab[lreg].ru_block = instr_ptr;
912 fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
913
914 instr_ptr += block_len;
915 fp_register = reg_no;
916
917 }
918 break;
919
920 /* END DWARF3 new ops. */
921
922
923 #ifdef DW_CFA_GNU_window_save
924 case DW_CFA_GNU_window_save:
925 {
926 /* no information: this just tells unwinder to restore
927 the window registers from the previous frame's
928 window save area */
929 break;
930 }
931 #endif
932 #ifdef DW_CFA_GNU_args_size
933 /* single uleb128 is the current arg area size in bytes. No
934 register exists yet to save this in */
935 case DW_CFA_GNU_args_size:
936 {
937 Dwarf_Unsigned lreg;
938
939 DECODE_LEB128_UWORD(instr_ptr, lreg);
940 reg_no = (reg_num_type) lreg;
941
942 break;
943 }
944 #endif
945 default:
946 /* ERROR, we have an opcode we know nothing about. Memory
947 leak here, but an error like this is not supposed to
948 happen so we ignore the leak. These used to be ignored,
949 now we notice and report. */
950 SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
951
952 }
953
954 if (make_instr) {
955 instr_count++;
956
957 curr_instr = (Dwarf_Frame_Op *)
958 _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
959 if (curr_instr == NULL) {
960 SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
961 }
962
963 curr_instr->fp_base_op = fp_base_op;
964 curr_instr->fp_extended_op = fp_extended_op;
965 curr_instr->fp_register = fp_register;
966 curr_instr->fp_offset = fp_offset;
967 curr_instr->fp_instr_offset = fp_instr_offset;
968
969 curr_instr_item = (Dwarf_Chain)
970 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
971 if (curr_instr_item == NULL) {
972 SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
973 }
974
975 curr_instr_item->ch_item = curr_instr;
976 if (head_instr_chain == NULL)
977 head_instr_chain = tail_instr_chain = curr_instr_item;
978 else {
979 tail_instr_chain->ch_next = curr_instr_item;
980 tail_instr_chain = curr_instr_item;
981 }
982 }
983 }
984
985 /*
986 If frame instruction decoding was right we would stop exactly at
987 final_instr_ptr. */
988 if (instr_ptr > final_instr_ptr) {
989 SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
990 }
991
992 /* Fill in the actual output table, the space the caller passed in. */
993 if (table != NULL) {
994
995 struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg;
996 struct Dwarf_Reg_Rule_s *t3reg = localregtab;
997 struct Dwarf_Reg_Rule_s *t3end = t3reg + reg_count;
998
999 table->fr_loc = current_loc;
1000 for (; t3reg < t3end; t3reg++, t2reg++) {
1001 *t2reg = *t3reg;
1002 }
1003
1004 /* CONSTCOND */
1005 /* Do not update the main table with the cfa_reg.
1006 Just leave cfa_reg as cfa_reg. */
1007 table->fr_cfa_rule = cfa_reg;
1008 }
1009
1010 /* Dealloc anything remaining on stack. */
1011 for (; top_stack != NULL;) {
1012 stack_table = top_stack;
1013 top_stack = top_stack->fr_next;
1014 dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
1015 }
1016
1017 if (make_instr) {
1018 /* Allocate list of pointers to Dwarf_Frame_Op's. */
1019 head_instr_block = (Dwarf_Frame_Op *)
1020 _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
1021 if (head_instr_block == NULL) {
1022 SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
1023 }
1024
1025 /*
1026 Store pointers to Dwarf_Frame_Op's in this list and
1027 deallocate the structs that chain the Dwarf_Frame_Op's. */
1028 curr_instr_item = head_instr_chain;
1029 for (i = 0; i < instr_count; i++) {
1030 *(head_instr_block + i) =
1031 *(Dwarf_Frame_Op *) curr_instr_item->ch_item;
1032 dealloc_instr_item = curr_instr_item;
1033 curr_instr_item = curr_instr_item->ch_next;
1034 dwarf_dealloc(dbg, dealloc_instr_item->ch_item,
1035 DW_DLA_FRAME_OP);
1036 dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
1037 }
1038 *ret_frame_instr = head_instr_block;
1039
1040 *returned_count = (Dwarf_Sword) instr_count;
1041 } else {
1042 *returned_count = 0;
1043 }
1044 free(localregtab);
1045 return DW_DLV_OK;
1046 #undef ERROR_IF_REG_NUM_TOO_HIGH
1047 #undef SIMPLE_ERROR_RETURN
1048 }
1049
1050 /* Depending on version, either read the return address register
1051 as a ubyte or as an leb number.
1052 The form of this value changed for DWARF3.
1053 */
1054 Dwarf_Unsigned
_dwarf_get_return_address_reg(Dwarf_Small * frame_ptr,int version,unsigned long * size)1055 _dwarf_get_return_address_reg(Dwarf_Small * frame_ptr,
1056 int version, unsigned long *size)
1057 {
1058 Dwarf_Unsigned uvalue = 0;
1059 Dwarf_Word leb128_length = 0;
1060
1061 if (version == 1) {
1062 *size = 1;
1063 uvalue = *(unsigned char *) frame_ptr;
1064 return uvalue;
1065 }
1066 uvalue = _dwarf_decode_u_leb128(frame_ptr, &leb128_length);
1067 *size = leb128_length;
1068 return uvalue;
1069 }
1070
1071
1072 /* Trivial consumer function.
1073 */
1074 int
dwarf_get_cie_of_fde(Dwarf_Fde fde,Dwarf_Cie * cie_returned,Dwarf_Error * error)1075 dwarf_get_cie_of_fde(Dwarf_Fde fde,
1076 Dwarf_Cie * cie_returned, Dwarf_Error * error)
1077 {
1078 if (fde == NULL) {
1079 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
1080 return (DW_DLV_ERROR);
1081 }
1082
1083 *cie_returned = fde->fd_cie;
1084 return DW_DLV_OK;
1085
1086 }
1087
dwarf_get_cie_index(Dwarf_Cie cie,Dwarf_Signed * index,Dwarf_Error * error)1088 int dwarf_get_cie_index(
1089 Dwarf_Cie cie,
1090 Dwarf_Signed* index,
1091 Dwarf_Error* error )
1092 {
1093 if( cie == NULL )
1094 {
1095 _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
1096 return (DW_DLV_ERROR);
1097 }
1098
1099 *index = cie->ci_index;
1100 return (DW_DLV_OK);
1101 }
1102
1103
1104 /*
1105 For g++ .eh_frame fde and cie.
1106 the cie id is different as the
1107 definition of the cie_id in an fde
1108 is the distance back from the address of the
1109 value to the cie.
1110 Or 0 if this is a true cie.
1111 Non standard dwarf, designed this way to be
1112 convenient at run time for an allocated
1113 (mapped into memory as part of the running image) section.
1114 */
1115 int
dwarf_get_fde_list_eh(Dwarf_Debug dbg,Dwarf_Cie ** cie_data,Dwarf_Signed * cie_element_count,Dwarf_Fde ** fde_data,Dwarf_Signed * fde_element_count,Dwarf_Error * error)1116 dwarf_get_fde_list_eh(Dwarf_Debug dbg,
1117 Dwarf_Cie ** cie_data,
1118 Dwarf_Signed * cie_element_count,
1119 Dwarf_Fde ** fde_data,
1120 Dwarf_Signed * fde_element_count,
1121 Dwarf_Error * error)
1122 {
1123 int res = _dwarf_load_section(dbg, &dbg->de_debug_frame_eh_gnu,error);
1124 if (res != DW_DLV_OK) {
1125 return res;
1126 }
1127
1128 res = _dwarf_get_fde_list_internal(dbg,
1129 cie_data,
1130 cie_element_count,
1131 fde_data,
1132 fde_element_count,
1133 dbg->de_debug_frame_eh_gnu.dss_data,
1134 dbg->de_debug_frame_eh_gnu.dss_index,
1135 dbg->de_debug_frame_eh_gnu.dss_size,
1136 /* cie_id_value */ 0,
1137 /* use_gnu_cie_calc= */ 1,
1138 error);
1139 return res;
1140 }
1141
1142
1143
1144 /*
1145 For standard dwarf .debug_frame
1146 cie_id is -1 in a cie, and
1147 is the section offset in the .debug_frame section
1148 of the cie otherwise. Standard dwarf
1149 */
1150 int
dwarf_get_fde_list(Dwarf_Debug dbg,Dwarf_Cie ** cie_data,Dwarf_Signed * cie_element_count,Dwarf_Fde ** fde_data,Dwarf_Signed * fde_element_count,Dwarf_Error * error)1151 dwarf_get_fde_list(Dwarf_Debug dbg,
1152 Dwarf_Cie ** cie_data,
1153 Dwarf_Signed * cie_element_count,
1154 Dwarf_Fde ** fde_data,
1155 Dwarf_Signed * fde_element_count,
1156 Dwarf_Error * error)
1157 {
1158 int res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
1159 if (res != DW_DLV_OK) {
1160 return res;
1161 }
1162
1163 res = _dwarf_get_fde_list_internal(dbg, cie_data,
1164 cie_element_count,
1165 fde_data,
1166 fde_element_count,
1167 dbg->de_debug_frame.dss_data,
1168 dbg->de_debug_frame.dss_index,
1169 dbg->de_debug_frame.dss_size,
1170 DW_CIE_ID,
1171 /* use_gnu_cie_calc= */ 0,
1172 error);
1173
1174 return res;
1175 }
1176
1177
1178 /*
1179 Only works on dwarf sections, not eh_frame
1180 Given a Dwarf_Die, see if it has a
1181 DW_AT_MIPS_fde attribute and if so use that
1182 to get an fde offset.
1183 Then create a Dwarf_Fde to return thru the ret_fde pointer.
1184 Also creates a cie (pointed at from the Dwarf_Fde).
1185 */
1186 int
dwarf_get_fde_for_die(Dwarf_Debug dbg,Dwarf_Die die,Dwarf_Fde * ret_fde,Dwarf_Error * error)1187 dwarf_get_fde_for_die(Dwarf_Debug dbg,
1188 Dwarf_Die die,
1189 Dwarf_Fde * ret_fde, Dwarf_Error * error)
1190 {
1191 Dwarf_Attribute attr;
1192 Dwarf_Unsigned fde_offset = 0;
1193 Dwarf_Signed signdval = 0;
1194 Dwarf_Fde new_fde = 0;
1195 unsigned char *fde_ptr = 0;
1196 unsigned char *cie_ptr = 0;
1197 Dwarf_Unsigned cie_id = 0;
1198
1199 /* Fields for the current Cie being read. */
1200 int res = 0;
1201 int resattr = 0;
1202 int sdatares = 0;
1203
1204 struct cie_fde_prefix_s prefix;
1205 struct cie_fde_prefix_s prefix_c;
1206
1207 if (die == NULL) {
1208 _dwarf_error(NULL, error, DW_DLE_DIE_NULL);
1209 return (DW_DLV_ERROR);
1210 }
1211
1212 resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error);
1213 if (resattr != DW_DLV_OK) {
1214 return resattr;
1215 }
1216
1217 /* why is this formsdata? FIX */
1218 sdatares = dwarf_formsdata(attr, &signdval, error);
1219 if (sdatares != DW_DLV_OK) {
1220 return sdatares;
1221 }
1222
1223 res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
1224 if (res != DW_DLV_OK) {
1225 return res;
1226 }
1227
1228 fde_offset = signdval;
1229 fde_ptr = (dbg->de_debug_frame.dss_data + fde_offset);
1230
1231
1232 /* First read in the 'common prefix' to figure out what * we are to
1233 do with this entry. */
1234 memset(&prefix_c, 0, sizeof(prefix_c));
1235 memset(&prefix, 0, sizeof(prefix));
1236 res = dwarf_read_cie_fde_prefix(dbg, fde_ptr,
1237 dbg->de_debug_frame.dss_data,
1238 dbg->de_debug_frame.dss_index,
1239 dbg->de_debug_frame.dss_size,
1240 &prefix,
1241 error);
1242 if (res == DW_DLV_ERROR) {
1243 return res;
1244 }
1245 if (res == DW_DLV_NO_ENTRY)
1246 return res;
1247 fde_ptr = prefix.cf_addr_after_prefix;
1248 cie_id = prefix.cf_cie_id;
1249 /* Pass NULL, not section pointer, for 3rd argument.
1250 de_debug_frame.dss_data has no eh_frame relevance. */
1251 res = dwarf_create_fde_from_after_start(dbg, &prefix,
1252 (Dwarf_Small *) NULL,
1253 fde_ptr,
1254 /* use_gnu_cie_calc= */ 0,
1255 /* Dwarf_Cie = */ 0,
1256 &new_fde, error);
1257 if (res == DW_DLV_ERROR) {
1258 return res;
1259 } else if (res == DW_DLV_NO_ENTRY) {
1260 return res;
1261 }
1262 /* DW_DLV_OK */
1263
1264 /* now read the cie corresponding to the fde */
1265 cie_ptr = new_fde->fd_section_ptr + cie_id;
1266 res = dwarf_read_cie_fde_prefix(dbg, cie_ptr,
1267 dbg->de_debug_frame.dss_data,
1268 dbg->de_debug_frame.dss_index,
1269 dbg->de_debug_frame.dss_size,
1270 &prefix_c, error);
1271 if (res == DW_DLV_ERROR) {
1272 return res;
1273 }
1274 if (res == DW_DLV_NO_ENTRY)
1275 return res;
1276
1277 cie_ptr = prefix_c.cf_addr_after_prefix;
1278 cie_id = prefix_c.cf_cie_id;
1279
1280 if (cie_id == DW_CIE_ID) {
1281 int res2 = 0;
1282 Dwarf_Cie new_cie = 0;
1283
1284 /* Pass NULL, not section pointer, for 3rd argument.
1285 de_debug_frame.dss_data has no eh_frame relevance. */
1286 res2 = dwarf_create_cie_from_after_start(dbg,
1287 &prefix_c,
1288 (Dwarf_Small *) NULL,
1289 cie_ptr,
1290 /* cie_count= */ 0,
1291 /* use_gnu_cie_calc= */
1292 0, &new_cie, error);
1293 if (res2 == DW_DLV_ERROR) {
1294 dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
1295 return res;
1296 } else if (res2 == DW_DLV_NO_ENTRY) {
1297 dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
1298 return res;
1299 }
1300 new_fde->fd_cie = new_cie;
1301 } else {
1302 _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
1303 return (DW_DLV_ERROR);
1304 }
1305
1306 *ret_fde = new_fde;
1307 return DW_DLV_OK;
1308 }
1309
1310 /* A dwarf consumer operation, see the consumer library documentation.
1311 */
1312 int
dwarf_get_fde_range(Dwarf_Fde fde,Dwarf_Addr * low_pc,Dwarf_Unsigned * func_length,Dwarf_Ptr * fde_bytes,Dwarf_Unsigned * fde_byte_length,Dwarf_Off * cie_offset,Dwarf_Signed * cie_index,Dwarf_Off * fde_offset,Dwarf_Error * error)1313 dwarf_get_fde_range(Dwarf_Fde fde,
1314 Dwarf_Addr * low_pc,
1315 Dwarf_Unsigned * func_length,
1316 Dwarf_Ptr * fde_bytes,
1317 Dwarf_Unsigned * fde_byte_length,
1318 Dwarf_Off * cie_offset,
1319 Dwarf_Signed * cie_index,
1320 Dwarf_Off * fde_offset, Dwarf_Error * error)
1321 {
1322 Dwarf_Debug dbg;
1323
1324 if (fde == NULL) {
1325 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
1326 return (DW_DLV_ERROR);
1327 }
1328
1329 dbg = fde->fd_dbg;
1330 if (dbg == NULL) {
1331 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1332 return (DW_DLV_ERROR);
1333 }
1334
1335
1336 /* We have always already done the section load here, so no need to
1337 load the section. We did the section load in order to create the
1338 Dwarf_Fde pointer passed in here. */
1339
1340
1341 if (low_pc != NULL)
1342 *low_pc = fde->fd_initial_location;
1343 if (func_length != NULL)
1344 *func_length = fde->fd_address_range;
1345 if (fde_bytes != NULL)
1346 *fde_bytes = fde->fd_fde_start;
1347 if (fde_byte_length != NULL)
1348 *fde_byte_length = fde->fd_length;
1349 if (cie_offset != NULL)
1350 *cie_offset = fde->fd_cie_offset;
1351 if (cie_index != NULL)
1352 *cie_index = fde->fd_cie_index;
1353 if (fde_offset != NULL)
1354 *fde_offset = fde->fd_fde_start - fde->fd_section_ptr;
1355
1356 return DW_DLV_OK;
1357 }
1358
1359 /* IRIX specific function. The exception tables
1360 have C++ destructor information and are
1361 at present undocumented. */
1362 int
dwarf_get_fde_exception_info(Dwarf_Fde fde,Dwarf_Signed * offset_into_exception_tables,Dwarf_Error * error)1363 dwarf_get_fde_exception_info(Dwarf_Fde fde,
1364 Dwarf_Signed *
1365 offset_into_exception_tables,
1366 Dwarf_Error * error)
1367 {
1368 Dwarf_Debug dbg;
1369
1370 dbg = fde->fd_dbg;
1371 if (dbg == NULL) {
1372 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1373 return (DW_DLV_ERROR);
1374 }
1375 *offset_into_exception_tables =
1376 fde->fd_offset_into_exception_tables;
1377 return DW_DLV_OK;
1378 }
1379
1380
1381 /* A consumer code function.
1382 Given a CIE pointer, return the normal CIE data thru
1383 pointers.
1384 Special augmentation data is not returned here.
1385 */
1386 int
dwarf_get_cie_info(Dwarf_Cie cie,Dwarf_Unsigned * bytes_in_cie,Dwarf_Small * ptr_to_version,char ** augmenter,Dwarf_Unsigned * code_alignment_factor,Dwarf_Signed * data_alignment_factor,Dwarf_Half * return_address_register,Dwarf_Ptr * initial_instructions,Dwarf_Unsigned * initial_instructions_length,Dwarf_Error * error)1387 dwarf_get_cie_info(Dwarf_Cie cie,
1388 Dwarf_Unsigned * bytes_in_cie,
1389 Dwarf_Small * ptr_to_version,
1390 char **augmenter,
1391 Dwarf_Unsigned * code_alignment_factor,
1392 Dwarf_Signed * data_alignment_factor,
1393 Dwarf_Half * return_address_register,
1394 Dwarf_Ptr * initial_instructions,
1395 Dwarf_Unsigned * initial_instructions_length,
1396 Dwarf_Error * error)
1397 {
1398 Dwarf_Debug dbg;
1399
1400 if (cie == NULL) {
1401 _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
1402 return (DW_DLV_ERROR);
1403 }
1404
1405 dbg = cie->ci_dbg;
1406 if (dbg == NULL) {
1407 _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
1408 return (DW_DLV_ERROR);
1409 }
1410
1411 if (ptr_to_version != NULL)
1412 *ptr_to_version = cie->ci_cie_version_number;
1413 if (augmenter != NULL)
1414 *augmenter = cie->ci_augmentation;
1415 if (code_alignment_factor != NULL)
1416 *code_alignment_factor = cie->ci_code_alignment_factor;
1417 if (data_alignment_factor != NULL)
1418 *data_alignment_factor = cie->ci_data_alignment_factor;
1419 if (return_address_register != NULL)
1420 *return_address_register = cie->ci_return_address_register;
1421 if (initial_instructions != NULL)
1422 *initial_instructions = cie->ci_cie_instr_start;
1423 if (initial_instructions_length != NULL) {
1424 *initial_instructions_length = cie->ci_length +
1425 cie->ci_length_size +
1426 cie->ci_extension_size -
1427 (cie->ci_cie_instr_start - cie->ci_cie_start);
1428
1429 }
1430 *bytes_in_cie = (cie->ci_length);
1431 return (DW_DLV_OK);
1432 }
1433
1434 /* Return the register rules for all registers at a given pc.
1435 */
1436 static int
_dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Frame table,Dwarf_Half cfa_reg_col_num,Dwarf_Error * error)1437 _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,
1438 Dwarf_Addr pc_requested,
1439 Dwarf_Frame table,
1440 Dwarf_Half cfa_reg_col_num,
1441 Dwarf_Error * error)
1442 {
1443 Dwarf_Debug dbg = 0;
1444 Dwarf_Cie cie = 0;
1445 int dw_err = 0;
1446 Dwarf_Sword icount = 0;
1447 int res = 0;
1448
1449 if (fde == NULL) {
1450 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
1451 return (DW_DLV_ERROR);
1452 }
1453
1454 dbg = fde->fd_dbg;
1455 if (dbg == NULL) {
1456 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1457 return (DW_DLV_ERROR);
1458 }
1459
1460 if (pc_requested < fde->fd_initial_location ||
1461 pc_requested >=
1462 fde->fd_initial_location + fde->fd_address_range) {
1463 _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
1464 return (DW_DLV_ERROR);
1465 }
1466
1467 cie = fde->fd_cie;
1468 if (cie->ci_initial_table == NULL) {
1469 cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
1470
1471 if (cie->ci_initial_table == NULL) {
1472 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1473 return (DW_DLV_ERROR);
1474 }
1475 _dwarf_init_regrule_table(cie->ci_initial_table->fr_reg,
1476 dbg->de_frame_reg_rules_entry_count,
1477 dbg->de_frame_rule_initial_value);
1478 _dwarf_init_regrule_table(&cie->ci_initial_table->fr_cfa_rule,
1479 1, dbg->de_frame_rule_initial_value);
1480 res = _dwarf_exec_frame_instr( /* make_instr= */ false,
1481 /* ret_frame_instr= */ NULL,
1482 /* search_pc */ false,
1483 /* search_pc_val */ 0,
1484 /* location */ 0,
1485 cie->ci_cie_instr_start,
1486 cie->ci_cie_instr_start + (cie->ci_length +
1487 cie->ci_length_size +
1488 cie->ci_extension_size -
1489 (cie->ci_cie_instr_start -
1490 cie->ci_cie_start)),
1491 cie->ci_initial_table, cie, dbg,
1492 cfa_reg_col_num, &icount,
1493 &dw_err);
1494 if (res == DW_DLV_ERROR) {
1495 _dwarf_error(dbg, error, dw_err);
1496 return (res);
1497 } else if (res == DW_DLV_NO_ENTRY) {
1498 return res;
1499 }
1500 }
1501
1502 {
1503 Dwarf_Small *instr_end = fde->fd_fde_instr_start +
1504 fde->fd_length +
1505 fde->fd_length_size +
1506 fde->fd_extension_size - (fde->fd_fde_instr_start -
1507 fde->fd_fde_start);
1508
1509 res = _dwarf_exec_frame_instr( /* make_instr= */ false,
1510 /* ret_frame_instr= */ NULL,
1511 /* search_pc */ true,
1512 /* search_pc_val */ pc_requested,
1513 fde->fd_initial_location,
1514 fde->fd_fde_instr_start,
1515 instr_end,
1516 table,
1517 cie, dbg,
1518 cfa_reg_col_num, &icount,
1519 &dw_err);
1520 }
1521 if (res == DW_DLV_ERROR) {
1522 _dwarf_error(dbg, error, dw_err);
1523 return (res);
1524 } else if (res == DW_DLV_NO_ENTRY) {
1525 return res;
1526 }
1527
1528 return DW_DLV_OK;
1529 }
1530
1531 /* A consumer call for efficiently getting the register info
1532 for all registers in one call.
1533
1534 The output table rules array is size DW_REG_TABLE_SIZE.
1535 The frame info rules array in fde_table is of size
1536 DW_REG_TABLE_SIZE too.
1537
1538 This interface really only works well with MIPS/IRIX
1539 where DW_FRAME_CFA_COL is zero (in that case it's safe).
1540
1541 It is also restricted to the case where
1542 DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM ==
1543 dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX).
1544 If this condition is not met calling this routine can result in
1545 incorrect output or in memory corruption.
1546
1547 It is much better to use dwarf_get_fde_info_for_all_regs3()
1548 instead of this interface.
1549 */
1550 int
dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Regtable * reg_table,Dwarf_Addr * row_pc,Dwarf_Error * error)1551 dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,
1552 Dwarf_Addr pc_requested,
1553 Dwarf_Regtable * reg_table,
1554 Dwarf_Addr * row_pc,
1555 Dwarf_Error * error)
1556 {
1557
1558 /* Table size: DW_REG_TABLE_SIZE */
1559 struct Dwarf_Frame_s fde_table;
1560 Dwarf_Sword i = 0;
1561 struct Dwarf_Reg_Rule_s *rule = NULL;
1562 struct Dwarf_Regtable_Entry_s *out_rule = NULL;
1563 int res = 0;
1564 Dwarf_Debug dbg = 0;
1565
1566 /* For this interface the size is fixed at compile time. */
1567 int output_table_real_data_size = DW_REG_TABLE_SIZE;
1568
1569 FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1570
1571 res = dwarf_initialize_fde_table(dbg, &fde_table,
1572 output_table_real_data_size,
1573 error);
1574 if (res != DW_DLV_OK)
1575 return res;
1576
1577 /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1578 */
1579 res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
1580 &fde_table, dbg->de_frame_cfa_col_number, error);
1581 if (res != DW_DLV_OK) {
1582 dwarf_free_fde_table(&fde_table);
1583 return res;
1584 }
1585
1586 out_rule = ®_table->rules[0];
1587 rule = &fde_table.fr_reg[0];
1588 for (i = 0; i < output_table_real_data_size;
1589 i++, ++out_rule, ++rule) {
1590 out_rule->dw_offset_relevant = rule->ru_is_off;
1591 out_rule->dw_value_type = rule->ru_value_type;
1592 out_rule->dw_regnum = rule->ru_register;
1593 out_rule->dw_offset = rule->ru_offset_or_block_len;
1594 }
1595 for (; i < DW_REG_TABLE_SIZE; ++i, ++out_rule) {
1596 out_rule->dw_offset_relevant = 0;
1597 out_rule->dw_value_type = DW_EXPR_OFFSET;
1598 out_rule->dw_regnum = dbg->de_frame_undefined_value_number;
1599 out_rule->dw_offset = 0;
1600 }
1601
1602 /* The test is just in case it's not inside the table. For non-MIPS
1603 it could be outside the table and that is just fine, it was
1604 really a mistake to put it in the table in 1993. */
1605 /* CONSTCOND */
1606 if (dbg->de_frame_cfa_col_number < DW_REG_TABLE_SIZE) {
1607 out_rule = ®_table->rules[dbg->de_frame_cfa_col_number];
1608 out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1609 out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type;
1610 out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register;
1611 out_rule->dw_offset =
1612 fde_table.fr_cfa_rule.ru_offset_or_block_len;
1613 }
1614
1615 if (row_pc != NULL)
1616 *row_pc = fde_table.fr_loc;
1617 dwarf_free_fde_table(&fde_table);
1618 return DW_DLV_OK;
1619 }
1620
1621 /* A consumer call for efficiently getting the register info
1622 for all registers in one call.
1623
1624 The output table rules array is size output_table_real_data_size.
1625 (normally DW_REG_TABLE_SIZE).
1626 The frame info rules array in fde_table is normally of size
1627 DW_FRAME_LAST_REG_NUM.
1628 */
1629 int
dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Regtable3 * reg_table,Dwarf_Addr * row_pc,Dwarf_Error * error)1630 dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
1631 Dwarf_Addr pc_requested,
1632 Dwarf_Regtable3 * reg_table,
1633 Dwarf_Addr * row_pc,
1634 Dwarf_Error * error)
1635 {
1636
1637 struct Dwarf_Frame_s fde_table;
1638 Dwarf_Sword i = 0;
1639 int res = 0;
1640 struct Dwarf_Reg_Rule_s *rule = NULL;
1641 struct Dwarf_Regtable_Entry3_s *out_rule = NULL;
1642 Dwarf_Debug dbg = 0;
1643 int output_table_real_data_size = reg_table->rt3_reg_table_size;
1644
1645 FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1646
1647 output_table_real_data_size =
1648 MIN(output_table_real_data_size,
1649 dbg->de_frame_reg_rules_entry_count);
1650
1651 res = dwarf_initialize_fde_table(dbg, &fde_table,
1652 output_table_real_data_size,
1653 error);
1654
1655 /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1656 */
1657 res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
1658 &fde_table,
1659 dbg->de_frame_cfa_col_number,
1660 error);
1661 if (res != DW_DLV_OK) {
1662 dwarf_free_fde_table(&fde_table);
1663 return res;
1664 }
1665
1666 out_rule = ®_table->rt3_rules[0];
1667 rule = &fde_table.fr_reg[0];
1668 for (i = 0; i < output_table_real_data_size;
1669 i++, ++out_rule, ++rule) {
1670 out_rule->dw_offset_relevant = rule->ru_is_off;
1671 out_rule->dw_value_type = rule->ru_value_type;
1672 out_rule->dw_regnum = rule->ru_register;
1673 out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len;
1674 out_rule->dw_block_ptr = rule->ru_block;
1675 }
1676 for (; i < reg_table->rt3_reg_table_size; i++, ++out_rule) {
1677 out_rule->dw_offset_relevant = 0;
1678 out_rule->dw_value_type = DW_EXPR_OFFSET;
1679 out_rule->dw_regnum = dbg->de_frame_undefined_value_number;
1680 out_rule->dw_offset_or_block_len = 0;
1681 out_rule->dw_block_ptr = 0;
1682 }
1683 reg_table->rt3_cfa_rule.dw_offset_relevant =
1684 fde_table.fr_cfa_rule.ru_is_off;
1685 reg_table->rt3_cfa_rule.dw_value_type =
1686 fde_table.fr_cfa_rule.ru_value_type;
1687 reg_table->rt3_cfa_rule.dw_regnum =
1688 fde_table.fr_cfa_rule.ru_register;
1689 reg_table->rt3_cfa_rule.dw_offset_or_block_len =
1690 fde_table.fr_cfa_rule.ru_offset_or_block_len;
1691 reg_table->rt3_cfa_rule.dw_block_ptr =
1692 fde_table.fr_cfa_rule.ru_block;
1693
1694 if (row_pc != NULL)
1695 *row_pc = fde_table.fr_loc;
1696
1697 dwarf_free_fde_table(&fde_table);
1698 return DW_DLV_OK;
1699 }
1700
1701
1702 /* Gets the register info for a single register at a given PC value
1703 for the FDE specified.
1704
1705 This is the old MIPS interface and should no longer be used.
1706 Use dwarf_get_fde_info_for_reg3() instead.
1707 */
1708 int
dwarf_get_fde_info_for_reg(Dwarf_Fde fde,Dwarf_Half table_column,Dwarf_Addr pc_requested,Dwarf_Signed * offset_relevant,Dwarf_Signed * register_num,Dwarf_Signed * offset,Dwarf_Addr * row_pc,Dwarf_Error * error)1709 dwarf_get_fde_info_for_reg(Dwarf_Fde fde,
1710 Dwarf_Half table_column,
1711 Dwarf_Addr pc_requested,
1712 Dwarf_Signed * offset_relevant,
1713 Dwarf_Signed * register_num,
1714 Dwarf_Signed * offset,
1715 Dwarf_Addr * row_pc, Dwarf_Error * error)
1716 {
1717 struct Dwarf_Frame_s fde_table;
1718 int res = DW_DLV_ERROR;
1719 Dwarf_Debug dbg = 0;
1720 int output_table_real_data_size = 0;
1721
1722 FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1723 output_table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1724
1725 res = dwarf_initialize_fde_table(dbg, &fde_table,
1726 output_table_real_data_size,
1727 error);
1728 if (res != DW_DLV_OK)
1729 return res;
1730
1731 if (table_column >= output_table_real_data_size) {
1732 dwarf_free_fde_table(&fde_table);
1733 _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
1734 return (DW_DLV_ERROR);
1735 }
1736
1737 /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1738 */
1739 res =
1740 _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1741 dbg->de_frame_cfa_col_number, error);
1742 if (res != DW_DLV_OK) {
1743 dwarf_free_fde_table(&fde_table);
1744 return res;
1745 }
1746
1747 if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) {
1748 /* The problem here is that this interface cannot deal with
1749 other sorts of (newer) dwarf frame values. Code must
1750 use dwarf_get_fde_info_for_reg3() to get these
1751 values correctly. We error rather than return
1752 misleading incomplete data. */
1753 dwarf_free_fde_table(&fde_table);
1754 _dwarf_error(NULL, error,
1755 DW_DLE_FRAME_REGISTER_UNREPRESENTABLE);
1756 return (DW_DLV_ERROR);
1757 }
1758 if(table_column == dbg->de_frame_cfa_col_number) {
1759 if (register_num != NULL)
1760 *register_num = fde_table.fr_cfa_rule.ru_register;
1761 if (offset != NULL)
1762 *offset = fde_table.fr_cfa_rule.ru_offset_or_block_len;
1763 if (row_pc != NULL)
1764 *row_pc = fde_table.fr_loc;
1765 *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1766
1767 } else {
1768 if (register_num != NULL)
1769 *register_num = fde_table.fr_reg[table_column].ru_register;
1770 if (offset != NULL)
1771 *offset = fde_table.fr_reg[table_column].ru_offset_or_block_len;
1772 if (row_pc != NULL)
1773 *row_pc = fde_table.fr_loc;
1774
1775 *offset_relevant = fde_table.fr_reg[table_column].ru_is_off;
1776 }
1777 dwarf_free_fde_table(&fde_table);
1778 return DW_DLV_OK;
1779 }
1780
1781 /* In this interface, table_column of DW_FRAME_CFA_COL
1782 is not meaningful.
1783 Use dwarf_get_fde_info_for_cfa_reg3() to get the CFA.
1784 Call dwarf_set_frame_cfa_value() to set the correct column
1785 after calling dwarf_init()
1786 (DW_FRAME_CFA_COL3 is a sensible column to use).
1787 */
1788 int
dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,Dwarf_Half table_column,Dwarf_Addr pc_requested,Dwarf_Small * value_type,Dwarf_Signed * offset_relevant,Dwarf_Signed * register_num,Dwarf_Signed * offset_or_block_len,Dwarf_Ptr * block_ptr,Dwarf_Addr * row_pc_out,Dwarf_Error * error)1789 dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,
1790 Dwarf_Half table_column,
1791 Dwarf_Addr pc_requested,
1792 Dwarf_Small * value_type,
1793 Dwarf_Signed * offset_relevant,
1794 Dwarf_Signed * register_num,
1795 Dwarf_Signed * offset_or_block_len,
1796 Dwarf_Ptr * block_ptr,
1797 Dwarf_Addr * row_pc_out,
1798 Dwarf_Error * error)
1799 {
1800 struct Dwarf_Frame_s fde_table;
1801 int res = DW_DLV_ERROR;
1802
1803 Dwarf_Debug dbg = 0;
1804 int table_real_data_size = 0;
1805
1806 FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1807 table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1808 res = dwarf_initialize_fde_table(dbg, &fde_table,
1809 table_real_data_size, error);
1810 if (res != DW_DLV_OK)
1811 return res;
1812 if (table_column >= table_real_data_size) {
1813 dwarf_free_fde_table(&fde_table);
1814 _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
1815 return (DW_DLV_ERROR);
1816 }
1817
1818 /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1819 */
1820 res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1821 dbg->de_frame_cfa_col_number,
1822 error);
1823 if (res != DW_DLV_OK) {
1824 dwarf_free_fde_table(&fde_table);
1825 return res;
1826 }
1827
1828 if (register_num != NULL)
1829 *register_num = fde_table.fr_reg[table_column].ru_register;
1830 if (offset_or_block_len != NULL)
1831 *offset_or_block_len =
1832 fde_table.fr_reg[table_column].ru_offset_or_block_len;
1833 if (row_pc_out != NULL)
1834 *row_pc_out = fde_table.fr_loc;
1835 if (block_ptr)
1836 *block_ptr = fde_table.fr_reg[table_column].ru_block;
1837
1838 /* Without value_type the data cannot be understood, so we insist
1839 on it being present, we don't test it. */
1840 *value_type = fde_table.fr_reg[table_column].ru_value_type;
1841 *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
1842 dwarf_free_fde_table(&fde_table);
1843 return DW_DLV_OK;
1844
1845 }
1846
1847 /* For latest DWARF, this is the preferred interface.
1848 It more portably deals with the CFA by not
1849 making the CFA a column number, which means
1850 DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE,
1851 a special value, not something one uses as an index.
1852
1853 Call dwarf_set_frame_cfa_value() to set the correct column
1854 after calling dwarf_init()
1855 (DW_FRAME_CFA_COL3 is a sensible column to use, and
1856 is the default unless '--enable-oldframecol'
1857 is used to configure libdwarf). */
1858 int
dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Small * value_type,Dwarf_Signed * offset_relevant,Dwarf_Signed * register_num,Dwarf_Signed * offset_or_block_len,Dwarf_Ptr * block_ptr,Dwarf_Addr * row_pc_out,Dwarf_Error * error)1859 dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,
1860 Dwarf_Addr pc_requested,
1861 Dwarf_Small * value_type,
1862 Dwarf_Signed * offset_relevant,
1863 Dwarf_Signed * register_num,
1864 Dwarf_Signed * offset_or_block_len,
1865 Dwarf_Ptr * block_ptr,
1866 Dwarf_Addr * row_pc_out,
1867 Dwarf_Error * error)
1868 {
1869 struct Dwarf_Frame_s fde_table;
1870 int res = DW_DLV_ERROR;
1871 Dwarf_Debug dbg = 0;
1872
1873 int table_real_data_size = 0;
1874
1875 FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1876
1877 table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1878 res = dwarf_initialize_fde_table(dbg, &fde_table,
1879 table_real_data_size, error);
1880 if (res != DW_DLV_OK)
1881 return res;
1882 res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1883 dbg->de_frame_cfa_col_number,error);
1884 if (res != DW_DLV_OK) {
1885 dwarf_free_fde_table(&fde_table);
1886 return res;
1887 }
1888
1889 if (register_num != NULL)
1890 *register_num = fde_table.fr_cfa_rule.ru_register;
1891 if (offset_or_block_len != NULL)
1892 *offset_or_block_len =
1893 fde_table.fr_cfa_rule.ru_offset_or_block_len;
1894 if (row_pc_out != NULL)
1895 *row_pc_out = fde_table.fr_loc;
1896 if (block_ptr)
1897 *block_ptr = fde_table.fr_cfa_rule.ru_block;
1898
1899 /* Without value_type the data cannot be understood, so we insist
1900 on it being present, we don't test it. */
1901 *value_type = fde_table.fr_cfa_rule.ru_value_type;
1902 *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1903 dwarf_free_fde_table(&fde_table);
1904 return DW_DLV_OK;
1905 }
1906
1907
1908
1909 /*
1910 Return pointer to the instructions in the dwarf
1911 fde.
1912 */
1913 int
dwarf_get_fde_instr_bytes(Dwarf_Fde inFde,Dwarf_Ptr * outinstraddr,Dwarf_Unsigned * outaddrlen,Dwarf_Error * error)1914 dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr,
1915 Dwarf_Unsigned * outaddrlen,
1916 Dwarf_Error * error)
1917 {
1918 Dwarf_Unsigned len = 0;
1919 unsigned char *instrs = 0;
1920 Dwarf_Debug dbg = 0;
1921
1922 if (inFde == NULL) {
1923 _dwarf_error(dbg, error, DW_DLE_FDE_NULL);
1924 return (DW_DLV_ERROR);
1925 }
1926
1927 dbg = inFde->fd_dbg;
1928 if (dbg == NULL) {
1929 _dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL);
1930 return (DW_DLV_ERROR);
1931 }
1932
1933 instrs = inFde->fd_fde_instr_start;
1934
1935 len = (inFde->fd_fde_start + inFde->fd_length +
1936 inFde->fd_length_size + inFde->fd_extension_size) - instrs;
1937
1938 *outinstraddr = instrs;
1939 *outaddrlen = len;
1940 return DW_DLV_OK;
1941 }
1942
1943 /* Allows getting an fde from its table via an index.
1944 With more error checking than simply indexing oneself.
1945 */
1946 int
dwarf_get_fde_n(Dwarf_Fde * fde_data,Dwarf_Unsigned fde_index,Dwarf_Fde * returned_fde,Dwarf_Error * error)1947 dwarf_get_fde_n(Dwarf_Fde * fde_data,
1948 Dwarf_Unsigned fde_index,
1949 Dwarf_Fde * returned_fde, Dwarf_Error * error)
1950 {
1951 Dwarf_Debug dbg = 0;
1952 Dwarf_Signed fdecount = 0;
1953
1954 if (fde_data == NULL) {
1955 _dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL);
1956 return (DW_DLV_ERROR);
1957 }
1958
1959 FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg);
1960 /* Assumes fde_data table has at least one entry. */
1961 fdecount = fde_data[0]->fd_is_eh?
1962 dbg->de_fde_count_eh:dbg->de_fde_count;
1963 if (fde_index >= fdecount) {
1964 return (DW_DLV_NO_ENTRY);
1965 }
1966 *returned_fde = (*(fde_data + fde_index));
1967 return DW_DLV_OK;
1968 }
1969
1970
1971 /*
1972 Lopc and hipc are extensions to the interface to
1973 return the range of addresses that are described
1974 by the returned fde.
1975 */
1976 int
dwarf_get_fde_at_pc(Dwarf_Fde * fde_data,Dwarf_Addr pc_of_interest,Dwarf_Fde * returned_fde,Dwarf_Addr * lopc,Dwarf_Addr * hipc,Dwarf_Error * error)1977 dwarf_get_fde_at_pc(Dwarf_Fde * fde_data,
1978 Dwarf_Addr pc_of_interest,
1979 Dwarf_Fde * returned_fde,
1980 Dwarf_Addr * lopc,
1981 Dwarf_Addr * hipc, Dwarf_Error * error)
1982 {
1983 Dwarf_Debug dbg = NULL;
1984 Dwarf_Fde fde = NULL;
1985 Dwarf_Fde entryfde = NULL;
1986 Dwarf_Signed fdecount = 0;
1987
1988 if (fde_data == NULL) {
1989 _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
1990 return (DW_DLV_ERROR);
1991 }
1992
1993 /* Assumes fde_data table has at least one entry. */
1994 entryfde = *fde_data;
1995 FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg);
1996
1997 if (dbg == NULL) {
1998 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1999 return (DW_DLV_ERROR);
2000 }
2001 fdecount = entryfde->fd_is_eh?
2002 dbg->de_fde_count_eh:dbg->de_fde_count;
2003 {
2004 /* The fde's are sorted by their addresses. Binary search to
2005 find correct fde. */
2006 Dwarf_Signed low = 0;
2007 Dwarf_Signed high = fdecount - 1L;
2008 Dwarf_Signed middle = 0;
2009 Dwarf_Fde cur_fde;
2010
2011 while (low <= high) {
2012 middle = (low + high) / 2;
2013 cur_fde = fde_data[middle];
2014 if (pc_of_interest < cur_fde->fd_initial_location) {
2015 high = middle - 1;
2016 } else if (pc_of_interest >=
2017 (cur_fde->fd_initial_location +
2018 cur_fde->fd_address_range)) {
2019 low = middle + 1;
2020 } else {
2021 fde = fde_data[middle];
2022 break;
2023 }
2024 }
2025 }
2026
2027 if (fde) {
2028 if (lopc != NULL)
2029 *lopc = fde->fd_initial_location;
2030 if (hipc != NULL)
2031 *hipc =
2032 fde->fd_initial_location + fde->fd_address_range - 1;
2033 *returned_fde = fde;
2034 return (DW_DLV_OK);
2035 }
2036
2037 return (DW_DLV_NO_ENTRY);
2038 }
2039
2040
2041 /* Expands a single frame instruction block
2042 from a specific cie
2043 into a n array of Dwarf_Frame_Op-s.
2044 This depends on having the cfa column set sensibly.
2045
2046 Call dwarf_set_frame_cfa_value() to set the correct column
2047 after calling dwarf_init() unless you are using
2048 the old MIPS frame interfaces (in which case the default
2049 will be ok). (DW_FRAME_CFA_COL3 is a sensible column to use ).
2050 */
2051 int
dwarf_expand_frame_instructions(Dwarf_Cie cie,Dwarf_Ptr instruction,Dwarf_Unsigned i_length,Dwarf_Frame_Op ** returned_op_list,Dwarf_Signed * returned_op_count,Dwarf_Error * error)2052 dwarf_expand_frame_instructions(Dwarf_Cie cie,
2053 Dwarf_Ptr instruction,
2054 Dwarf_Unsigned i_length,
2055 Dwarf_Frame_Op ** returned_op_list,
2056 Dwarf_Signed * returned_op_count,
2057 Dwarf_Error * error)
2058 {
2059 Dwarf_Sword instr_count;
2060 int res = DW_DLV_ERROR;
2061 int dw_err;
2062 Dwarf_Debug dbg = 0;
2063
2064 if (cie == 0) {
2065 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
2066 return (DW_DLV_ERROR);
2067 }
2068 dbg = cie->ci_dbg;
2069
2070 if (returned_op_list == 0 || returned_op_count == 0) {
2071 _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL);
2072 return (DW_DLV_ERROR);
2073 }
2074
2075 /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe
2076 as it is just an i_length offset from 'instruction' itself. A
2077 caller has made a big mistake if the result is not a valid
2078 pointer. */
2079 res = _dwarf_exec_frame_instr( /* make_instr= */ true,
2080 returned_op_list,
2081 /* search_pc */ false,
2082 /* search_pc_val */ 0,
2083 /* location */ 0,
2084 instruction,
2085 (Dwarf_Ptr)((char *)instruction + i_length),
2086 /* Dwarf_Frame */ NULL,
2087 cie,
2088 dbg,
2089 dbg->de_frame_cfa_col_number, &instr_count,
2090 &dw_err);
2091 if (res != DW_DLV_OK) {
2092 if (res == DW_DLV_ERROR) {
2093 _dwarf_error(dbg, error, dw_err);
2094 }
2095 return (res);
2096 }
2097
2098 *returned_op_count = instr_count;
2099 return DW_DLV_OK;
2100 }
2101
2102
2103 /* Used by dwarfdump -v to print offsets, for debugging
2104 dwarf info.
2105 The dwarf_ version is preferred over the obsolete _dwarf version.
2106 _dwarf version kept for compatibility.
2107 */
2108 /* ARGSUSED 4 */
2109 int
_dwarf_fde_section_offset(Dwarf_Debug dbg,Dwarf_Fde in_fde,Dwarf_Off * fde_off,Dwarf_Off * cie_off,Dwarf_Error * err)2110 _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
2111 Dwarf_Off * fde_off, Dwarf_Off * cie_off,
2112 Dwarf_Error * err)
2113 {
2114 return dwarf_fde_section_offset(dbg,in_fde,fde_off,
2115 cie_off,err);
2116 }
2117 /* ARGSUSED 4 */
2118 int
dwarf_fde_section_offset(Dwarf_Debug dbg,Dwarf_Fde in_fde,Dwarf_Off * fde_off,Dwarf_Off * cie_off,Dwarf_Error * err)2119 dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
2120 Dwarf_Off * fde_off, Dwarf_Off * cie_off,
2121 Dwarf_Error * err)
2122 {
2123 char *start = 0;
2124 char *loc = 0;
2125
2126
2127
2128 start = (char *) in_fde->fd_section_ptr;
2129 loc = (char *) in_fde->fd_fde_start;
2130
2131 *fde_off = (loc - start);
2132 *cie_off = in_fde->fd_cie_offset;
2133 return DW_DLV_OK;
2134 }
2135
2136 /* Used by dwarfdump -v to print offsets, for debugging
2137 dwarf info.
2138 The dwarf_ version is preferred over the obsolete _dwarf version.
2139 _dwarf version kept for compatibility.
2140 */
2141 /* ARGSUSED 4 */
2142 int
_dwarf_cie_section_offset(Dwarf_Debug dbg,Dwarf_Cie in_cie,Dwarf_Off * cie_off,Dwarf_Error * err)2143 _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
2144 Dwarf_Off * cie_off, Dwarf_Error * err)
2145 {
2146 return dwarf_cie_section_offset(dbg,in_cie,cie_off,err);
2147 }
2148 /* ARGSUSED 4 */
2149 int
dwarf_cie_section_offset(Dwarf_Debug dbg,Dwarf_Cie in_cie,Dwarf_Off * cie_off,Dwarf_Error * err)2150 dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
2151 Dwarf_Off * cie_off, Dwarf_Error * err)
2152 {
2153 char *start = 0;
2154 char *loc = 0;
2155
2156 start = (char *) in_cie->ci_section_ptr;
2157 loc = (char *) in_cie->ci_cie_start;
2158
2159 *cie_off = (loc - start);
2160 return DW_DLV_OK;
2161 }
2162
2163 /* Returns a pointer to target-specific augmentation data thru augdata
2164 and returns the length of the data thru augdata_len.
2165
2166 It's up to the consumer code to know how to interpret the bytes
2167 of target-specific data (endian issues apply too, these
2168 are just raw bytes pointed to).
2169 See Linux Standard Base Core Specification version 3.0 for
2170 the details on .eh_frame info.
2171
2172 Returns DW_DLV_ERROR if fde is NULL or some other serious
2173 error.
2174 Returns DW_DLV_NO_ENTRY if there is no target-specific
2175 augmentation data.
2176
2177 The bytes pointed to are in the Dwarf_Cie, and as long as that
2178 is valid the bytes are there. No 'dealloc' call is needed
2179 for the bytes.
2180 */
2181 int
dwarf_get_cie_augmentation_data(Dwarf_Cie cie,Dwarf_Small ** augdata,Dwarf_Unsigned * augdata_len,Dwarf_Error * error)2182 dwarf_get_cie_augmentation_data(Dwarf_Cie cie,
2183 Dwarf_Small ** augdata,
2184 Dwarf_Unsigned * augdata_len,
2185 Dwarf_Error * error)
2186 {
2187 if (cie == NULL) {
2188 _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
2189 return (DW_DLV_ERROR);
2190 }
2191 if (cie->ci_gnu_eh_augmentation_len == 0) {
2192 return DW_DLV_NO_ENTRY;
2193 }
2194 *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes);
2195 *augdata_len = cie->ci_gnu_eh_augmentation_len;
2196 return DW_DLV_OK;
2197 }
2198
2199
2200 /* Returns a pointer to target-specific augmentation data thru augdata
2201 and returns the length of the data thru augdata_len.
2202
2203 It's up to the consumer code to know how to interpret the bytes
2204 of target-specific data (endian issues apply too, these
2205 are just raw bytes pointed to).
2206 See Linux Standard Base Core Specification version 3.0 for
2207 the details on .eh_frame info.
2208
2209 Returns DW_DLV_ERROR if fde is NULL or some other serious
2210 error.
2211 Returns DW_DLV_NO_ENTRY if there is no target-specific
2212 augmentation data.
2213
2214 The bytes pointed to are in the Dwarf_Fde, and as long as that
2215 is valid the bytes are there. No 'dealloc' call is needed
2216 for the bytes.
2217
2218 */
2219 int
dwarf_get_fde_augmentation_data(Dwarf_Fde fde,Dwarf_Small ** augdata,Dwarf_Unsigned * augdata_len,Dwarf_Error * error)2220 dwarf_get_fde_augmentation_data(Dwarf_Fde fde,
2221 Dwarf_Small * *augdata,
2222 Dwarf_Unsigned * augdata_len,
2223 Dwarf_Error * error)
2224 {
2225 Dwarf_Cie cie = 0;
2226
2227 if (fde == NULL) {
2228 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
2229 return (DW_DLV_ERROR);
2230 }
2231 cie = fde->fd_cie;
2232 if (cie == NULL) {
2233 _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
2234 return (DW_DLV_ERROR);
2235 }
2236 if (cie->ci_gnu_eh_augmentation_len == 0) {
2237 return DW_DLV_NO_ENTRY;
2238 }
2239 *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes;
2240 *augdata_len = fde->fd_gnu_eh_augmentation_len;
2241 return DW_DLV_OK;
2242 }
2243
2244
2245 /* Initialize with same_value , a value which makes sense
2246 for IRIX/MIPS.
2247 The correct value to use is ABI dependent.
2248 For register-windows machines most
2249 or all registers should get DW_FRAME_UNDEFINED_VAL as the
2250 correct initial value.
2251 Some think DW_FRAME_UNDEFINED_VAL is always the
2252 right value.
2253
2254 For some ABIs a setting which varies by register
2255 would be more appropriate.
2256
2257 FIXME. */
2258
2259 static void
_dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s * t1reg,int last_reg_num,int initial_value)2260 _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
2261 int last_reg_num, int initial_value)
2262 {
2263 struct Dwarf_Reg_Rule_s *t1end = t1reg + last_reg_num;
2264
2265 for (; t1reg < t1end; t1reg++) {
2266 t1reg->ru_is_off = 0;
2267 t1reg->ru_value_type = DW_EXPR_OFFSET;
2268 t1reg->ru_register = initial_value;
2269 t1reg->ru_offset_or_block_len = 0;
2270 t1reg->ru_block = 0;
2271 }
2272 }
2273
2274 #if 0
2275 /* Used solely for debugging libdwarf. */
2276 static void
2277 dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule)
2278 {
2279 printf
2280 ("%s type %s (" DW_PR_DUx "), is_off "
2281 DW_PR_DUu " reg " DW_PR_DUu " offset " DW_PR_DUx " blockp "
2282 DW_PR_DUx "\n",
2283 msg,
2284 (reg_rule->ru_value_type == DW_EXPR_OFFSET) ?
2285 "DW_EXPR_OFFSET" :
2286 (reg_rule->ru_value_type == DW_EXPR_VAL_OFFSET) ?
2287 "DW_EXPR_VAL_OFFSET" :
2288 (reg_rule->ru_value_type == DW_EXPR_VAL_EXPRESSION) ?
2289 "DW_EXPR_VAL_EXPRESSION" :
2290 (reg_rule->ru_value_type == DW_EXPR_EXPRESSION) ?
2291 "DW_EXPR_EXPRESSION" : "Unknown",
2292 (Dwarf_Unsigned) reg_rule->ru_value_type,
2293 (Dwarf_Unsigned) reg_rule->ru_is_off,
2294 (Dwarf_Unsigned) reg_rule->ru_register,
2295 (Dwarf_Unsigned) reg_rule->ru_offset_or_block_len,
2296 (Dwarf_Unsigned) reg_rule->ru_block);
2297 return;
2298 }
2299 #endif
2300
2301 /* This allows consumers to set the 'initial value' so that
2302 an ISA/ABI specific default can be used, dynamically,
2303 at run time. Useful for dwarfdump and non-MIPS architectures..
2304 The value defaults to one of
2305 DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE
2306 but dwarfdump can dump multiple ISA/ABI objects so
2307 we may want to get this set to what the ABI says is correct.
2308
2309 Returns the value that was present before we changed it here.
2310 */
2311 Dwarf_Half
dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg,Dwarf_Half value)2312 dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value)
2313 {
2314 Dwarf_Half orig = dbg->de_frame_rule_initial_value;
2315 dbg->de_frame_rule_initial_value = value;
2316 return orig;
2317 }
2318
2319 /* The following spelling for backwards compatibility. */
2320 Dwarf_Half
dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg,Dwarf_Half value)2321 dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value)
2322 {
2323 return dwarf_set_frame_rule_initial_value(dbg,value);
2324 }
2325
2326 /* This allows consumers to set the array size of the reg rules
2327 table so that
2328 an ISA/ABI specific value can be used, dynamically,
2329 at run time. Useful for non-MIPS archtectures.
2330 The value defaults to DW_FRAME_LAST_REG_NUM.
2331 but dwarfdump can dump multiple ISA/ABI objects so
2332 consumers want to get this set to what the ABI says is correct.
2333
2334 Returns the value that was present before we changed it here.
2335 */
2336
2337 Dwarf_Half
dwarf_set_frame_rule_table_size(Dwarf_Debug dbg,Dwarf_Half value)2338 dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value)
2339 {
2340 Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count;
2341 dbg->de_frame_reg_rules_entry_count = value;
2342 return orig;
2343 }
2344 /* This allows consumers to set the CFA register value
2345 * so that an ISA/ABI specific value can be used, dynamically,
2346 * at run time. Useful for non-MIPS archtectures.
2347 * The value defaults to DW_FRAME_CFA_COL3 and should be
2348 * higher than any real register in the ABI.
2349 * Dwarfdump can dump multiple ISA/ABI objects so
2350 * consumers want to get this set to what the ABI says is correct.
2351
2352 * Returns the value that was present before we changed it here.
2353 * */
2354
2355 Dwarf_Half
dwarf_set_frame_cfa_value(Dwarf_Debug dbg,Dwarf_Half value)2356 dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value)
2357 {
2358 Dwarf_Half orig = dbg->de_frame_cfa_col_number;
2359 dbg->de_frame_cfa_col_number = value;
2360 return orig;
2361 }
2362 /* Similar to above, but for the other crucial fields for frames. */
2363 Dwarf_Half
dwarf_set_frame_same_value(Dwarf_Debug dbg,Dwarf_Half value)2364 dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value)
2365 {
2366 Dwarf_Half orig = dbg->de_frame_same_value_number;
2367 dbg->de_frame_same_value_number = value;
2368 return orig;
2369 }
2370 Dwarf_Half
dwarf_set_frame_undefined_value(Dwarf_Debug dbg,Dwarf_Half value)2371 dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value)
2372 {
2373 Dwarf_Half orig = dbg->de_frame_same_value_number;
2374 dbg->de_frame_undefined_value_number = value;
2375 return orig;
2376 }
2377
2378
2379
2380
2381
2382 static int
dwarf_initialize_fde_table(Dwarf_Debug dbg,struct Dwarf_Frame_s * fde_table,unsigned table_real_data_size,Dwarf_Error * error)2383 dwarf_initialize_fde_table(Dwarf_Debug dbg,
2384 struct Dwarf_Frame_s *fde_table,
2385 unsigned table_real_data_size,
2386 Dwarf_Error * error)
2387 {
2388 unsigned entry_size = sizeof(struct Dwarf_Frame_s);
2389
2390 fde_table->fr_loc = 0;
2391 fde_table->fr_reg_count = table_real_data_size;
2392 fde_table->fr_next = 0;
2393
2394 fde_table->fr_reg = (struct Dwarf_Reg_Rule_s *)
2395 calloc(entry_size, table_real_data_size);
2396 if (fde_table->fr_reg == 0) {
2397 _dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL);
2398 return (DW_DLV_ERROR);
2399 }
2400 return DW_DLV_OK;
2401
2402 }
2403 static void
dwarf_free_fde_table(struct Dwarf_Frame_s * fde_table)2404 dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table)
2405 {
2406 free(fde_table->fr_reg);
2407 fde_table->fr_reg_count = 0;
2408 fde_table->fr_reg = 0;
2409 }
2410
2411
2412 /* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR.
2413 */
2414 int
_dwarf_frame_constructor(Dwarf_Debug dbg,void * frame)2415 _dwarf_frame_constructor(Dwarf_Debug dbg, void *frame)
2416 {
2417 struct Dwarf_Frame_s *fp = frame;
2418
2419 if (!dbg) {
2420 return DW_DLV_ERROR;
2421 }
2422
2423 fp->fr_reg = calloc(dbg->de_frame_reg_rules_entry_count,
2424 sizeof(struct Dwarf_Reg_Rule_s));
2425 if (!fp->fr_reg) {
2426 return DW_DLV_ERROR;
2427 }
2428 fp->fr_reg_count = dbg->de_frame_reg_rules_entry_count;
2429 return DW_DLV_OK;
2430 }
2431
2432 void
_dwarf_frame_destructor(void * frame)2433 _dwarf_frame_destructor(void *frame)
2434 {
2435 struct Dwarf_Frame_s *fp = frame;
2436
2437 if (fp->fr_reg) {
2438 free(fp->fr_reg);
2439 }
2440 fp->fr_reg = 0;
2441 fp->fr_reg_count = 0;
2442 }
2443