diff options
Diffstat (limited to 'gdb/dwarf2-frame.c')
-rw-r--r-- | gdb/dwarf2-frame.c | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 6e420cd..59f4481 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -99,19 +99,18 @@ static struct dwarf2_fde *dwarf2_frame_find_fde (CORE_ADDR *pc); enum dwarf2_reg_rule { - /* Make certain that 0 maps onto the correct enum value - the + /* Make certain that 0 maps onto the correct enum value; the corresponding structure is being initialized using memset zero. This indicates that CFI didn't provide any information at all - about a register - leaving how to obtain it's value totally + about a register, leaving how to obtain its value totally unspecified. */ REG_UNSPECIFIED = 0, /* The term "undefined" comes from the DWARF2 CFI spec which this - code is moddeling - it indicates that the register's value is - "undefined". */ - /* NOTE: cagney/2003-09-08: GCC uses the less formal term "unsaved" - - it's definition is a combination of REG_UNDEFINED and - REG_UNSPECIFIED - the failure to differentiate the two helps - explain a few problems with the CFI GCC outputs. */ + code is moddeling; it indicates that the register's value is + "undefined". GCC uses the less formal term "unsaved". Its + definition is a combination of REG_UNDEFINED and REG_UNSPECIFIED. + The failure to differentiate the two helps explain a few problems + with the CFI generated by GCC. */ REG_UNDEFINED, REG_SAVED_OFFSET, REG_SAVED_REG, @@ -500,18 +499,15 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) to abort), the compiler might optimize away the instruction at NEXT_FRAME's return address. As a result the return address will point at some random instruction, and the CFI for that - instruction is probably wortless to us. GCC's unwinder solves + instruction is probably worthless to us. GCC's unwinder solves this problem by substracting 1 from the return address to get an address in the middle of a presumed call instruction (or the instruction in the associated delay slot). This should only be done for "normal" frames and not for resume-type frames (signal - handlers, sentinel frames, dummy frames). - - frame_unwind_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. */ + handlers, sentinel frames, dummy frames). The function + frame_unwind_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 = frame_unwind_address_in_block (next_frame); /* Find the correct FDE. */ @@ -555,6 +551,7 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) unspecified. */ { int regnum; + for (regnum = 0; regnum < num_regs; regnum++) cache->reg[regnum].how = REG_UNSPECIFIED; } @@ -563,6 +560,7 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) location information in the cache. */ { int column; /* CFI speak for "register number". */ + for (column = 0; column < fs->regs.num_regs; column++) { int regnum; @@ -573,9 +571,10 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) RETADDR_COLUMN corresponds to a real register (and, worse, that isn't the PC_REGNUM)? I'm guessing that the PC_REGNUM further down is trying to handle this. That - can't be right though - PC_REGNUM may not be valid (it - can be -ve). I think, instead when RETADDR_COLUM isn't a - real register, it should map itself onto frame_pc_unwind. */ + can't be right though; PC_REGNUM may not be valid (it can + be negative). I think, instead when RETADDR_COLUM isn't + a real register, it should map itself onto + frame_pc_unwind. */ continue; /* Use the GDB register number as the destination index. */ @@ -586,15 +585,15 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) continue; /* NOTE: cagney/2003-09-05: CFI should specify the disposition - of all debug info registers. If it doesn't complain (but - not too loudly). It turns out that GCC, assumes that an + of all debug info registers. If it doesn't, complain (but + not too loudly). It turns out that GCC assumes that an unspecified register implies "same value" when CFI (draft 7) specifies nothing at all. Such a register could equally be interpreted as "undefined". Also note that this check - isn't sufficient - it only checks that all registers in the - range [0 .. max column] are specified - and won't detect + isn't sufficient; it only checks that all registers in the + range [0 .. max column] are specified, and won't detect problems when a debug info register falls outside of the - table. Need a way of iterating through all the valid + table. We need a way of iterating through all the valid DWARF2 register numbers. */ if (fs->regs.reg[column].how == REG_UNSPECIFIED) complaint (&symfile_complaints, @@ -606,27 +605,26 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) } /* Store the location of the return addess. If the return address - column (adjusted) is not the same as gdb's PC_REGNUM, then this - implies a copy from the ra column register. */ + column (adjusted) is not the same as GDB's PC_REGNUM, then this + implies a copy from the return address column register. */ if (fs->retaddr_column < fs->regs.num_regs && fs->regs.reg[fs->retaddr_column].how != REG_UNDEFINED) { - /* See comment above about a possibly -ve PC_REGNUM. If this - assertion fails, it's a problem with this code and not the - architecture. */ + /* See comment above about a possibly negative PC_REGNUM. If + this assertion fails, it's a problem with this code and not + the architecture. */ gdb_assert (PC_REGNUM >= 0); cache->reg[PC_REGNUM] = fs->regs.reg[fs->retaddr_column]; } else { - int reg = DWARF2_REG_TO_REGNUM (fs->retaddr_column); - if (reg != PC_REGNUM) + if (DWARF2_REG_TO_REGNUM (fs->retaddr_column) != PC_REGNUM) { - /* See comment above about PC_REGNUM being -ve. If this - assertion fails, it's a problem with this code and not - the architecture. */ + /* See comment above about PC_REGNUM being negative. If + this assertion fails, it's a problem with this code and + not the architecture. */ gdb_assert (PC_REGNUM >= 0); - cache->reg[PC_REGNUM].loc.reg = reg; + cache->reg[PC_REGNUM].loc.reg = fs->retaddr_column; cache->reg[PC_REGNUM].how = REG_SAVED_REG; } } @@ -660,7 +658,7 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache, { case REG_UNDEFINED: /* If CFI explicitly specified that the value isn't defined, - mark it as optimized away - the value isn't available. */ + mark it as optimized away; the value isn't available. */ *optimizedp = 1; *lvalp = not_lval; *addrp = 0; @@ -681,8 +679,8 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache, /* FIXME: cagney/2003-07-07: I don't understand this. The CFI info should have provided unwind information for the SP register and then pointed ->cfa_reg at it, not the - reverse. Assuming that SP_REGNUM is !-ve, there is a - very real posibility that CFA is an offset from some + reverse. Assuming that SP_REGNUM isn't negative, there + is a very real posibility that CFA is an offset from some other register, having nothing to do with the unwound SP value. */ /* FIXME: cagney/2003-09-05: I think I understand. GDB was @@ -770,7 +768,7 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache, defines the rule which computes the CFA value; it may be either a register and a signed offset that are added together or a DWARF expression that is evaluated. */ - /* NOTE: cagney/2003-09-05: Should issue a complain. + /* NOTE: cagney/2003-09-05: Should issue a complaint. Unfortunately it turns out that DWARF2 CFI has a problem. Since CFI specifies the location at which a register was saved (not its value) it isn't possible to specify @@ -1508,16 +1506,11 @@ decode_frame_entry (struct comp_unit *unit, char *start, int eh_frame_p) dwarf2read.c in a better way. */ /* Imported from dwarf2read.c. */ -extern file_ptr dwarf_frame_offset; -extern unsigned int dwarf_frame_size; extern asection *dwarf_frame_section; -extern file_ptr dwarf_eh_frame_offset; -extern unsigned int dwarf_eh_frame_size; extern asection *dwarf_eh_frame_section; /* Imported from dwarf2read.c. */ -extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset, - unsigned int size, asection *sectp); +extern char *dwarf2_read_section (struct objfile *objfile, asection *sectp); void dwarf2_build_frame_info (struct objfile *objfile) @@ -1534,17 +1527,16 @@ dwarf2_build_frame_info (struct objfile *objfile) /* First add the information from the .eh_frame section. That way, the FDEs from that section are searched last. */ - if (dwarf_eh_frame_offset) + if (dwarf_eh_frame_section) { asection *got, *txt; unit.cie = NULL; unit.dwarf_frame_buffer = dwarf2_read_section (objfile, - dwarf_eh_frame_offset, - dwarf_eh_frame_size, dwarf_eh_frame_section); - unit.dwarf_frame_size = dwarf_eh_frame_size; + unit.dwarf_frame_size + = bfd_get_section_size_before_reloc (dwarf_eh_frame_section); unit.dwarf_frame_section = dwarf_eh_frame_section; /* FIXME: kettenis/20030602: This is the DW_EH_PE_datarel base @@ -1566,14 +1558,13 @@ dwarf2_build_frame_info (struct objfile *objfile) frame_ptr = decode_frame_entry (&unit, frame_ptr, 1); } - if (dwarf_frame_offset) + if (dwarf_frame_section) { unit.cie = NULL; unit.dwarf_frame_buffer = dwarf2_read_section (objfile, - dwarf_frame_offset, - dwarf_frame_size, dwarf_frame_section); - unit.dwarf_frame_size = dwarf_frame_size; + unit.dwarf_frame_size + = bfd_get_section_size_before_reloc (dwarf_frame_section); unit.dwarf_frame_section = dwarf_frame_section; frame_ptr = unit.dwarf_frame_buffer; |