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