149d3bc9Richard Lowe/*
207dc194Richard Lowe  Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
34d9fdb4Robert Mustacchi  Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved.
44d9fdb4Robert Mustacchi  Portions Copyright 2012 SN Systems Ltd. All rights reserved.
54d9fdb4Robert Mustacchi
64d9fdb4Robert Mustacchi  This program is free software; you can redistribute it
74d9fdb4Robert Mustacchi  and/or modify it under the terms of version 2.1 of the
84d9fdb4Robert Mustacchi  GNU Lesser General Public License as published by the Free
94d9fdb4Robert Mustacchi  Software Foundation.
104d9fdb4Robert Mustacchi
114d9fdb4Robert Mustacchi  This program is distributed in the hope that it would be
124d9fdb4Robert Mustacchi  useful, but WITHOUT ANY WARRANTY; without even the implied
134d9fdb4Robert Mustacchi  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
144d9fdb4Robert Mustacchi  PURPOSE.
154d9fdb4Robert Mustacchi
164d9fdb4Robert Mustacchi  Further, this software is distributed without any warranty
174d9fdb4Robert Mustacchi  that it is free of the rightful claim of any third person
184d9fdb4Robert Mustacchi  regarding infringement or the like.  Any license provided
194d9fdb4Robert Mustacchi  herein, whether implied or otherwise, applies only to this
204d9fdb4Robert Mustacchi  software file.  Patent licenses, if any, provided herein
214d9fdb4Robert Mustacchi  do not apply to combinations of this program with other
224d9fdb4Robert Mustacchi  software, or any other product whatsoever.
234d9fdb4Robert Mustacchi
244d9fdb4Robert Mustacchi  You should have received a copy of the GNU Lesser General
254d9fdb4Robert Mustacchi  Public License along with this program; if not, write the
264d9fdb4Robert Mustacchi  Free Software Foundation, Inc., 51 Franklin Street - Fifth
274d9fdb4Robert Mustacchi  Floor, Boston MA 02110-1301, USA.
2849d3bc9Richard Lowe
2949d3bc9Richard Lowe*/
3049d3bc9Richard Lowe
3149d3bc9Richard Lowe#include "config.h"
3249d3bc9Richard Lowe#include <stdio.h>
334d9fdb4Robert Mustacchi#ifdef HAVE_STDLIB_H
3449d3bc9Richard Lowe#include <stdlib.h>
354d9fdb4Robert Mustacchi#endif /* HAVE_STDLIB_H */
364d9fdb4Robert Mustacchi#ifdef HAVE_STDINT_H
374d9fdb4Robert Mustacchi#include <stdint.h> /* For uintptr_t */
384d9fdb4Robert Mustacchi#endif /* HAVE_STDINT_H */
394d9fdb4Robert Mustacchi#include "dwarf_incl.h"
404d9fdb4Robert Mustacchi#include "dwarf_alloc.h"
414d9fdb4Robert Mustacchi#include "dwarf_error.h"
424d9fdb4Robert Mustacchi#include "dwarf_util.h"
4349d3bc9Richard Lowe#include "dwarf_frame.h"
444d9fdb4Robert Mustacchi#include "dwarf_arange.h" /* Using Arange as a way to build a list */
4507dc194Richard Lowe
4607dc194Richard Lowe#define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg )          \
4707dc194Richard Lowe    do {                                               \
484d9fdb4Robert Mustacchi        if ((fde) == NULL) {                           \
494d9fdb4Robert Mustacchi            _dwarf_error(NULL, error, DW_DLE_FDE_NULL);\
5007dc194Richard Lowe        return (DW_DLV_ERROR);                         \
5107dc194Richard Lowe    }                                                  \
5207dc194Richard Lowe    (dbg)= (fde)->fd_dbg;                              \
5307dc194Richard Lowe    if ((dbg) == NULL) {                               \
5407dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\
5507dc194Richard Lowe        return (DW_DLV_ERROR);                         \
5607dc194Richard Lowe    } } while (0)
5707dc194Richard Lowe
5807dc194Richard Lowe
5907dc194Richard Lowe#define MIN(a,b)  (((a) < (b))? a:b)
6007dc194Richard Lowe
614d9fdb4Robert Mustacchi#if 0
624d9fdb4Robert Mustacchistatic void
634d9fdb4Robert Mustacchidump_bytes(const char *msg,Dwarf_Small * start, long len)
644d9fdb4Robert Mustacchi{
654d9fdb4Robert Mustacchi    Dwarf_Small *end = start + len;
664d9fdb4Robert Mustacchi    Dwarf_Small *cur = start;
674d9fdb4Robert Mustacchi    printf("%s (0x%lx) ",msg,(unsigned long)start);
684d9fdb4Robert Mustacchi    for (; cur < end; cur++) {
694d9fdb4Robert Mustacchi        printf("%02x", *cur);
704d9fdb4Robert Mustacchi    }
714d9fdb4Robert Mustacchi    printf("\n");
724d9fdb4Robert Mustacchi}
734d9fdb4Robert Mustacchi#endif /* 0 */
744d9fdb4Robert Mustacchi
754d9fdb4Robert Mustacchi
7607dc194Richard Lowestatic int dwarf_initialize_fde_table(Dwarf_Debug dbg,
774d9fdb4Robert Mustacchi    struct Dwarf_Frame_s *fde_table,
784d9fdb4Robert Mustacchi    unsigned table_real_data_size,
794d9fdb4Robert Mustacchi    Dwarf_Error * error);
8007dc194Richard Lowestatic void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table);
814d9fdb4Robert Mustacchistatic void dwarf_init_reg_rules_ru(struct Dwarf_Reg_Rule_s *base,
824d9fdb4Robert Mustacchi    unsigned first, unsigned last,int initial_value);
834d9fdb4Robert Mustacchistatic void dwarf_init_reg_rules_dw(struct Dwarf_Regtable_Entry_s *base,
844d9fdb4Robert Mustacchi    unsigned first, unsigned last,int initial_value);
854d9fdb4Robert Mustacchistatic void dwarf_init_reg_rules_dw3(struct Dwarf_Regtable_Entry3_s *base,
864d9fdb4Robert Mustacchi    unsigned first, unsigned last,int initial_value);
8707dc194Richard Lowe
884d9fdb4Robert Mustacchi
894d9fdb4Robert Mustacchi#if 0  /* FOR DEBUGGING */
9007dc194Richard Lowe/* Only used for debugging libdwarf. */
9107dc194Richard Lowestatic void dump_frame_rule(char *msg,
924d9fdb4Robert Mustacchi    struct Dwarf_Reg_Rule_s *reg_rule);
9307dc194Richard Lowe#endif
9449d3bc9Richard Lowe
9549d3bc9Richard Lowe
964d9fdb4Robert Mustacchiint
974d9fdb4Robert Mustacchidwarf_get_frame_section_name(Dwarf_Debug dbg,
984d9fdb4Robert Mustacchi   const char **sec_name,
994d9fdb4Robert Mustacchi   Dwarf_Error *error)
1004d9fdb4Robert Mustacchi{
1014d9fdb4Robert Mustacchi    struct Dwarf_Section_s *sec = 0;
1024d9fdb4Robert Mustacchi    if (error != NULL) {
1034d9fdb4Robert Mustacchi        *error = NULL;
1044d9fdb4Robert Mustacchi    }
1054d9fdb4Robert Mustacchi    sec = &dbg->de_debug_frame;
1064d9fdb4Robert Mustacchi    if (sec->dss_size == 0) {
1074d9fdb4Robert Mustacchi        /* We don't have such a  section at all. */
1084d9fdb4Robert Mustacchi        return DW_DLV_NO_ENTRY;
1094d9fdb4Robert Mustacchi    }
1104d9fdb4Robert Mustacchi    *sec_name = sec->dss_name;
1114d9fdb4Robert Mustacchi    return DW_DLV_OK;
1124d9fdb4Robert Mustacchi}
1134d9fdb4Robert Mustacchi
1144d9fdb4Robert Mustacchiint
1154d9fdb4Robert Mustacchidwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg,
1164d9fdb4Robert Mustacchi   const char **sec_name,
1174d9fdb4Robert Mustacchi   Dwarf_Error *error)
1184d9fdb4Robert Mustacchi{
1194d9fdb4Robert Mustacchi    struct Dwarf_Section_s *sec = 0;
1204d9fdb4Robert Mustacchi    if (error != NULL) {
1214d9fdb4Robert Mustacchi        *error = NULL;
1224d9fdb4Robert Mustacchi    }
1234d9fdb4Robert Mustacchi    sec = &dbg->de_debug_frame_eh_gnu;
1244d9fdb4Robert Mustacchi    if (sec->dss_size == 0) {
1254d9fdb4Robert Mustacchi        /* We don't have such a  section at all. */
1264d9fdb4Robert Mustacchi        return DW_DLV_NO_ENTRY;
1274d9fdb4Robert Mustacchi    }
1284d9fdb4Robert Mustacchi    *sec_name = sec->dss_name;
1294d9fdb4Robert Mustacchi    return DW_DLV_OK;
1304d9fdb4Robert Mustacchi}
13149d3bc9Richard Lowe
1324d9fdb4Robert Mustacchi/*
13349d3bc9Richard Lowe    This function is the heart of the debug_frame stuff.  Don't even
1344d9fdb4Robert Mustacchi    think of reading this without reading both the Libdwarf and
1354d9fdb4Robert Mustacchi    consumer API carefully first.  This function basically executes
1364d9fdb4Robert Mustacchi    frame instructions contained in a Cie or an Fde, but does in a
1374d9fdb4Robert Mustacchi    number of different ways depending on the information sought.
1384d9fdb4Robert Mustacchi    Start_instr_ptr points to the first byte of the frame instruction
1394d9fdb4Robert Mustacchi    stream, and final_instr_ptr to the to the first byte after the
1404d9fdb4Robert Mustacchi    last.
1414d9fdb4Robert Mustacchi
1424d9fdb4Robert Mustacchi    The offsets returned in the frame instructions are factored.  That
1434d9fdb4Robert Mustacchi    is they need to be multiplied by either the code_alignment_factor
1444d9fdb4Robert Mustacchi    or the data_alignment_factor, as appropriate to obtain the actual
1454d9fdb4Robert Mustacchi    offset.  This makes it possible to expand an instruction stream
1464d9fdb4Robert Mustacchi    without the corresponding Cie.  However, when an Fde frame instr
1474d9fdb4Robert Mustacchi    sequence is being expanded there must be a valid Cie with a pointer
1484d9fdb4Robert Mustacchi    to an initial table row.
1494d9fdb4Robert Mustacchi
15049d3bc9Richard Lowe
15149d3bc9Richard Lowe    If successful, returns DW_DLV_OK
1524d9fdb4Robert Mustacchi        And sets returned_count thru the pointer
1534d9fdb4Robert Mustacchi        if make_instr is true.
1544d9fdb4Robert Mustacchi        If make_instr is false returned_count
1554d9fdb4Robert Mustacchi        should NOT be used by the caller (returned_count
1564d9fdb4Robert Mustacchi        is set to 0 thru the pointer by this routine...)
15749d3bc9Richard Lowe    If unsuccessful, returns DW_DLV_ERROR
1584d9fdb4Robert Mustacchi        and sets returned_error to the error code
15949d3bc9Richard Lowe
1604d9fdb4Robert Mustacchi    It does not do a whole lot of input validation being a private
16149d3bc9Richard Lowe    function.  Please make sure inputs are valid.
1624d9fdb4Robert Mustacchi
1634d9fdb4Robert Mustacchi    (1) If make_instr is true, it makes a list of pointers to
1644d9fdb4Robert Mustacchi    Dwarf_Frame_Op structures containing the frame instructions
1654d9fdb4Robert Mustacchi    executed.  A pointer to this list is returned in ret_frame_instr.
1664d9fdb4Robert Mustacchi    Make_instr is true only when a list of frame instructions is to be
1674d9fdb4Robert Mustacchi    returned.  In this case since we are not interested in the contents
16849d3bc9Richard Lowe    of the table, the input Cie can be NULL.  This is the only case
16949d3bc9Richard Lowe    where the inpute Cie can be NULL.
17049d3bc9Richard Lowe
1714d9fdb4Robert Mustacchi    (2) If search_pc is true, frame instructions are executed till
17249d3bc9Richard Lowe    either a location is reached that is greater than the search_pc_val
1734d9fdb4Robert Mustacchi    provided, or all instructions are executed.  At this point the
1744d9fdb4Robert Mustacchi    last row of the table generated is returned in a structure.
1754d9fdb4Robert Mustacchi    A pointer to this structure is supplied in table.
1764d9fdb4Robert Mustacchi
1774d9fdb4Robert Mustacchi    (3) This function is also used to create the initial table row
1784d9fdb4Robert Mustacchi    defined by a Cie.  In this case, the Dwarf_Cie pointer cie, is
1794d9fdb4Robert Mustacchi    NULL.  For an FDE, however, cie points to the associated Cie.
1804d9fdb4Robert Mustacchi
1814d9fdb4Robert Mustacchi    (4) If search_pc is true and (has_more_rows and subsequent_pc
1824d9fdb4Robert Mustacchi        are non-null) then:
1834d9fdb4Robert Mustacchi            has_more_rows is set true if there are instruction
1844d9fdb4Robert Mustacchi            bytes following the detection of search_over.
1854d9fdb4Robert Mustacchi            If all the instruction bytes have been seen
1864d9fdb4Robert Mustacchi            then *has_more_rows is set false.
1874d9fdb4Robert Mustacchi
1884d9fdb4Robert Mustacchi            If *has_more_rows is true then *subsequent_pc
1894d9fdb4Robert Mustacchi            is set to the pc value that is the following
1904d9fdb4Robert Mustacchi            row in the table.
19107dc194Richard Lowe
19207dc194Richard Lowe    make_instr - make list of frame instr? 0/1
19307dc194Richard Lowe    ret_frame_instr -  Ptr to list of ptrs to frame instrs
19407dc194Richard Lowe    search_pc  - Search for a pc value?  0/1
1954d9fdb4Robert Mustacchi    search_pc_val -  Search for this pc value
19607dc194Richard Lowe    initial_loc - Initial code location value.
19707dc194Richard Lowe    start_instr_ptr -   Ptr to start of frame instrs.
1984d9fdb4Robert Mustacchi    final_instr_ptr -   Ptr just past frame instrs.
1994d9fdb4Robert Mustacchi    table       -     Ptr to struct with last row.
20007dc194Richard Lowe    cie     -   Ptr to Cie used by the Fde.
2014d9fdb4Robert Mustacchi
2024d9fdb4Robert Mustacchi    Different cies may have distinct address-sizes, so the cie
2034d9fdb4Robert Mustacchi    is used, not de_pointer_size.
20407dc194Richard Lowe
20549d3bc9Richard Lowe*/
20607dc194Richard Lowe
20707dc194Richard Loweint
20807dc194Richard Lowe_dwarf_exec_frame_instr(Dwarf_Bool make_instr,
20907dc194Richard Lowe    Dwarf_Frame_Op ** ret_frame_instr,
21007dc194Richard Lowe    Dwarf_Bool search_pc,
21107dc194Richard Lowe    Dwarf_Addr search_pc_val,
21207dc194Richard Lowe    Dwarf_Addr initial_loc,
21307dc194Richard Lowe    Dwarf_Small * start_instr_ptr,
21407dc194Richard Lowe    Dwarf_Small * final_instr_ptr,
21507dc194Richard Lowe    Dwarf_Frame table,
21607dc194Richard Lowe    Dwarf_Cie cie,
21707dc194Richard Lowe    Dwarf_Debug dbg,
21807dc194Richard Lowe    Dwarf_Half reg_num_of_cfa,
2194d9fdb4Robert Mustacchi    Dwarf_Signed * returned_count,
2204d9fdb4Robert Mustacchi    Dwarf_Bool * has_more_rows,
2214d9fdb4Robert Mustacchi    Dwarf_Addr * subsequent_pc,
2224d9fdb4Robert Mustacchi    Dwarf_Error *error)
22349d3bc9Richard Lowe{
2244d9fdb4Robert Mustacchi/*  The following macro depends on macreg and
2254d9fdb4Robert Mustacchi    machigh_reg both being unsigned to avoid
2264d9fdb4Robert Mustacchi    unintended behavior and to avoid compiler warnings when
2274d9fdb4Robert Mustacchi    high warning levels are turned on.  */
2284d9fdb4Robert Mustacchi#define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg)        \
2294d9fdb4Robert Mustacchi    do {                                                     \
2304d9fdb4Robert Mustacchi        if ((macreg) >= (machigh_reg)) {                     \
2314d9fdb4Robert Mustacchi            SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \
2324d9fdb4Robert Mustacchi        }                                                    \
2334d9fdb4Robert Mustacchi    } /*CONSTCOND */ while (0)
23407dc194Richard Lowe#define SIMPLE_ERROR_RETURN(code) \
2354d9fdb4Robert Mustacchi        free(localregtab);        \
2364d9fdb4Robert Mustacchi        _dwarf_error(dbg,error,code); \
23707dc194Richard Lowe        return DW_DLV_ERROR
23807dc194Richard Lowe
2394d9fdb4Robert Mustacchi    /*  Sweeps the frame instructions. */
2404d9fdb4Robert Mustacchi    Dwarf_Small *instr_ptr = 0;
24149d3bc9Richard Lowe
2424d9fdb4Robert Mustacchi    /*  Register numbers not limited to just 255, thus not using
2434d9fdb4Robert Mustacchi        Dwarf_Small.  */
2444d9fdb4Robert Mustacchi    typedef unsigned reg_num_type;
24507dc194Richard Lowe
2464d9fdb4Robert Mustacchi    Dwarf_Unsigned factored_N_value = 0;
2474d9fdb4Robert Mustacchi    Dwarf_Signed signed_factored_N_value = 0;
24807dc194Richard Lowe    Dwarf_Addr current_loc = initial_loc;       /* code location/
2494d9fdb4Robert Mustacchi        pc-value corresponding to the frame instructions.
2504d9fdb4Robert Mustacchi        Starts at zero when the caller has no value to pass in. */
2514d9fdb4Robert Mustacchi
2524d9fdb4Robert Mustacchi    /*  Must be min de_pointer_size bytes and must be at least 4 */
25307dc194Richard Lowe    Dwarf_Unsigned adv_loc = 0;
25407dc194Richard Lowe
2554d9fdb4Robert Mustacchi    unsigned reg_count = dbg->de_frame_reg_rules_entry_count;
25607dc194Richard Lowe    struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count,
2574d9fdb4Robert Mustacchi        sizeof(struct Dwarf_Reg_Rule_s));
25807dc194Richard Lowe
25907dc194Richard Lowe    struct Dwarf_Reg_Rule_s cfa_reg;
26049d3bc9Richard Lowe
2614d9fdb4Robert Mustacchi    /*  This is used to end executing frame instructions.  */
2624d9fdb4Robert Mustacchi    /*  Becomes true when search_pc is true and current_loc */
2634d9fdb4Robert Mustacchi    /*  is greater than search_pc_val.  */
26449d3bc9Richard Lowe    Dwarf_Bool search_over = false;
26549d3bc9Richard Lowe
2664d9fdb4Robert Mustacchi    Dwarf_Addr possible_subsequent_pc = 0;
26749d3bc9Richard Lowe
2684d9fdb4Robert Mustacchi    /*  Used by the DW_FRAME_advance_loc instr */
2694d9fdb4Robert Mustacchi    /*  to hold the increment in pc value.  */
2704d9fdb4Robert Mustacchi    Dwarf_Addr adv_pc = 0;
27149d3bc9Richard Lowe
2724d9fdb4Robert Mustacchi    Dwarf_Half address_size = (cie)? cie->ci_address_size:
27307dc194Richard Lowe        dbg->de_pointer_size;
27407dc194Richard Lowe
2754d9fdb4Robert Mustacchi    /*  Counts the number of frame instructions executed.  */
2764d9fdb4Robert Mustacchi    Dwarf_Unsigned instr_count = 0;
27749d3bc9Richard Lowe
2784d9fdb4Robert Mustacchi    /*  These contain the current fields of the current frame
2794d9fdb4Robert Mustacchi        instruction. */
28049d3bc9Richard Lowe    Dwarf_Small fp_base_op = 0;
2814d9fdb4Robert Mustacchi    Dwarf_Small fp_extended_op = 0;
2824d9fdb4Robert Mustacchi    reg_num_type fp_register = 0;
2834d9fdb4Robert Mustacchi
2844d9fdb4Robert Mustacchi    /*  The value in fp_offset may be signed, though we call it
2854d9fdb4Robert Mustacchi        unsigned. This works ok for 2-s complement arithmetic. */
2864d9fdb4Robert Mustacchi    Dwarf_Unsigned fp_offset = 0;
2874d9fdb4Robert Mustacchi    Dwarf_Off fp_instr_offset = 0;
2884d9fdb4Robert Mustacchi
2894d9fdb4Robert Mustacchi    /*  Stack_table points to the row (Dwarf_Frame ie) being pushed or
2904d9fdb4Robert Mustacchi        popped by a remember or restore instruction. Top_stack points to
2914d9fdb4Robert Mustacchi        the top of the stack of rows. */
29207dc194Richard Lowe    Dwarf_Frame stack_table = NULL;
29349d3bc9Richard Lowe    Dwarf_Frame top_stack = NULL;
29449d3bc9Richard Lowe
2954d9fdb4Robert Mustacchi    /*  These are used only when make_instr is true. Curr_instr is a
2964d9fdb4Robert Mustacchi        pointer to the current frame instruction executed.
2974d9fdb4Robert Mustacchi        Curr_instr_ptr, head_instr_list, and curr_instr_list are used to
2984d9fdb4Robert Mustacchi        form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is
2994d9fdb4Robert Mustacchi        used to deallocate the structs used to form the chain.
3004d9fdb4Robert Mustacchi        Head_instr_block points to a contiguous list of pointers to the
3014d9fdb4Robert Mustacchi        Dwarf_Frame_Op structs executed. */
3024d9fdb4Robert Mustacchi    Dwarf_Frame_Op *curr_instr = 0;
3034d9fdb4Robert Mustacchi    Dwarf_Chain curr_instr_item = 0;
30449d3bc9Richard Lowe    Dwarf_Chain head_instr_chain = NULL;
30549d3bc9Richard Lowe    Dwarf_Chain tail_instr_chain = NULL;
3064d9fdb4Robert Mustacchi    Dwarf_Frame_Op *head_instr_block = 0;
3074d9fdb4Robert Mustacchi
3084d9fdb4Robert Mustacchi    /*  These are the alignment_factors taken from the Cie provided.
3094d9fdb4Robert Mustacchi        When no input Cie is provided they are set to 1, because only
3104d9fdb4Robert Mustacchi        factored offsets are required. */
3114d9fdb4Robert Mustacchi    Dwarf_Signed code_alignment_factor = 1;
3124d9fdb4Robert Mustacchi    Dwarf_Signed data_alignment_factor = 1;
3134d9fdb4Robert Mustacchi
3144d9fdb4Robert Mustacchi    /*  This flag indicates when an actual alignment factor is needed.
3154d9fdb4Robert Mustacchi        So if a frame instruction that computes an offset using an
3164d9fdb4Robert Mustacchi        alignment factor is encountered when this flag is set, an error
3174d9fdb4Robert Mustacchi        is returned because the Cie did not have a valid augmentation. */
31849d3bc9Richard Lowe    Dwarf_Bool need_augmentation = false;
31949d3bc9Richard Lowe
3204d9fdb4Robert Mustacchi    Dwarf_Unsigned i = 0;
32149d3bc9Richard Lowe
3224d9fdb4Robert Mustacchi    /*  Initialize first row from associated Cie. Using temp regs
3234d9fdb4Robert Mustacchi        explicity */
32407dc194Richard Lowe
32507dc194Richard Lowe    if (localregtab == 0) {
32607dc194Richard Lowe        SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL);
32707dc194Richard Lowe    }
32807dc194Richard Lowe    {
32907dc194Richard Lowe        struct Dwarf_Reg_Rule_s *t1reg = localregtab;
33007dc194Richard Lowe        if (cie != NULL && cie->ci_initial_table != NULL) {
3314d9fdb4Robert Mustacchi            unsigned minregcount = 0;
3324d9fdb4Robert Mustacchi            unsigned curreg = 0;
3334d9fdb4Robert Mustacchi            struct Dwarf_Reg_Rule_s *t2reg = cie->ci_initial_table->fr_reg;
33407dc194Richard Lowe
33507dc194Richard Lowe            if (reg_count != cie->ci_initial_table->fr_reg_count) {
3364d9fdb4Robert Mustacchi                /*  Should never happen, it makes no sense to have the
3374d9fdb4Robert Mustacchi                    table sizes change. There is no real allowance for
3384d9fdb4Robert Mustacchi                    the set of registers to change dynamically in a
3394d9fdb4Robert Mustacchi                    single Dwarf_Debug (except the size can be set near
3404d9fdb4Robert Mustacchi                    initial Dwarf_Debug creation time). */
34107dc194Richard Lowe                SIMPLE_ERROR_RETURN
34207dc194Richard Lowe                    (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH);
34307dc194Richard Lowe            }
3444d9fdb4Robert Mustacchi            minregcount = MIN(reg_count,cie->ci_initial_table->fr_reg_count);
3454d9fdb4Robert Mustacchi            for (; curreg < minregcount ;curreg++, t1reg++, t2reg++) {
34607dc194Richard Lowe                *t1reg = *t2reg;
34707dc194Richard Lowe            }
34807dc194Richard Lowe            cfa_reg = cie->ci_initial_table->fr_cfa_rule;
34907dc194Richard Lowe        } else {
3504d9fdb4Robert Mustacchi            dwarf_init_reg_rules_ru(localregtab,0,reg_count,
3514d9fdb4Robert Mustacchi                dbg->de_frame_rule_initial_value);
3524d9fdb4Robert Mustacchi            dwarf_init_reg_rules_ru(&cfa_reg,0, 1,
3534d9fdb4Robert Mustacchi                dbg->de_frame_rule_initial_value);
35407dc194Richard Lowe        }
35549d3bc9Richard Lowe    }
35649d3bc9Richard Lowe
3574d9fdb4Robert Mustacchi    /*  The idea here is that the code_alignment_factor and
3584d9fdb4Robert Mustacchi        data_alignment_factor which are needed for certain instructions
3594d9fdb4Robert Mustacchi        are valid only when the Cie has a proper augmentation string. So
3604d9fdb4Robert Mustacchi        if the augmentation is not right, only Frame instruction can be
3614d9fdb4Robert Mustacchi        read. */
36249d3bc9Richard Lowe    if (cie != NULL && cie->ci_augmentation != NULL) {
36307dc194Richard Lowe        code_alignment_factor = cie->ci_code_alignment_factor;
36407dc194Richard Lowe        data_alignment_factor = cie->ci_data_alignment_factor;
36507dc194Richard Lowe    } else {
36607dc194Richard Lowe        need_augmentation = !make_instr;
36707dc194Richard Lowe    }
36849d3bc9Richard Lowe    instr_ptr = start_instr_ptr;
36949d3bc9Richard Lowe    while ((instr_ptr < final_instr_ptr) && (!search_over)) {
37007dc194Richard Lowe        Dwarf_Small instr = 0;
37107dc194Richard Lowe        Dwarf_Small opcode = 0;
37207dc194Richard Lowe        reg_num_type reg_no = 0;
37307dc194Richard Lowe
37407dc194Richard Lowe        fp_instr_offset = instr_ptr - start_instr_ptr;
37507dc194Richard Lowe        instr = *(Dwarf_Small *) instr_ptr;
37607dc194Richard Lowe        instr_ptr += sizeof(Dwarf_Small);
37707dc194Richard Lowe
37807dc194Richard Lowe        fp_base_op = (instr & 0xc0) >> 6;
37907dc194Richard Lowe        if ((instr & 0xc0) == 0x00) {
38007dc194Richard Lowe            opcode = instr;     /* is really extended op */
38107dc194Richard Lowe            fp_extended_op = (instr & (~(0xc0))) & 0xff;
38207dc194Richard Lowe        } else {
38307dc194Richard Lowe            opcode = instr & 0xc0;      /* is base op */
38407dc194Richard Lowe            fp_extended_op = 0;
38507dc194Richard Lowe        }
38607dc194Richard Lowe
38707dc194Richard Lowe        fp_register = 0;
38807dc194Richard Lowe        fp_offset = 0;
38907dc194Richard Lowe        switch (opcode) {
39007dc194Richard Lowe        case DW_CFA_advance_loc:
39107dc194Richard Lowe            {
39207dc194Richard Lowe                /* base op */
39307dc194Richard Lowe                fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
39407dc194Richard Lowe
39507dc194Richard Lowe                if (need_augmentation) {
39607dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
39707dc194Richard Lowe                }
39807dc194Richard Lowe                adv_pc = adv_pc * code_alignment_factor;
3994d9fdb4Robert Mustacchi                possible_subsequent_pc =  current_loc + adv_pc;
40007dc194Richard Lowe                search_over = search_pc &&
4014d9fdb4Robert Mustacchi                    (possible_subsequent_pc > search_pc_val);
40207dc194Richard Lowe                /* If gone past pc needed, retain old pc.  */
40307dc194Richard Lowe                if (!search_over) {
4044d9fdb4Robert Mustacchi                    current_loc = possible_subsequent_pc;
40507dc194Richard Lowe                }
40607dc194Richard Lowe                break;
40707dc194Richard Lowe            }
40807dc194Richard Lowe
40907dc194Richard Lowe        case DW_CFA_offset:
41007dc194Richard Lowe            {                   /* base op */
41107dc194Richard Lowe                reg_no =
41207dc194Richard Lowe                    (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK);
41307dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
41407dc194Richard Lowe
4154d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value,
4164d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
41707dc194Richard Lowe
41807dc194Richard Lowe                fp_register = reg_no;
41907dc194Richard Lowe                fp_offset = factored_N_value;
42007dc194Richard Lowe
42107dc194Richard Lowe                if (need_augmentation) {
42207dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
42307dc194Richard Lowe                }
42407dc194Richard Lowe
42507dc194Richard Lowe                localregtab[reg_no].ru_is_off = 1;
42607dc194Richard Lowe                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
42707dc194Richard Lowe                localregtab[reg_no].ru_register = reg_num_of_cfa;
42807dc194Richard Lowe                localregtab[reg_no].ru_offset_or_block_len =
42907dc194Richard Lowe                    factored_N_value * data_alignment_factor;
43007dc194Richard Lowe
43107dc194Richard Lowe                break;
43207dc194Richard Lowe            }
43307dc194Richard Lowe
43407dc194Richard Lowe        case DW_CFA_restore:
43507dc194Richard Lowe            {                   /* base op */
43607dc194Richard Lowe                reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
43707dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
43807dc194Richard Lowe
43907dc194Richard Lowe                fp_register = reg_no;
44007dc194Richard Lowe
44107dc194Richard Lowe                if (cie != NULL && cie->ci_initial_table != NULL)
4424d9fdb4Robert Mustacchi                    localregtab[reg_no] =
4434d9fdb4Robert Mustacchi                        cie->ci_initial_table->fr_reg[reg_no];
44407dc194Richard Lowe                else if (!make_instr) {
44507dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT);
44607dc194Richard Lowe                }
44707dc194Richard Lowe
44807dc194Richard Lowe                break;
44907dc194Richard Lowe            }
45007dc194Richard Lowe        case DW_CFA_set_loc:
45107dc194Richard Lowe            {
45207dc194Richard Lowe                Dwarf_Addr new_loc = 0;
45307dc194Richard Lowe
4544d9fdb4Robert Mustacchi                READ_UNALIGNED_CK(dbg, new_loc, Dwarf_Addr,
4554d9fdb4Robert Mustacchi                    instr_ptr, address_size,
4564d9fdb4Robert Mustacchi                    error,final_instr_ptr);
45707dc194Richard Lowe                instr_ptr += address_size;
45807dc194Richard Lowe                if (new_loc != 0 && current_loc != 0) {
4594d9fdb4Robert Mustacchi                    /*  Pre-relocation or before current_loc is set the
4604d9fdb4Robert Mustacchi                        test comparing new_loc and current_loc makes no
4614d9fdb4Robert Mustacchi                        sense. Testing for non-zero (above) is a way
4624d9fdb4Robert Mustacchi                        (fallible) to check that current_loc, new_loc
4634d9fdb4Robert Mustacchi                        are already relocated.  */
46407dc194Richard Lowe                    if (new_loc <= current_loc) {
4654d9fdb4Robert Mustacchi                        /*  Within a frame, address must increase.
4664d9fdb4Robert Mustacchi                            Seemingly it has not.
4674d9fdb4Robert Mustacchi                            Seems to be an error. */
46807dc194Richard Lowe                        SIMPLE_ERROR_RETURN
46907dc194Richard Lowe                            (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
47007dc194Richard Lowe                    }
47107dc194Richard Lowe                }
47207dc194Richard Lowe
47307dc194Richard Lowe                search_over = search_pc && (new_loc > search_pc_val);
47407dc194Richard Lowe
47507dc194Richard Lowe                /* If gone past pc needed, retain old pc.  */
4764d9fdb4Robert Mustacchi                possible_subsequent_pc =  new_loc;
47707dc194Richard Lowe                if (!search_over) {
4784d9fdb4Robert Mustacchi                    current_loc = possible_subsequent_pc;
47907dc194Richard Lowe                }
48007dc194Richard Lowe                fp_offset = new_loc;
48107dc194Richard Lowe                break;
48207dc194Richard Lowe            }
48307dc194Richard Lowe
48407dc194Richard Lowe        case DW_CFA_advance_loc1:
48507dc194Richard Lowe            {
4864d9fdb4Robert Mustacchi                READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned,
4874d9fdb4Robert Mustacchi                    instr_ptr, sizeof(Dwarf_Small),
4884d9fdb4Robert Mustacchi                    error,final_instr_ptr);
48907dc194Richard Lowe                instr_ptr += sizeof(Dwarf_Small);
4904d9fdb4Robert Mustacchi                fp_offset = adv_loc;
49107dc194Richard Lowe
49207dc194Richard Lowe                if (need_augmentation) {
49307dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
49407dc194Richard Lowe                }
49507dc194Richard Lowe                adv_loc *= code_alignment_factor;
49607dc194Richard Lowe
4974d9fdb4Robert Mustacchi                possible_subsequent_pc =  current_loc + adv_loc;
49807dc194Richard Lowe                search_over = search_pc &&
4994d9fdb4Robert Mustacchi                    (possible_subsequent_pc > search_pc_val);
50007dc194Richard Lowe
50107dc194Richard Lowe                /* If gone past pc needed, retain old pc.  */
50207dc194Richard Lowe                if (!search_over) {
5034d9fdb4Robert Mustacchi                    current_loc = possible_subsequent_pc;
50407dc194Richard Lowe                }
50507dc194Richard Lowe                break;
50607dc194Richard Lowe            }
50707dc194Richard Lowe
50807dc194Richard Lowe        case DW_CFA_advance_loc2:
50907dc194Richard Lowe            {
5104d9fdb4Robert Mustacchi                READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned,
5114d9fdb4Robert Mustacchi                    instr_ptr, DWARF_HALF_SIZE,
5124d9fdb4Robert Mustacchi                    error,final_instr_ptr);
5134d9fdb4Robert Mustacchi                instr_ptr += DWARF_HALF_SIZE;
51407dc194Richard Lowe                fp_offset = adv_loc;
51507dc194Richard Lowe
51607dc194Richard Lowe                if (need_augmentation) {
51707dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
51807dc194Richard Lowe                }
51907dc194Richard Lowe                adv_loc *= code_alignment_factor;
52007dc194Richard Lowe
5214d9fdb4Robert Mustacchi                possible_subsequent_pc =  current_loc + adv_loc;
52207dc194Richard Lowe                search_over = search_pc &&
5234d9fdb4Robert Mustacchi                    (possible_subsequent_pc > search_pc_val);
52407dc194Richard Lowe                /* If gone past pc needed, retain old pc.  */
52507dc194Richard Lowe                if (!search_over) {
5264d9fdb4Robert Mustacchi                    current_loc = possible_subsequent_pc;
52707dc194Richard Lowe                }
52807dc194Richard Lowe                break;
52907dc194Richard Lowe            }
53007dc194Richard Lowe
53107dc194Richard Lowe        case DW_CFA_advance_loc4:
53207dc194Richard Lowe            {
5334d9fdb4Robert Mustacchi                READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned,
5344d9fdb4Robert Mustacchi                    instr_ptr, DWARF_32BIT_SIZE,
5354d9fdb4Robert Mustacchi                    error,final_instr_ptr);
5364d9fdb4Robert Mustacchi                instr_ptr += DWARF_32BIT_SIZE;
53707dc194Richard Lowe                fp_offset = adv_loc;
53807dc194Richard Lowe
53907dc194Richard Lowe                if (need_augmentation) {
54007dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
54107dc194Richard Lowe                }
54207dc194Richard Lowe                adv_loc *= code_alignment_factor;
54307dc194Richard Lowe
5444d9fdb4Robert Mustacchi                possible_subsequent_pc =  current_loc + adv_loc;
54507dc194Richard Lowe                search_over = search_pc &&
5464d9fdb4Robert Mustacchi                    (possible_subsequent_pc > search_pc_val);
5474d9fdb4Robert Mustacchi                /* If gone past pc needed, retain old pc.  */
5484d9fdb4Robert Mustacchi                if (!search_over) {
5494d9fdb4Robert Mustacchi                    current_loc = possible_subsequent_pc;
5504d9fdb4Robert Mustacchi                }
5514d9fdb4Robert Mustacchi                break;
5524d9fdb4Robert Mustacchi            }
5534d9fdb4Robert Mustacchi        case DW_CFA_MIPS_advance_loc8:
5544d9fdb4Robert Mustacchi            {
5554d9fdb4Robert Mustacchi                READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned,
5564d9fdb4Robert Mustacchi                    instr_ptr, DWARF_64BIT_SIZE,
5574d9fdb4Robert Mustacchi                    error,final_instr_ptr);
5584d9fdb4Robert Mustacchi                instr_ptr += DWARF_64BIT_SIZE;
5594d9fdb4Robert Mustacchi                fp_offset = adv_loc;
5604d9fdb4Robert Mustacchi
5614d9fdb4Robert Mustacchi                if (need_augmentation) {
5624d9fdb4Robert Mustacchi                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
5634d9fdb4Robert Mustacchi                }
5644d9fdb4Robert Mustacchi                adv_loc *= code_alignment_factor;
56507dc194Richard Lowe
5664d9fdb4Robert Mustacchi                possible_subsequent_pc =  current_loc + adv_loc;
5674d9fdb4Robert Mustacchi                search_over = search_pc &&
5684d9fdb4Robert Mustacchi                    (possible_subsequent_pc > search_pc_val);
56907dc194Richard Lowe                /* If gone past pc needed, retain old pc.  */
57007dc194Richard Lowe                if (!search_over) {
5714d9fdb4Robert Mustacchi                    current_loc = possible_subsequent_pc;
57207dc194Richard Lowe                }
57307dc194Richard Lowe                break;
57407dc194Richard Lowe            }
57507dc194Richard Lowe
57607dc194Richard Lowe        case DW_CFA_offset_extended:
57707dc194Richard Lowe            {
5784d9fdb4Robert Mustacchi                Dwarf_Unsigned lreg = 0;
57907dc194Richard Lowe
5804d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
5814d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
58207dc194Richard Lowe                reg_no = (reg_num_type) lreg;
5834d9fdb4Robert Mustacchi                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
5844d9fdb4Robert Mustacchi
5854d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value,
5864d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
58707dc194Richard Lowe
58807dc194Richard Lowe                if (need_augmentation) {
58907dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
59007dc194Richard Lowe                }
59107dc194Richard Lowe                localregtab[reg_no].ru_is_off = 1;
59207dc194Richard Lowe                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
59307dc194Richard Lowe                localregtab[reg_no].ru_register = reg_num_of_cfa;
59407dc194Richard Lowe                localregtab[reg_no].ru_offset_or_block_len = factored_N_value *
59507dc194Richard Lowe                    data_alignment_factor;
59607dc194Richard Lowe
59707dc194Richard Lowe                fp_register = reg_no;
59807dc194Richard Lowe                fp_offset = factored_N_value;
59907dc194Richard Lowe                break;
60007dc194Richard Lowe            }
60107dc194Richard Lowe
60207dc194Richard Lowe        case DW_CFA_restore_extended:
60307dc194Richard Lowe            {
6044d9fdb4Robert Mustacchi                Dwarf_Unsigned lreg = 0;
60507dc194Richard Lowe
6064d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
6074d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
60807dc194Richard Lowe                reg_no = (reg_num_type) lreg;
60907dc194Richard Lowe
61007dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
61107dc194Richard Lowe
61207dc194Richard Lowe                if (cie != NULL && cie->ci_initial_table != NULL) {
61307dc194Richard Lowe                    localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
61407dc194Richard Lowe                } else {
61507dc194Richard Lowe                    if (!make_instr) {
61607dc194Richard Lowe                        SIMPLE_ERROR_RETURN
61707dc194Richard Lowe                            (DW_DLE_DF_MAKE_INSTR_NO_INIT);
61807dc194Richard Lowe                    }
61907dc194Richard Lowe                }
62007dc194Richard Lowe
62107dc194Richard Lowe                fp_register = reg_no;
62207dc194Richard Lowe                break;
62307dc194Richard Lowe            }
62407dc194Richard Lowe
62507dc194Richard Lowe        case DW_CFA_undefined:
62607dc194Richard Lowe            {
6274d9fdb4Robert Mustacchi                Dwarf_Unsigned lreg = 0;
62807dc194Richard Lowe
6294d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
6304d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
63107dc194Richard Lowe                reg_no = (reg_num_type) lreg;
63207dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
63307dc194Richard Lowe
63407dc194Richard Lowe                localregtab[reg_no].ru_is_off = 0;
63507dc194Richard Lowe                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
6364d9fdb4Robert Mustacchi                localregtab[reg_no].ru_register =
63707dc194Richard Lowe                    dbg->de_frame_undefined_value_number;
63807dc194Richard Lowe                localregtab[reg_no].ru_offset_or_block_len = 0;
63907dc194Richard Lowe
64007dc194Richard Lowe                fp_register = reg_no;
64107dc194Richard Lowe                break;
64207dc194Richard Lowe            }
64307dc194Richard Lowe
64407dc194Richard Lowe        case DW_CFA_same_value:
64507dc194Richard Lowe            {
6464d9fdb4Robert Mustacchi                Dwarf_Unsigned lreg = 0;
64707dc194Richard Lowe
6484d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
6494d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
65007dc194Richard Lowe                reg_no = (reg_num_type) lreg;
65107dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
65207dc194Richard Lowe
65307dc194Richard Lowe                localregtab[reg_no].ru_is_off = 0;
65407dc194Richard Lowe                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
6554d9fdb4Robert Mustacchi                localregtab[reg_no].ru_register =
65607dc194Richard Lowe                    dbg->de_frame_same_value_number;
65707dc194Richard Lowe                localregtab[reg_no].ru_offset_or_block_len = 0;
65807dc194Richard Lowe                fp_register = reg_no;
65907dc194Richard Lowe                break;
66007dc194Richard Lowe            }
66107dc194Richard Lowe
66207dc194Richard Lowe        case DW_CFA_register:
66307dc194Richard Lowe            {
66407dc194Richard Lowe                Dwarf_Unsigned lreg;
66507dc194Richard Lowe                reg_num_type reg_noA = 0;
66607dc194Richard Lowe                reg_num_type reg_noB = 0;
66707dc194Richard Lowe
6684d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
6694d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
67007dc194Richard Lowe                reg_noA = (reg_num_type) lreg;
67107dc194Richard Lowe
67207dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count);
67307dc194Richard Lowe
6744d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
6754d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
67607dc194Richard Lowe                reg_noB = (reg_num_type) lreg;
67707dc194Richard Lowe
67807dc194Richard Lowe                if (reg_noB > reg_count) {
67907dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH);
68007dc194Richard Lowe                }
68107dc194Richard Lowe
68207dc194Richard Lowe
68307dc194Richard Lowe                localregtab[reg_noA].ru_is_off = 0;
68407dc194Richard Lowe                localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET;
68507dc194Richard Lowe                localregtab[reg_noA].ru_register = reg_noB;
68607dc194Richard Lowe                localregtab[reg_noA].ru_offset_or_block_len = 0;
68707dc194Richard Lowe
68807dc194Richard Lowe                fp_register = reg_noA;
68907dc194Richard Lowe                fp_offset = reg_noB;
69007dc194Richard Lowe                break;
69107dc194Richard Lowe            }
69207dc194Richard Lowe
69307dc194Richard Lowe        case DW_CFA_remember_state:
69407dc194Richard Lowe            {
69507dc194Richard Lowe                stack_table = (Dwarf_Frame)
69607dc194Richard Lowe                    _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
69707dc194Richard Lowe                if (stack_table == NULL) {
69807dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
69907dc194Richard Lowe                }
70007dc194Richard Lowe
70107dc194Richard Lowe                for (i = 0; i < reg_count; i++)
70207dc194Richard Lowe                    stack_table->fr_reg[i] = localregtab[i];
70307dc194Richard Lowe                stack_table->fr_cfa_rule = cfa_reg;
70407dc194Richard Lowe
70507dc194Richard Lowe                if (top_stack != NULL)
70607dc194Richard Lowe                    stack_table->fr_next = top_stack;
70707dc194Richard Lowe                top_stack = stack_table;
70807dc194Richard Lowe
70907dc194Richard Lowe                break;
71007dc194Richard Lowe            }
71107dc194Richard Lowe
71207dc194Richard Lowe        case DW_CFA_restore_state:
71307dc194Richard Lowe            {
71407dc194Richard Lowe                if (top_stack == NULL) {
71507dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK);
71607dc194Richard Lowe                }
71707dc194Richard Lowe                stack_table = top_stack;
71807dc194Richard Lowe                top_stack = stack_table->fr_next;
71907dc194Richard Lowe
72007dc194Richard Lowe                for (i = 0; i < reg_count; i++)
72107dc194Richard Lowe                    localregtab[i] = stack_table->fr_reg[i];
72207dc194Richard Lowe                cfa_reg = stack_table->fr_cfa_rule;
72307dc194Richard Lowe
72407dc194Richard Lowe                dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
72507dc194Richard Lowe                break;
72607dc194Richard Lowe            }
72707dc194Richard Lowe
72807dc194Richard Lowe        case DW_CFA_def_cfa:
72907dc194Richard Lowe            {
7304d9fdb4Robert Mustacchi                Dwarf_Unsigned lreg = 0;
73107dc194Richard Lowe
7324d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
7334d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
73407dc194Richard Lowe                reg_no = (reg_num_type) lreg;
73507dc194Richard Lowe
73607dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
73707dc194Richard Lowe
7384d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value,
7394d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
74007dc194Richard Lowe
74107dc194Richard Lowe                if (need_augmentation) {
74207dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
74307dc194Richard Lowe                }
74407dc194Richard Lowe                cfa_reg.ru_is_off = 1;
74507dc194Richard Lowe                cfa_reg.ru_value_type = DW_EXPR_OFFSET;
74607dc194Richard Lowe                cfa_reg.ru_register = reg_no;
74707dc194Richard Lowe                cfa_reg.ru_offset_or_block_len = factored_N_value;
74807dc194Richard Lowe
74907dc194Richard Lowe                fp_register = reg_no;
75007dc194Richard Lowe                fp_offset = factored_N_value;
75107dc194Richard Lowe                break;
75207dc194Richard Lowe            }
75307dc194Richard Lowe
75407dc194Richard Lowe        case DW_CFA_def_cfa_register:
75507dc194Richard Lowe            {
7564d9fdb4Robert Mustacchi                Dwarf_Unsigned lreg = 0;
75707dc194Richard Lowe
7584d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
7594d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
76007dc194Richard Lowe                reg_no = (reg_num_type) lreg;
76107dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
76207dc194Richard Lowe
76307dc194Richard Lowe                cfa_reg.ru_register = reg_no;
7644d9fdb4Robert Mustacchi                /*  Do NOT set ru_offset_or_block_len or ru_is_off here.
7654d9fdb4Robert Mustacchi                    See dwarf2/3 spec.  */
76607dc194Richard Lowe                fp_register = reg_no;
76707dc194Richard Lowe                break;
76807dc194Richard Lowe            }
76907dc194Richard Lowe
77007dc194Richard Lowe        case DW_CFA_def_cfa_offset:
77107dc194Richard Lowe            {
7724d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value,
7734d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
77407dc194Richard Lowe
77507dc194Richard Lowe                if (need_augmentation) {
77607dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
77707dc194Richard Lowe                }
7784d9fdb4Robert Mustacchi                /*  Do set ru_is_off here, as here factored_N_value
7794d9fdb4Robert Mustacchi                    counts.  */
78007dc194Richard Lowe                cfa_reg.ru_is_off = 1;
78107dc194Richard Lowe                cfa_reg.ru_value_type = DW_EXPR_OFFSET;
78207dc194Richard Lowe                cfa_reg.ru_offset_or_block_len = factored_N_value;
78307dc194Richard Lowe
78407dc194Richard Lowe                fp_offset = factored_N_value;
78507dc194Richard Lowe                break;
78607dc194Richard Lowe            }
7874d9fdb4Robert Mustacchi        /*  This is for Metaware with augmentation string HC
7884d9fdb4Robert Mustacchi            We do not really know what to do with it. */
7894d9fdb4Robert Mustacchi        case DW_CFA_METAWARE_info:
7904d9fdb4Robert Mustacchi            {
7914d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value,
7924d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
7934d9fdb4Robert Mustacchi
7944d9fdb4Robert Mustacchi                /* Not really known what the value means or is. */
7954d9fdb4Robert Mustacchi                cfa_reg.ru_is_off = 1;
7964d9fdb4Robert Mustacchi                cfa_reg.ru_value_type = DW_EXPR_OFFSET;
7974d9fdb4Robert Mustacchi                cfa_reg.ru_offset_or_block_len = factored_N_value;
7984d9fdb4Robert Mustacchi
7994d9fdb4Robert Mustacchi                break;
8004d9fdb4Robert Mustacchi            }
80107dc194Richard Lowe        case DW_CFA_nop:
80207dc194Richard Lowe            {
80307dc194Richard Lowe                break;
80407dc194Richard Lowe            }
80507dc194Richard Lowe            /* DWARF3 ops begin here. */
80607dc194Richard Lowe        case DW_CFA_def_cfa_expression:
80707dc194Richard Lowe            {
8084d9fdb4Robert Mustacchi                /*  A single DW_FORM_block representing a dwarf
8094d9fdb4Robert Mustacchi                    expression. The form block establishes the way to
8104d9fdb4Robert Mustacchi                    compute the CFA. */
81107dc194Richard Lowe                Dwarf_Unsigned block_len = 0;
81207dc194Richard Lowe
8134d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, block_len,
8144d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
81507dc194Richard Lowe                cfa_reg.ru_is_off = 0;  /* arbitrary */
81607dc194Richard Lowe                cfa_reg.ru_value_type = DW_EXPR_EXPRESSION;
81707dc194Richard Lowe                cfa_reg.ru_offset_or_block_len = block_len;
81807dc194Richard Lowe                cfa_reg.ru_block = instr_ptr;
81907dc194Richard Lowe                fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
82007dc194Richard Lowe                instr_ptr += block_len;
82107dc194Richard Lowe            }
82207dc194Richard Lowe            break;
82307dc194Richard Lowe        case DW_CFA_expression:
82407dc194Richard Lowe            {
8254d9fdb4Robert Mustacchi                /*  An unsigned leb128 value is the first operand (a
8264d9fdb4Robert Mustacchi                    register number). The second operand is single
8274d9fdb4Robert Mustacchi                    DW_FORM_block representing a dwarf expression. The
8284d9fdb4Robert Mustacchi                    evaluator pushes the CFA on the evaluation stack
8294d9fdb4Robert Mustacchi                    then evaluates the expression to compute the value
8304d9fdb4Robert Mustacchi                    of the register contents. */
83107dc194Richard Lowe                Dwarf_Unsigned lreg = 0;
83207dc194Richard Lowe                Dwarf_Unsigned block_len = 0;
83307dc194Richard Lowe
8344d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
8354d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
83607dc194Richard Lowe                reg_no = (reg_num_type) lreg;
83707dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
8384d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, block_len,
8394d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
84007dc194Richard Lowe                localregtab[lreg].ru_is_off = 0;        /* arbitrary */
84107dc194Richard Lowe                localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION;
84207dc194Richard Lowe                localregtab[lreg].ru_offset_or_block_len = block_len;
84307dc194Richard Lowe                localregtab[lreg].ru_block = instr_ptr;
84407dc194Richard Lowe                fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
84507dc194Richard Lowe                fp_register = reg_no;
84607dc194Richard Lowe                instr_ptr += block_len;
84707dc194Richard Lowe            }
84807dc194Richard Lowe            break;
84907dc194Richard Lowe        case DW_CFA_offset_extended_sf:
85007dc194Richard Lowe            {
8514d9fdb4Robert Mustacchi                /*  The first operand is an unsigned leb128 register
8524d9fdb4Robert Mustacchi                    number. The second is a signed factored offset.
8534d9fdb4Robert Mustacchi                    Identical to DW_CFA_offset_extended except the
8544d9fdb4Robert Mustacchi                    second operand is signed */
8554d9fdb4Robert Mustacchi                Dwarf_Unsigned lreg = 0;
85607dc194Richard Lowe
8574d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
8584d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
85907dc194Richard Lowe                reg_no = (reg_num_type) lreg;
86007dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
8614d9fdb4Robert Mustacchi
8624d9fdb4Robert Mustacchi                DECODE_LEB128_SWORD_CK(instr_ptr, signed_factored_N_value,
8634d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
86407dc194Richard Lowe
86507dc194Richard Lowe                if (need_augmentation) {
86607dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
86707dc194Richard Lowe                }
86807dc194Richard Lowe                localregtab[reg_no].ru_is_off = 1;
86907dc194Richard Lowe                localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
87007dc194Richard Lowe                localregtab[reg_no].ru_register = reg_num_of_cfa;
87107dc194Richard Lowe                localregtab[reg_no].ru_offset_or_block_len =
87207dc194Richard Lowe                    signed_factored_N_value * data_alignment_factor;
87307dc194Richard Lowe
87407dc194Richard Lowe                fp_register = reg_no;
87507dc194Richard Lowe                fp_offset = signed_factored_N_value;
87607dc194Richard Lowe            }
87707dc194Richard Lowe            break;
87807dc194Richard Lowe        case DW_CFA_def_cfa_sf:
87907dc194Richard Lowe            {
8804d9fdb4Robert Mustacchi                /*  The first operand is an unsigned leb128 register
8814d9fdb4Robert Mustacchi                    number. The second is a signed leb128 factored
8824d9fdb4Robert Mustacchi                    offset. Identical to DW_CFA_def_cfa except that the
8834d9fdb4Robert Mustacchi                    second operand is signed and factored. */
88407dc194Richard Lowe                Dwarf_Unsigned lreg;
88507dc194Richard Lowe
8864d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
8874d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
88807dc194Richard Lowe                reg_no = (reg_num_type) lreg;
88907dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
89007dc194Richard Lowe
8914d9fdb4Robert Mustacchi                DECODE_LEB128_SWORD_CK(instr_ptr, signed_factored_N_value,
8924d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
89307dc194Richard Lowe
89407dc194Richard Lowe                if (need_augmentation) {
89507dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
89607dc194Richard Lowe                }
89707dc194Richard Lowe                cfa_reg.ru_is_off = 1;
89807dc194Richard Lowe                cfa_reg.ru_value_type = DW_EXPR_OFFSET;
89907dc194Richard Lowe                cfa_reg.ru_register = reg_no;
90007dc194Richard Lowe                cfa_reg.ru_offset_or_block_len =
90107dc194Richard Lowe                    signed_factored_N_value * data_alignment_factor;
90207dc194Richard Lowe
90307dc194Richard Lowe                fp_register = reg_no;
90407dc194Richard Lowe                fp_offset = signed_factored_N_value;
90507dc194Richard Lowe            }
90607dc194Richard Lowe            break;
90707dc194Richard Lowe        case DW_CFA_def_cfa_offset_sf:
90807dc194Richard Lowe            {
9094d9fdb4Robert Mustacchi                /*  The operand is a signed leb128 operand representing
9104d9fdb4Robert Mustacchi                    a factored offset.  Identical to
9114d9fdb4Robert Mustacchi                    DW_CFA_def_cfa_offset excep the operand is signed
9124d9fdb4Robert Mustacchi                    and factored. */
91307dc194Richard Lowe
9144d9fdb4Robert Mustacchi                DECODE_LEB128_SWORD_CK(instr_ptr, signed_factored_N_value,
9154d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
91607dc194Richard Lowe                if (need_augmentation) {
91707dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
91807dc194Richard Lowe                }
9194d9fdb4Robert Mustacchi                /*  Do set ru_is_off here, as here factored_N_value
9204d9fdb4Robert Mustacchi                    counts.  */
92107dc194Richard Lowe                cfa_reg.ru_is_off = 1;
92207dc194Richard Lowe                cfa_reg.ru_value_type = DW_EXPR_OFFSET;
92307dc194Richard Lowe                cfa_reg.ru_offset_or_block_len =
92407dc194Richard Lowe                    signed_factored_N_value * data_alignment_factor;
92507dc194Richard Lowe
92607dc194Richard Lowe                fp_offset = signed_factored_N_value;
92707dc194Richard Lowe            }
92807dc194Richard Lowe            break;
92907dc194Richard Lowe        case DW_CFA_val_offset:
93007dc194Richard Lowe            {
9314d9fdb4Robert Mustacchi                /*  The first operand is an unsigned leb128 register
9324d9fdb4Robert Mustacchi                    number. The second is a factored unsigned offset.
9334d9fdb4Robert Mustacchi                    Makes the register be a val_offset(N) rule with N =
9344d9fdb4Robert Mustacchi                    factored_offset*data_alignment_factor. */
93507dc194Richard Lowe
9364d9fdb4Robert Mustacchi                Dwarf_Unsigned lreg = 0;
93707dc194Richard Lowe
9384d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
9394d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
94007dc194Richard Lowe                reg_no = (reg_num_type) lreg;
94107dc194Richard Lowe
94207dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
94307dc194Richard Lowe
9444d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value,
9454d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
94607dc194Richard Lowe
94707dc194Richard Lowe                if (need_augmentation) {
94807dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
94907dc194Richard Lowe                }
9504d9fdb4Robert Mustacchi                /*  Do set ru_is_off here, as here factored_N_value
9514d9fdb4Robert Mustacchi                    counts.  */
95207dc194Richard Lowe                localregtab[reg_no].ru_is_off = 1;
95307dc194Richard Lowe                localregtab[reg_no].ru_register = reg_num_of_cfa;
95407dc194Richard Lowe                localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
95507dc194Richard Lowe                localregtab[reg_no].ru_offset_or_block_len =
95607dc194Richard Lowe                    factored_N_value * data_alignment_factor;
95707dc194Richard Lowe
95807dc194Richard Lowe                fp_offset = factored_N_value;
95907dc194Richard Lowe                break;
96007dc194Richard Lowe            }
96107dc194Richard Lowe        case DW_CFA_val_offset_sf:
96207dc194Richard Lowe            {
9634d9fdb4Robert Mustacchi                /*  The first operand is an unsigned leb128 register
9644d9fdb4Robert Mustacchi                    number. The second is a factored signed offset.
9654d9fdb4Robert Mustacchi                    Makes the register be a val_offset(N) rule with N =
9664d9fdb4Robert Mustacchi                    factored_offset*data_alignment_factor. */
9674d9fdb4Robert Mustacchi                Dwarf_Unsigned lreg = 0;
96807dc194Richard Lowe
9694d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
9704d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
97107dc194Richard Lowe                reg_no = (reg_num_type) lreg;
97207dc194Richard Lowe
97307dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
9744d9fdb4Robert Mustacchi                DECODE_LEB128_SWORD_CK(instr_ptr, signed_factored_N_value,
9754d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
97607dc194Richard Lowe                if (need_augmentation) {
97707dc194Richard Lowe                    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
97807dc194Richard Lowe                }
9794d9fdb4Robert Mustacchi                /*  Do set ru_is_off here, as here factored_N_value
9804d9fdb4Robert Mustacchi                    counts.  */
98107dc194Richard Lowe                localregtab[reg_no].ru_is_off = 1;
98207dc194Richard Lowe                localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
98307dc194Richard Lowe                localregtab[reg_no].ru_offset_or_block_len =
98407dc194Richard Lowe                    signed_factored_N_value * data_alignment_factor;
98507dc194Richard Lowe
98607dc194Richard Lowe                fp_offset = signed_factored_N_value;
98707dc194Richard Lowe
98807dc194Richard Lowe            }
98907dc194Richard Lowe            break;
99007dc194Richard Lowe        case DW_CFA_val_expression:
99107dc194Richard Lowe            {
9924d9fdb4Robert Mustacchi                /*  The first operand is an unsigned leb128 register
9934d9fdb4Robert Mustacchi                    number. The second is a DW_FORM_block representing a
9944d9fdb4Robert Mustacchi                    DWARF expression. The rule for the register number
9954d9fdb4Robert Mustacchi                    becomes a val_expression(E) rule. */
99607dc194Richard Lowe                Dwarf_Unsigned lreg = 0;
99707dc194Richard Lowe                Dwarf_Unsigned block_len = 0;
99807dc194Richard Lowe
9994d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
10004d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
100107dc194Richard Lowe                reg_no = (reg_num_type) lreg;
100207dc194Richard Lowe                ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
10034d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, block_len,
10044d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
100507dc194Richard Lowe                localregtab[lreg].ru_is_off = 0;        /* arbitrary */
100607dc194Richard Lowe                localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION;
100707dc194Richard Lowe                localregtab[lreg].ru_offset_or_block_len = block_len;
100807dc194Richard Lowe                localregtab[lreg].ru_block = instr_ptr;
100907dc194Richard Lowe                fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
101007dc194Richard Lowe
101107dc194Richard Lowe                instr_ptr += block_len;
101207dc194Richard Lowe                fp_register = reg_no;
101307dc194Richard Lowe
101407dc194Richard Lowe            }
101507dc194Richard Lowe            break;
101607dc194Richard Lowe
101707dc194Richard Lowe            /* END DWARF3 new ops. */
101849d3bc9Richard Lowe
101949d3bc9Richard Lowe
102049d3bc9Richard Lowe#ifdef DW_CFA_GNU_window_save
102107dc194Richard Lowe        case DW_CFA_GNU_window_save:
102207dc194Richard Lowe            {
10234d9fdb4Robert Mustacchi                /*  No information: this just tells unwinder to restore
10244d9fdb4Robert Mustacchi                    the window registers from the previous frame's
10254d9fdb4Robert Mustacchi                    window save area */
102607dc194Richard Lowe                break;
102707dc194Richard Lowe            }
102849d3bc9Richard Lowe#endif
102949d3bc9Richard Lowe#ifdef  DW_CFA_GNU_args_size
10304d9fdb4Robert Mustacchi            /*  Single uleb128 is the current arg area size in bytes. No
10314d9fdb4Robert Mustacchi                register exists yet to save this in */
103207dc194Richard Lowe        case DW_CFA_GNU_args_size:
103307dc194Richard Lowe            {
10344d9fdb4Robert Mustacchi                UNUSEDARG Dwarf_Unsigned lreg = 0;
103549d3bc9Richard Lowe
10364d9fdb4Robert Mustacchi                DECODE_LEB128_UWORD_CK(instr_ptr, lreg,
10374d9fdb4Robert Mustacchi                    dbg,error,final_instr_ptr);
10384d9fdb4Robert Mustacchi                /*  We have nowhere to store lreg.
10394d9fdb4Robert Mustacchi                    FIXME
10404d9fdb4Robert Mustacchi                    This is the total size of arguments pushed on
10414d9fdb4Robert Mustacchi                    the stack.
10424d9fdb4Robert Mustacchi                    https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA.junk/dwarfext.html
10434d9fdb4Robert Mustacchi                    */
104449d3bc9Richard Lowe
104507dc194Richard Lowe                break;
104607dc194Richard Lowe            }
104749d3bc9Richard Lowe#endif
104807dc194Richard Lowe        default:
10494d9fdb4Robert Mustacchi            /*  ERROR, we have an opcode we know nothing about. Memory
10504d9fdb4Robert Mustacchi                leak here, but an error like this is not supposed to
10514d9fdb4Robert Mustacchi                happen so we ignore the leak. These used to be ignored,
10524d9fdb4Robert Mustacchi                now we notice and report. */
105307dc194Richard Lowe            SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
105407dc194Richard Lowe
105507dc194Richard Lowe        }
105607dc194Richard Lowe
105707dc194Richard Lowe        if (make_instr) {
105807dc194Richard Lowe            instr_count++;
105907dc194Richard Lowe
106007dc194Richard Lowe            curr_instr = (Dwarf_Frame_Op *)
106107dc194Richard Lowe                _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
106207dc194Richard Lowe            if (curr_instr == NULL) {
106307dc194Richard Lowe                SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
106407dc194Richard Lowe            }
106507dc194Richard Lowe
106607dc194Richard Lowe            curr_instr->fp_base_op = fp_base_op;
106707dc194Richard Lowe            curr_instr->fp_extended_op = fp_extended_op;
106807dc194Richard Lowe            curr_instr->fp_register = fp_register;
106907dc194Richard Lowe            curr_instr->fp_offset = fp_offset;
107007dc194Richard Lowe            curr_instr->fp_instr_offset = fp_instr_offset;
107107dc194Richard Lowe
107207dc194Richard Lowe            curr_instr_item = (Dwarf_Chain)
107307dc194Richard Lowe                _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
107407dc194Richard Lowe            if (curr_instr_item == NULL) {
107507dc194Richard Lowe                SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
107607dc194Richard Lowe            }
107707dc194Richard Lowe
107807dc194Richard Lowe            curr_instr_item->ch_item = curr_instr;
10794d9fdb4Robert Mustacchi            curr_instr_item->ch_itemtype = DW_DLA_FRAME_OP;
108007dc194Richard Lowe            if (head_instr_chain == NULL)
108107dc194Richard Lowe                head_instr_chain = tail_instr_chain = curr_instr_item;
108207dc194Richard Lowe            else {
108307dc194Richard Lowe                tail_instr_chain->ch_next = curr_instr_item;
108407dc194Richard Lowe                tail_instr_chain = curr_instr_item;
108507dc194Richard Lowe            }
108607dc194Richard Lowe        }
108749d3bc9Richard Lowe    }
108849d3bc9Richard Lowe
10894d9fdb4Robert Mustacchi    /*  If frame instruction decoding was right we would stop exactly at
10904d9fdb4Robert Mustacchi        final_instr_ptr. */
109149d3bc9Richard Lowe    if (instr_ptr > final_instr_ptr) {
109207dc194Richard Lowe        SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
109349d3bc9Richard Lowe    }
10944d9fdb4Robert Mustacchi    /*  If search_over is set the last instr was an advance_loc
10954d9fdb4Robert Mustacchi        so we are not done with rows. */
10964d9fdb4Robert Mustacchi    if ((instr_ptr == final_instr_ptr) && !search_over) {
10974d9fdb4Robert Mustacchi        if (has_more_rows) {
10984d9fdb4Robert Mustacchi            *has_more_rows = false;
10994d9fdb4Robert Mustacchi        }
11004d9fdb4Robert Mustacchi        if (subsequent_pc) {
11014d9fdb4Robert Mustacchi            *subsequent_pc = 0;
11024d9fdb4Robert Mustacchi        }
11034d9fdb4Robert Mustacchi    } else {
11044d9fdb4Robert Mustacchi        if (has_more_rows) {
11054d9fdb4Robert Mustacchi            *has_more_rows = true;
11064d9fdb4Robert Mustacchi        }
11074d9fdb4Robert Mustacchi        if (subsequent_pc) {
11084d9fdb4Robert Mustacchi            *subsequent_pc = possible_subsequent_pc;
11094d9fdb4Robert Mustacchi        }
11104d9fdb4Robert Mustacchi    }
111149d3bc9Richard Lowe
111207dc194Richard Lowe    /* Fill in the actual output table, the space the caller passed in. */
111349d3bc9Richard Lowe    if (table != NULL) {
111407dc194Richard Lowe
111507dc194Richard Lowe        struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg;
111607dc194Richard Lowe        struct Dwarf_Reg_Rule_s *t3reg = localregtab;
11174d9fdb4Robert Mustacchi        unsigned minregcount =  MIN(table->fr_reg_count,reg_count);
11184d9fdb4Robert Mustacchi        unsigned curreg = 0;
111907dc194Richard Lowe
112007dc194Richard Lowe        table->fr_loc = current_loc;
11214d9fdb4Robert Mustacchi        for (; curreg < minregcount ; curreg++, t3reg++, t2reg++) {
112207dc194Richard Lowe            *t2reg = *t3reg;
112307dc194Richard Lowe        }
112407dc194Richard Lowe
11254d9fdb4Robert Mustacchi        /*  CONSTCOND */
11264d9fdb4Robert Mustacchi        /*  Do not update the main table with the cfa_reg.
11274d9fdb4Robert Mustacchi            Just leave cfa_reg as cfa_reg. */
112807dc194Richard Lowe        table->fr_cfa_rule = cfa_reg;
112949d3bc9Richard Lowe    }
113049d3bc9Richard Lowe
113149d3bc9Richard Lowe    /* Dealloc anything remaining on stack. */
113249d3bc9Richard Lowe    for (; top_stack != NULL;) {
113307dc194Richard Lowe        stack_table = top_stack;
113407dc194Richard Lowe        top_stack = top_stack->fr_next;
113507dc194Richard Lowe        dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
113649d3bc9Richard Lowe    }
113749d3bc9Richard Lowe
113849d3bc9Richard Lowe    if (make_instr) {
11394d9fdb4Robert Mustacchi        /*  Allocate array of Dwarf_Frame_Op structs.  */
114007dc194Richard Lowe        head_instr_block = (Dwarf_Frame_Op *)
114107dc194Richard Lowe            _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
114207dc194Richard Lowe        if (head_instr_block == NULL) {
114307dc194Richard Lowe            SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
114407dc194Richard Lowe        }
114507dc194Richard Lowe
11464d9fdb4Robert Mustacchi        /*  Store Dwarf_Frame_Op instances in this array and
11474d9fdb4Robert Mustacchi            deallocate the structs that chain the Dwarf_Frame_Op's. */
114807dc194Richard Lowe        curr_instr_item = head_instr_chain;
114907dc194Richard Lowe        for (i = 0; i < instr_count; i++) {
11504d9fdb4Robert Mustacchi            void *item = curr_instr_item->ch_item;
11514d9fdb4Robert Mustacchi            int itemtype = curr_instr_item->ch_itemtype;
11524d9fdb4Robert Mustacchi            Dwarf_Chain prev_instr =  0;
11534d9fdb4Robert Mustacchi
11544d9fdb4Robert Mustacchi            /* This copies the structs, not pointers */
11554d9fdb4Robert Mustacchi            *(head_instr_block + i) = *(Dwarf_Frame_Op *)item;
11564d9fdb4Robert Mustacchi            prev_instr = curr_instr_item;
115707dc194Richard Lowe            curr_instr_item = curr_instr_item->ch_next;
11584d9fdb4Robert Mustacchi            /*  Now the pointed-to are space to dealloc */
11594d9fdb4Robert Mustacchi            dwarf_dealloc(dbg, item, itemtype);
11604d9fdb4Robert Mustacchi            dwarf_dealloc(dbg, prev_instr, DW_DLA_CHAIN);
116107dc194Richard Lowe        }
116207dc194Richard Lowe        *ret_frame_instr = head_instr_block;
11634d9fdb4Robert Mustacchi        *returned_count = (Dwarf_Signed) instr_count;
116449d3bc9Richard Lowe    } else {
116507dc194Richard Lowe        *returned_count = 0;
116649d3bc9Richard Lowe    }
116707dc194Richard Lowe    free(localregtab);
116849d3bc9Richard Lowe    return DW_DLV_OK;
116907dc194Richard Lowe#undef ERROR_IF_REG_NUM_TOO_HIGH
117007dc194Richard Lowe#undef SIMPLE_ERROR_RETURN
117149d3bc9Richard Lowe}
117249d3bc9Richard Lowe
117307dc194Richard Lowe/*  Depending on version, either read the return address register
117407dc194Richard Lowe    as a ubyte or as an leb number.
117507dc194Richard Lowe    The form of this value changed for DWARF3.
117607dc194Richard Lowe*/
11774d9fdb4Robert Mustacchiint
11784d9fdb4Robert Mustacchi_dwarf_get_return_address_reg(Dwarf_Small *frame_ptr,
11794d9fdb4Robert Mustacchi    int version,
11804d9fdb4Robert Mustacchi    Dwarf_Debug dbg,
11814d9fdb4Robert Mustacchi    Dwarf_Byte_Ptr section_end,
11824d9fdb4Robert Mustacchi    unsigned long *size,
11834d9fdb4Robert Mustacchi    Dwarf_Unsigned *return_address_register,
11844d9fdb4Robert Mustacchi    Dwarf_Error *error)
118549d3bc9Richard Lowe{
118607dc194Richard Lowe    Dwarf_Unsigned uvalue = 0;
11874d9fdb4Robert Mustacchi    Dwarf_Unsigned leb128_length = 0;
118849d3bc9Richard Lowe
118907dc194Richard Lowe    if (version == 1) {
11904d9fdb4Robert Mustacchi        if (frame_ptr >= section_end) {
11914d9fdb4Robert Mustacchi            _dwarf_error(NULL, error, DW_DLE_DF_FRAME_DECODING_ERROR);
11924d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
11934d9fdb4Robert Mustacchi        }
119407dc194Richard Lowe        *size = 1;
119507dc194Richard Lowe        uvalue = *(unsigned char *) frame_ptr;
11964d9fdb4Robert Mustacchi        *return_address_register = uvalue;
11974d9fdb4Robert Mustacchi        return DW_DLV_OK;
119849d3bc9Richard Lowe    }
11994d9fdb4Robert Mustacchi    DECODE_LEB128_UWORD_LEN_CK(frame_ptr,uvalue,leb128_length,
12004d9fdb4Robert Mustacchi        dbg,error,section_end);
120107dc194Richard Lowe    *size = leb128_length;
12024d9fdb4Robert Mustacchi    *return_address_register = uvalue;
12034d9fdb4Robert Mustacchi    return DW_DLV_OK;
120449d3bc9Richard Lowe}
120549d3bc9Richard Lowe
120649d3bc9Richard Lowe
12074d9fdb4Robert Mustacchi/* Trivial consumer function.
120807dc194Richard Lowe*/
120949d3bc9Richard Loweint
121049d3bc9Richard Lowedwarf_get_cie_of_fde(Dwarf_Fde fde,
121107dc194Richard Lowe    Dwarf_Cie * cie_returned, Dwarf_Error * error)
121249d3bc9Richard Lowe{
121349d3bc9Richard Lowe    if (fde == NULL) {
121407dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
121507dc194Richard Lowe        return (DW_DLV_ERROR);
121649d3bc9Richard Lowe    }
121749d3bc9Richard Lowe
121849d3bc9Richard Lowe    *cie_returned = fde->fd_cie;
121949d3bc9Richard Lowe    return DW_DLV_OK;
122049d3bc9Richard Lowe
122149d3bc9Richard Lowe}
122249d3bc9Richard Lowe
122307dc194Richard Loweint dwarf_get_cie_index(
122407dc194Richard Lowe    Dwarf_Cie cie,
12254d9fdb4Robert Mustacchi    Dwarf_Signed* indx,
122607dc194Richard Lowe    Dwarf_Error* error )
122707dc194Richard Lowe{
12284d9fdb4Robert Mustacchi    if (cie == NULL)
122907dc194Richard Lowe    {
123007dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
123107dc194Richard Lowe        return (DW_DLV_ERROR);
123207dc194Richard Lowe    }
123307dc194Richard Lowe
12344d9fdb4Robert Mustacchi    *indx = cie->ci_index;
123507dc194Richard Lowe    return (DW_DLV_OK);
123607dc194Richard Lowe}
123707dc194Richard Lowe
12384d9fdb4Robert Mustacchi/*  For g++ .eh_frame fde and cie.
12394d9fdb4Robert Mustacchi    the cie id is different as the
12404d9fdb4Robert Mustacchi    definition of the cie_id in an fde
124107dc194Richard Lowe        is the distance back from the address of the
124207dc194Richard Lowe        value to the cie.
12434d9fdb4Robert Mustacchi    Or 0 if this is a true cie.
12444d9fdb4Robert Mustacchi    Non standard dwarf, designed this way to be
12454d9fdb4Robert Mustacchi    convenient at run time for an allocated
12464d9fdb4Robert Mustacchi    (mapped into memory as part of the running image) section.
124749d3bc9Richard Lowe*/
124849d3bc9Richard Loweint
124949d3bc9Richard Lowedwarf_get_fde_list_eh(Dwarf_Debug dbg,
125007dc194Richard Lowe    Dwarf_Cie ** cie_data,
125107dc194Richard Lowe    Dwarf_Signed * cie_element_count,
125207dc194Richard Lowe    Dwarf_Fde ** fde_data,
125307dc194Richard Lowe    Dwarf_Signed * fde_element_count,
125407dc194Richard Lowe    Dwarf_Error * error)
125549d3bc9Richard Lowe{
125607dc194Richard Lowe    int res = _dwarf_load_section(dbg, &dbg->de_debug_frame_eh_gnu,error);
125749d3bc9Richard Lowe    if (res != DW_DLV_OK) {
125807dc194Richard Lowe        return res;
125949d3bc9Richard Lowe    }
126049d3bc9Richard Lowe
126107dc194Richard Lowe    res = _dwarf_get_fde_list_internal(dbg,
126207dc194Richard Lowe        cie_data,
126307dc194Richard Lowe        cie_element_count,
126407dc194Richard Lowe        fde_data,
126507dc194Richard Lowe        fde_element_count,
126607dc194Richard Lowe        dbg->de_debug_frame_eh_gnu.dss_data,
126707dc194Richard Lowe        dbg->de_debug_frame_eh_gnu.dss_index,
126807dc194Richard Lowe        dbg->de_debug_frame_eh_gnu.dss_size,
126907dc194Richard Lowe        /* cie_id_value */ 0,
127007dc194Richard Lowe        /* use_gnu_cie_calc= */ 1,
127107dc194Richard Lowe        error);
127249d3bc9Richard Lowe    return res;
127349d3bc9Richard Lowe}
127449d3bc9Richard Lowe
127549d3bc9Richard Lowe
127649d3bc9Richard Lowe
12774d9fdb4Robert Mustacchi/*  For standard dwarf .debug_frame
12784d9fdb4Robert Mustacchi    cie_id is -1  in a cie, and
12794d9fdb4Robert Mustacchi    is the section offset in the .debug_frame section
12804d9fdb4Robert Mustacchi    of the cie otherwise.  Standard dwarf
128149d3bc9Richard Lowe*/
128249d3bc9Richard Loweint
128349d3bc9Richard Lowedwarf_get_fde_list(Dwarf_Debug dbg,
128407dc194Richard Lowe    Dwarf_Cie ** cie_data,
128507dc194Richard Lowe    Dwarf_Signed * cie_element_count,
128607dc194Richard Lowe    Dwarf_Fde ** fde_data,
128707dc194Richard Lowe    Dwarf_Signed * fde_element_count,
128807dc194Richard Lowe    Dwarf_Error * error)
128949d3bc9Richard Lowe{
129007dc194Richard Lowe    int res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
129149d3bc9Richard Lowe    if (res != DW_DLV_OK) {
129207dc194Richard Lowe        return res;
129349d3bc9Richard Lowe    }
129449d3bc9Richard Lowe
129507dc194Richard Lowe    res = _dwarf_get_fde_list_internal(dbg, cie_data,
129607dc194Richard Lowe        cie_element_count,
129707dc194Richard Lowe        fde_data,
129807dc194Richard Lowe        fde_element_count,
129907dc194Richard Lowe        dbg->de_debug_frame.dss_data,
130007dc194Richard Lowe        dbg->de_debug_frame.dss_index,
130107dc194Richard Lowe        dbg->de_debug_frame.dss_size,
130207dc194Richard Lowe        DW_CIE_ID,
130307dc194Richard Lowe        /* use_gnu_cie_calc= */ 0,
130407dc194Richard Lowe        error);
130549d3bc9Richard Lowe    return res;
130649d3bc9Richard Lowe}
130749d3bc9Richard Lowe
130849d3bc9Richard Lowe
13094d9fdb4Robert Mustacchi/*  Only works on dwarf sections, not eh_frame
13104d9fdb4Robert Mustacchi    because based on DW_AT_MIPS_fde.
13114d9fdb4Robert Mustacchi    Given a Dwarf_Die, see if it has a
13124d9fdb4Robert Mustacchi    DW_AT_MIPS_fde attribute and if so use that
13134d9fdb4Robert Mustacchi    to get an fde offset.
13144d9fdb4Robert Mustacchi    Then create a Dwarf_Fde to return thru the ret_fde pointer.
13154d9fdb4Robert Mustacchi    Also creates a cie (pointed at from the Dwarf_Fde).  */
131649d3bc9Richard Loweint
131749d3bc9Richard Lowedwarf_get_fde_for_die(Dwarf_Debug dbg,
131807dc194Richard Lowe    Dwarf_Die die,
131907dc194Richard Lowe    Dwarf_Fde * ret_fde, Dwarf_Error * error)
132049d3bc9Richard Lowe{
132149d3bc9Richard Lowe    Dwarf_Attribute attr;
132207dc194Richard Lowe    Dwarf_Unsigned fde_offset = 0;
132307dc194Richard Lowe    Dwarf_Signed signdval = 0;
132407dc194Richard Lowe    Dwarf_Fde new_fde = 0;
132507dc194Richard Lowe    unsigned char *fde_ptr = 0;
13264d9fdb4Robert Mustacchi    unsigned char *fde_start_ptr = 0;
13274d9fdb4Robert Mustacchi    unsigned char *fde_end_ptr = 0;
132807dc194Richard Lowe    unsigned char *cie_ptr = 0;
132907dc194Richard Lowe    Dwarf_Unsigned cie_id = 0;
133049d3bc9Richard Lowe
133149d3bc9Richard Lowe    /* Fields for the current Cie being read. */
133207dc194Richard Lowe    int res = 0;
133307dc194Richard Lowe    int resattr = 0;
133407dc194Richard Lowe    int sdatares = 0;
133549d3bc9Richard Lowe
133607dc194Richard Lowe    struct cie_fde_prefix_s prefix;
133707dc194Richard Lowe    struct cie_fde_prefix_s prefix_c;
133849d3bc9Richard Lowe
133949d3bc9Richard Lowe    if (die == NULL) {
134007dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_DIE_NULL);
134107dc194Richard Lowe        return (DW_DLV_ERROR);
134249d3bc9Richard Lowe    }
134349d3bc9Richard Lowe
134449d3bc9Richard Lowe    resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error);
134549d3bc9Richard Lowe    if (resattr != DW_DLV_OK) {
134607dc194Richard Lowe        return resattr;
134749d3bc9Richard Lowe    }
134849d3bc9Richard Lowe
134949d3bc9Richard Lowe    /* why is this formsdata? FIX */
135049d3bc9Richard Lowe    sdatares = dwarf_formsdata(attr, &signdval, error);
135149d3bc9Richard Lowe    if (sdatares != DW_DLV_OK) {
135207dc194Richard Lowe        return sdatares;
135349d3bc9Richard Lowe    }
135449d3bc9Richard Lowe
135507dc194Richard Lowe    res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
135649d3bc9Richard Lowe    if (res != DW_DLV_OK) {
135707dc194Richard Lowe        return res;
135849d3bc9Richard Lowe    }
135949d3bc9Richard Lowe
136049d3bc9Richard Lowe    fde_offset = signdval;
13614d9fdb4Robert Mustacchi    fde_start_ptr = dbg->de_debug_frame.dss_data;
13624d9fdb4Robert Mustacchi    fde_ptr = fde_start_ptr + fde_offset;
13634d9fdb4Robert Mustacchi    fde_end_ptr = fde_start_ptr + dbg->de_debug_frame.dss_size;
136407dc194Richard Lowe
136507dc194Richard Lowe
13664d9fdb4Robert Mustacchi    /*  First read in the 'common prefix' to figure out what * we are to
13674d9fdb4Robert Mustacchi        do with this entry. */
136807dc194Richard Lowe    memset(&prefix_c, 0, sizeof(prefix_c));
136907dc194Richard Lowe    memset(&prefix, 0, sizeof(prefix));
137007dc194Richard Lowe    res = dwarf_read_cie_fde_prefix(dbg, fde_ptr,
137107dc194Richard Lowe        dbg->de_debug_frame.dss_data,
137207dc194Richard Lowe        dbg->de_debug_frame.dss_index,
13734d9fdb4Robert Mustacchi        dbg->de_debug_frame.dss_size,
137407dc194Richard Lowe        &prefix,
137507dc194Richard Lowe        error);
137607dc194Richard Lowe    if (res == DW_DLV_ERROR) {
137707dc194Richard Lowe        return res;
137849d3bc9Richard Lowe    }
13794d9fdb4Robert Mustacchi    if (res == DW_DLV_NO_ENTRY) {
138007dc194Richard Lowe        return res;
13814d9fdb4Robert Mustacchi    }
138207dc194Richard Lowe    fde_ptr = prefix.cf_addr_after_prefix;
138307dc194Richard Lowe    cie_id = prefix.cf_cie_id;
13844d9fdb4Robert Mustacchi    /*  Pass NULL, not section pointer, for 3rd argument.
13854d9fdb4Robert Mustacchi        de_debug_frame.dss_data has no eh_frame relevance. */
138607dc194Richard Lowe    res = dwarf_create_fde_from_after_start(dbg, &prefix,
13874d9fdb4Robert Mustacchi        fde_start_ptr,
138807dc194Richard Lowe        fde_ptr,
13894d9fdb4Robert Mustacchi        fde_end_ptr,
139007dc194Richard Lowe        /* use_gnu_cie_calc= */ 0,
139107dc194Richard Lowe        /* Dwarf_Cie = */ 0,
139207dc194Richard Lowe        &new_fde, error);
139307dc194Richard Lowe    if (res == DW_DLV_ERROR) {
139407dc194Richard Lowe        return res;
139507dc194Richard Lowe    } else if (res == DW_DLV_NO_ENTRY) {
139607dc194Richard Lowe        return res;
139707dc194Richard Lowe    }
139807dc194Richard Lowe    /* DW_DLV_OK */
139949d3bc9Richard Lowe
140049d3bc9Richard Lowe    /* now read the cie corresponding to the fde */
140107dc194Richard Lowe    cie_ptr = new_fde->fd_section_ptr + cie_id;
140207dc194Richard Lowe    res = dwarf_read_cie_fde_prefix(dbg, cie_ptr,
140307dc194Richard Lowe        dbg->de_debug_frame.dss_data,
140407dc194Richard Lowe        dbg->de_debug_frame.dss_index,
140507dc194Richard Lowe        dbg->de_debug_frame.dss_size,
140607dc194Richard Lowe        &prefix_c, error);
140707dc194Richard Lowe    if (res == DW_DLV_ERROR) {
140807dc194Richard Lowe        return res;
140907dc194Richard Lowe    }
141007dc194Richard Lowe    if (res == DW_DLV_NO_ENTRY)
141107dc194Richard Lowe        return res;
141207dc194Richard Lowe
141307dc194Richard Lowe    cie_ptr = prefix_c.cf_addr_after_prefix;
141407dc194Richard Lowe    cie_id = prefix_c.cf_cie_id;
141507dc194Richard Lowe
14164d9fdb4Robert Mustacchi    if (cie_id == (Dwarf_Unsigned)DW_CIE_ID) {
141707dc194Richard Lowe        int res2 = 0;
141807dc194Richard Lowe        Dwarf_Cie new_cie = 0;
141907dc194Richard Lowe
14204d9fdb4Robert Mustacchi        /*  Pass NULL, not section pointer, for 3rd argument.
14214d9fdb4Robert Mustacchi            de_debug_frame.dss_data has no eh_frame relevance. */
142207dc194Richard Lowe        res2 = dwarf_create_cie_from_after_start(dbg,
142307dc194Richard Lowe            &prefix_c,
14244d9fdb4Robert Mustacchi            fde_start_ptr,
142507dc194Richard Lowe            cie_ptr,
14264d9fdb4Robert Mustacchi            fde_end_ptr,
142707dc194Richard Lowe            /* cie_count= */ 0,
142807dc194Richard Lowe            /* use_gnu_cie_calc= */
142907dc194Richard Lowe            0, &new_cie, error);
143007dc194Richard Lowe        if (res2 == DW_DLV_ERROR) {
143107dc194Richard Lowe            dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
143207dc194Richard Lowe            return res;
143307dc194Richard Lowe        } else if (res2 == DW_DLV_NO_ENTRY) {
143407dc194Richard Lowe            dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
143507dc194Richard Lowe            return res;
143607dc194Richard Lowe        }
143707dc194Richard Lowe        new_fde->fd_cie = new_cie;
143849d3bc9Richard Lowe    } else {
143907dc194Richard Lowe        _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
144007dc194Richard Lowe        return (DW_DLV_ERROR);
144149d3bc9Richard Lowe    }
144249d3bc9Richard Lowe
144349d3bc9Richard Lowe    *ret_fde = new_fde;
144449d3bc9Richard Lowe    return DW_DLV_OK;
144549d3bc9Richard Lowe}
144649d3bc9Richard Lowe
144707dc194Richard Lowe/* A dwarf consumer operation, see the consumer library documentation.
144807dc194Richard Lowe*/
144949d3bc9Richard Loweint
145049d3bc9Richard Lowedwarf_get_fde_range(Dwarf_Fde fde,
145107dc194Richard Lowe    Dwarf_Addr * low_pc,
145207dc194Richard Lowe    Dwarf_Unsigned * func_length,
145307dc194Richard Lowe    Dwarf_Ptr * fde_bytes,
145407dc194Richard Lowe    Dwarf_Unsigned * fde_byte_length,
145507dc194Richard Lowe    Dwarf_Off * cie_offset,
145607dc194Richard Lowe    Dwarf_Signed * cie_index,
145707dc194Richard Lowe    Dwarf_Off * fde_offset, Dwarf_Error * error)
145849d3bc9Richard Lowe{
145949d3bc9Richard Lowe    Dwarf_Debug dbg;
146049d3bc9Richard Lowe
146149d3bc9Richard Lowe    if (fde == NULL) {
146207dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
146307dc194Richard Lowe        return (DW_DLV_ERROR);
146449d3bc9Richard Lowe    }
146549d3bc9Richard Lowe
146649d3bc9Richard Lowe    dbg = fde->fd_dbg;
146749d3bc9Richard Lowe    if (dbg == NULL) {
146807dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
146907dc194Richard Lowe        return (DW_DLV_ERROR);
147049d3bc9Richard Lowe    }
147149d3bc9Richard Lowe
147207dc194Richard Lowe
14734d9fdb4Robert Mustacchi    /*  We have always already done the section load here, so no need to
14744d9fdb4Robert Mustacchi        load the section. We did the section load in order to create the
14754d9fdb4Robert Mustacchi        Dwarf_Fde pointer passed in here. */
147607dc194Richard Lowe
147749d3bc9Richard Lowe
147849d3bc9Richard Lowe    if (low_pc != NULL)
147907dc194Richard Lowe        *low_pc = fde->fd_initial_location;
148049d3bc9Richard Lowe    if (func_length != NULL)
148107dc194Richard Lowe        *func_length = fde->fd_address_range;
148249d3bc9Richard Lowe    if (fde_bytes != NULL)
148307dc194Richard Lowe        *fde_bytes = fde->fd_fde_start;
148449d3bc9Richard Lowe    if (fde_byte_length != NULL)
148507dc194Richard Lowe        *fde_byte_length = fde->fd_length;
148649d3bc9Richard Lowe    if (cie_offset != NULL)
148707dc194Richard Lowe        *cie_offset = fde->fd_cie_offset;
148849d3bc9Richard Lowe    if (cie_index != NULL)
148907dc194Richard Lowe        *cie_index = fde->fd_cie_index;
149049d3bc9Richard Lowe    if (fde_offset != NULL)
149107dc194Richard Lowe        *fde_offset = fde->fd_fde_start - fde->fd_section_ptr;
149249d3bc9Richard Lowe
149349d3bc9Richard Lowe    return DW_DLV_OK;
149449d3bc9Richard Lowe}
149549d3bc9Richard Lowe
14964d9fdb4Robert Mustacchi/*  IRIX specific function.   The exception tables
14974d9fdb4Robert Mustacchi    have C++ destructor information and are
14984d9fdb4Robert Mustacchi    at present undocumented.  */
149949d3bc9Richard Loweint
150049d3bc9Richard Lowedwarf_get_fde_exception_info(Dwarf_Fde fde,
150107dc194Richard Lowe    Dwarf_Signed *
150207dc194Richard Lowe    offset_into_exception_tables,
150307dc194Richard Lowe    Dwarf_Error * error)
150449d3bc9Richard Lowe{
150549d3bc9Richard Lowe    Dwarf_Debug dbg;
150649d3bc9Richard Lowe
150749d3bc9Richard Lowe    dbg = fde->fd_dbg;
150849d3bc9Richard Lowe    if (dbg == NULL) {
150907dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
151007dc194Richard Lowe        return (DW_DLV_ERROR);
151149d3bc9Richard Lowe    }
151249d3bc9Richard Lowe    *offset_into_exception_tables =
151307dc194Richard Lowe        fde->fd_offset_into_exception_tables;
151449d3bc9Richard Lowe    return DW_DLV_OK;
151549d3bc9Richard Lowe}
151649d3bc9Richard Lowe
151749d3bc9Richard Lowe
15184d9fdb4Robert Mustacchi
15194d9fdb4Robert Mustacchi/*  A consumer code function.
15204d9fdb4Robert Mustacchi    Given a CIE pointer, return the normal CIE data thru
15214d9fdb4Robert Mustacchi    pointers.
15224d9fdb4Robert Mustacchi    Special augmentation data is not returned here.
152307dc194Richard Lowe*/
152449d3bc9Richard Loweint
152549d3bc9Richard Lowedwarf_get_cie_info(Dwarf_Cie cie,
152607dc194Richard Lowe    Dwarf_Unsigned * bytes_in_cie,
152707dc194Richard Lowe    Dwarf_Small * ptr_to_version,
152807dc194Richard Lowe    char **augmenter,
152907dc194Richard Lowe    Dwarf_Unsigned * code_alignment_factor,
153007dc194Richard Lowe    Dwarf_Signed * data_alignment_factor,
153107dc194Richard Lowe    Dwarf_Half * return_address_register,
153207dc194Richard Lowe    Dwarf_Ptr * initial_instructions,
153307dc194Richard Lowe    Dwarf_Unsigned * initial_instructions_length,
153407dc194Richard Lowe    Dwarf_Error * error)
153549d3bc9Richard Lowe{
15364d9fdb4Robert Mustacchi    Dwarf_Half offset_size = 0;
15374d9fdb4Robert Mustacchi    return dwarf_get_cie_info_b(cie,
15384d9fdb4Robert Mustacchi        bytes_in_cie,
15394d9fdb4Robert Mustacchi        ptr_to_version,
15404d9fdb4Robert Mustacchi        augmenter,
15414d9fdb4Robert Mustacchi        code_alignment_factor,
15424d9fdb4Robert Mustacchi        data_alignment_factor,
15434d9fdb4Robert Mustacchi        return_address_register,
15444d9fdb4Robert Mustacchi        initial_instructions,
15454d9fdb4Robert Mustacchi        initial_instructions_length,
15464d9fdb4Robert Mustacchi        &offset_size,
15474d9fdb4Robert Mustacchi        error);
15484d9fdb4Robert Mustacchi}
15494d9fdb4Robert Mustacchiint
15504d9fdb4Robert Mustacchidwarf_get_cie_info_b(Dwarf_Cie cie,
15514d9fdb4Robert Mustacchi    Dwarf_Unsigned * bytes_in_cie,
15524d9fdb4Robert Mustacchi    Dwarf_Small * ptr_to_version,
15534d9fdb4Robert Mustacchi    char **augmenter,
15544d9fdb4Robert Mustacchi    Dwarf_Unsigned * code_alignment_factor,
15554d9fdb4Robert Mustacchi    Dwarf_Signed * data_alignment_factor,
15564d9fdb4Robert Mustacchi    Dwarf_Half * return_address_register,
15574d9fdb4Robert Mustacchi    Dwarf_Ptr * initial_instructions,
15584d9fdb4Robert Mustacchi    Dwarf_Unsigned * initial_instructions_length,
15594d9fdb4Robert Mustacchi    Dwarf_Half * offset_size,
15604d9fdb4Robert Mustacchi    Dwarf_Error * error)
15614d9fdb4Robert Mustacchi{
15624d9fdb4Robert Mustacchi    Dwarf_Debug dbg = 0;
156349d3bc9Richard Lowe
156449d3bc9Richard Lowe    if (cie == NULL) {
156507dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
156607dc194Richard Lowe        return (DW_DLV_ERROR);
156749d3bc9Richard Lowe    }
156849d3bc9Richard Lowe
156949d3bc9Richard Lowe    dbg = cie->ci_dbg;
157049d3bc9Richard Lowe    if (dbg == NULL) {
157107dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
157207dc194Richard Lowe        return (DW_DLV_ERROR);
157349d3bc9Richard Lowe    }
157449d3bc9Richard Lowe
157507dc194Richard Lowe    if (ptr_to_version != NULL)
157607dc194Richard Lowe        *ptr_to_version = cie->ci_cie_version_number;
157749d3bc9Richard Lowe    if (augmenter != NULL)
157807dc194Richard Lowe        *augmenter = cie->ci_augmentation;
157949d3bc9Richard Lowe    if (code_alignment_factor != NULL)
158007dc194Richard Lowe        *code_alignment_factor = cie->ci_code_alignment_factor;
158149d3bc9Richard Lowe    if (data_alignment_factor != NULL)
158207dc194Richard Lowe        *data_alignment_factor = cie->ci_data_alignment_factor;
158349d3bc9Richard Lowe    if (return_address_register != NULL)
158407dc194Richard Lowe        *return_address_register = cie->ci_return_address_register;
158549d3bc9Richard Lowe    if (initial_instructions != NULL)
158607dc194Richard Lowe        *initial_instructions = cie->ci_cie_instr_start;
158749d3bc9Richard Lowe    if (initial_instructions_length != NULL) {
158807dc194Richard Lowe        *initial_instructions_length = cie->ci_length +
158907dc194Richard Lowe            cie->ci_length_size +
159007dc194Richard Lowe            cie->ci_extension_size -
159107dc194Richard Lowe            (cie->ci_cie_instr_start - cie->ci_cie_start);
15924d9fdb4Robert Mustacchi    }
15934d9fdb4Robert Mustacchi    if (offset_size) {
15944d9fdb4Robert Mustacchi        *offset_size = cie->ci_length_size;
159549d3bc9Richard Lowe    }
159649d3bc9Richard Lowe    *bytes_in_cie = (cie->ci_length);
159749d3bc9Richard Lowe    return (DW_DLV_OK);
159849d3bc9Richard Lowe}
159949d3bc9Richard Lowe
16004d9fdb4Robert Mustacchi/* Return the register rules for all registers at a given pc.
160107dc194Richard Lowe*/
160249d3bc9Richard Lowestatic int
160349d3bc9Richard Lowe_dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,
160407dc194Richard Lowe    Dwarf_Addr pc_requested,
160507dc194Richard Lowe    Dwarf_Frame table,
160607dc194Richard Lowe    Dwarf_Half cfa_reg_col_num,
16074d9fdb4Robert Mustacchi    Dwarf_Bool * has_more_rows,
16084d9fdb4Robert Mustacchi    Dwarf_Addr * subsequent_pc,
160907dc194Richard Lowe    Dwarf_Error * error)
161049d3bc9Richard Lowe{
161107dc194Richard Lowe    Dwarf_Debug dbg = 0;
161207dc194Richard Lowe    Dwarf_Cie cie = 0;
16134d9fdb4Robert Mustacchi    Dwarf_Signed icount = 0;
161407dc194Richard Lowe    int res = 0;
161549d3bc9Richard Lowe
161649d3bc9Richard Lowe    if (fde == NULL) {
161707dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
16184d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
161949d3bc9Richard Lowe    }
162049d3bc9Richard Lowe
162149d3bc9Richard Lowe    dbg = fde->fd_dbg;
162249d3bc9Richard Lowe    if (dbg == NULL) {
162307dc194Richard Lowe        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
16244d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
162549d3bc9Richard Lowe    }
162649d3bc9Richard Lowe
162749d3bc9Richard Lowe    if (pc_requested < fde->fd_initial_location ||
162807dc194Richard Lowe        pc_requested >=
162907dc194Richard Lowe        fde->fd_initial_location + fde->fd_address_range) {
163007dc194Richard Lowe        _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
16314d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
163249d3bc9Richard Lowe    }
163349d3bc9Richard Lowe
163449d3bc9Richard Lowe    cie = fde->fd_cie;
163549d3bc9Richard Lowe    if (cie->ci_initial_table == NULL) {
16364d9fdb4Robert Mustacchi        Dwarf_Small *instrstart = cie->ci_cie_instr_start;
16374d9fdb4Robert Mustacchi        Dwarf_Small *instrend = instrstart +cie->ci_length +
16384d9fdb4Robert Mustacchi            cie->ci_length_size +
16394d9fdb4Robert Mustacchi            cie->ci_extension_size -
16404d9fdb4Robert Mustacchi            (cie->ci_cie_instr_start -
16414d9fdb4Robert Mustacchi            cie->ci_cie_start);
16424d9fdb4Robert Mustacchi
16434d9fdb4Robert Mustacchi        if (instrend > cie->ci_cie_end) {
16444d9fdb4Robert Mustacchi            _dwarf_error(dbg, error,DW_DLE_CIE_INSTR_PTR_ERROR);
16454d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
16464d9fdb4Robert Mustacchi        }
16474d9fdb4Robert Mustacchi        cie->ci_initial_table = (Dwarf_Frame)_dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
164807dc194Richard Lowe
164907dc194Richard Lowe        if (cie->ci_initial_table == NULL) {
165007dc194Richard Lowe            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
16514d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
165207dc194Richard Lowe        }
16534d9fdb4Robert Mustacchi        dwarf_init_reg_rules_ru(cie->ci_initial_table->fr_reg,
16544d9fdb4Robert Mustacchi            0, cie->ci_initial_table->fr_reg_count,
165507dc194Richard Lowe            dbg->de_frame_rule_initial_value);
16564d9fdb4Robert Mustacchi        dwarf_init_reg_rules_ru(&cie->ci_initial_table->fr_cfa_rule,
16574d9fdb4Robert Mustacchi            0,1,dbg->de_frame_rule_initial_value);
165807dc194Richard Lowe        res = _dwarf_exec_frame_instr( /* make_instr= */ false,
165907dc194Richard Lowe            /* ret_frame_instr= */ NULL,
166007dc194Richard Lowe            /* search_pc */ false,
166107dc194Richard Lowe            /* search_pc_val */ 0,
166207dc194Richard Lowe            /* location */ 0,
16634d9fdb4Robert Mustacchi            instrstart,
16644d9fdb4Robert Mustacchi            instrend,
166507dc194Richard Lowe            cie->ci_initial_table, cie, dbg,
166607dc194Richard Lowe            cfa_reg_col_num, &icount,
16674d9fdb4Robert Mustacchi            NULL,NULL,
16684d9fdb4Robert Mustacchi            error);
16694d9fdb4Robert Mustacchi        if (res != DW_DLV_OK) {
167007dc194Richard Lowe            return res;
167107dc194Richard Lowe        }
167207dc194Richard Lowe    }
167307dc194Richard Lowe
167407dc194Richard Lowe    {
167507dc194Richard Lowe        Dwarf_Small *instr_end = fde->fd_fde_instr_start +
167607dc194Richard Lowe            fde->fd_length +
167707dc194Richard Lowe            fde->fd_length_size +
167807dc194Richard Lowe            fde->fd_extension_size - (fde->fd_fde_instr_start -
16794d9fdb4Robert Mustacchi                fde->fd_fde_start);
16804d9fdb4Robert Mustacchi        if (instr_end > fde->fd_fde_end) {
16814d9fdb4Robert Mustacchi            _dwarf_error(dbg, error,DW_DLE_FDE_INSTR_PTR_ERROR);
16824d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
16834d9fdb4Robert Mustacchi        }
168407dc194Richard Lowe
168507dc194Richard Lowe        res = _dwarf_exec_frame_instr( /* make_instr= */ false,
168607dc194Richard Lowe            /* ret_frame_instr= */ NULL,
168707dc194Richard Lowe            /* search_pc */ true,
168807dc194Richard Lowe            /* search_pc_val */ pc_requested,
168907dc194Richard Lowe            fde->fd_initial_location,
169007dc194Richard Lowe            fde->fd_fde_instr_start,
169107dc194Richard Lowe            instr_end,
169207dc194Richard Lowe            table,
169307dc194Richard Lowe            cie, dbg,
169407dc194Richard Lowe            cfa_reg_col_num, &icount,
16954d9fdb4Robert Mustacchi            has_more_rows,
16964d9fdb4Robert Mustacchi            subsequent_pc,
16974d9fdb4Robert Mustacchi            error);
169807dc194Richard Lowe    }
16994d9fdb4Robert Mustacchi    if (res != DW_DLV_OK) {
170007dc194Richard Lowe        return res;
170149d3bc9Richard Lowe    }
170249d3bc9Richard Lowe
170349d3bc9Richard Lowe    return DW_DLV_OK;
170449d3bc9Richard Lowe}
170549d3bc9Richard Lowe
17064d9fdb4Robert Mustacchi/*  A consumer call for efficiently getting the register info
17074d9fdb4Robert Mustacchi    for all registers in one call.
170807dc194Richard Lowe
17094d9fdb4Robert Mustacchi    The output table rules array is size DW_REG_TABLE_SIZE.
17104d9fdb4Robert Mustacchi    The frame info  rules array in fde_table is of size
17114d9fdb4Robert Mustacchi    DW_REG_TABLE_SIZE too.
171207dc194Richard Lowe
17134d9fdb4Robert Mustacchi    This interface  really only works well with MIPS/IRIX
17144d9fdb4Robert Mustacchi    where DW_FRAME_CFA_COL is zero (in that case it's safe).
171507dc194Richard Lowe
17164d9fdb4Robert Mustacchi    It is also restricted to the case  where
17174d9fdb4Robert Mustacchi    DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM  ==
17184d9fdb4Robert Mustacchi    dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX).
17194d9fdb4Robert Mustacchi    If this condition is not met calling this routine can result in
17204d9fdb4Robert Mustacchi    incorrect output or in memory corruption.
172107dc194Richard Lowe
17224d9fdb4Robert Mustacchi    It is much better to use dwarf_get_fde_info_for_all_regs3()
17234d9fdb4Robert Mustacchi    instead of this interface.
172407dc194Richard Lowe*/
172549d3bc9Richard Loweint
172649d3bc9Richard Lowedwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,
172707dc194Richard Lowe    Dwarf_Addr pc_requested,
172807dc194Richard Lowe    Dwarf_Regtable * reg_table,
172907dc194Richard Lowe    Dwarf_Addr * row_pc,
173007dc194Richard Lowe    Dwarf_Error * error)
173149d3bc9Richard Lowe{
173249d3bc9Richard Lowe
173307dc194Richard Lowe    /* Table size: DW_REG_TABLE_SIZE */
173449d3bc9Richard Lowe    struct Dwarf_Frame_s fde_table;
17354d9fdb4Robert Mustacchi    Dwarf_Signed i = 0;
173607dc194Richard Lowe    struct Dwarf_Reg_Rule_s *rule = NULL;
173707dc194Richard Lowe    struct Dwarf_Regtable_Entry_s *out_rule = NULL;
173807dc194Richard Lowe    int res = 0;
173907dc194Richard Lowe    Dwarf_Debug dbg = 0;
174007dc194Richard Lowe
174107dc194Richard Lowe    /* For this interface the size is fixed at compile time. */
174207dc194Richard Lowe    int output_table_real_data_size = DW_REG_TABLE_SIZE;
174307dc194Richard Lowe
174407dc194Richard Lowe    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
174507dc194Richard Lowe
174607dc194Richard Lowe    res = dwarf_initialize_fde_table(dbg, &fde_table,
174707dc194Richard Lowe        output_table_real_data_size,
174807dc194Richard Lowe        error);
174907dc194Richard Lowe    if (res != DW_DLV_OK)
175007dc194Richard Lowe        return res;
175149d3bc9Richard Lowe
17524d9fdb4Robert Mustacchi    /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
17534d9fdb4Robert Mustacchi    */
175449d3bc9Richard Lowe    res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
17554d9fdb4Robert Mustacchi        &fde_table, dbg->de_frame_cfa_col_number,NULL,NULL, error);
175649d3bc9Richard Lowe    if (res != DW_DLV_OK) {
175707dc194Richard Lowe        dwarf_free_fde_table(&fde_table);
175807dc194Richard Lowe        return res;
175949d3bc9Richard Lowe    }
176049d3bc9Richard Lowe
176107dc194Richard Lowe    out_rule = &reg_table->rules[0];
176207dc194Richard Lowe    rule = &fde_table.fr_reg[0];
176307dc194Richard Lowe    for (i = 0; i < output_table_real_data_size;
17644d9fdb4Robert Mustacchi        i++, ++out_rule, ++rule) {
176507dc194Richard Lowe        out_rule->dw_offset_relevant = rule->ru_is_off;
176607dc194Richard Lowe        out_rule->dw_value_type = rule->ru_value_type;
176707dc194Richard Lowe        out_rule->dw_regnum = rule->ru_register;
176807dc194Richard Lowe        out_rule->dw_offset = rule->ru_offset_or_block_len;
176907dc194Richard Lowe    }
17704d9fdb4Robert Mustacchi    dwarf_init_reg_rules_dw(&reg_table->rules[0],i,DW_REG_TABLE_SIZE,
17714d9fdb4Robert Mustacchi        dbg->de_frame_undefined_value_number);
177207dc194Richard Lowe
17734d9fdb4Robert Mustacchi    /*  The test is just in case it's not inside the table. For non-MIPS
17744d9fdb4Robert Mustacchi        it could be outside the table and that is just fine, it was
17754d9fdb4Robert Mustacchi        really a mistake to put it in the table in 1993.  */
177607dc194Richard Lowe    /* CONSTCOND */
177707dc194Richard Lowe    if (dbg->de_frame_cfa_col_number < DW_REG_TABLE_SIZE) {
177807dc194Richard Lowe        out_rule = &reg_table->rules[dbg->de_frame_cfa_col_number];
177907dc194Richard Lowe        out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
178007dc194Richard Lowe        out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type;
178107dc194Richard Lowe        out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register;
178207dc194Richard Lowe        out_rule->dw_offset =
178307dc194Richard Lowe            fde_table.fr_cfa_rule.ru_offset_or_block_len;
178449d3bc9Richard Lowe    }
178549d3bc9Richard Lowe
178649d3bc9Richard Lowe    if (row_pc != NULL)
178707dc194Richard Lowe        *row_pc = fde_table.fr_loc;
178807dc194Richard Lowe    dwarf_free_fde_table(&fde_table);
178907dc194Richard Lowe    return DW_DLV_OK;
179007dc194Richard Lowe}
179107dc194Richard Lowe
17924d9fdb4Robert Mustacchi/*  A consumer call for efficiently getting the register info
17934d9fdb4Robert Mustacchi    for all registers in one call.
179407dc194Richard Lowe
17954d9fdb4Robert Mustacchi    The output table rules array is size output_table_real_data_size.
17964d9fdb4Robert Mustacchi    (normally  DW_REG_TABLE_SIZE).
17974d9fdb4Robert Mustacchi    The frame info  rules array in fde_table is normally of size
17984d9fdb4Robert Mustacchi    DW_FRAME_LAST_REG_NUM.  */
179907dc194Richard Loweint
180007dc194Richard Lowedwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
180107dc194Richard Lowe    Dwarf_Addr pc_requested,
180207dc194Richard Lowe    Dwarf_Regtable3 * reg_table,
180307dc194Richard Lowe    Dwarf_Addr * row_pc,
180407dc194Richard Lowe    Dwarf_Error * error)
180507dc194Richard Lowe{
180607dc194Richard Lowe
180707dc194Richard Lowe    struct Dwarf_Frame_s fde_table;
1808