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