1 /* $NetBSD: libdwarf_frame.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
4 * Copyright (c) 2009-2011 Kai Wang
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
29 #include "_libdwarf.h"
31 __RCSID("$NetBSD: libdwarf_frame.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
32 ELFTC_VCSID("Id: libdwarf_frame.c 2529 2012-07-29 23:31:12Z kaiwang27 ");
35 _dwarf_frame_find_cie(Dwarf_FrameSec fs
, Dwarf_Unsigned offset
,
40 STAILQ_FOREACH(cie
, &fs
->fs_cielist
, cie_next
) {
41 if (cie
->cie_offset
== offset
)
46 return (DW_DLE_NO_ENTRY
);
55 _dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg
, uint64_t *val
, uint8_t *data
,
56 uint64_t *offsetp
, uint8_t encode
, Dwarf_Addr pc
, Dwarf_Error
*error
)
60 if (encode
== DW_EH_PE_omit
)
63 application
= encode
& 0xf0;
68 *val
= dbg
->read(data
, offsetp
, dbg
->dbg_pointer_size
);
70 case DW_EH_PE_uleb128
:
71 *val
= _dwarf_read_uleb128(data
, offsetp
);
74 *val
= dbg
->read(data
, offsetp
, 2);
77 *val
= dbg
->read(data
, offsetp
, 4);
80 *val
= dbg
->read(data
, offsetp
, 8);
82 case DW_EH_PE_sleb128
:
83 *val
= _dwarf_read_sleb128(data
, offsetp
);
86 *val
= (int16_t) dbg
->read(data
, offsetp
, 2);
89 *val
= (int32_t) dbg
->read(data
, offsetp
, 4);
92 *val
= dbg
->read(data
, offsetp
, 8);
95 DWARF_SET_ERROR(dbg
, error
, DW_DLE_FRAME_AUGMENTATION_UNKNOWN
);
96 return (DW_DLE_FRAME_AUGMENTATION_UNKNOWN
);
99 if (application
== DW_EH_PE_pcrel
) {
101 * Value is relative to .eh_frame section virtual addr.
104 case DW_EH_PE_uleb128
:
105 case DW_EH_PE_udata2
:
106 case DW_EH_PE_udata4
:
107 case DW_EH_PE_udata8
:
110 case DW_EH_PE_sleb128
:
111 case DW_EH_PE_sdata2
:
112 case DW_EH_PE_sdata4
:
113 case DW_EH_PE_sdata8
:
114 *val
= pc
+ (int64_t) *val
;
117 /* DW_EH_PE_absptr is absolute value. */
122 /* XXX Applications other than DW_EH_PE_pcrel are not handled. */
124 return (DW_DLE_NONE
);
128 _dwarf_frame_parse_lsb_cie_augment(Dwarf_Debug dbg
, Dwarf_Cie cie
,
131 uint8_t *aug_p
, *augdata_p
;
132 uint64_t val
, offset
;
136 assert(cie
->cie_augment
!= NULL
&& *cie
->cie_augment
== 'z');
139 * Here we're only interested in the presence of augment 'R'
140 * and associated CIE augment data, which describes the
141 * encoding scheme of FDE PC begin and range.
143 aug_p
= &cie
->cie_augment
[1];
144 augdata_p
= cie
->cie_augdata
;
145 while (*aug_p
!= '\0') {
148 /* Skip one augment in augment data. */
152 /* Skip two augments in augment data. */
153 encode
= *augdata_p
++;
155 ret
= _dwarf_frame_read_lsb_encoded(dbg
, &val
,
156 augdata_p
, &offset
, encode
, 0, error
);
157 if (ret
!= DW_DLE_NONE
)
162 cie
->cie_fde_encode
= *augdata_p
++;
165 DWARF_SET_ERROR(dbg
, error
,
166 DW_DLE_FRAME_AUGMENTATION_UNKNOWN
);
167 return (DW_DLE_FRAME_AUGMENTATION_UNKNOWN
);
172 return (DW_DLE_NONE
);
176 _dwarf_frame_add_cie(Dwarf_Debug dbg
, Dwarf_FrameSec fs
, Dwarf_Section
*ds
,
177 Dwarf_Unsigned
*off
, Dwarf_Cie
*ret_cie
, Dwarf_Error
*error
)
184 /* Check if we already added this CIE. */
185 if (_dwarf_frame_find_cie(fs
, *off
, &cie
) != DW_DLE_NO_ENTRY
) {
186 *off
+= cie
->cie_length
+ 4;
187 return (DW_DLE_NONE
);
190 if ((cie
= calloc(1, sizeof(struct _Dwarf_Cie
))) == NULL
) {
191 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
192 return (DW_DLE_MEMORY
);
194 STAILQ_INSERT_TAIL(&fs
->fs_cielist
, cie
, cie_next
);
197 cie
->cie_index
= fs
->fs_cielen
;
198 cie
->cie_offset
= *off
;
200 length
= dbg
->read(ds
->ds_data
, off
, 4);
201 if (length
== 0xffffffff) {
203 length
= dbg
->read(ds
->ds_data
, off
, 8);
207 if (length
> ds
->ds_size
- *off
) {
208 DWARF_SET_ERROR(dbg
, error
, DW_DLE_DEBUG_FRAME_LENGTH_BAD
);
209 return (DW_DLE_DEBUG_FRAME_LENGTH_BAD
);
212 (void) dbg
->read(ds
->ds_data
, off
, dwarf_size
); /* Skip CIE id. */
213 cie
->cie_length
= length
;
215 cie
->cie_version
= dbg
->read(ds
->ds_data
, off
, 1);
216 if (cie
->cie_version
!= 1 && cie
->cie_version
!= 3 &&
217 cie
->cie_version
!= 4) {
218 DWARF_SET_ERROR(dbg
, error
, DW_DLE_FRAME_VERSION_BAD
);
219 return (DW_DLE_FRAME_VERSION_BAD
);
222 cie
->cie_augment
= ds
->ds_data
+ *off
;
223 p
= (char *) ds
->ds_data
;
224 while (p
[(*off
)++] != '\0')
227 /* We only recognize normal .dwarf_frame and GNU .eh_frame sections. */
228 if (*cie
->cie_augment
!= 0 && *cie
->cie_augment
!= 'z') {
229 *off
= cie
->cie_offset
+ ((dwarf_size
== 4) ? 4 : 12) +
231 return (DW_DLE_NONE
);
234 /* Optional EH Data field for .eh_frame section. */
235 if (strstr((char *)cie
->cie_augment
, "eh") != NULL
)
236 cie
->cie_ehdata
= dbg
->read(ds
->ds_data
, off
,
237 dbg
->dbg_pointer_size
);
239 cie
->cie_caf
= _dwarf_read_uleb128(ds
->ds_data
, off
);
240 cie
->cie_daf
= _dwarf_read_sleb128(ds
->ds_data
, off
);
242 /* Return address register. */
243 if (cie
->cie_version
== 1)
244 cie
->cie_ra
= dbg
->read(ds
->ds_data
, off
, 1);
246 cie
->cie_ra
= _dwarf_read_uleb128(ds
->ds_data
, off
);
248 /* Optional CIE augmentation data for .eh_frame section. */
249 if (*cie
->cie_augment
== 'z') {
250 cie
->cie_auglen
= _dwarf_read_uleb128(ds
->ds_data
, off
);
251 cie
->cie_augdata
= ds
->ds_data
+ *off
;
252 *off
+= cie
->cie_auglen
;
254 * XXX Use DW_EH_PE_absptr for default FDE PC start/range,
255 * in case _dwarf_frame_parse_lsb_cie_augment fails to
256 * find out the real encode.
258 cie
->cie_fde_encode
= DW_EH_PE_absptr
;
259 ret
= _dwarf_frame_parse_lsb_cie_augment(dbg
, cie
, error
);
260 if (ret
!= DW_DLE_NONE
)
264 /* CIE Initial instructions. */
265 cie
->cie_initinst
= ds
->ds_data
+ *off
;
267 cie
->cie_instlen
= cie
->cie_offset
+ 4 + length
- *off
;
269 cie
->cie_instlen
= cie
->cie_offset
+ 12 + length
- *off
;
271 *off
+= cie
->cie_instlen
;
275 printf("\tcie_version=%u cie_offset=%ju cie_length=%ju cie_augment=%s"
276 " cie_instlen=%ju cie->cie_caf=%ju cie->cie_daf=%jd off=%ju\n",
277 cie
->cie_version
, cie
->cie_offset
, cie
->cie_length
,
278 (char *)cie
->cie_augment
, cie
->cie_instlen
, cie
->cie_caf
,
287 return (DW_DLE_NONE
);
291 _dwarf_frame_add_fde(Dwarf_Debug dbg
, Dwarf_FrameSec fs
, Dwarf_Section
*ds
,
292 Dwarf_Unsigned
*off
, int eh_frame
, Dwarf_Error
*error
)
296 Dwarf_Unsigned cieoff
;
297 uint64_t length
, val
;
300 if ((fde
= calloc(1, sizeof(struct _Dwarf_Fde
))) == NULL
) {
301 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
302 return (DW_DLE_MEMORY
);
304 STAILQ_INSERT_TAIL(&fs
->fs_fdelist
, fde
, fde_next
);
308 fde
->fde_addr
= ds
->ds_data
+ *off
;
309 fde
->fde_offset
= *off
;
311 length
= dbg
->read(ds
->ds_data
, off
, 4);
312 if (length
== 0xffffffff) {
314 length
= dbg
->read(ds
->ds_data
, off
, 8);
318 if (length
> ds
->ds_size
- *off
) {
319 DWARF_SET_ERROR(dbg
, error
, DW_DLE_DEBUG_FRAME_LENGTH_BAD
);
320 return (DW_DLE_DEBUG_FRAME_LENGTH_BAD
);
323 fde
->fde_length
= length
;
326 fde
->fde_cieoff
= dbg
->read(ds
->ds_data
, off
, 4);
327 cieoff
= *off
- (4 + fde
->fde_cieoff
);
328 /* This delta should never be 0. */
329 if (cieoff
== fde
->fde_offset
) {
330 DWARF_SET_ERROR(dbg
, error
, DW_DLE_NO_CIE_FOR_FDE
);
331 return (DW_DLE_NO_CIE_FOR_FDE
);
334 fde
->fde_cieoff
= dbg
->read(ds
->ds_data
, off
, dwarf_size
);
335 cieoff
= fde
->fde_cieoff
;
338 if (_dwarf_frame_find_cie(fs
, cieoff
, &cie
) ==
340 ret
= _dwarf_frame_add_cie(dbg
, fs
, ds
, &cieoff
, &cie
,
342 if (ret
!= DW_DLE_NONE
)
348 * The FDE PC start/range for .eh_frame is encoded according
349 * to the LSB spec's extension to DWARF2.
351 ret
= _dwarf_frame_read_lsb_encoded(dbg
, &val
, ds
->ds_data
,
352 off
, cie
->cie_fde_encode
, ds
->ds_addr
+ *off
, error
);
353 if (ret
!= DW_DLE_NONE
)
355 fde
->fde_initloc
= val
;
357 * FDE PC range should not be relative value to anything.
358 * So pass 0 for pc value.
360 ret
= _dwarf_frame_read_lsb_encoded(dbg
, &val
, ds
->ds_data
,
361 off
, cie
->cie_fde_encode
, 0, error
);
362 if (ret
!= DW_DLE_NONE
)
364 fde
->fde_adrange
= val
;
366 fde
->fde_initloc
= dbg
->read(ds
->ds_data
, off
,
367 dbg
->dbg_pointer_size
);
368 fde
->fde_adrange
= dbg
->read(ds
->ds_data
, off
,
369 dbg
->dbg_pointer_size
);
372 /* Optional FDE augmentation data for .eh_frame section. (ignored) */
373 if (eh_frame
&& *cie
->cie_augment
== 'z') {
374 fde
->fde_auglen
= _dwarf_read_uleb128(ds
->ds_data
, off
);
375 fde
->fde_augdata
= ds
->ds_data
+ *off
;
376 *off
+= fde
->fde_auglen
;
379 fde
->fde_inst
= ds
->ds_data
+ *off
;
381 fde
->fde_instlen
= fde
->fde_offset
+ 4 + length
- *off
;
383 fde
->fde_instlen
= fde
->fde_offset
+ 12 + length
- *off
;
385 *off
+= fde
->fde_instlen
;
390 printf("(eh_frame)");
392 printf("\tfde_offset=%ju fde_length=%ju fde_cieoff=%ju"
393 " fde_instlen=%ju off=%ju\n", fde
->fde_offset
, fde
->fde_length
,
394 fde
->fde_cieoff
, fde
->fde_instlen
, *off
);
399 return (DW_DLE_NONE
);
403 _dwarf_frame_section_cleanup(Dwarf_FrameSec fs
)
408 STAILQ_FOREACH_SAFE(cie
, &fs
->fs_cielist
, cie_next
, tcie
) {
409 STAILQ_REMOVE(&fs
->fs_cielist
, cie
, _Dwarf_Cie
, cie_next
);
413 STAILQ_FOREACH_SAFE(fde
, &fs
->fs_fdelist
, fde_next
, tfde
) {
414 STAILQ_REMOVE(&fs
->fs_fdelist
, fde
, _Dwarf_Fde
, fde_next
);
418 if (fs
->fs_ciearray
!= NULL
)
419 free(fs
->fs_ciearray
);
420 if (fs
->fs_fdearray
!= NULL
)
421 free(fs
->fs_fdearray
);
427 _dwarf_frame_section_init(Dwarf_Debug dbg
, Dwarf_FrameSec
*frame_sec
,
428 Dwarf_Section
*ds
, int eh_frame
, Dwarf_Error
*error
)
433 uint64_t length
, offset
, cie_id
, entry_off
;
434 int dwarf_size
, i
, ret
;
436 assert(frame_sec
!= NULL
);
437 assert(*frame_sec
== NULL
);
439 if ((fs
= calloc(1, sizeof(struct _Dwarf_FrameSec
))) == NULL
) {
440 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
441 return (DW_DLE_MEMORY
);
443 STAILQ_INIT(&fs
->fs_cielist
);
444 STAILQ_INIT(&fs
->fs_fdelist
);
447 while (offset
< ds
->ds_size
) {
449 length
= dbg
->read(ds
->ds_data
, &offset
, 4);
450 if (length
== 0xffffffff) {
452 length
= dbg
->read(ds
->ds_data
, &offset
, 8);
456 if (length
> ds
->ds_size
- offset
||
457 (length
== 0 && !eh_frame
)) {
458 DWARF_SET_ERROR(dbg
, error
,
459 DW_DLE_DEBUG_FRAME_LENGTH_BAD
);
460 return (DW_DLE_DEBUG_FRAME_LENGTH_BAD
);
463 /* Check terminator for .eh_frame */
464 if (eh_frame
&& length
== 0)
467 cie_id
= dbg
->read(ds
->ds_data
, &offset
, dwarf_size
);
470 /* GNU .eh_frame use CIE id 0. */
472 ret
= _dwarf_frame_add_cie(dbg
, fs
, ds
,
473 &entry_off
, NULL
, error
);
475 ret
= _dwarf_frame_add_fde(dbg
, fs
, ds
,
476 &entry_off
, 1, error
);
478 /* .dwarf_frame use CIE id ~0 */
479 if ((dwarf_size
== 4 && cie_id
== ~0U) ||
480 (dwarf_size
== 8 && cie_id
== ~0ULL))
481 ret
= _dwarf_frame_add_cie(dbg
, fs
, ds
,
482 &entry_off
, NULL
, error
);
484 ret
= _dwarf_frame_add_fde(dbg
, fs
, ds
,
485 &entry_off
, 0, error
);
488 if (ret
!= DW_DLE_NONE
)
494 /* Create CIE array. */
495 if (fs
->fs_cielen
> 0) {
496 if ((fs
->fs_ciearray
= malloc(sizeof(Dwarf_Cie
) *
497 fs
->fs_cielen
)) == NULL
) {
499 DWARF_SET_ERROR(dbg
, error
, ret
);
503 STAILQ_FOREACH(cie
, &fs
->fs_cielist
, cie_next
) {
504 fs
->fs_ciearray
[i
++] = cie
;
506 assert((Dwarf_Unsigned
)i
== fs
->fs_cielen
);
509 /* Create FDE array. */
510 if (fs
->fs_fdelen
> 0) {
511 if ((fs
->fs_fdearray
= malloc(sizeof(Dwarf_Fde
) *
512 fs
->fs_fdelen
)) == NULL
) {
514 DWARF_SET_ERROR(dbg
, error
, ret
);
518 STAILQ_FOREACH(fde
, &fs
->fs_fdelist
, fde_next
) {
519 fs
->fs_fdearray
[i
++] = fde
;
521 assert((Dwarf_Unsigned
)i
== fs
->fs_fdelen
);
526 return (DW_DLE_NONE
);
530 _dwarf_frame_section_cleanup(fs
);
536 _dwarf_frame_run_inst(Dwarf_Debug dbg
, Dwarf_Regtable3
*rt
, uint8_t *insts
,
537 Dwarf_Unsigned len
, Dwarf_Unsigned caf
, Dwarf_Signed daf
, Dwarf_Addr pc
,
538 Dwarf_Addr pc_req
, Dwarf_Addr
*row_pc
, Dwarf_Error
*error
)
540 Dwarf_Regtable3
*init_rt
, *saved_rt
;
543 uint64_t reg
, reg2
, uoff
, soff
;
546 #define CFA rt->rt3_cfa_rule
547 #define INITCFA init_rt->rt3_cfa_rule
548 #define RL rt->rt3_rules
549 #define INITRL init_rt->rt3_rules
551 #define CHECK_TABLE_SIZE(x) \
553 if ((x) >= rt->rt3_reg_table_size) { \
554 DWARF_SET_ERROR(dbg, error, \
555 DW_DLE_DF_REG_NUM_TOO_HIGH); \
556 ret = DW_DLE_DF_REG_NUM_TOO_HIGH; \
562 printf("frame_run_inst: (caf=%ju, daf=%jd)\n", caf
, daf
);
566 init_rt
= saved_rt
= NULL
;
569 /* Save a copy of the table as initial state. */
570 _dwarf_frame_regtable_copy(dbg
, &init_rt
, rt
, error
);
578 printf("p=%p pe=%p pc=%#jx pc_req=%#jx\n", p
, pe
, pc
, pc_req
);
581 if (*p
== DW_CFA_nop
) {
583 printf("DW_CFA_nop\n");
595 case DW_CFA_advance_loc
:
598 printf("DW_CFA_advance_loc(%#jx(%u))\n", pc
,
606 CHECK_TABLE_SIZE(low6
);
607 RL
[low6
].dw_offset_relevant
= 1;
608 RL
[low6
].dw_value_type
= DW_EXPR_OFFSET
;
609 RL
[low6
].dw_regnum
= dbg
->dbg_frame_cfa_value
;
610 RL
[low6
].dw_offset_or_block_len
=
611 _dwarf_decode_uleb128(&p
) * daf
;
613 printf("DW_CFA_offset(%jd)\n",
614 RL
[low6
].dw_offset_or_block_len
);
619 CHECK_TABLE_SIZE(low6
);
620 memcpy(&RL
[low6
], &INITRL
[low6
],
621 sizeof(Dwarf_Regtable_Entry3
));
623 printf("DW_CFA_restore(%u)\n", low6
);
627 DWARF_SET_ERROR(dbg
, error
,
628 DW_DLE_FRAME_INSTR_EXEC_ERROR
);
629 ret
= DW_DLE_FRAME_INSTR_EXEC_ERROR
;
638 pc
= dbg
->decode(&p
, dbg
->dbg_pointer_size
);
640 printf("DW_CFA_set_loc(pc=%#jx)\n", pc
);
645 case DW_CFA_advance_loc1
:
646 pc
+= dbg
->decode(&p
, 1) * caf
;
648 printf("DW_CFA_set_loc1(pc=%#jx)\n", pc
);
653 case DW_CFA_advance_loc2
:
654 pc
+= dbg
->decode(&p
, 2) * caf
;
656 printf("DW_CFA_set_loc2(pc=%#jx)\n", pc
);
661 case DW_CFA_advance_loc4
:
662 pc
+= dbg
->decode(&p
, 4) * caf
;
664 printf("DW_CFA_set_loc4(pc=%#jx)\n", pc
);
669 case DW_CFA_offset_extended
:
671 reg
= _dwarf_decode_uleb128(&p
);
672 uoff
= _dwarf_decode_uleb128(&p
);
673 CHECK_TABLE_SIZE(reg
);
674 RL
[reg
].dw_offset_relevant
= 1;
675 RL
[reg
].dw_value_type
= DW_EXPR_OFFSET
;
676 RL
[reg
].dw_regnum
= dbg
->dbg_frame_cfa_value
;
677 RL
[reg
].dw_offset_or_block_len
= uoff
* daf
;
679 printf("DW_CFA_offset_extended(reg=%ju,uoff=%ju)\n",
683 case DW_CFA_restore_extended
:
685 reg
= _dwarf_decode_uleb128(&p
);
686 CHECK_TABLE_SIZE(reg
);
687 memcpy(&RL
[reg
], &INITRL
[reg
],
688 sizeof(Dwarf_Regtable_Entry3
));
690 printf("DW_CFA_restore_extended(%ju)\n", reg
);
693 case DW_CFA_undefined
:
695 reg
= _dwarf_decode_uleb128(&p
);
696 CHECK_TABLE_SIZE(reg
);
697 RL
[reg
].dw_offset_relevant
= 0;
698 RL
[reg
].dw_regnum
= dbg
->dbg_frame_undefined_value
;
700 printf("DW_CFA_undefined(%ju)\n", reg
);
703 case DW_CFA_same_value
:
704 reg
= _dwarf_decode_uleb128(&p
);
705 CHECK_TABLE_SIZE(reg
);
706 RL
[reg
].dw_offset_relevant
= 0;
707 RL
[reg
].dw_regnum
= dbg
->dbg_frame_same_value
;
709 printf("DW_CFA_same_value(%ju)\n", reg
);
712 case DW_CFA_register
:
714 reg
= _dwarf_decode_uleb128(&p
);
715 reg2
= _dwarf_decode_uleb128(&p
);
716 CHECK_TABLE_SIZE(reg
);
717 RL
[reg
].dw_offset_relevant
= 0;
718 RL
[reg
].dw_regnum
= reg2
;
720 printf("DW_CFA_register(reg=%ju,reg2=%ju)\n", reg
,
724 case DW_CFA_remember_state
:
725 _dwarf_frame_regtable_copy(dbg
, &saved_rt
, rt
, error
);
727 printf("DW_CFA_remember_state\n");
730 case DW_CFA_restore_state
:
732 _dwarf_frame_regtable_copy(dbg
, &rt
, saved_rt
, error
);
734 printf("DW_CFA_restore_state\n");
739 reg
= _dwarf_decode_uleb128(&p
);
740 uoff
= _dwarf_decode_uleb128(&p
);
741 CFA
.dw_offset_relevant
= 1;
742 CFA
.dw_value_type
= DW_EXPR_OFFSET
;
744 CFA
.dw_offset_or_block_len
= uoff
;
746 printf("DW_CFA_def_cfa(reg=%ju,uoff=%ju)\n", reg
, uoff
);
749 case DW_CFA_def_cfa_register
:
751 reg
= _dwarf_decode_uleb128(&p
);
754 * Note that DW_CFA_def_cfa_register change the CFA
755 * rule register while keep the old offset. So we
756 * should not touch the CFA.dw_offset_relevant flag
760 printf("DW_CFA_def_cfa_register(%ju)\n", reg
);
763 case DW_CFA_def_cfa_offset
:
765 uoff
= _dwarf_decode_uleb128(&p
);
766 CFA
.dw_offset_relevant
= 1;
767 CFA
.dw_value_type
= DW_EXPR_OFFSET
;
768 CFA
.dw_offset_or_block_len
= uoff
;
770 printf("DW_CFA_def_cfa_offset(%ju)\n", uoff
);
773 case DW_CFA_def_cfa_expression
:
775 CFA
.dw_offset_relevant
= 0;
776 CFA
.dw_value_type
= DW_EXPR_EXPRESSION
;
777 CFA
.dw_offset_or_block_len
= _dwarf_decode_uleb128(&p
);
778 CFA
.dw_block_ptr
= p
;
779 p
+= CFA
.dw_offset_or_block_len
;
781 printf("DW_CFA_def_cfa_expression\n");
784 case DW_CFA_expression
:
786 reg
= _dwarf_decode_uleb128(&p
);
787 CHECK_TABLE_SIZE(reg
);
788 RL
[reg
].dw_offset_relevant
= 0;
789 RL
[reg
].dw_value_type
= DW_EXPR_EXPRESSION
;
790 RL
[reg
].dw_offset_or_block_len
=
791 _dwarf_decode_uleb128(&p
);
792 RL
[reg
].dw_block_ptr
= p
;
793 p
+= RL
[reg
].dw_offset_or_block_len
;
795 printf("DW_CFA_expression\n");
798 case DW_CFA_offset_extended_sf
:
800 reg
= _dwarf_decode_uleb128(&p
);
801 soff
= _dwarf_decode_sleb128(&p
);
802 CHECK_TABLE_SIZE(reg
);
803 RL
[reg
].dw_offset_relevant
= 1;
804 RL
[reg
].dw_value_type
= DW_EXPR_OFFSET
;
805 RL
[reg
].dw_regnum
= dbg
->dbg_frame_cfa_value
;
806 RL
[reg
].dw_offset_or_block_len
= soff
* daf
;
808 printf("DW_CFA_offset_extended_sf(reg=%ju,soff=%jd)\n",
812 case DW_CFA_def_cfa_sf
:
814 reg
= _dwarf_decode_uleb128(&p
);
815 soff
= _dwarf_decode_sleb128(&p
);
816 CFA
.dw_offset_relevant
= 1;
817 CFA
.dw_value_type
= DW_EXPR_OFFSET
;
819 CFA
.dw_offset_or_block_len
= soff
* daf
;
821 printf("DW_CFA_def_cfa_sf(reg=%ju,soff=%jd)\n", reg
,
825 case DW_CFA_def_cfa_offset_sf
:
827 soff
= _dwarf_decode_sleb128(&p
);
828 CFA
.dw_offset_relevant
= 1;
829 CFA
.dw_value_type
= DW_EXPR_OFFSET
;
830 CFA
.dw_offset_or_block_len
= soff
* daf
;
832 printf("DW_CFA_def_cfa_offset_sf(soff=%jd)\n", soff
);
835 case DW_CFA_val_offset
:
837 reg
= _dwarf_decode_uleb128(&p
);
838 uoff
= _dwarf_decode_uleb128(&p
);
839 CHECK_TABLE_SIZE(reg
);
840 RL
[reg
].dw_offset_relevant
= 1;
841 RL
[reg
].dw_value_type
= DW_EXPR_VAL_OFFSET
;
842 RL
[reg
].dw_regnum
= dbg
->dbg_frame_cfa_value
;
843 RL
[reg
].dw_offset_or_block_len
= uoff
* daf
;
845 printf("DW_CFA_val_offset(reg=%ju,uoff=%ju)\n", reg
,
849 case DW_CFA_val_offset_sf
:
851 reg
= _dwarf_decode_uleb128(&p
);
852 soff
= _dwarf_decode_sleb128(&p
);
853 CHECK_TABLE_SIZE(reg
);
854 RL
[reg
].dw_offset_relevant
= 1;
855 RL
[reg
].dw_value_type
= DW_EXPR_VAL_OFFSET
;
856 RL
[reg
].dw_regnum
= dbg
->dbg_frame_cfa_value
;
857 RL
[reg
].dw_offset_or_block_len
= soff
* daf
;
859 printf("DW_CFA_val_offset_sf(reg=%ju,soff=%jd)\n", reg
,
863 case DW_CFA_val_expression
:
865 reg
= _dwarf_decode_uleb128(&p
);
866 CHECK_TABLE_SIZE(reg
);
867 RL
[reg
].dw_offset_relevant
= 0;
868 RL
[reg
].dw_value_type
= DW_EXPR_VAL_EXPRESSION
;
869 RL
[reg
].dw_offset_or_block_len
=
870 _dwarf_decode_uleb128(&p
);
871 RL
[reg
].dw_block_ptr
= p
;
872 p
+= RL
[reg
].dw_offset_or_block_len
;
874 printf("DW_CFA_val_expression\n");
878 DWARF_SET_ERROR(dbg
, error
,
879 DW_DLE_FRAME_INSTR_EXEC_ERROR
);
880 ret
= DW_DLE_FRAME_INSTR_EXEC_ERROR
;
887 free(init_rt
->rt3_rules
);
890 free(saved_rt
->rt3_rules
);
900 #undef CHECK_TABLE_SIZE
904 _dwarf_frame_convert_inst(Dwarf_Debug dbg
, uint8_t *insts
, Dwarf_Unsigned len
,
905 Dwarf_Unsigned
*count
, Dwarf_Frame_Op
*fop
, Dwarf_Frame_Op3
*fop3
,
910 uint64_t reg
, reg2
, uoff
, soff
, blen
;
913 #define SET_BASE_OP(x) \
916 fop[*count].fp_base_op = (x) >> 6; \
918 fop3[*count].fp_base_op = (x) >> 6; \
921 #define SET_EXTENDED_OP(x) \
924 fop[*count].fp_extended_op = (x); \
926 fop3[*count].fp_extended_op = (x); \
929 #define SET_REGISTER(x) \
932 fop[*count].fp_register = (x); \
934 fop3[*count].fp_register = (x); \
937 #define SET_OFFSET(x) \
940 fop[*count].fp_offset = (x); \
942 fop3[*count].fp_offset_or_block_len = \
946 #define SET_INSTR_OFFSET(x) \
949 fop[*count].fp_instr_offset = (x); \
951 fop3[*count].fp_instr_offset = (x); \
954 #define SET_BLOCK_LEN(x) \
957 fop3[*count].fp_offset_or_block_len = \
961 #define SET_EXPR_BLOCK(addr, len) \
963 if (fop3 != NULL) { \
964 fop3[*count].fp_expr_block = \
965 malloc((size_t) (len)); \
966 if (fop3[*count].fp_expr_block == NULL) { \
967 DWARF_SET_ERROR(dbg, error, \
969 return (DW_DLE_MEMORY); \
971 memcpy(&fop3[*count].fp_expr_block, \
984 SET_INSTR_OFFSET(p
- insts
);
986 if (*p
== DW_CFA_nop
) {
998 case DW_CFA_advance_loc
:
1005 uoff
= _dwarf_decode_uleb128(&p
);
1008 case DW_CFA_restore
:
1013 DWARF_SET_ERROR(dbg
, error
,
1014 DW_DLE_FRAME_INSTR_EXEC_ERROR
);
1015 return (DW_DLE_FRAME_INSTR_EXEC_ERROR
);
1022 SET_EXTENDED_OP(low6
);
1025 case DW_CFA_set_loc
:
1026 uoff
= dbg
->decode(&p
, dbg
->dbg_pointer_size
);
1029 case DW_CFA_advance_loc1
:
1030 uoff
= dbg
->decode(&p
, 1);
1033 case DW_CFA_advance_loc2
:
1034 uoff
= dbg
->decode(&p
, 2);
1037 case DW_CFA_advance_loc4
:
1038 uoff
= dbg
->decode(&p
, 4);
1041 case DW_CFA_offset_extended
:
1042 case DW_CFA_def_cfa
:
1043 case DW_CFA_val_offset
:
1044 reg
= _dwarf_decode_uleb128(&p
);
1045 uoff
= _dwarf_decode_uleb128(&p
);
1049 case DW_CFA_restore_extended
:
1050 case DW_CFA_undefined
:
1051 case DW_CFA_same_value
:
1052 case DW_CFA_def_cfa_register
:
1053 reg
= _dwarf_decode_uleb128(&p
);
1056 case DW_CFA_register
:
1057 reg
= _dwarf_decode_uleb128(&p
);
1058 reg2
= _dwarf_decode_uleb128(&p
);
1062 case DW_CFA_remember_state
:
1063 case DW_CFA_restore_state
:
1065 case DW_CFA_def_cfa_offset
:
1066 uoff
= _dwarf_decode_uleb128(&p
);
1069 case DW_CFA_def_cfa_expression
:
1070 blen
= _dwarf_decode_uleb128(&p
);
1071 SET_BLOCK_LEN(blen
);
1072 SET_EXPR_BLOCK(p
, blen
);
1075 case DW_CFA_expression
:
1076 case DW_CFA_val_expression
:
1077 reg
= _dwarf_decode_uleb128(&p
);
1078 blen
= _dwarf_decode_uleb128(&p
);
1080 SET_BLOCK_LEN(blen
);
1081 SET_EXPR_BLOCK(p
, blen
);
1084 case DW_CFA_offset_extended_sf
:
1085 case DW_CFA_def_cfa_sf
:
1086 case DW_CFA_val_offset_sf
:
1087 reg
= _dwarf_decode_uleb128(&p
);
1088 soff
= _dwarf_decode_sleb128(&p
);
1092 case DW_CFA_def_cfa_offset_sf
:
1093 soff
= _dwarf_decode_sleb128(&p
);
1097 DWARF_SET_ERROR(dbg
, error
,
1098 DW_DLE_FRAME_INSTR_EXEC_ERROR
);
1099 return (DW_DLE_FRAME_INSTR_EXEC_ERROR
);
1105 return (DW_DLE_NONE
);
1109 _dwarf_frame_get_fop(Dwarf_Debug dbg
, uint8_t *insts
, Dwarf_Unsigned len
,
1110 Dwarf_Frame_Op
**ret_oplist
, Dwarf_Signed
*ret_opcnt
, Dwarf_Error
*error
)
1112 Dwarf_Frame_Op
*oplist
;
1113 Dwarf_Unsigned count
;
1116 ret
= _dwarf_frame_convert_inst(dbg
, insts
, len
, &count
, NULL
, NULL
,
1118 if (ret
!= DW_DLE_NONE
)
1121 if ((oplist
= calloc(count
, sizeof(Dwarf_Frame_Op
))) == NULL
) {
1122 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
1123 return (DW_DLE_MEMORY
);
1126 ret
= _dwarf_frame_convert_inst(dbg
, insts
, len
, &count
, oplist
, NULL
,
1128 if (ret
!= DW_DLE_NONE
) {
1133 *ret_oplist
= oplist
;
1136 return (DW_DLE_NONE
);
1140 _dwarf_frame_regtable_copy(Dwarf_Debug dbg
, Dwarf_Regtable3
**dest
,
1141 Dwarf_Regtable3
*src
, Dwarf_Error
*error
)
1145 assert(dest
!= NULL
);
1146 assert(src
!= NULL
);
1148 if (*dest
== NULL
) {
1149 if ((*dest
= malloc(sizeof(Dwarf_Regtable3
))) == NULL
) {
1150 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
1151 return (DW_DLE_MEMORY
);
1153 (*dest
)->rt3_reg_table_size
= src
->rt3_reg_table_size
;
1154 (*dest
)->rt3_rules
= malloc(src
->rt3_reg_table_size
*
1155 sizeof(Dwarf_Regtable_Entry3
));
1156 if ((*dest
)->rt3_rules
== NULL
) {
1158 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
1159 return (DW_DLE_MEMORY
);
1163 memcpy(&(*dest
)->rt3_cfa_rule
, &src
->rt3_cfa_rule
,
1164 sizeof(Dwarf_Regtable_Entry3
));
1166 for (i
= 0; i
< (*dest
)->rt3_reg_table_size
&&
1167 i
< src
->rt3_reg_table_size
; i
++)
1168 memcpy(&(*dest
)->rt3_rules
[i
], &src
->rt3_rules
[i
],
1169 sizeof(Dwarf_Regtable_Entry3
));
1171 for (; i
< (*dest
)->rt3_reg_table_size
; i
++)
1172 (*dest
)->rt3_rules
[i
].dw_regnum
=
1173 dbg
->dbg_frame_undefined_value
;
1175 return (DW_DLE_NONE
);
1179 _dwarf_frame_get_internal_table(Dwarf_Fde fde
, Dwarf_Addr pc_req
,
1180 Dwarf_Regtable3
**ret_rt
, Dwarf_Addr
*ret_row_pc
, Dwarf_Error
*error
)
1184 Dwarf_Regtable3
*rt
;
1188 assert(ret_rt
!= NULL
);
1191 assert(dbg
!= NULL
);
1193 rt
= dbg
->dbg_internal_reg_table
;
1195 /* Clear the content of regtable from previous run. */
1196 memset(&rt
->rt3_cfa_rule
, 0, sizeof(Dwarf_Regtable_Entry3
));
1197 memset(rt
->rt3_rules
, 0, rt
->rt3_reg_table_size
*
1198 sizeof(Dwarf_Regtable_Entry3
));
1200 /* Set rules to initial values. */
1201 for (i
= 0; i
< rt
->rt3_reg_table_size
; i
++)
1202 rt
->rt3_rules
[i
].dw_regnum
= dbg
->dbg_frame_rule_initial_value
;
1204 /* Run initial instructions in CIE. */
1206 assert(cie
!= NULL
);
1207 ret
= _dwarf_frame_run_inst(dbg
, rt
, cie
->cie_initinst
,
1208 cie
->cie_instlen
, cie
->cie_caf
, cie
->cie_daf
, 0, ~0ULL,
1210 if (ret
!= DW_DLE_NONE
)
1213 /* Run instructions in FDE. */
1214 if (pc_req
>= fde
->fde_initloc
) {
1215 ret
= _dwarf_frame_run_inst(dbg
, rt
, fde
->fde_inst
,
1216 fde
->fde_instlen
, cie
->cie_caf
, cie
->cie_daf
,
1217 fde
->fde_initloc
, pc_req
, &row_pc
, error
);
1218 if (ret
!= DW_DLE_NONE
)
1223 *ret_row_pc
= row_pc
;
1225 return (DW_DLE_NONE
);
1229 _dwarf_frame_cleanup(Dwarf_Debug dbg
)
1231 Dwarf_Regtable3
*rt
;
1233 assert(dbg
!= NULL
&& dbg
->dbg_mode
== DW_DLC_READ
);
1235 if (dbg
->dbg_internal_reg_table
) {
1236 rt
= dbg
->dbg_internal_reg_table
;
1237 free(rt
->rt3_rules
);
1239 dbg
->dbg_internal_reg_table
= NULL
;
1242 if (dbg
->dbg_frame
) {
1243 _dwarf_frame_section_cleanup(dbg
->dbg_frame
);
1244 dbg
->dbg_frame
= NULL
;
1247 if (dbg
->dbg_eh_frame
) {
1248 _dwarf_frame_section_cleanup(dbg
->dbg_eh_frame
);
1249 dbg
->dbg_eh_frame
= NULL
;
1254 _dwarf_frame_section_load(Dwarf_Debug dbg
, Dwarf_Error
*error
)
1258 if ((ds
= _dwarf_find_section(dbg
, ".debug_frame")) != NULL
) {
1259 return (_dwarf_frame_section_init(dbg
, &dbg
->dbg_frame
,
1263 return (DW_DLE_NONE
);
1267 _dwarf_frame_section_load_eh(Dwarf_Debug dbg
, Dwarf_Error
*error
)
1271 if ((ds
= _dwarf_find_section(dbg
, ".eh_frame")) != NULL
) {
1272 return (_dwarf_frame_section_init(dbg
, &dbg
->dbg_eh_frame
,
1276 return (DW_DLE_NONE
);
1280 _dwarf_frame_params_init(Dwarf_Debug dbg
)
1283 /* Initialise call frame related parameters. */
1284 dbg
->dbg_frame_rule_table_size
= DW_FRAME_LAST_REG_NUM
;
1285 dbg
->dbg_frame_rule_initial_value
= DW_FRAME_REG_INITIAL_VALUE
;
1286 dbg
->dbg_frame_cfa_value
= DW_FRAME_CFA_COL3
;
1287 dbg
->dbg_frame_same_value
= DW_FRAME_SAME_VAL
;
1288 dbg
->dbg_frame_undefined_value
= DW_FRAME_UNDEFINED_VAL
;
1292 _dwarf_frame_interal_table_init(Dwarf_Debug dbg
, Dwarf_Error
*error
)
1294 Dwarf_Regtable3
*rt
;
1296 if (dbg
->dbg_internal_reg_table
!= NULL
)
1297 return (DW_DLE_NONE
);
1299 /* Initialise internal register table. */
1300 if ((rt
= calloc(1, sizeof(Dwarf_Regtable3
))) == NULL
) {
1301 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
1302 return (DW_DLE_MEMORY
);
1305 rt
->rt3_reg_table_size
= dbg
->dbg_frame_rule_table_size
;
1306 if ((rt
->rt3_rules
= calloc(rt
->rt3_reg_table_size
,
1307 sizeof(Dwarf_Regtable_Entry3
))) == NULL
) {
1309 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
1310 return (DW_DLE_MEMORY
);
1313 dbg
->dbg_internal_reg_table
= rt
;
1315 return (DW_DLE_NONE
);
1318 #define _FDE_INST_INIT_SIZE 128
1321 _dwarf_frame_fde_add_inst(Dwarf_P_Fde fde
, Dwarf_Small op
, Dwarf_Unsigned val1
,
1322 Dwarf_Unsigned val2
, Dwarf_Error
*error
)
1325 uint8_t high2
, low6
;
1329 #define ds_data fde_inst
1330 #define ds_cap fde_instcap
1331 #define ds_size fde_instlen
1333 assert(fde
!= NULL
&& fde
->fde_dbg
!= NULL
);
1336 if (fde
->fde_inst
== NULL
) {
1337 fde
->fde_instcap
= _FDE_INST_INIT_SIZE
;
1338 fde
->fde_instlen
= 0;
1339 if ((fde
->fde_inst
= malloc((size_t) fde
->fde_instcap
)) ==
1341 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
1342 return (DW_DLE_MEMORY
);
1345 assert(fde
->fde_instcap
!= 0);
1347 RCHECK(WRITE_VALUE(op
, 1));
1348 if (op
== DW_CFA_nop
)
1349 return (DW_DLE_NONE
);
1356 case DW_CFA_advance_loc
:
1357 case DW_CFA_restore
:
1360 RCHECK(WRITE_ULEB128(val1
));
1363 DWARF_SET_ERROR(dbg
, error
,
1364 DW_DLE_FRAME_INSTR_EXEC_ERROR
);
1365 return (DW_DLE_FRAME_INSTR_EXEC_ERROR
);
1367 return (DW_DLE_NONE
);
1371 case DW_CFA_set_loc
:
1372 RCHECK(WRITE_VALUE(val1
, dbg
->dbg_pointer_size
));
1374 case DW_CFA_advance_loc1
:
1375 RCHECK(WRITE_VALUE(val1
, 1));
1377 case DW_CFA_advance_loc2
:
1378 RCHECK(WRITE_VALUE(val1
, 2));
1380 case DW_CFA_advance_loc4
:
1381 RCHECK(WRITE_VALUE(val1
, 4));
1383 case DW_CFA_offset_extended
:
1384 case DW_CFA_def_cfa
:
1385 case DW_CFA_register
:
1386 RCHECK(WRITE_ULEB128(val1
));
1387 RCHECK(WRITE_ULEB128(val2
));
1389 case DW_CFA_restore_extended
:
1390 case DW_CFA_undefined
:
1391 case DW_CFA_same_value
:
1392 case DW_CFA_def_cfa_register
:
1393 case DW_CFA_def_cfa_offset
:
1394 RCHECK(WRITE_ULEB128(val1
));
1396 case DW_CFA_remember_state
:
1397 case DW_CFA_restore_state
:
1400 DWARF_SET_ERROR(dbg
, error
, DW_DLE_FRAME_INSTR_EXEC_ERROR
);
1401 return (DW_DLE_FRAME_INSTR_EXEC_ERROR
);
1404 return (DW_DLE_NONE
);
1416 _dwarf_frame_gen_cie(Dwarf_P_Debug dbg
, Dwarf_P_Section ds
, Dwarf_P_Cie cie
,
1423 assert(dbg
!= NULL
&& ds
!= NULL
&& cie
!= NULL
);
1425 cie
->cie_offset
= offset
= ds
->ds_size
;
1426 cie
->cie_length
= 0;
1427 cie
->cie_version
= 1;
1429 /* Length placeholder. */
1430 RCHECK(WRITE_VALUE(cie
->cie_length
, 4));
1432 /* .debug_frame use CIE id ~0. */
1433 RCHECK(WRITE_VALUE(~0U, 4));
1435 /* .debug_frame version is 1. (DWARF2) */
1436 RCHECK(WRITE_VALUE(cie
->cie_version
, 1));
1438 /* Write augmentation, if present. */
1439 if (cie
->cie_augment
!= NULL
)
1440 RCHECK(WRITE_BLOCK(cie
->cie_augment
,
1441 strlen((char *) cie
->cie_augment
) + 1));
1443 RCHECK(WRITE_VALUE(0, 1));
1445 /* Write caf, daf and ra. */
1446 RCHECK(WRITE_ULEB128(cie
->cie_caf
));
1447 RCHECK(WRITE_SLEB128(cie
->cie_daf
));
1448 RCHECK(WRITE_VALUE(cie
->cie_ra
, 1));
1450 /* Write initial instructions, if present. */
1451 if (cie
->cie_initinst
!= NULL
)
1452 RCHECK(WRITE_BLOCK(cie
->cie_initinst
, cie
->cie_instlen
));
1455 len
= ds
->ds_size
- cie
->cie_offset
- 4;
1456 cie
->cie_length
= roundup(len
, dbg
->dbg_pointer_size
);
1457 while (len
++ < cie
->cie_length
)
1458 RCHECK(WRITE_VALUE(DW_CFA_nop
, 1));
1460 /* Fill in the length field. */
1461 dbg
->write(ds
->ds_data
, &offset
, cie
->cie_length
, 4);
1463 return (DW_DLE_NONE
);
1470 _dwarf_frame_gen_fde(Dwarf_P_Debug dbg
, Dwarf_P_Section ds
,
1471 Dwarf_Rel_Section drs
, Dwarf_P_Fde fde
, Dwarf_Error
*error
)
1477 assert(dbg
!= NULL
&& ds
!= NULL
&& drs
!= NULL
);
1478 assert(fde
!= NULL
&& fde
->fde_cie
!= NULL
);
1480 fde
->fde_offset
= offset
= ds
->ds_size
;
1481 fde
->fde_length
= 0;
1482 fde
->fde_cieoff
= fde
->fde_cie
->cie_offset
;
1484 /* Length placeholder. */
1485 RCHECK(WRITE_VALUE(fde
->fde_length
, 4));
1487 /* Write CIE pointer. */
1488 RCHECK(_dwarf_reloc_entry_add(dbg
, drs
, ds
, dwarf_drt_data_reloc
, 4,
1489 ds
->ds_size
, 0, fde
->fde_cieoff
, ".debug_frame", error
));
1491 /* Write FDE initial location. */
1492 RCHECK(_dwarf_reloc_entry_add(dbg
, drs
, ds
, dwarf_drt_data_reloc
,
1493 dbg
->dbg_pointer_size
, ds
->ds_size
, fde
->fde_symndx
,
1494 fde
->fde_initloc
, NULL
, error
));
1497 * Write FDE address range. Use a pair of relocation entries if
1498 * application provided end symbol index. Otherwise write the
1499 * length without assoicating any relocation info.
1501 if (fde
->fde_esymndx
> 0)
1502 RCHECK(_dwarf_reloc_entry_add_pair(dbg
, drs
, ds
,
1503 dbg
->dbg_pointer_size
, ds
->ds_size
, fde
->fde_symndx
,
1504 fde
->fde_esymndx
, fde
->fde_initloc
, fde
->fde_eoff
, error
));
1506 RCHECK(WRITE_VALUE(fde
->fde_adrange
, dbg
->dbg_pointer_size
));
1508 /* Write FDE frame instructions. */
1509 RCHECK(WRITE_BLOCK(fde
->fde_inst
, fde
->fde_instlen
));
1512 len
= ds
->ds_size
- fde
->fde_offset
- 4;
1513 fde
->fde_length
= roundup(len
, dbg
->dbg_pointer_size
);
1514 while (len
++ < fde
->fde_length
)
1515 RCHECK(WRITE_VALUE(DW_CFA_nop
, 1));
1517 /* Fill in the length field. */
1518 dbg
->write(ds
->ds_data
, &offset
, fde
->fde_length
, 4);
1520 return (DW_DLE_NONE
);
1527 _dwarf_frame_gen(Dwarf_P_Debug dbg
, Dwarf_Error
*error
)
1530 Dwarf_Rel_Section drs
;
1535 if (STAILQ_EMPTY(&dbg
->dbgp_cielist
))
1536 return (DW_DLE_NONE
);
1538 /* Create .debug_frame section. */
1539 if ((ret
= _dwarf_section_init(dbg
, &ds
, ".debug_frame", 0, error
)) !=
1543 /* Create relocation section for .debug_frame */
1544 RCHECK(_dwarf_reloc_section_init(dbg
, &drs
, ds
, error
));
1546 /* Generate list of CIE. */
1547 STAILQ_FOREACH(cie
, &dbg
->dbgp_cielist
, cie_next
)
1548 RCHECK(_dwarf_frame_gen_cie(dbg
, ds
, cie
, error
));
1550 /* Generate list of FDE. */
1551 STAILQ_FOREACH(fde
, &dbg
->dbgp_fdelist
, fde_next
)
1552 RCHECK(_dwarf_frame_gen_fde(dbg
, ds
, drs
, fde
, error
));
1554 /* Inform application the creation of .debug_frame ELF section. */
1555 RCHECK(_dwarf_section_callback(dbg
, ds
, SHT_PROGBITS
, 0, 0, 0, error
));
1557 /* Finalize relocation section for .debug_frame */
1558 RCHECK(_dwarf_reloc_section_finalize(dbg
, drs
, error
));
1560 return (DW_DLE_NONE
);
1563 _dwarf_reloc_section_free(dbg
, &drs
);
1566 _dwarf_section_free(dbg
, &ds
);
1572 _dwarf_frame_pro_cleanup(Dwarf_P_Debug dbg
)
1574 Dwarf_P_Cie cie
, tcie
;
1575 Dwarf_P_Fde fde
, tfde
;
1577 assert(dbg
!= NULL
&& dbg
->dbg_mode
== DW_DLC_WRITE
);
1579 STAILQ_FOREACH_SAFE(cie
, &dbg
->dbgp_cielist
, cie_next
, tcie
) {
1580 STAILQ_REMOVE(&dbg
->dbgp_cielist
, cie
, _Dwarf_Cie
, cie_next
);
1581 if (cie
->cie_augment
)
1582 free(cie
->cie_augment
);
1583 if (cie
->cie_initinst
)
1584 free(cie
->cie_initinst
);
1587 dbg
->dbgp_cielen
= 0;
1589 STAILQ_FOREACH_SAFE(fde
, &dbg
->dbgp_fdelist
, fde_next
, tfde
) {
1590 STAILQ_REMOVE(&dbg
->dbgp_fdelist
, fde
, _Dwarf_Fde
, fde_next
);
1591 if (fde
->fde_inst
!= NULL
)
1592 free(fde
->fde_inst
);
1595 dbg
->dbgp_fdelen
= 0;