2 * Copyright (c) 2009-2011,2014 Kai Wang
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include "_libdwarf.h"
29 ELFTC_VCSID("$Id: libdwarf_frame.c 3589 2018-03-13 20:34:33Z kaiwang27 $");
32 _dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset,
37 STAILQ_FOREACH(cie, &fs->fs_cielist, cie_next) {
38 if (cie->cie_offset == offset)
43 return (DW_DLE_NO_ENTRY);
52 _dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, Dwarf_Cie cie, uint64_t *val,
53 uint8_t *data, uint64_t *offsetp, uint8_t encode, Dwarf_Addr pc,
58 if (encode == DW_EH_PE_omit)
61 application = encode & 0xf0;
66 *val = dbg->read(data, offsetp, cie->cie_addrsize);
68 case DW_EH_PE_uleb128:
69 *val = _dwarf_read_uleb128(data, offsetp);
72 *val = dbg->read(data, offsetp, 2);
75 *val = dbg->read(data, offsetp, 4);
78 *val = dbg->read(data, offsetp, 8);
80 case DW_EH_PE_sleb128:
81 *val = _dwarf_read_sleb128(data, offsetp);
84 *val = (int16_t) dbg->read(data, offsetp, 2);
87 *val = (int32_t) dbg->read(data, offsetp, 4);
90 *val = dbg->read(data, offsetp, 8);
93 DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
94 return (DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
97 if (application == DW_EH_PE_pcrel) {
99 * Value is relative to .eh_frame section virtual addr.
102 case DW_EH_PE_uleb128:
103 case DW_EH_PE_udata2:
104 case DW_EH_PE_udata4:
105 case DW_EH_PE_udata8:
108 case DW_EH_PE_sleb128:
109 case DW_EH_PE_sdata2:
110 case DW_EH_PE_sdata4:
111 case DW_EH_PE_sdata8:
112 *val = pc + (int64_t) *val;
115 /* DW_EH_PE_absptr is absolute value. */
120 /* XXX Applications other than DW_EH_PE_pcrel are not handled. */
122 return (DW_DLE_NONE);
126 _dwarf_frame_parse_lsb_cie_augment(Dwarf_Debug dbg, Dwarf_Cie cie,
129 uint8_t *aug_p, *augdata_p;
130 uint64_t val, offset;
134 assert(cie->cie_augment != NULL && *cie->cie_augment == 'z');
137 * Here we're only interested in the presence of augment 'R'
138 * and associated CIE augment data, which describes the
139 * encoding scheme of FDE PC begin and range.
141 aug_p = &cie->cie_augment[1];
142 augdata_p = cie->cie_augdata;
143 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, cie, &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 /* DWARF4 added "address_size" and "segment_size". */
240 if (cie->cie_version == 4) {
241 cie->cie_addrsize = dbg->read(ds->ds_data, off, 1);
242 cie->cie_segmentsize = dbg->read(ds->ds_data, off, 1);
245 * Otherwise (DWARF[23]) we just set CIE addrsize to the
246 * debug context pointer size.
248 cie->cie_addrsize = dbg->dbg_pointer_size;
251 cie->cie_caf = _dwarf_read_uleb128(ds->ds_data, off);
252 cie->cie_daf = _dwarf_read_sleb128(ds->ds_data, off);
254 /* Return address register. */
255 if (cie->cie_version == 1)
256 cie->cie_ra = dbg->read(ds->ds_data, off, 1);
258 cie->cie_ra = _dwarf_read_uleb128(ds->ds_data, off);
260 /* Optional CIE augmentation data for .eh_frame section. */
261 if (*cie->cie_augment == 'z') {
262 cie->cie_auglen = _dwarf_read_uleb128(ds->ds_data, off);
263 cie->cie_augdata = ds->ds_data + *off;
264 *off += cie->cie_auglen;
266 * XXX Use DW_EH_PE_absptr for default FDE PC start/range,
267 * in case _dwarf_frame_parse_lsb_cie_augment fails to
268 * find out the real encode.
270 cie->cie_fde_encode = DW_EH_PE_absptr;
271 ret = _dwarf_frame_parse_lsb_cie_augment(dbg, cie, error);
272 if (ret != DW_DLE_NONE)
276 /* CIE Initial instructions. */
277 cie->cie_initinst = ds->ds_data + *off;
279 cie->cie_instlen = cie->cie_offset + 4 + length - *off;
281 cie->cie_instlen = cie->cie_offset + 12 + length - *off;
283 *off += cie->cie_instlen;
287 printf("\tcie_version=%u cie_offset=%ju cie_length=%ju cie_augment=%s"
288 " cie_instlen=%ju cie->cie_caf=%ju cie->cie_daf=%jd off=%ju\n",
289 cie->cie_version, cie->cie_offset, cie->cie_length,
290 (char *)cie->cie_augment, cie->cie_instlen, cie->cie_caf,
299 return (DW_DLE_NONE);
303 _dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds,
304 Dwarf_Unsigned *off, int eh_frame, Dwarf_Error *error)
308 Dwarf_Unsigned cieoff;
309 uint64_t length, val;
312 if ((fde = calloc(1, sizeof(struct _Dwarf_Fde))) == NULL) {
313 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
314 return (DW_DLE_MEMORY);
316 STAILQ_INSERT_TAIL(&fs->fs_fdelist, fde, fde_next);
320 fde->fde_addr = ds->ds_data + *off;
321 fde->fde_offset = *off;
323 length = dbg->read(ds->ds_data, off, 4);
324 if (length == 0xffffffff) {
326 length = dbg->read(ds->ds_data, off, 8);
330 if (length > ds->ds_size - *off) {
331 DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
332 return (DW_DLE_DEBUG_FRAME_LENGTH_BAD);
335 fde->fde_length = length;
338 fde->fde_cieoff = dbg->read(ds->ds_data, off, 4);
339 cieoff = *off - (4 + fde->fde_cieoff);
340 /* This delta should never be 0. */
341 if (cieoff == fde->fde_offset) {
342 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
343 return (DW_DLE_NO_CIE_FOR_FDE);
346 fde->fde_cieoff = dbg->read(ds->ds_data, off, dwarf_size);
347 cieoff = fde->fde_cieoff;
350 if (_dwarf_frame_find_cie(fs, cieoff, &cie) ==
352 ret = _dwarf_frame_add_cie(dbg, fs, ds, &cieoff, &cie,
354 if (ret != DW_DLE_NONE)
360 * The FDE PC start/range for .eh_frame is encoded according
361 * to the LSB spec's extension to DWARF2.
363 ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val,
364 ds->ds_data, off, cie->cie_fde_encode, ds->ds_addr + *off,
366 if (ret != DW_DLE_NONE)
368 fde->fde_initloc = val;
370 * FDE PC range should not be relative value to anything.
371 * So pass 0 for pc value.
373 ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val,
374 ds->ds_data, off, cie->cie_fde_encode, 0, error);
375 if (ret != DW_DLE_NONE)
377 fde->fde_adrange = val;
379 fde->fde_initloc = dbg->read(ds->ds_data, off,
381 fde->fde_adrange = dbg->read(ds->ds_data, off,
385 /* Optional FDE augmentation data for .eh_frame section. (ignored) */
386 if (eh_frame && *cie->cie_augment == 'z') {
387 fde->fde_auglen = _dwarf_read_uleb128(ds->ds_data, off);
388 fde->fde_augdata = ds->ds_data + *off;
389 *off += fde->fde_auglen;
392 fde->fde_inst = ds->ds_data + *off;
394 fde->fde_instlen = fde->fde_offset + 4 + length - *off;
396 fde->fde_instlen = fde->fde_offset + 12 + length - *off;
398 *off += fde->fde_instlen;
403 printf("(eh_frame)");
405 printf("\tfde_offset=%ju fde_length=%ju fde_cieoff=%ju"
406 " fde_instlen=%ju off=%ju\n", fde->fde_offset, fde->fde_length,
407 fde->fde_cieoff, fde->fde_instlen, *off);
412 return (DW_DLE_NONE);
416 _dwarf_frame_section_cleanup(Dwarf_FrameSec fs)
421 STAILQ_FOREACH_SAFE(cie, &fs->fs_cielist, cie_next, tcie) {
422 STAILQ_REMOVE(&fs->fs_cielist, cie, _Dwarf_Cie, cie_next);
426 STAILQ_FOREACH_SAFE(fde, &fs->fs_fdelist, fde_next, tfde) {
427 STAILQ_REMOVE(&fs->fs_fdelist, fde, _Dwarf_Fde, fde_next);
431 if (fs->fs_ciearray != NULL)
432 free(fs->fs_ciearray);
433 if (fs->fs_fdearray != NULL)
434 free(fs->fs_fdearray);
440 _dwarf_frame_section_init(Dwarf_Debug dbg, Dwarf_FrameSec *frame_sec,
441 Dwarf_Section *ds, int eh_frame, Dwarf_Error *error)
446 uint64_t length, offset, cie_id, entry_off;
447 int dwarf_size, i, ret;
449 assert(frame_sec != NULL);
450 assert(*frame_sec == NULL);
452 if ((fs = calloc(1, sizeof(struct _Dwarf_FrameSec))) == NULL) {
453 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
454 return (DW_DLE_MEMORY);
456 STAILQ_INIT(&fs->fs_cielist);
457 STAILQ_INIT(&fs->fs_fdelist);
460 while (offset < ds->ds_size) {
462 length = dbg->read(ds->ds_data, &offset, 4);
463 if (length == 0xffffffff) {
465 length = dbg->read(ds->ds_data, &offset, 8);
469 if (length > ds->ds_size - offset ||
470 (length == 0 && !eh_frame)) {
471 DWARF_SET_ERROR(dbg, error,
472 DW_DLE_DEBUG_FRAME_LENGTH_BAD);
473 return (DW_DLE_DEBUG_FRAME_LENGTH_BAD);
476 /* Check terminator for .eh_frame */
477 if (eh_frame && length == 0)
480 cie_id = dbg->read(ds->ds_data, &offset, dwarf_size);
483 /* GNU .eh_frame use CIE id 0. */
485 ret = _dwarf_frame_add_cie(dbg, fs, ds,
486 &entry_off, NULL, error);
488 ret = _dwarf_frame_add_fde(dbg, fs, ds,
489 &entry_off, 1, error);
491 /* .dwarf_frame use CIE id ~0 */
492 if ((dwarf_size == 4 && cie_id == ~0U) ||
493 (dwarf_size == 8 && cie_id == ~0ULL))
494 ret = _dwarf_frame_add_cie(dbg, fs, ds,
495 &entry_off, NULL, error);
497 ret = _dwarf_frame_add_fde(dbg, fs, ds,
498 &entry_off, 0, error);
501 if (ret != DW_DLE_NONE)
507 /* Create CIE array. */
508 if (fs->fs_cielen > 0) {
509 if ((fs->fs_ciearray = malloc(sizeof(Dwarf_Cie) *
510 fs->fs_cielen)) == NULL) {
512 DWARF_SET_ERROR(dbg, error, ret);
516 STAILQ_FOREACH(cie, &fs->fs_cielist, cie_next) {
517 fs->fs_ciearray[i++] = cie;
519 assert((Dwarf_Unsigned)i == fs->fs_cielen);
522 /* Create FDE array. */
523 if (fs->fs_fdelen > 0) {
524 if ((fs->fs_fdearray = malloc(sizeof(Dwarf_Fde) *
525 fs->fs_fdelen)) == NULL) {
527 DWARF_SET_ERROR(dbg, error, ret);
531 STAILQ_FOREACH(fde, &fs->fs_fdelist, fde_next) {
532 fs->fs_fdearray[i++] = fde;
534 assert((Dwarf_Unsigned)i == fs->fs_fdelen);
539 return (DW_DLE_NONE);
543 _dwarf_frame_section_cleanup(fs);
549 _dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t addr_size,
550 uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf,
551 Dwarf_Addr pc, Dwarf_Addr pc_req, Dwarf_Addr *row_pc, Dwarf_Error *error)
553 Dwarf_Regtable3 *init_rt, *saved_rt;
556 uint64_t reg, reg2, uoff, soff;
559 #define CFA rt->rt3_cfa_rule
560 #define INITCFA init_rt->rt3_cfa_rule
561 #define RL rt->rt3_rules
562 #define INITRL init_rt->rt3_rules
564 #define CHECK_TABLE_SIZE(x) \
566 if ((x) >= rt->rt3_reg_table_size) { \
567 DWARF_SET_ERROR(dbg, error, \
568 DW_DLE_DF_REG_NUM_TOO_HIGH); \
569 ret = DW_DLE_DF_REG_NUM_TOO_HIGH; \
575 printf("frame_run_inst: (caf=%ju, daf=%jd)\n", caf, daf);
579 init_rt = saved_rt = NULL;
582 /* Save a copy of the table as initial state. */
583 _dwarf_frame_regtable_copy(dbg, &init_rt, rt, error);
591 printf("p=%p pe=%p pc=%#jx pc_req=%#jx\n", p, pe, pc, pc_req);
594 if (*p == DW_CFA_nop) {
596 printf("DW_CFA_nop\n");
608 case DW_CFA_advance_loc:
611 printf("DW_CFA_advance_loc(%#jx(%u))\n", pc,
619 CHECK_TABLE_SIZE(low6);
620 RL[low6].dw_offset_relevant = 1;
621 RL[low6].dw_value_type = DW_EXPR_OFFSET;
622 RL[low6].dw_regnum = dbg->dbg_frame_cfa_value;
623 RL[low6].dw_offset_or_block_len =
624 _dwarf_decode_uleb128(&p) * daf;
626 printf("DW_CFA_offset(%jd)\n",
627 RL[low6].dw_offset_or_block_len);
632 CHECK_TABLE_SIZE(low6);
633 memcpy(&RL[low6], &INITRL[low6],
634 sizeof(Dwarf_Regtable_Entry3));
636 printf("DW_CFA_restore(%u)\n", low6);
640 DWARF_SET_ERROR(dbg, error,
641 DW_DLE_FRAME_INSTR_EXEC_ERROR);
642 ret = DW_DLE_FRAME_INSTR_EXEC_ERROR;
651 pc = dbg->decode(&p, addr_size);
653 printf("DW_CFA_set_loc(pc=%#jx)\n", pc);
658 case DW_CFA_advance_loc1:
659 pc += dbg->decode(&p, 1) * caf;
661 printf("DW_CFA_set_loc1(pc=%#jx)\n", pc);
666 case DW_CFA_advance_loc2:
667 pc += dbg->decode(&p, 2) * caf;
669 printf("DW_CFA_set_loc2(pc=%#jx)\n", pc);
674 case DW_CFA_advance_loc4:
675 pc += dbg->decode(&p, 4) * caf;
677 printf("DW_CFA_set_loc4(pc=%#jx)\n", pc);
682 case DW_CFA_offset_extended:
684 reg = _dwarf_decode_uleb128(&p);
685 uoff = _dwarf_decode_uleb128(&p);
686 CHECK_TABLE_SIZE(reg);
687 RL[reg].dw_offset_relevant = 1;
688 RL[reg].dw_value_type = DW_EXPR_OFFSET;
689 RL[reg].dw_regnum = dbg->dbg_frame_cfa_value;
690 RL[reg].dw_offset_or_block_len = uoff * daf;
692 printf("DW_CFA_offset_extended(reg=%ju,uoff=%ju)\n",
696 case DW_CFA_restore_extended:
698 reg = _dwarf_decode_uleb128(&p);
699 CHECK_TABLE_SIZE(reg);
700 memcpy(&RL[reg], &INITRL[reg],
701 sizeof(Dwarf_Regtable_Entry3));
703 printf("DW_CFA_restore_extended(%ju)\n", reg);
706 case DW_CFA_undefined:
708 reg = _dwarf_decode_uleb128(&p);
709 CHECK_TABLE_SIZE(reg);
710 RL[reg].dw_offset_relevant = 0;
711 RL[reg].dw_regnum = dbg->dbg_frame_undefined_value;
713 printf("DW_CFA_undefined(%ju)\n", reg);
716 case DW_CFA_same_value:
717 reg = _dwarf_decode_uleb128(&p);
718 CHECK_TABLE_SIZE(reg);
719 RL[reg].dw_offset_relevant = 0;
720 RL[reg].dw_regnum = dbg->dbg_frame_same_value;
722 printf("DW_CFA_same_value(%ju)\n", reg);
725 case DW_CFA_register:
727 reg = _dwarf_decode_uleb128(&p);
728 reg2 = _dwarf_decode_uleb128(&p);
729 CHECK_TABLE_SIZE(reg);
730 RL[reg].dw_offset_relevant = 0;
731 RL[reg].dw_regnum = reg2;
733 printf("DW_CFA_register(reg=%ju,reg2=%ju)\n", reg,
737 case DW_CFA_remember_state:
738 _dwarf_frame_regtable_copy(dbg, &saved_rt, rt, error);
740 printf("DW_CFA_remember_state\n");
743 case DW_CFA_restore_state:
745 _dwarf_frame_regtable_copy(dbg, &rt, saved_rt, error);
747 printf("DW_CFA_restore_state\n");
752 reg = _dwarf_decode_uleb128(&p);
753 uoff = _dwarf_decode_uleb128(&p);
754 CFA.dw_offset_relevant = 1;
755 CFA.dw_value_type = DW_EXPR_OFFSET;
757 CFA.dw_offset_or_block_len = uoff;
759 printf("DW_CFA_def_cfa(reg=%ju,uoff=%ju)\n", reg, uoff);
762 case DW_CFA_def_cfa_register:
764 reg = _dwarf_decode_uleb128(&p);
767 * Note that DW_CFA_def_cfa_register change the CFA
768 * rule register while keep the old offset. So we
769 * should not touch the CFA.dw_offset_relevant flag
773 printf("DW_CFA_def_cfa_register(%ju)\n", reg);
776 case DW_CFA_def_cfa_offset:
778 uoff = _dwarf_decode_uleb128(&p);
779 CFA.dw_offset_relevant = 1;
780 CFA.dw_value_type = DW_EXPR_OFFSET;
781 CFA.dw_offset_or_block_len = uoff;
783 printf("DW_CFA_def_cfa_offset(%ju)\n", uoff);
786 case DW_CFA_def_cfa_expression:
788 CFA.dw_offset_relevant = 0;
789 CFA.dw_value_type = DW_EXPR_EXPRESSION;
790 CFA.dw_offset_or_block_len = _dwarf_decode_uleb128(&p);
791 CFA.dw_block_ptr = p;
792 p += CFA.dw_offset_or_block_len;
794 printf("DW_CFA_def_cfa_expression\n");
797 case DW_CFA_expression:
799 reg = _dwarf_decode_uleb128(&p);
800 CHECK_TABLE_SIZE(reg);
801 RL[reg].dw_offset_relevant = 0;
802 RL[reg].dw_value_type = DW_EXPR_EXPRESSION;
803 RL[reg].dw_offset_or_block_len =
804 _dwarf_decode_uleb128(&p);
805 RL[reg].dw_block_ptr = p;
806 p += RL[reg].dw_offset_or_block_len;
808 printf("DW_CFA_expression\n");
811 case DW_CFA_offset_extended_sf:
813 reg = _dwarf_decode_uleb128(&p);
814 soff = _dwarf_decode_sleb128(&p);
815 CHECK_TABLE_SIZE(reg);
816 RL[reg].dw_offset_relevant = 1;
817 RL[reg].dw_value_type = DW_EXPR_OFFSET;
818 RL[reg].dw_regnum = dbg->dbg_frame_cfa_value;
819 RL[reg].dw_offset_or_block_len = soff * daf;
821 printf("DW_CFA_offset_extended_sf(reg=%ju,soff=%jd)\n",
825 case DW_CFA_def_cfa_sf:
827 reg = _dwarf_decode_uleb128(&p);
828 soff = _dwarf_decode_sleb128(&p);
829 CFA.dw_offset_relevant = 1;
830 CFA.dw_value_type = DW_EXPR_OFFSET;
832 CFA.dw_offset_or_block_len = soff * daf;
834 printf("DW_CFA_def_cfa_sf(reg=%ju,soff=%jd)\n", reg,
838 case DW_CFA_def_cfa_offset_sf:
840 soff = _dwarf_decode_sleb128(&p);
841 CFA.dw_offset_relevant = 1;
842 CFA.dw_value_type = DW_EXPR_OFFSET;
843 CFA.dw_offset_or_block_len = soff * daf;
845 printf("DW_CFA_def_cfa_offset_sf(soff=%jd)\n", soff);
848 case DW_CFA_val_offset:
850 reg = _dwarf_decode_uleb128(&p);
851 uoff = _dwarf_decode_uleb128(&p);
852 CHECK_TABLE_SIZE(reg);
853 RL[reg].dw_offset_relevant = 1;
854 RL[reg].dw_value_type = DW_EXPR_VAL_OFFSET;
855 RL[reg].dw_regnum = dbg->dbg_frame_cfa_value;
856 RL[reg].dw_offset_or_block_len = uoff * daf;
858 printf("DW_CFA_val_offset(reg=%ju,uoff=%ju)\n", reg,
862 case DW_CFA_val_offset_sf:
864 reg = _dwarf_decode_uleb128(&p);
865 soff = _dwarf_decode_sleb128(&p);
866 CHECK_TABLE_SIZE(reg);
867 RL[reg].dw_offset_relevant = 1;
868 RL[reg].dw_value_type = DW_EXPR_VAL_OFFSET;
869 RL[reg].dw_regnum = dbg->dbg_frame_cfa_value;
870 RL[reg].dw_offset_or_block_len = soff * daf;
872 printf("DW_CFA_val_offset_sf(reg=%ju,soff=%jd)\n", reg,
876 case DW_CFA_val_expression:
878 reg = _dwarf_decode_uleb128(&p);
879 CHECK_TABLE_SIZE(reg);
880 RL[reg].dw_offset_relevant = 0;
881 RL[reg].dw_value_type = DW_EXPR_VAL_EXPRESSION;
882 RL[reg].dw_offset_or_block_len =
883 _dwarf_decode_uleb128(&p);
884 RL[reg].dw_block_ptr = p;
885 p += RL[reg].dw_offset_or_block_len;
887 printf("DW_CFA_val_expression\n");
891 DWARF_SET_ERROR(dbg, error,
892 DW_DLE_FRAME_INSTR_EXEC_ERROR);
893 ret = DW_DLE_FRAME_INSTR_EXEC_ERROR;
900 free(init_rt->rt3_rules);
903 free(saved_rt->rt3_rules);
913 #undef CHECK_TABLE_SIZE
917 _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts,
918 Dwarf_Unsigned len, Dwarf_Unsigned *count, Dwarf_Frame_Op *fop,
919 Dwarf_Frame_Op3 *fop3, Dwarf_Error *error)
923 uint64_t reg, reg2, uoff, soff, blen;
925 #define SET_BASE_OP(x) \
928 fop[*count].fp_base_op = (x) >> 6; \
930 fop3[*count].fp_base_op = (x) >> 6; \
933 #define SET_EXTENDED_OP(x) \
936 fop[*count].fp_extended_op = (x); \
938 fop3[*count].fp_extended_op = (x); \
941 #define SET_REGISTER(x) \
944 fop[*count].fp_register = (x); \
946 fop3[*count].fp_register = (x); \
949 #define SET_OFFSET(x) \
952 fop[*count].fp_offset = (x); \
954 fop3[*count].fp_offset_or_block_len = \
958 #define SET_INSTR_OFFSET(x) \
961 fop[*count].fp_instr_offset = (x); \
963 fop3[*count].fp_instr_offset = (x); \
966 #define SET_BLOCK_LEN(x) \
969 fop3[*count].fp_offset_or_block_len = \
973 #define SET_EXPR_BLOCK(addr, len) \
975 if (fop3 != NULL) { \
976 fop3[*count].fp_expr_block = \
977 malloc((size_t) (len)); \
978 if (fop3[*count].fp_expr_block == NULL) { \
979 DWARF_SET_ERROR(dbg, error, \
981 return (DW_DLE_MEMORY); \
983 memcpy(&fop3[*count].fp_expr_block, \
995 SET_INSTR_OFFSET(p - insts);
997 if (*p == DW_CFA_nop) {
1009 case DW_CFA_advance_loc:
1016 uoff = _dwarf_decode_uleb128(&p);
1019 case DW_CFA_restore:
1024 DWARF_SET_ERROR(dbg, error,
1025 DW_DLE_FRAME_INSTR_EXEC_ERROR);
1026 return (DW_DLE_FRAME_INSTR_EXEC_ERROR);
1033 SET_EXTENDED_OP(low6);
1036 case DW_CFA_set_loc:
1037 uoff = dbg->decode(&p, addr_size);
1040 case DW_CFA_advance_loc1:
1041 uoff = dbg->decode(&p, 1);
1044 case DW_CFA_advance_loc2:
1045 uoff = dbg->decode(&p, 2);
1048 case DW_CFA_advance_loc4:
1049 uoff = dbg->decode(&p, 4);
1052 case DW_CFA_offset_extended:
1053 case DW_CFA_def_cfa:
1054 case DW_CFA_val_offset:
1055 reg = _dwarf_decode_uleb128(&p);
1056 uoff = _dwarf_decode_uleb128(&p);
1060 case DW_CFA_restore_extended:
1061 case DW_CFA_undefined:
1062 case DW_CFA_same_value:
1063 case DW_CFA_def_cfa_register:
1064 reg = _dwarf_decode_uleb128(&p);
1067 case DW_CFA_register:
1068 reg = _dwarf_decode_uleb128(&p);
1069 reg2 = _dwarf_decode_uleb128(&p);
1073 case DW_CFA_remember_state:
1074 case DW_CFA_restore_state:
1076 case DW_CFA_def_cfa_offset:
1077 uoff = _dwarf_decode_uleb128(&p);
1080 case DW_CFA_def_cfa_expression:
1081 blen = _dwarf_decode_uleb128(&p);
1082 SET_BLOCK_LEN(blen);
1083 SET_EXPR_BLOCK(p, blen);
1086 case DW_CFA_expression:
1087 case DW_CFA_val_expression:
1088 reg = _dwarf_decode_uleb128(&p);
1089 blen = _dwarf_decode_uleb128(&p);
1091 SET_BLOCK_LEN(blen);
1092 SET_EXPR_BLOCK(p, blen);
1095 case DW_CFA_offset_extended_sf:
1096 case DW_CFA_def_cfa_sf:
1097 case DW_CFA_val_offset_sf:
1098 reg = _dwarf_decode_uleb128(&p);
1099 soff = _dwarf_decode_sleb128(&p);
1103 case DW_CFA_def_cfa_offset_sf:
1104 soff = _dwarf_decode_sleb128(&p);
1108 DWARF_SET_ERROR(dbg, error,
1109 DW_DLE_FRAME_INSTR_EXEC_ERROR);
1110 return (DW_DLE_FRAME_INSTR_EXEC_ERROR);
1116 return (DW_DLE_NONE);
1120 _dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts,
1121 Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt,
1124 Dwarf_Frame_Op *oplist;
1125 Dwarf_Unsigned count;
1128 ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count,
1130 if (ret != DW_DLE_NONE)
1133 if ((oplist = calloc(count, sizeof(Dwarf_Frame_Op))) == NULL) {
1134 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
1135 return (DW_DLE_MEMORY);
1138 ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count,
1139 oplist, NULL, error);
1140 if (ret != DW_DLE_NONE) {
1145 *ret_oplist = oplist;
1148 return (DW_DLE_NONE);
1152 _dwarf_frame_regtable_copy(Dwarf_Debug dbg, Dwarf_Regtable3 **dest,
1153 Dwarf_Regtable3 *src, Dwarf_Error *error)
1157 assert(dest != NULL);
1158 assert(src != NULL);
1160 if (*dest == NULL) {
1161 if ((*dest = malloc(sizeof(Dwarf_Regtable3))) == NULL) {
1162 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
1163 return (DW_DLE_MEMORY);
1165 (*dest)->rt3_reg_table_size = src->rt3_reg_table_size;
1166 (*dest)->rt3_rules = malloc(src->rt3_reg_table_size *
1167 sizeof(Dwarf_Regtable_Entry3));
1168 if ((*dest)->rt3_rules == NULL) {
1170 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
1171 return (DW_DLE_MEMORY);
1175 memcpy(&(*dest)->rt3_cfa_rule, &src->rt3_cfa_rule,
1176 sizeof(Dwarf_Regtable_Entry3));
1178 for (i = 0; i < (*dest)->rt3_reg_table_size &&
1179 i < src->rt3_reg_table_size; i++)
1180 memcpy(&(*dest)->rt3_rules[i], &src->rt3_rules[i],
1181 sizeof(Dwarf_Regtable_Entry3));
1183 for (; i < (*dest)->rt3_reg_table_size; i++)
1184 (*dest)->rt3_rules[i].dw_regnum =
1185 dbg->dbg_frame_undefined_value;
1187 return (DW_DLE_NONE);
1191 _dwarf_frame_get_internal_table(Dwarf_Fde fde, Dwarf_Addr pc_req,
1192 Dwarf_Regtable3 **ret_rt, Dwarf_Addr *ret_row_pc, Dwarf_Error *error)
1196 Dwarf_Regtable3 *rt;
1200 assert(ret_rt != NULL);
1203 assert(dbg != NULL);
1205 rt = dbg->dbg_internal_reg_table;
1207 /* Clear the content of regtable from previous run. */
1208 memset(&rt->rt3_cfa_rule, 0, sizeof(Dwarf_Regtable_Entry3));
1209 memset(rt->rt3_rules, 0, rt->rt3_reg_table_size *
1210 sizeof(Dwarf_Regtable_Entry3));
1212 /* Set rules to initial values. */
1213 for (i = 0; i < rt->rt3_reg_table_size; i++)
1214 rt->rt3_rules[i].dw_regnum = dbg->dbg_frame_rule_initial_value;
1216 /* Run initial instructions in CIE. */
1218 assert(cie != NULL);
1219 ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize,
1220 cie->cie_initinst, cie->cie_instlen, cie->cie_caf, cie->cie_daf, 0,
1221 ~0ULL, &row_pc, error);
1222 if (ret != DW_DLE_NONE)
1225 /* Run instructions in FDE. */
1226 if (pc_req >= fde->fde_initloc) {
1227 ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize,
1228 fde->fde_inst, fde->fde_instlen, cie->cie_caf,
1229 cie->cie_daf, fde->fde_initloc, pc_req, &row_pc, error);
1230 if (ret != DW_DLE_NONE)
1235 *ret_row_pc = row_pc;
1237 return (DW_DLE_NONE);
1241 _dwarf_frame_cleanup(Dwarf_Debug dbg)
1243 Dwarf_Regtable3 *rt;
1245 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ);
1247 if (dbg->dbg_internal_reg_table) {
1248 rt = dbg->dbg_internal_reg_table;
1249 free(rt->rt3_rules);
1251 dbg->dbg_internal_reg_table = NULL;
1254 if (dbg->dbg_frame) {
1255 _dwarf_frame_section_cleanup(dbg->dbg_frame);
1256 dbg->dbg_frame = NULL;
1259 if (dbg->dbg_eh_frame) {
1260 _dwarf_frame_section_cleanup(dbg->dbg_eh_frame);
1261 dbg->dbg_eh_frame = NULL;
1266 _dwarf_frame_section_load(Dwarf_Debug dbg, Dwarf_Error *error)
1270 if ((ds = _dwarf_find_section(dbg, ".debug_frame")) != NULL) {
1271 return (_dwarf_frame_section_init(dbg, &dbg->dbg_frame,
1275 return (DW_DLE_NONE);
1279 _dwarf_frame_section_load_eh(Dwarf_Debug dbg, Dwarf_Error *error)
1283 if ((ds = _dwarf_find_section(dbg, ".eh_frame")) != NULL) {
1284 return (_dwarf_frame_section_init(dbg, &dbg->dbg_eh_frame,
1288 return (DW_DLE_NONE);
1292 _dwarf_frame_params_init(Dwarf_Debug dbg)
1295 /* Initialise call frame related parameters. */
1296 dbg->dbg_frame_rule_table_size = DW_FRAME_LAST_REG_NUM;
1297 dbg->dbg_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE;
1298 dbg->dbg_frame_cfa_value = DW_FRAME_CFA_COL3;
1299 dbg->dbg_frame_same_value = DW_FRAME_SAME_VAL;
1300 dbg->dbg_frame_undefined_value = DW_FRAME_UNDEFINED_VAL;
1304 _dwarf_frame_interal_table_init(Dwarf_Debug dbg, Dwarf_Error *error)
1306 Dwarf_Regtable3 *rt;
1308 if (dbg->dbg_internal_reg_table != NULL)
1309 return (DW_DLE_NONE);
1311 /* Initialise internal register table. */
1312 if ((rt = calloc(1, sizeof(Dwarf_Regtable3))) == NULL) {
1313 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
1314 return (DW_DLE_MEMORY);
1317 rt->rt3_reg_table_size = dbg->dbg_frame_rule_table_size;
1318 if ((rt->rt3_rules = calloc(rt->rt3_reg_table_size,
1319 sizeof(Dwarf_Regtable_Entry3))) == NULL) {
1321 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
1322 return (DW_DLE_MEMORY);
1325 dbg->dbg_internal_reg_table = rt;
1327 return (DW_DLE_NONE);
1330 #define _FDE_INST_INIT_SIZE 128
1333 _dwarf_frame_fde_add_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1,
1334 Dwarf_Unsigned val2, Dwarf_Error *error)
1337 uint8_t high2, low6;
1341 #define ds_data fde_inst
1342 #define ds_cap fde_instcap
1343 #define ds_size fde_instlen
1345 assert(fde != NULL && fde->fde_dbg != NULL);
1348 if (fde->fde_inst == NULL) {
1349 fde->fde_instcap = _FDE_INST_INIT_SIZE;
1350 fde->fde_instlen = 0;
1351 if ((fde->fde_inst = malloc((size_t) fde->fde_instcap)) ==
1353 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
1354 return (DW_DLE_MEMORY);
1357 assert(fde->fde_instcap != 0);
1359 RCHECK(WRITE_VALUE(op, 1));
1360 if (op == DW_CFA_nop)
1361 return (DW_DLE_NONE);
1368 case DW_CFA_advance_loc:
1369 case DW_CFA_restore:
1372 RCHECK(WRITE_ULEB128(val1));
1375 DWARF_SET_ERROR(dbg, error,
1376 DW_DLE_FRAME_INSTR_EXEC_ERROR);
1377 return (DW_DLE_FRAME_INSTR_EXEC_ERROR);
1379 return (DW_DLE_NONE);
1383 case DW_CFA_set_loc:
1384 RCHECK(WRITE_VALUE(val1, dbg->dbg_pointer_size));
1386 case DW_CFA_advance_loc1:
1387 RCHECK(WRITE_VALUE(val1, 1));
1389 case DW_CFA_advance_loc2:
1390 RCHECK(WRITE_VALUE(val1, 2));
1392 case DW_CFA_advance_loc4:
1393 RCHECK(WRITE_VALUE(val1, 4));
1395 case DW_CFA_offset_extended:
1396 case DW_CFA_def_cfa:
1397 case DW_CFA_register:
1398 RCHECK(WRITE_ULEB128(val1));
1399 RCHECK(WRITE_ULEB128(val2));
1401 case DW_CFA_restore_extended:
1402 case DW_CFA_undefined:
1403 case DW_CFA_same_value:
1404 case DW_CFA_def_cfa_register:
1405 case DW_CFA_def_cfa_offset:
1406 RCHECK(WRITE_ULEB128(val1));
1408 case DW_CFA_remember_state:
1409 case DW_CFA_restore_state:
1412 DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_INSTR_EXEC_ERROR);
1413 return (DW_DLE_FRAME_INSTR_EXEC_ERROR);
1416 return (DW_DLE_NONE);
1428 _dwarf_frame_gen_cie(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_P_Cie cie,
1435 assert(dbg != NULL && ds != NULL && cie != NULL);
1437 cie->cie_offset = offset = ds->ds_size;
1438 cie->cie_length = 0;
1439 cie->cie_version = 1;
1441 /* Length placeholder. */
1442 RCHECK(WRITE_VALUE(cie->cie_length, 4));
1444 /* .debug_frame use CIE id ~0. */
1445 RCHECK(WRITE_VALUE(~0U, 4));
1447 /* .debug_frame version is 1. (DWARF2) */
1448 RCHECK(WRITE_VALUE(cie->cie_version, 1));
1450 /* Write augmentation, if present. */
1451 if (cie->cie_augment != NULL)
1452 RCHECK(WRITE_BLOCK(cie->cie_augment,
1453 strlen((char *) cie->cie_augment) + 1));
1455 RCHECK(WRITE_VALUE(0, 1));
1457 /* Write caf, daf and ra. */
1458 RCHECK(WRITE_ULEB128(cie->cie_caf));
1459 RCHECK(WRITE_SLEB128(cie->cie_daf));
1460 RCHECK(WRITE_VALUE(cie->cie_ra, 1));
1462 /* Write initial instructions, if present. */
1463 if (cie->cie_initinst != NULL)
1464 RCHECK(WRITE_BLOCK(cie->cie_initinst, cie->cie_instlen));
1467 len = ds->ds_size - cie->cie_offset - 4;
1468 cie->cie_length = roundup(len, dbg->dbg_pointer_size);
1469 while (len++ < cie->cie_length)
1470 RCHECK(WRITE_VALUE(DW_CFA_nop, 1));
1472 /* Fill in the length field. */
1473 dbg->write(ds->ds_data, &offset, cie->cie_length, 4);
1475 return (DW_DLE_NONE);
1482 _dwarf_frame_gen_fde(Dwarf_P_Debug dbg, Dwarf_P_Section ds,
1483 Dwarf_Rel_Section drs, Dwarf_P_Fde fde, Dwarf_Error *error)
1489 assert(dbg != NULL && ds != NULL && drs != NULL);
1490 assert(fde != NULL && fde->fde_cie != NULL);
1492 fde->fde_offset = offset = ds->ds_size;
1493 fde->fde_length = 0;
1494 fde->fde_cieoff = fde->fde_cie->cie_offset;
1496 /* Length placeholder. */
1497 RCHECK(WRITE_VALUE(fde->fde_length, 4));
1499 /* Write CIE pointer. */
1500 RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4,
1501 ds->ds_size, 0, fde->fde_cieoff, ".debug_frame", error));
1503 /* Write FDE initial location. */
1504 RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc,
1505 dbg->dbg_pointer_size, ds->ds_size, fde->fde_symndx,
1506 fde->fde_initloc, NULL, error));
1509 * Write FDE address range. Use a pair of relocation entries if
1510 * application provided end symbol index. Otherwise write the
1511 * length without assoicating any relocation info.
1513 if (fde->fde_esymndx > 0)
1514 RCHECK(_dwarf_reloc_entry_add_pair(dbg, drs, ds,
1515 dbg->dbg_pointer_size, ds->ds_size, fde->fde_symndx,
1516 fde->fde_esymndx, fde->fde_initloc, fde->fde_eoff, error));
1518 RCHECK(WRITE_VALUE(fde->fde_adrange, dbg->dbg_pointer_size));
1520 /* Write FDE frame instructions. */
1521 RCHECK(WRITE_BLOCK(fde->fde_inst, fde->fde_instlen));
1524 len = ds->ds_size - fde->fde_offset - 4;
1525 fde->fde_length = roundup(len, dbg->dbg_pointer_size);
1526 while (len++ < fde->fde_length)
1527 RCHECK(WRITE_VALUE(DW_CFA_nop, 1));
1529 /* Fill in the length field. */
1530 dbg->write(ds->ds_data, &offset, fde->fde_length, 4);
1532 return (DW_DLE_NONE);
1539 _dwarf_frame_gen(Dwarf_P_Debug dbg, Dwarf_Error *error)
1542 Dwarf_Rel_Section drs;
1547 if (STAILQ_EMPTY(&dbg->dbgp_cielist))
1548 return (DW_DLE_NONE);
1550 /* Create .debug_frame section. */
1551 if ((ret = _dwarf_section_init(dbg, &ds, ".debug_frame", 0, error)) !=
1555 /* Create relocation section for .debug_frame */
1556 RCHECK(_dwarf_reloc_section_init(dbg, &drs, ds, error));
1558 /* Generate list of CIE. */
1559 STAILQ_FOREACH(cie, &dbg->dbgp_cielist, cie_next)
1560 RCHECK(_dwarf_frame_gen_cie(dbg, ds, cie, error));
1562 /* Generate list of FDE. */
1563 STAILQ_FOREACH(fde, &dbg->dbgp_fdelist, fde_next)
1564 RCHECK(_dwarf_frame_gen_fde(dbg, ds, drs, fde, error));
1566 /* Inform application the creation of .debug_frame ELF section. */
1567 RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error));
1569 /* Finalize relocation section for .debug_frame */
1570 RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error));
1572 return (DW_DLE_NONE);
1575 _dwarf_reloc_section_free(dbg, &drs);
1578 _dwarf_section_free(dbg, &ds);
1584 _dwarf_frame_pro_cleanup(Dwarf_P_Debug dbg)
1586 Dwarf_P_Cie cie, tcie;
1587 Dwarf_P_Fde fde, tfde;
1589 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE);
1591 STAILQ_FOREACH_SAFE(cie, &dbg->dbgp_cielist, cie_next, tcie) {
1592 STAILQ_REMOVE(&dbg->dbgp_cielist, cie, _Dwarf_Cie, cie_next);
1593 if (cie->cie_augment)
1594 free(cie->cie_augment);
1595 if (cie->cie_initinst)
1596 free(cie->cie_initinst);
1599 dbg->dbgp_cielen = 0;
1601 STAILQ_FOREACH_SAFE(fde, &dbg->dbgp_fdelist, fde_next, tfde) {
1602 STAILQ_REMOVE(&dbg->dbgp_fdelist, fde, _Dwarf_Fde, fde_next);
1603 if (fde->fde_inst != NULL)
1604 free(fde->fde_inst);
1607 dbg->dbgp_fdelen = 0;