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, ®_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