1 /* $NetBSD: dwarf_frame.c,v 1.4 2022/05/01 17:20:47 jkoshy 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.4 2022/05/01 17:20:47 jkoshy Exp $");
32 ELFTC_VCSID("Id: dwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27");
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, ®_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, 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
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