1 /*	$NetBSD: dwarf_frame.c,v 1.2 2014/03/09 16:58:03 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.2 2014/03/09 16:58:03 christos Exp $");
32 ELFTC_VCSID("Id: dwarf_frame.c 2073 2011-10-27 03:30:47Z jkoshy ");
33 
34 int
dwarf_get_fde_list(Dwarf_Debug dbg,Dwarf_Cie ** cie_list,Dwarf_Signed * cie_count,Dwarf_Fde ** fde_list,Dwarf_Signed * fde_count,Dwarf_Error * error)35 dwarf_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 
74 int
dwarf_get_fde_list_eh(Dwarf_Debug dbg,Dwarf_Cie ** cie_list,Dwarf_Signed * cie_count,Dwarf_Fde ** fde_list,Dwarf_Signed * fde_count,Dwarf_Error * error)75 dwarf_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 
114 int
dwarf_get_fde_n(Dwarf_Fde * fdelist,Dwarf_Unsigned fde_index,Dwarf_Fde * ret_fde,Dwarf_Error * error)115 dwarf_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 
141 int
dwarf_get_fde_at_pc(Dwarf_Fde * fdelist,Dwarf_Addr pc,Dwarf_Fde * ret_fde,Dwarf_Addr * lopc,Dwarf_Addr * hipc,Dwarf_Error * error)142 dwarf_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 
176 int
dwarf_get_cie_of_fde(Dwarf_Fde fde,Dwarf_Cie * ret_cie,Dwarf_Error * error)177 dwarf_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 
193 int
dwarf_get_fde_range(Dwarf_Fde fde,Dwarf_Addr * low_pc,Dwarf_Unsigned * func_len,Dwarf_Ptr * fde_bytes,Dwarf_Unsigned * fde_byte_len,Dwarf_Off * cie_offset,Dwarf_Signed * cie_index,Dwarf_Off * fde_offset,Dwarf_Error * error)194 dwarf_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 
220 int
dwarf_get_cie_info(Dwarf_Cie cie,Dwarf_Unsigned * bytes_in_cie,Dwarf_Small * version,char ** augmenter,Dwarf_Unsigned * caf,Dwarf_Unsigned * daf,Dwarf_Half * ra,Dwarf_Ptr * initinst,Dwarf_Unsigned * inst_len,Dwarf_Error * error)221 dwarf_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 
246 int
dwarf_get_cie_index(Dwarf_Cie cie,Dwarf_Signed * cie_index,Dwarf_Error * error)247 dwarf_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 
260 int
dwarf_get_fde_instr_bytes(Dwarf_Fde fde,Dwarf_Ptr * ret_inst,Dwarf_Unsigned * ret_len,Dwarf_Error * error)261 dwarf_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 
282 int
dwarf_get_fde_info_for_reg(Dwarf_Fde fde,Dwarf_Half table_column,Dwarf_Addr pc_requested,Dwarf_Signed * offset_relevant,Dwarf_Signed * register_num,Dwarf_Signed * offset,Dwarf_Addr * row_pc,Dwarf_Error * error)283 dwarf_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 
335 int
dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Regtable * reg_table,Dwarf_Addr * row_pc,Dwarf_Error * error)336 dwarf_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 
399 int
dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,Dwarf_Half table_column,Dwarf_Addr pc_requested,Dwarf_Small * value_type,Dwarf_Signed * offset_relevant,Dwarf_Signed * register_num,Dwarf_Signed * offset_or_block_len,Dwarf_Ptr * block_ptr,Dwarf_Addr * row_pc,Dwarf_Error * error)400 dwarf_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 
446 int
dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Small * value_type,Dwarf_Signed * offset_relevant,Dwarf_Signed * register_num,Dwarf_Signed * offset_or_block_len,Dwarf_Ptr * block_ptr,Dwarf_Addr * row_pc,Dwarf_Error * error)447 dwarf_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 
490 int
dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,Dwarf_Addr pc_requested,Dwarf_Regtable3 * reg_table,Dwarf_Addr * row_pc,Dwarf_Error * error)491 dwarf_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 
529 int
dwarf_expand_frame_instructions(Dwarf_Cie cie,Dwarf_Ptr instruction,Dwarf_Unsigned len,Dwarf_Frame_Op ** ret_oplist,Dwarf_Signed * ret_opcnt,Dwarf_Error * error)530 dwarf_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, instruction, len, ret_oplist, ret_opcnt,
546 	    error);
547 	if (ret != DW_DLE_NONE)
548 		return (DW_DLV_ERROR);
549 
550 	return (DW_DLV_OK);
551 }
552 
553 Dwarf_Half
dwarf_set_frame_rule_table_size(Dwarf_Debug dbg,Dwarf_Half value)554 dwarf_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 
564 Dwarf_Half
dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg,Dwarf_Half value)565 dwarf_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 
575 Dwarf_Half
dwarf_set_frame_cfa_value(Dwarf_Debug dbg,Dwarf_Half value)576 dwarf_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 
586 Dwarf_Half
dwarf_set_frame_same_value(Dwarf_Debug dbg,Dwarf_Half value)587 dwarf_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 
597 Dwarf_Half
dwarf_set_frame_undefined_value(Dwarf_Debug dbg,Dwarf_Half value)598 dwarf_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