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