X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarf2cfi.c;h=ddb42ab65f5402839b5687c4bd5e374545321d69;hb=b64bbf8c48a18ee3e1c158d5df43141033144bbf;hp=ed319fb64b642df81c46d47e33ce3f90b42bd91c;hpb=7f0c12ed449f88fa4cfd83151d61669445ba9672;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2cfi.c b/gdb/dwarf2cfi.c index ed319fb64b..ddb42ab65f 100644 --- a/gdb/dwarf2cfi.c +++ b/gdb/dwarf2cfi.c @@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" +#include "gdbcore.h" #include "symtab.h" #include "symfile.h" #include "objfiles.h" @@ -29,6 +30,7 @@ #include "inferior.h" #include "regcache.h" #include "dwarf2cfi.h" +#include "gdb_assert.h" /* Common Information Entry - holds information that is shared among many Frame Descriptors. */ @@ -88,37 +90,6 @@ struct fde_array int array_size; }; -struct context_reg -{ - union - { - unsigned int reg; - long offset; - CORE_ADDR addr; - } - loc; - enum - { - REG_CTX_UNSAVED, - REG_CTX_SAVED_OFFSET, - REG_CTX_SAVED_REG, - REG_CTX_SAVED_ADDR, - REG_CTX_VALUE, - } - how; -}; - -/* This is the register and unwind state for a particular frame. */ -struct context -{ - struct context_reg *reg; - - CORE_ADDR cfa; - CORE_ADDR ra; - void *lsda; - int args_size; -}; - struct frame_state_reg { union @@ -176,7 +147,8 @@ struct frame_state struct objfile *objfile; }; -enum ptr_encoding { +enum ptr_encoding +{ PE_absptr = DW_EH_PE_absptr, PE_pcrel = DW_EH_PE_pcrel, PE_textrel = DW_EH_PE_textrel, @@ -205,11 +177,8 @@ static struct fde_unit *fde_unit_alloc (void); static struct cie_unit *cie_unit_alloc (void); static void fde_chunks_need_space (); -static struct context *context_alloc (); -static struct frame_state *frame_state_alloc (); static void unwind_tmp_obstack_init (); static void unwind_tmp_obstack_free (); -static void context_cpy (struct context *dst, struct context *src); static unsigned int read_1u (bfd * abfd, char **p); static int read_1s (bfd * abfd, char **p); @@ -271,7 +240,7 @@ cie_unit_alloc (void) } static void -fde_chunks_need_space () +fde_chunks_need_space (void) { if (fde_chunks.elems < fde_chunks.array_size) return; @@ -283,8 +252,8 @@ fde_chunks_need_space () } /* Alocate a new `struct context' on temporary obstack. */ -static struct context * -context_alloc () +struct context * +context_alloc (void) { struct context *context; @@ -300,8 +269,8 @@ context_alloc () } /* Alocate a new `struct frame_state' on temporary obstack. */ -static struct frame_state * -frame_state_alloc () +struct frame_state * +frame_state_alloc (void) { struct frame_state *fs; @@ -317,19 +286,19 @@ frame_state_alloc () } static void -unwind_tmp_obstack_init () +unwind_tmp_obstack_init (void) { obstack_init (&unwind_tmp_obstack); } static void -unwind_tmp_obstack_free () +unwind_tmp_obstack_free (void) { obstack_free (&unwind_tmp_obstack, NULL); unwind_tmp_obstack_init (); } -static void +void context_cpy (struct context *dst, struct context *src) { int regs_size = sizeof (struct context_reg) * NUM_REGS; @@ -561,7 +530,7 @@ pointer_encoding (unsigned char encoding) if (encoding & DW_EH_PE_indirect) warning ("CFI: Unsupported pointer encoding: DW_EH_PE_indirect"); - + switch (encoding & 0x70) { case DW_EH_PE_absptr: @@ -572,8 +541,7 @@ pointer_encoding (unsigned char encoding) ret = encoding & 0x70; break; default: - internal_error (__FILE__, __LINE__, - "CFI: unknown pointer encoding"); + internal_error (__FILE__, __LINE__, "CFI: unknown pointer encoding"); } return ret; } @@ -649,10 +617,10 @@ execute_cfa_program (struct objfile *objfile, char *insn_ptr, char *insn_end, case DW_CFA_set_loc: fs->pc = read_encoded_pointer (objfile->obfd, &insn_ptr, fs->addr_encoding); - + if (pointer_encoding (fs->addr_encoding) != PE_absptr) - warning ("CFI: DW_CFA_set_loc uses relative addressing"); - + warning ("CFI: DW_CFA_set_loc uses relative addressing"); + break; case DW_CFA_advance_loc1: @@ -843,24 +811,20 @@ frame_state_for (struct context *context, struct frame_state *fs) fs->pc = fde->initial_location; - if (fde->cie_ptr) - { - cie = fde->cie_ptr; - - fs->code_align = cie->code_align; - fs->data_align = cie->data_align; - fs->retaddr_column = cie->ra; - fs->addr_encoding = cie->addr_encoding; - fs->objfile = cie->objfile; - - execute_cfa_program (cie->objfile, cie->data, - cie->data + cie->data_length, context, fs); - execute_cfa_program (cie->objfile, fde->data, - fde->data + fde->data_length, context, fs); - } - else - internal_error (__FILE__, __LINE__, - "%s(): Internal error: fde->cie_ptr==NULL !", __func__); + gdb_assert (fde->cie_ptr != NULL); + + cie = fde->cie_ptr; + + fs->code_align = cie->code_align; + fs->data_align = cie->data_align; + fs->retaddr_column = cie->ra; + fs->addr_encoding = cie->addr_encoding; + fs->objfile = cie->objfile; + + execute_cfa_program (cie->objfile, cie->data, + cie->data + cie->data_length, context, fs); + execute_cfa_program (cie->objfile, fde->data, + fde->data + fde->data_length, context, fs); } static void @@ -1119,32 +1083,21 @@ execute_stack_op (struct objfile *objfile, { case DW_OP_deref: { - char *ptr = (char *) result; - result = read_pointer (objfile->obfd, &ptr); + int len = TARGET_ADDR_BIT / TARGET_CHAR_BIT; + if (len != 4 && len != 8) + internal_error (__FILE__, __LINE__, + "execute_stack_op error"); + result = read_memory_unsigned_integer (result, len); } break; case DW_OP_deref_size: { - char *ptr = (char *) result; - switch (*op_ptr++) - { - case 1: - result = read_1u (objfile->obfd, &ptr); - break; - case 2: - result = read_2u (objfile->obfd, &ptr); - break; - case 4: - result = read_4u (objfile->obfd, &ptr); - break; - case 8: - result = read_8u (objfile->obfd, &ptr); - break; - default: - internal_error (__FILE__, __LINE__, - "execute_stack_op error"); - } + int len = *op_ptr++; + if (len != 1 && len != 2 && len != 4 && len != 8) + internal_error (__FILE__, __LINE__, + "execute_stack_op error"); + result = read_memory_unsigned_integer (result, len); } break; @@ -1240,7 +1193,8 @@ execute_stack_op (struct objfile *objfile, case DW_OP_ne: result = (LONGEST) first != (LONGEST) second; break; - default: /* This label is here just to avoid warning. */ + default: + error ("execute_stack_op: Unknown DW_OP_ value"); break; } } @@ -1284,7 +1238,7 @@ static void update_context (struct context *context, struct frame_state *fs, int chain) { struct context *orig_context; - CORE_ADDR cfa; + CORE_ADDR cfa = 0; long i; unwind_tmp_obstack_init (); @@ -1359,9 +1313,9 @@ update_context (struct context *context, struct frame_state *fs, int chain) context->reg[i].how = REG_CTX_SAVED_ADDR; context->reg[i].loc.addr = orig_context->reg[fs->regs.reg[i].loc.reg].loc.addr; + break; default: - internal_error (__FILE__, __LINE__, - "%s: unknown register rule", __func__); + internal_error (__FILE__, __LINE__, "bad switch"); } break; case REG_SAVED_EXP: @@ -1378,8 +1332,7 @@ update_context (struct context *context, struct frame_state *fs, int chain) } break; default: - internal_error (__FILE__, __LINE__, - "%s: unknown register rule", __func__); + internal_error (__FILE__, __LINE__, "bad switch"); } get_reg ((char *) &context->ra, context, fs->retaddr_column); unwind_tmp_obstack_free (); @@ -1454,7 +1407,7 @@ parse_frame_info (struct objfile *objfile, file_ptr frame_offset, unsigned long length; ULONGEST cie_id; ULONGEST unit_offset = start - frame_buffer; - int bytes_read, dwarf64, flag_pcrel; + int bytes_read, dwarf64; char *block_end; length = read_initial_length (abfd, start, &bytes_read); @@ -1596,17 +1549,17 @@ parse_frame_info (struct objfile *objfile, file_ptr frame_offset, cie->addr_encoding); switch (pointer_encoding (cie->addr_encoding)) - { + { case PE_absptr: - break; + break; case PE_pcrel: - /* start-frame_buffer gives offset from - the beginning of actual section. */ - init_loc += curr_section_vma + start - frame_buffer; - break; + /* start-frame_buffer gives offset from + the beginning of actual section. */ + init_loc += curr_section_vma + start - frame_buffer; + break; default: - warning ("CFI: Unsupported pointer encoding\n"); - } + warning ("CFI: Unsupported pointer encoding\n"); + } /* For relocatable objects we must add an offset telling where the section is actually mapped in the memory. */ @@ -1625,23 +1578,23 @@ parse_frame_info (struct objfile *objfile, file_ptr frame_offset, and don't need to care about duplicate FDEs, because .debug_frame is parsed first. */ if (eh_frame == 2) - for (i = 0; eh_frame == 2 && i < fde_chunks.elems; i++) - { - /* We assume that FDEs in .debug_frame and .eh_frame - have the same order (if they are present, of course). - If we find a duplicate entry for one FDE and save - it's index to last_dup_fde it's very likely, that - we'll find an entry for the following FDE right after - the previous one. Thus in many cases we'll run this - loop only once. */ - last_dup_fde = (last_dup_fde + i) % fde_chunks.elems; - if (fde_chunks.array[last_dup_fde]->initial_location - == init_loc) - { - dup = 1; - break; - } - } + for (i = 0; eh_frame == 2 && i < fde_chunks.elems; i++) + { + /* We assume that FDEs in .debug_frame and .eh_frame + have the same order (if they are present, of course). + If we find a duplicate entry for one FDE and save + it's index to last_dup_fde it's very likely, that + we'll find an entry for the following FDE right after + the previous one. Thus in many cases we'll run this + loop only once. */ + last_dup_fde = (last_dup_fde + i) % fde_chunks.elems; + if (fde_chunks.array[last_dup_fde]->initial_location + == init_loc) + { + dup = 1; + break; + } + } /* Allocate a new entry only if this FDE isn't a duplicate of something we have already seen. */ @@ -1688,20 +1641,20 @@ dwarf2_build_frame_info (struct objfile *objfile) eh_frame==1. */ if (dwarf_frame_offset) - { - parse_frame_info (objfile, dwarf_frame_offset, - dwarf_frame_size, 0 /* = debug_frame */); - after_debug_frame = 1; - } + { + parse_frame_info (objfile, dwarf_frame_offset, + dwarf_frame_size, 0 /* = debug_frame */ ); + after_debug_frame = 1; + } if (dwarf_eh_frame_offset) - parse_frame_info (objfile, dwarf_eh_frame_offset, dwarf_eh_frame_size, - 1 /* = eh_frame */ + after_debug_frame); + parse_frame_info (objfile, dwarf_eh_frame_offset, dwarf_eh_frame_size, + 1 /* = eh_frame */ + after_debug_frame); } /* Return the frame address. */ CORE_ADDR -cfi_read_fp () +cfi_read_fp (void) { struct context *context; struct frame_state *fs; @@ -1757,11 +1710,9 @@ cfi_write_fp (CORE_ADDR val) void cfi_pop_frame (struct frame_info *fi) { - char regbuf[MAX_REGISTER_RAW_SIZE]; + char *regbuf = alloca (MAX_REGISTER_RAW_SIZE); int regnum; - fi = get_current_frame (); - for (regnum = 0; regnum < NUM_REGS; regnum++) { get_reg (regbuf, UNWIND_CONTEXT (fi), regnum); @@ -1861,7 +1812,7 @@ cfi_get_ra (struct frame_info *fi) void cfi_get_saved_register (char *raw_buffer, int *optimized, - CORE_ADDR * addrp, + CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval) {