xref: /titanic_50/usr/src/lib/libdwarf/common/dwarf_frame.c (revision f3e7f55e73a39377d55a030f124cc86b3b66a9cc)
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 = &reg_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 = &reg_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 = &reg_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