diff options
Diffstat (limited to 'gdb/dwarf2-frame.c')
-rw-r--r-- | gdb/dwarf2-frame.c | 280 |
1 files changed, 128 insertions, 152 deletions
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index d7f985b..f8e6522 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -38,6 +38,10 @@ #include "ax.h" #include "dwarf2loc.h" #include "dwarf2-frame-tailcall.h" +#if GDB_SELF_TEST +#include "selftest.h" +#include "selftest-arch.h" +#endif struct comp_unit; @@ -169,67 +173,11 @@ static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding, which is unused in that case. */ #define cfa_exp_len cfa_reg -/* Assert that the register set RS is large enough to store gdbarch_num_regs - columns. If necessary, enlarge the register set. */ - -void -dwarf2_frame_state_alloc_regs (struct dwarf2_frame_state_reg_info *rs, - int num_regs) +dwarf2_frame_state::dwarf2_frame_state (CORE_ADDR pc_, struct dwarf2_cie *cie) + : pc (pc_), data_align (cie->data_alignment_factor), + code_align (cie->code_alignment_factor), + retaddr_column (cie->return_address_register) { - size_t size = sizeof (struct dwarf2_frame_state_reg); - - if (num_regs <= rs->num_regs) - return; - - rs->reg = (struct dwarf2_frame_state_reg *) - xrealloc (rs->reg, num_regs * size); - - /* Initialize newly allocated registers. */ - memset (rs->reg + rs->num_regs, 0, (num_regs - rs->num_regs) * size); - rs->num_regs = num_regs; -} - -/* Copy the register columns in register set RS into newly allocated - memory and return a pointer to this newly created copy. */ - -static struct dwarf2_frame_state_reg * -dwarf2_frame_state_copy_regs (struct dwarf2_frame_state_reg_info *rs) -{ - size_t size = rs->num_regs * sizeof (struct dwarf2_frame_state_reg); - struct dwarf2_frame_state_reg *reg; - - reg = (struct dwarf2_frame_state_reg *) xmalloc (size); - memcpy (reg, rs->reg, size); - - return reg; -} - -/* Release the memory allocated to register set RS. */ - -static void -dwarf2_frame_state_free_regs (struct dwarf2_frame_state_reg_info *rs) -{ - if (rs) - { - dwarf2_frame_state_free_regs (rs->prev); - - xfree (rs->reg); - xfree (rs); - } -} - -/* Release the memory allocated to the frame state FS. */ - -static void -dwarf2_frame_state_free (void *p) -{ - struct dwarf2_frame_state *fs = (struct dwarf2_frame_state *) p; - - dwarf2_frame_state_free_regs (fs->initial.prev); - dwarf2_frame_state_free_regs (fs->regs.prev); - xfree (fs->initial.reg); - xfree (fs->regs.reg); - xfree (fs); } @@ -254,7 +202,7 @@ dwarf2_restore_rule (struct gdbarch *gdbarch, ULONGEST reg_num, gdb_assert (fs->initial.reg); reg = dwarf2_frame_adjust_regnum (gdbarch, reg_num, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); /* Check if this register was explicitly initialized in the CIE initial instructions. If not, default the rule to @@ -408,7 +356,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; fs->regs.reg[reg].loc.offset = offset; } @@ -452,7 +400,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; fs->regs.reg[reg].loc.offset = offset; break; @@ -465,14 +413,14 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, case DW_CFA_undefined: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNDEFINED; break; case DW_CFA_same_value: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAME_VALUE; break; @@ -481,7 +429,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); utmp = dwarf2_frame_adjust_regnum (gdbarch, utmp, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG; fs->regs.reg[reg].loc.reg = utmp; break; @@ -490,9 +438,7 @@ execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, { struct dwarf2_frame_state_reg_info *new_rs; - new_rs = XNEW (struct dwarf2_frame_state_reg_info); - *new_rs = fs->regs; - fs->regs.reg = dwarf2_frame_state_copy_regs (&fs->regs); + new_rs = new dwarf2_frame_state_reg_info (fs->regs); fs->regs.prev = new_rs; } break; @@ -508,11 +454,7 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), paddress (gdbarch, fs->pc)); } else - { - xfree (fs->regs.reg); - fs->regs = *old_rs; - xfree (old_rs); - } + fs->regs = std::move (*old_rs); } break; @@ -559,10 +501,10 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), case DW_CFA_expression: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); - fs->regs.reg[reg].loc.exp = insn_ptr; - fs->regs.reg[reg].exp_len = utmp; + fs->regs.reg[reg].loc.exp.start = insn_ptr; + fs->regs.reg[reg].loc.exp.len = utmp; fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_EXP; insn_ptr += utmp; break; @@ -572,14 +514,14 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset); offset *= fs->data_align; - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; fs->regs.reg[reg].loc.offset = offset; break; case DW_CFA_val_offset: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET; @@ -588,7 +530,7 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), case DW_CFA_val_offset_sf: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset); offset *= fs->data_align; fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET; @@ -597,10 +539,10 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), case DW_CFA_val_expression: insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, ®); - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); - fs->regs.reg[reg].loc.exp = insn_ptr; - fs->regs.reg[reg].exp_len = utmp; + fs->regs.reg[reg].loc.exp.start = insn_ptr; + fs->regs.reg[reg].loc.exp.len = utmp; fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_EXP; insn_ptr += utmp; break; @@ -630,7 +572,7 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p); insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp); offset = utmp * fs->data_align; - dwarf2_frame_state_alloc_regs (&fs->regs, reg + 1); + fs->regs.alloc_regs (reg + 1); fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET; fs->regs.reg[reg].loc.offset = -offset; break; @@ -654,12 +596,73 @@ bad CFI data; mismatched DW_CFA_restore_state at %s"), if (fs->initial.reg == NULL) { /* Don't allow remember/restore between CIE and FDE programs. */ - dwarf2_frame_state_free_regs (fs->regs.prev); + delete fs->regs.prev; fs->regs.prev = NULL; } return insn_ptr; } + +#if GDB_SELF_TEST + +namespace selftests { + +/* Unit test to function execute_cfa_program. */ + +static void +execute_cfa_program_test (struct gdbarch *gdbarch) +{ + struct dwarf2_fde fde; + struct dwarf2_cie cie; + + memset (&fde, 0, sizeof fde); + memset (&cie, 0, sizeof cie); + + cie.data_alignment_factor = -4; + cie.code_alignment_factor = 2; + fde.cie = &cie; + + dwarf2_frame_state fs (0, fde.cie); + + gdb_byte insns[] = + { + DW_CFA_def_cfa, 1, 4, /* DW_CFA_def_cfa: r1 ofs 4 */ + DW_CFA_offset | 0x2, 1, /* DW_CFA_offset: r2 at cfa-4 */ + DW_CFA_remember_state, + DW_CFA_restore_state, + }; + + const gdb_byte *insn_end = insns + sizeof (insns); + const gdb_byte *out = execute_cfa_program (&fde, insns, insn_end, gdbarch, + 0, &fs); + + SELF_CHECK (out == insn_end); + SELF_CHECK (fs.pc == 0); + + /* The instructions above only use r1 and r2, but the register numbers + used are adjusted by dwarf2_frame_adjust_regnum. */ + auto r1 = dwarf2_frame_adjust_regnum (gdbarch, 1, fde.eh_frame_p); + auto r2 = dwarf2_frame_adjust_regnum (gdbarch, 2, fde.eh_frame_p); + + SELF_CHECK (fs.regs.num_regs == (std::max (r1, r2) + 1)); + + SELF_CHECK (fs.regs.reg[r2].how == DWARF2_FRAME_REG_SAVED_OFFSET); + SELF_CHECK (fs.regs.reg[r2].loc.offset == -4); + + for (auto i = 0; i < fs.regs.num_regs; i++) + if (i != r2) + SELF_CHECK (fs.regs.reg[i].how == DWARF2_FRAME_REG_UNSPECIFIED); + + SELF_CHECK (fs.regs.cfa_reg == 1); + SELF_CHECK (fs.regs.cfa_offset == 4); + SELF_CHECK (fs.regs.cfa_how == CFA_REG_OFFSET); + SELF_CHECK (fs.regs.cfa_exp == NULL); + SELF_CHECK (fs.regs.prev == NULL); +} + +} // namespace selftests +#endif /* GDB_SELF_TEST */ + /* Architecture-specific operations. */ @@ -865,21 +868,14 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc, { struct dwarf2_fde *fde; CORE_ADDR text_offset; - struct dwarf2_frame_state fs; - - memset (&fs, 0, sizeof (struct dwarf2_frame_state)); - - fs.pc = pc; + CORE_ADDR pc1 = pc; /* Find the correct FDE. */ - fde = dwarf2_frame_find_fde (&fs.pc, &text_offset); + fde = dwarf2_frame_find_fde (&pc1, &text_offset); if (fde == NULL) error (_("Could not compute CFA; needed to translate this expression")); - /* Extract any interesting information from the CIE. */ - fs.data_align = fde->cie->data_alignment_factor; - fs.code_align = fde->cie->code_alignment_factor; - fs.retaddr_column = fde->cie->return_address_register; + dwarf2_frame_state fs (pc1, fde->cie); /* Check for "quirks" - known bugs in producers. */ dwarf2_frame_find_quirks (&fs, fde); @@ -890,7 +886,6 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc, /* Save the initialized register set. */ fs.initial = fs.regs; - fs.initial.reg = dwarf2_frame_state_copy_regs (&fs.regs); /* Then decode the insns in the FDE up to our target PC. */ execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs); @@ -965,25 +960,13 @@ struct dwarf2_frame_cache int entry_cfa_sp_offset_p; }; -/* A cleanup that sets a pointer to NULL. */ - -static void -clear_pointer_cleanup (void *arg) -{ - void **ptr = (void **) arg; - - *ptr = NULL; -} - static struct dwarf2_frame_cache * dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) { - struct cleanup *reset_cache_cleanup, *old_chain; struct gdbarch *gdbarch = get_frame_arch (this_frame); const int num_regs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); struct dwarf2_frame_cache *cache; - struct dwarf2_frame_state *fs; struct dwarf2_fde *fde; CORE_ADDR entry_pc; const gdb_byte *instr; @@ -995,11 +978,6 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) cache = FRAME_OBSTACK_ZALLOC (struct dwarf2_frame_cache); cache->reg = FRAME_OBSTACK_CALLOC (num_regs, struct dwarf2_frame_state_reg); *this_cache = cache; - reset_cache_cleanup = make_cleanup (clear_pointer_cleanup, this_cache); - - /* Allocate and initialize the frame state. */ - fs = XCNEW (struct dwarf2_frame_state); - old_chain = make_cleanup (dwarf2_frame_state_free, fs); /* Unwind the PC. @@ -1016,41 +994,39 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) get_frame_address_in_block does just this. It's not clear how reliable the method is though; there is the potential for the register state pre-call being different to that on return. */ - fs->pc = get_frame_address_in_block (this_frame); + CORE_ADDR pc1 = get_frame_address_in_block (this_frame); /* Find the correct FDE. */ - fde = dwarf2_frame_find_fde (&fs->pc, &cache->text_offset); + fde = dwarf2_frame_find_fde (&pc1, &cache->text_offset); gdb_assert (fde != NULL); - /* Extract any interesting information from the CIE. */ - fs->data_align = fde->cie->data_alignment_factor; - fs->code_align = fde->cie->code_alignment_factor; - fs->retaddr_column = fde->cie->return_address_register; + /* Allocate and initialize the frame state. */ + struct dwarf2_frame_state fs (pc1, fde->cie); + cache->addr_size = fde->cie->addr_size; /* Check for "quirks" - known bugs in producers. */ - dwarf2_frame_find_quirks (fs, fde); + dwarf2_frame_find_quirks (&fs, fde); /* First decode all the insns in the CIE. */ execute_cfa_program (fde, fde->cie->initial_instructions, fde->cie->end, gdbarch, - get_frame_address_in_block (this_frame), fs); + get_frame_address_in_block (this_frame), &fs); /* Save the initialized register set. */ - fs->initial = fs->regs; - fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs); + fs.initial = fs.regs; if (get_frame_func_if_available (this_frame, &entry_pc)) { /* Decode the insns in the FDE up to the entry PC. */ instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, - entry_pc, fs); + entry_pc, &fs); - if (fs->regs.cfa_how == CFA_REG_OFFSET - && (dwarf_reg_to_regnum (gdbarch, fs->regs.cfa_reg) + if (fs.regs.cfa_how == CFA_REG_OFFSET + && (dwarf_reg_to_regnum (gdbarch, fs.regs.cfa_reg) == gdbarch_sp_regnum (gdbarch))) { - cache->entry_cfa_sp_offset = fs->regs.cfa_offset; + cache->entry_cfa_sp_offset = fs.regs.cfa_offset; cache->entry_cfa_sp_offset_p = 1; } } @@ -1059,24 +1035,24 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) /* Then decode the insns in the FDE up to our target PC. */ execute_cfa_program (fde, instr, fde->end, gdbarch, - get_frame_address_in_block (this_frame), fs); + get_frame_address_in_block (this_frame), &fs); TRY { /* Calculate the CFA. */ - switch (fs->regs.cfa_how) + switch (fs.regs.cfa_how) { case CFA_REG_OFFSET: - cache->cfa = read_addr_from_reg (this_frame, fs->regs.cfa_reg); - if (fs->armcc_cfa_offsets_reversed) - cache->cfa -= fs->regs.cfa_offset; + cache->cfa = read_addr_from_reg (this_frame, fs.regs.cfa_reg); + if (fs.armcc_cfa_offsets_reversed) + cache->cfa -= fs.regs.cfa_offset; else - cache->cfa += fs->regs.cfa_offset; + cache->cfa += fs.regs.cfa_offset; break; case CFA_EXP: cache->cfa = - execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len, + execute_stack_op (fs.regs.cfa_exp, fs.regs.cfa_exp_len, cache->addr_size, cache->text_offset, this_frame, 0, 0); break; @@ -1090,8 +1066,6 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) if (ex.error == NOT_AVAILABLE_ERROR) { cache->unavailable_retaddr = 1; - do_cleanups (old_chain); - discard_cleanups (reset_cache_cleanup); return cache; } @@ -1114,7 +1088,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) { int column; /* CFI speak for "register number". */ - for (column = 0; column < fs->regs.num_regs; column++) + for (column = 0; column < fs.regs.num_regs; column++) { /* Use the GDB register number as the destination index. */ int regnum = dwarf_reg_to_regnum (gdbarch, column); @@ -1134,16 +1108,16 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) problems when a debug info register falls outside of the table. We need a way of iterating through all the valid DWARF2 register numbers. */ - if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED) + if (fs.regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED) { if (cache->reg[regnum].how == DWARF2_FRAME_REG_UNSPECIFIED) complaint (&symfile_complaints, _("\ incomplete CFI data; unspecified registers (e.g., %s) at %s"), gdbarch_register_name (gdbarch, regnum), - paddress (gdbarch, fs->pc)); + paddress (gdbarch, fs.pc)); } else - cache->reg[regnum] = fs->regs.reg[column]; + cache->reg[regnum] = fs.regs.reg[column]; } } @@ -1158,7 +1132,7 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), || cache->reg[regnum].how == DWARF2_FRAME_REG_RA_OFFSET) { struct dwarf2_frame_state_reg *retaddr_reg = - &fs->regs.reg[fs->retaddr_column]; + &fs.regs.reg[fs.retaddr_column]; /* It seems rather bizarre to specify an "empty" column as the return adress column. However, this is exactly @@ -1167,7 +1141,7 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), register corresponding to the return address column. Incidentally, that's how we should treat a return address column specifying "same value" too. */ - if (fs->retaddr_column < fs->regs.num_regs + if (fs.retaddr_column < fs.regs.num_regs && retaddr_reg->how != DWARF2_FRAME_REG_UNSPECIFIED && retaddr_reg->how != DWARF2_FRAME_REG_SAME_VALUE) { @@ -1180,12 +1154,12 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), { if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA) { - cache->reg[regnum].loc.reg = fs->retaddr_column; + cache->reg[regnum].loc.reg = fs.retaddr_column; cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG; } else { - cache->retaddr_reg.loc.reg = fs->retaddr_column; + cache->retaddr_reg.loc.reg = fs.retaddr_column; cache->retaddr_reg.how = DWARF2_FRAME_REG_SAVED_REG; } } @@ -1193,12 +1167,10 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), } } - if (fs->retaddr_column < fs->regs.num_regs - && fs->regs.reg[fs->retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED) + if (fs.retaddr_column < fs.regs.num_regs + && fs.regs.reg[fs.retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED) cache->undefined_retaddr = 1; - do_cleanups (old_chain); - discard_cleanups (reset_cache_cleanup); return cache; } @@ -1286,8 +1258,8 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache, return frame_unwind_got_register (this_frame, regnum, realnum); case DWARF2_FRAME_REG_SAVED_EXP: - addr = execute_stack_op (cache->reg[regnum].loc.exp, - cache->reg[regnum].exp_len, + addr = execute_stack_op (cache->reg[regnum].loc.exp.start, + cache->reg[regnum].loc.exp.len, cache->addr_size, cache->text_offset, this_frame, cache->cfa, 1); return frame_unwind_got_memory (this_frame, regnum, addr); @@ -1297,8 +1269,8 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache, return frame_unwind_got_constant (this_frame, regnum, addr); case DWARF2_FRAME_REG_SAVED_VAL_EXP: - addr = execute_stack_op (cache->reg[regnum].loc.exp, - cache->reg[regnum].exp_len, + addr = execute_stack_op (cache->reg[regnum].loc.exp.start, + cache->reg[regnum].loc.exp.len, cache->addr_size, cache->text_offset, this_frame, cache->cfa, 1); return frame_unwind_got_constant (this_frame, regnum, addr); @@ -2432,4 +2404,8 @@ _initialize_dwarf2_frame (void) { dwarf2_frame_data = gdbarch_data_register_pre_init (dwarf2_frame_init); dwarf2_frame_objfile_data = register_objfile_data (); + +#if GDB_SELF_TEST + register_self_test_foreach_arch (selftests::execute_cfa_program_test); +#endif } |