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 
29 ELFTC_VCSID("$Id: dwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $");
30 
31 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)32 dwarf_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 
71 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)72 dwarf_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 
111 int
dwarf_get_fde_n(Dwarf_Fde * fdelist,Dwarf_Unsigned fde_index,Dwarf_Fde * ret_fde,Dwarf_Error * error)112 dwarf_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 
138 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)139 dwarf_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 
173 int
dwarf_get_cie_of_fde(Dwarf_Fde fde,Dwarf_Cie * ret_cie,Dwarf_Error * error)174 dwarf_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 
190 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)191 dwarf_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 
217 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)218 dwarf_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 
243 int
dwarf_get_cie_index(Dwarf_Cie cie,Dwarf_Signed * cie_index,Dwarf_Error * error)244 dwarf_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 
257 int
dwarf_get_fde_instr_bytes(Dwarf_Fde fde,Dwarf_Ptr * ret_inst,Dwarf_Unsigned * ret_len,Dwarf_Error * error)258 dwarf_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 
279 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)280 dwarf_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 
332 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)333 dwarf_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 
396 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)397 dwarf_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 
443 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)444 dwarf_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 
487 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)488 dwarf_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 
526 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)527 dwarf_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 
550 Dwarf_Half
dwarf_set_frame_rule_table_size(Dwarf_Debug dbg,Dwarf_Half value)551 dwarf_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 
561 Dwarf_Half
dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg,Dwarf_Half value)562 dwarf_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 
572 Dwarf_Half
dwarf_set_frame_cfa_value(Dwarf_Debug dbg,Dwarf_Half value)573 dwarf_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 
583 Dwarf_Half
dwarf_set_frame_same_value(Dwarf_Debug dbg,Dwarf_Half value)584 dwarf_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 
594 Dwarf_Half
dwarf_set_frame_undefined_value(Dwarf_Debug dbg,Dwarf_Half value)595 dwarf_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