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
62static void
63dump_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
76static 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);
80static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table);
81static void dwarf_init_reg_rules_ru(struct Dwarf_Reg_Rule_s *base,
82    unsigned first, unsigned last,int initial_value);
83static void dwarf_init_reg_rules_dw(struct Dwarf_Regtable_Entry_s *base,
84    unsigned first, unsigned last,int initial_value);
85static 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. */
91static void dump_frame_rule(char *msg,
92    struct Dwarf_Reg_Rule_s *reg_rule);
93#endif
94
95
96int
97dwarf_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
114int
115dwarf_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
207int
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*/
1177int
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*/
1209int
1210dwarf_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
1223int 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*/
1248int
1249dwarf_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*/
1282int
1283dwarf_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).  */
1316int
1317dwarf_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*/
1449int
1450dwarf_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.  */
1499int
1500dwarf_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*/
1524int
1525dwarf_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}
1549int
1550dwarf_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*/
1602static 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*/
1725int
1726dwarf_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.  */
1799int
1800dwarf_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. */
1879int
1880dwarf_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*/
1960int
1961dwarf_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    */
2000int
2001dwarf_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    */
2093int
2094dwarf_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).  */
2141int
2142dwarf_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.  */
2199int
2200dwarf_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.  */
2231int
2232dwarf_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.  */
2259int
2260dwarf_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*/
2329int
2330dwarf_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 */
2387int
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 */
2396int
2397dwarf_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 */
2422int
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 */
2429int
2430dwarf_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.  */
2464int
2465dwarf_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.  */
2500int
2501dwarf_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. */
2528static void
2529dump_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.  */
2563Dwarf_Half
2564dwarf_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. */
2572Dwarf_Half
2573dwarf_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
2589Dwarf_Half
2590dwarf_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
2615Dwarf_Half
2616dwarf_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. */
2623Dwarf_Half
2624dwarf_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}
2630Dwarf_Half
2631dwarf_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).  */
2640Dwarf_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
2650static int
2651init_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}
2667static int
2668dwarf_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}
2680static void
2681dwarf_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*/
2691int
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
2702void
2703_dwarf_frame_destructor(void *frame)
2704{
2705    struct Dwarf_Frame_s *fp = frame;
2706    dwarf_free_fde_table(fp);
2707}
2708void
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
2718static void
2719dwarf_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}
2732static void
2733dwarf_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}
2745static void
2746dwarf_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