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