1/*-
2 * Copyright (c) 2009,2011 Kai Wang
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include "_libdwarf.h"
28
29ELFTC_VCSID("$Id: dwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $");
30
31int
32dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie **cie_list,
33    Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count,
34    Dwarf_Error *error)
35{
36
37	if (dbg == NULL || cie_list == NULL || cie_count == NULL ||
38	    fde_list == NULL || fde_count == NULL) {
39		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
40		return (DW_DLV_ERROR);
41	}
42
43	if (dbg->dbg_internal_reg_table == NULL) {
44		if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE)
45			return (DW_DLV_ERROR);
46	}
47
48	if (dbg->dbg_frame == NULL) {
49		if (_dwarf_frame_section_load(dbg, error) != DW_DLE_NONE)
50			return (DW_DLV_ERROR);
51		if (dbg->dbg_frame == NULL) {
52			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
53			return (DW_DLV_NO_ENTRY);
54		}
55	}
56
57	if (dbg->dbg_frame->fs_ciearray == NULL ||
58	    dbg->dbg_frame->fs_fdearray == NULL) {
59		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
60		return (DW_DLV_NO_ENTRY);
61	}
62
63	*cie_list = dbg->dbg_frame->fs_ciearray;
64	*cie_count = dbg->dbg_frame->fs_cielen;
65	*fde_list = dbg->dbg_frame->fs_fdearray;
66	*fde_count = dbg->dbg_frame->fs_fdelen;
67
68	return (DW_DLV_OK);
69}
70
71int
72dwarf_get_fde_list_eh(Dwarf_Debug dbg, Dwarf_Cie **cie_list,
73    Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count,
74    Dwarf_Error *error)
75{
76
77	if (dbg == NULL || cie_list == NULL || cie_count == NULL ||
78	    fde_list == NULL || fde_count == NULL) {
79		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
80		return (DW_DLV_ERROR);
81	}
82
83	if (dbg->dbg_internal_reg_table == NULL) {
84		if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE)
85			return (DW_DLV_ERROR);
86	}
87
88	if (dbg->dbg_eh_frame == NULL) {
89		if (_dwarf_frame_section_load_eh(dbg, error) != DW_DLE_NONE)
90			return (DW_DLV_ERROR);
91		if (dbg->dbg_eh_frame == NULL) {
92			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
93			return (DW_DLV_NO_ENTRY);
94		}
95	}
96
97	if (dbg->dbg_eh_frame->fs_ciearray == NULL ||
98	    dbg->dbg_eh_frame->fs_fdearray == NULL) {
99		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
100		return (DW_DLV_NO_ENTRY);
101	}
102
103	*cie_list = dbg->dbg_eh_frame->fs_ciearray;
104	*cie_count = dbg->dbg_eh_frame->fs_cielen;
105	*fde_list = dbg->dbg_eh_frame->fs_fdearray;
106	*fde_count = dbg->dbg_eh_frame->fs_fdelen;
107
108	return (DW_DLV_OK);
109}
110
111int
112dwarf_get_fde_n(Dwarf_Fde *fdelist, Dwarf_Unsigned fde_index,
113    Dwarf_Fde *ret_fde, Dwarf_Error *error)
114{
115	Dwarf_FrameSec fs;
116	Dwarf_Debug dbg;
117
118	dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL;
119
120	if (fdelist == NULL || ret_fde == NULL) {
121		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
122		return (DW_DLV_ERROR);
123	}
124
125	fs = fdelist[0]->fde_fs;
126	assert(fs != NULL);
127
128	if (fde_index >= fs->fs_fdelen) {
129		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
130		return (DW_DLV_NO_ENTRY);
131	}
132
133	*ret_fde = fdelist[fde_index];
134
135	return (DW_DLV_OK);
136}
137
138int
139dwarf_get_fde_at_pc(Dwarf_Fde *fdelist, Dwarf_Addr pc, Dwarf_Fde *ret_fde,
140    Dwarf_Addr *lopc, Dwarf_Addr *hipc, Dwarf_Error *error)
141{
142	Dwarf_FrameSec fs;
143	Dwarf_Debug dbg;
144	Dwarf_Fde fde;
145	int i;
146
147	dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL;
148
149	if (fdelist == NULL || ret_fde == NULL || lopc == NULL ||
150	    hipc == NULL) {
151		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
152		return (DW_DLV_ERROR);
153	}
154
155	fs = fdelist[0]->fde_fs;
156	assert(fs != NULL);
157
158	for (i = 0; (Dwarf_Unsigned)i < fs->fs_fdelen; i++) {
159		fde = fdelist[i];
160		if (pc >= fde->fde_initloc && pc < fde->fde_initloc +
161		    fde->fde_adrange) {
162			*ret_fde = fde;
163			*lopc = fde->fde_initloc;
164			*hipc = fde->fde_initloc + fde->fde_adrange - 1;
165			return (DW_DLV_OK);
166		}
167	}
168
169	DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
170	return (DW_DLV_NO_ENTRY);
171}
172
173int
174dwarf_get_cie_of_fde(Dwarf_Fde fde, Dwarf_Cie *ret_cie, Dwarf_Error *error)
175{
176	Dwarf_Debug dbg;
177
178	dbg = fde != NULL ? fde->fde_dbg : NULL;
179
180	if (fde == NULL || ret_cie == NULL) {
181		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
182		return (DW_DLV_ERROR);
183	}
184
185	*ret_cie = fde->fde_cie;
186
187	return (DW_DLV_OK);
188}
189
190int
191dwarf_get_fde_range(Dwarf_Fde fde, Dwarf_Addr *low_pc, Dwarf_Unsigned *func_len,
192    Dwarf_Ptr *fde_bytes, Dwarf_Unsigned *fde_byte_len, Dwarf_Off *cie_offset,
193    Dwarf_Signed *cie_index, Dwarf_Off *fde_offset, Dwarf_Error *error)
194{
195	Dwarf_Debug dbg;
196
197	dbg = fde != NULL ? fde->fde_dbg : NULL;
198
199	if (fde == NULL || low_pc == NULL || func_len == NULL ||
200	    fde_bytes == NULL || fde_byte_len == NULL || cie_offset == NULL ||
201	    cie_index == NULL || fde_offset == NULL) {
202		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
203		return (DW_DLV_ERROR);
204	}
205
206	*low_pc = fde->fde_initloc;
207	*func_len = fde->fde_adrange;
208	*fde_bytes = fde->fde_addr;
209	*fde_byte_len = fde->fde_length;
210	*cie_offset = fde->fde_cieoff;
211	*cie_index = fde->fde_cie->cie_index;
212	*fde_offset = fde->fde_offset;
213
214	return (DW_DLV_OK);
215}
216
217int
218dwarf_get_cie_info(Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie,
219    Dwarf_Small *version, char **augmenter, Dwarf_Unsigned *caf,
220    Dwarf_Unsigned *daf, Dwarf_Half *ra, Dwarf_Ptr *initinst,
221    Dwarf_Unsigned *inst_len, Dwarf_Error *error)
222{
223
224	if (cie == NULL || bytes_in_cie == NULL || version == NULL ||
225	    augmenter == NULL || caf == NULL || daf == NULL || ra == NULL ||
226	    initinst == NULL || inst_len == NULL) {
227		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
228		return (DW_DLV_ERROR);
229	}
230
231	*bytes_in_cie = cie->cie_length;
232	*version = cie->cie_version;
233	*augmenter = (char *) cie->cie_augment;
234	*caf = cie->cie_caf;
235	*daf = cie->cie_daf;
236	*ra = cie->cie_ra;
237	*initinst = cie->cie_initinst;
238	*inst_len = cie->cie_instlen;
239
240	return (DW_DLV_OK);
241}
242
243int
244dwarf_get_cie_index(Dwarf_Cie cie, Dwarf_Signed *cie_index, Dwarf_Error *error)
245{
246
247	if (cie == NULL || cie_index == NULL) {
248		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
249		return (DW_DLV_ERROR);
250	}
251
252	*cie_index = cie->cie_index;
253
254	return (DW_DLV_OK);
255}
256
257int
258dwarf_get_fde_instr_bytes(Dwarf_Fde fde, Dwarf_Ptr *ret_inst,
259    Dwarf_Unsigned *ret_len, Dwarf_Error *error)
260{
261	Dwarf_Debug dbg;
262
263	dbg = fde != NULL ? fde->fde_dbg : NULL;
264
265	if (fde == NULL || ret_inst == NULL || ret_len == NULL) {
266		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
267		return (DW_DLV_ERROR);
268	}
269
270	*ret_inst = fde->fde_inst;
271	*ret_len = fde->fde_instlen;
272
273	return (DW_DLV_OK);
274}
275
276#define	RL	rt->rt3_rules[table_column]
277#define	CFA	rt->rt3_cfa_rule
278
279int
280dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column,
281    Dwarf_Addr pc_requested, Dwarf_Signed *offset_relevant,
282    Dwarf_Signed *register_num, Dwarf_Signed *offset, Dwarf_Addr *row_pc,
283    Dwarf_Error *error)
284{
285	Dwarf_Regtable3 *rt;
286	Dwarf_Debug dbg;
287	Dwarf_Addr pc;
288	int ret;
289
290	dbg = fde != NULL ? fde->fde_dbg : NULL;
291
292	if (fde == NULL || offset_relevant == NULL || register_num == NULL ||
293	    offset == NULL || row_pc == NULL) {
294		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
295		return (DW_DLV_ERROR);
296	}
297
298	if (pc_requested < fde->fde_initloc ||
299	    pc_requested >= fde->fde_initloc + fde->fde_adrange) {
300		DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
301		return (DW_DLV_ERROR);
302	}
303
304	ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
305	    error);
306	if (ret != DW_DLE_NONE)
307		return (DW_DLV_ERROR);
308
309	if (table_column == dbg->dbg_frame_cfa_value) {
310		/* Application ask for CFA. */
311		*offset_relevant = CFA.dw_offset_relevant;
312		*register_num = CFA.dw_regnum;
313		*offset = CFA.dw_offset_or_block_len;
314	} else {
315		/* Application ask for normal registers. */
316		if (table_column >= dbg->dbg_frame_rule_table_size ||
317		    table_column >= DW_REG_TABLE_SIZE) {
318			DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
319			return (DW_DLV_ERROR);
320		}
321
322		*offset_relevant = RL.dw_offset_relevant;
323		*register_num = RL.dw_regnum;
324		*offset = RL.dw_offset_or_block_len;
325	}
326
327	*row_pc = pc;
328
329	return (DW_DLV_OK);
330}
331
332int
333dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, Dwarf_Addr pc_requested,
334    Dwarf_Regtable *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error)
335{
336	Dwarf_Debug dbg;
337	Dwarf_Regtable3 *rt;
338	Dwarf_Addr pc;
339	Dwarf_Half cfa;
340	int i, ret;
341
342	dbg = fde != NULL ? fde->fde_dbg : NULL;
343
344	if (fde == NULL || reg_table == NULL || row_pc == NULL) {
345		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
346		return (DW_DLV_ERROR);
347	}
348
349	assert(dbg != NULL);
350
351	if (pc_requested < fde->fde_initloc ||
352	    pc_requested >= fde->fde_initloc + fde->fde_adrange) {
353		DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
354		return (DW_DLV_ERROR);
355	}
356
357	ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
358	    error);
359	if (ret != DW_DLE_NONE)
360		return (DW_DLV_ERROR);
361
362	/*
363	 * Copy the CFA rule to the column intended for holding the CFA,
364	 * if it's within the range of regtable.
365	 */
366	cfa = dbg->dbg_frame_cfa_value;
367	if (cfa < DW_REG_TABLE_SIZE) {
368		reg_table->rules[cfa].dw_offset_relevant =
369		    CFA.dw_offset_relevant;
370		reg_table->rules[cfa].dw_regnum = CFA.dw_regnum;
371		reg_table->rules[cfa].dw_offset = CFA.dw_offset_or_block_len;
372	}
373
374	/*
375	 * Copy other columns.
376	 */
377	for (i = 0; i < DW_REG_TABLE_SIZE && i < dbg->dbg_frame_rule_table_size;
378	     i++) {
379
380		/* Do not overwrite CFA column */
381		if (i == cfa)
382			continue;
383
384		reg_table->rules[i].dw_offset_relevant =
385		    rt->rt3_rules[i].dw_offset_relevant;
386		reg_table->rules[i].dw_regnum = rt->rt3_rules[i].dw_regnum;
387		reg_table->rules[i].dw_offset =
388		    rt->rt3_rules[i].dw_offset_or_block_len;
389	}
390
391	*row_pc = pc;
392
393	return (DW_DLV_OK);
394}
395
396int
397dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Half table_column,
398    Dwarf_Addr pc_requested, Dwarf_Small *value_type,
399    Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num,
400    Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr,
401    Dwarf_Addr *row_pc, Dwarf_Error *error)
402{
403	Dwarf_Regtable3 *rt;
404	Dwarf_Debug dbg;
405	Dwarf_Addr pc;
406	int ret;
407
408	dbg = fde != NULL ? fde->fde_dbg : NULL;
409
410	if (fde == NULL || value_type == NULL || offset_relevant == NULL ||
411	    register_num == NULL || offset_or_block_len == NULL ||
412	    block_ptr == NULL || row_pc == NULL) {
413		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
414		return (DW_DLV_ERROR);
415	}
416
417	if (pc_requested < fde->fde_initloc ||
418	    pc_requested >= fde->fde_initloc + fde->fde_adrange) {
419		DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
420		return (DW_DLV_ERROR);
421	}
422
423	ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
424	    error);
425	if (ret != DW_DLE_NONE)
426		return (DW_DLV_ERROR);
427
428	if (table_column >= dbg->dbg_frame_rule_table_size) {
429		DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
430		return (DW_DLV_ERROR);
431	}
432
433	*value_type = RL.dw_value_type;
434	*offset_relevant = RL.dw_offset_relevant;
435	*register_num = RL.dw_regnum;
436	*offset_or_block_len = RL.dw_offset_or_block_len;
437	*block_ptr = RL.dw_block_ptr;
438	*row_pc = pc;
439
440	return (DW_DLV_OK);
441}
442
443int
444dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested,
445    Dwarf_Small *value_type, Dwarf_Signed *offset_relevant,
446    Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len,
447    Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Error *error)
448{
449	Dwarf_Regtable3 *rt;
450	Dwarf_Debug dbg;
451	Dwarf_Addr pc;
452	int ret;
453
454	dbg = fde != NULL ? fde->fde_dbg : NULL;
455
456	if (fde == NULL || value_type == NULL || offset_relevant == NULL ||
457	    register_num == NULL || offset_or_block_len == NULL ||
458	    block_ptr == NULL || row_pc == NULL) {
459		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
460		return (DW_DLV_ERROR);
461	}
462
463	if (pc_requested < fde->fde_initloc ||
464	    pc_requested >= fde->fde_initloc + fde->fde_adrange) {
465		DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
466		return (DW_DLV_ERROR);
467	}
468
469	ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
470	    error);
471	if (ret != DW_DLE_NONE)
472		return (DW_DLV_ERROR);
473
474	*value_type = CFA.dw_value_type;
475	*offset_relevant = CFA.dw_offset_relevant;
476	*register_num = CFA.dw_regnum;
477	*offset_or_block_len = CFA.dw_offset_or_block_len;
478	*block_ptr = CFA.dw_block_ptr;
479	*row_pc = pc;
480
481	return (DW_DLV_OK);
482}
483
484#undef	RL
485#undef	CFA
486
487int
488dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, Dwarf_Addr pc_requested,
489    Dwarf_Regtable3 *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error)
490{
491	Dwarf_Regtable3 *rt;
492	Dwarf_Debug dbg;
493	Dwarf_Addr pc;
494	int ret;
495
496	dbg = fde != NULL ? fde->fde_dbg : NULL;
497
498	if (fde == NULL || reg_table == NULL || reg_table->rt3_rules == NULL ||
499	    row_pc == NULL) {
500		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
501		return (DW_DLV_ERROR);
502	}
503
504	assert(dbg != NULL);
505
506	if (pc_requested < fde->fde_initloc ||
507	    pc_requested >= fde->fde_initloc + fde->fde_adrange) {
508		DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
509		return (DW_DLV_ERROR);
510	}
511
512	ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc,
513	    error);
514	if (ret != DW_DLE_NONE)
515		return (DW_DLV_ERROR);
516
517	ret = _dwarf_frame_regtable_copy(dbg, &reg_table, rt, error);
518	if (ret != DW_DLE_NONE)
519		return (DW_DLV_ERROR);
520
521	*row_pc = pc;
522
523	return (DW_DLV_OK);
524}
525
526int
527dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction,
528    Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt,
529    Dwarf_Error *error)
530{
531	Dwarf_Debug dbg;
532	int ret;
533
534	dbg = cie != NULL ? cie->cie_dbg : NULL;
535
536	if (cie == NULL || instruction == NULL || len == 0 ||
537	    ret_oplist == NULL || ret_opcnt == NULL) {
538		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
539		return (DW_DLV_ERROR);
540	}
541
542	ret = _dwarf_frame_get_fop(dbg, cie->cie_addrsize, instruction, len,
543	    ret_oplist, ret_opcnt, error);
544	if (ret != DW_DLE_NONE)
545		return (DW_DLV_ERROR);
546
547	return (DW_DLV_OK);
548}
549
550Dwarf_Half
551dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value)
552{
553	Dwarf_Half old_value;
554
555	old_value = dbg->dbg_frame_rule_table_size;
556	dbg->dbg_frame_rule_table_size = value;
557
558	return (old_value);
559}
560
561Dwarf_Half
562dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value)
563{
564	Dwarf_Half old_value;
565
566	old_value = dbg->dbg_frame_rule_initial_value;
567	dbg->dbg_frame_rule_initial_value = value;
568
569	return (old_value);
570}
571
572Dwarf_Half
573dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value)
574{
575	Dwarf_Half old_value;
576
577	old_value = dbg->dbg_frame_cfa_value;
578	dbg->dbg_frame_cfa_value = value;
579
580	return (old_value);
581}
582
583Dwarf_Half
584dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value)
585{
586	Dwarf_Half old_value;
587
588	old_value = dbg->dbg_frame_same_value;
589	dbg->dbg_frame_same_value = value;
590
591	return (old_value);
592}
593
594Dwarf_Half
595dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value)
596{
597	Dwarf_Half old_value;
598
599	old_value = dbg->dbg_frame_undefined_value;
600	dbg->dbg_frame_undefined_value = value;
601
602	return (old_value);
603}
604