2008-03-18 Ulrich Weigand <uweigand@de.ibm.com>
authorUlrich Weigand <uweigand@de.ibm.com>
Tue, 18 Mar 2008 19:40:47 +0000 (19:40 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Tue, 18 Mar 2008 19:40:47 +0000 (19:40 +0000)
    Jim Blandy  <jimb@codesourcery.com>
    Daniel Jacobowitz  <drow@false.org>

* dwarf2expr.h (struct dwarf_expr_context): Add ADDR_SIZE member.
(dwarf2_read_address): Update prototype.

* dwarf2expr.c (unsigned_address_type): Add ADDR_SIZE parameter.
(signed_address_type): Likewise.
(dwarf2_read_address): Replace BYTES_READ parameter with ADDR_SIZE.
(execute_stack_op): Update calls to unsigned_address_type,
signed_address_type and dwarf2_read_address.  Fix implementation
of DW_OP_deref_size.

* dwarf2loc.h (dwarf2_per_cu_objfile): Add prototype.
(dwarf2_per_cu_addr_size): Likewise.
(struct dwarf2_locexpr_baton): Replace OBJFILE with PER_CU.
(struct dwarf2_loclist_baton): Likewise.

* dwarf2loc.c (find_location_expression): Update calls to
dwarf2_read_address.  Use dwarf2_per_cu_objfile and
dwarf2_per_cu_addr_size to retrieve PER_CU parameters.
(locexpr_describe_location): Likewise.
(dwarf2_evaluate_loc_desc): Replace OBJFILE with PER_CU parameter.
Set ctx->addr_size to dwarf2_per_cu_addr_size (per_cu).
(dwarf2_loc_desc_needs_frame): Add PER_CU parameter.  Set ctx->addr_size
to dwarf2_per_cu_addr_size (per_cu).
(locexpr_read_variable): Update dwarf2_evaluate_loc_desc call.
(loclist_read_variable): Likewise.
(locexpr_read_needs_frame): Update dwarf2_loc_desc_needs_frame call.

* dwarf2read.c (dwarf2_symbol_mark_computed): Set baton->per_cu
instead of baton->objfile.
(dwarf2_per_cu_obfile): New function.
(dwarf2_per_cu_addr_size): Likewise.

* dwarf2-frame.c (struct comp_unit): Move higher.
(struct dwarf2_cie): Add UNIT and ADDR_SIZE members.
(execute_stack_op): Add ADDR_SIZE parameter; set ctx->addr_size.
(execute_cfa_program): Add FDE parameter.  Replace EH_FRAME_P
parameter by using fde->eh_frame_p.  Use read_encoded_value
to implement DW_CFA_set_loc.
(struct dwarf2_frame_cache): Add ADDR_SIZE member.
(dwarf2_frame_cache): Set cache->addr_size.  Update calls to
execute_stack_op and execute_cfa_program.
(dwarf2_frame_prev_register): Update calls to execute_stack_op.
(size_of_encoded_value): Remove.
(read_encoded_value): Add PTR_LEN and FUNC_BASE parameters.
Remove call to size_of_encoded_value.  Implement DW_EH_PE_funcrel.
(add_cie): Set cie->unit backlink.
(decode_frame_entry_1): Set cie->addr_size.  Update calls to
read_encoded_value.
(dwarf2_build_frame_info): Allocate UNIT on objfile obstack.

gdb/ChangeLog
gdb/dwarf2-frame.c
gdb/dwarf2expr.c
gdb/dwarf2expr.h
gdb/dwarf2loc.c
gdb/dwarf2loc.h
gdb/dwarf2read.c

index b28267e0863fd83ebf0073de4d112a6888b7349e..deefe94e13649bd95882970947cc8e32ce6d8966 100644 (file)
@@ -1,3 +1,57 @@
+2008-03-18  Ulrich Weigand  <uweigand@de.ibm.com>
+           Jim Blandy  <jimb@codesourcery.com>
+           Daniel Jacobowitz  <drow@false.org>
+
+       * dwarf2expr.h (struct dwarf_expr_context): Add ADDR_SIZE member.
+       (dwarf2_read_address): Update prototype.
+
+       * dwarf2expr.c (unsigned_address_type): Add ADDR_SIZE parameter.
+       (signed_address_type): Likewise.
+       (dwarf2_read_address): Replace BYTES_READ parameter with ADDR_SIZE.
+       (execute_stack_op): Update calls to unsigned_address_type,
+       signed_address_type and dwarf2_read_address.  Fix implementation
+       of DW_OP_deref_size.
+
+       * dwarf2loc.h (dwarf2_per_cu_objfile): Add prototype.
+       (dwarf2_per_cu_addr_size): Likewise.
+       (struct dwarf2_locexpr_baton): Replace OBJFILE with PER_CU.
+       (struct dwarf2_loclist_baton): Likewise.
+
+       * dwarf2loc.c (find_location_expression): Update calls to
+       dwarf2_read_address.  Use dwarf2_per_cu_objfile and
+       dwarf2_per_cu_addr_size to retrieve PER_CU parameters.
+       (locexpr_describe_location): Likewise.
+       (dwarf2_evaluate_loc_desc): Replace OBJFILE with PER_CU parameter.
+       Set ctx->addr_size to dwarf2_per_cu_addr_size (per_cu).
+       (dwarf2_loc_desc_needs_frame): Add PER_CU parameter.  Set ctx->addr_size
+       to dwarf2_per_cu_addr_size (per_cu).
+       (locexpr_read_variable): Update dwarf2_evaluate_loc_desc call.
+       (loclist_read_variable): Likewise.
+       (locexpr_read_needs_frame): Update dwarf2_loc_desc_needs_frame call.
+
+       * dwarf2read.c (dwarf2_symbol_mark_computed): Set baton->per_cu
+       instead of baton->objfile.
+       (dwarf2_per_cu_obfile): New function.
+       (dwarf2_per_cu_addr_size): Likewise.
+
+       * dwarf2-frame.c (struct comp_unit): Move higher.
+       (struct dwarf2_cie): Add UNIT and ADDR_SIZE members.
+       (execute_stack_op): Add ADDR_SIZE parameter; set ctx->addr_size.
+       (execute_cfa_program): Add FDE parameter.  Replace EH_FRAME_P
+       parameter by using fde->eh_frame_p.  Use read_encoded_value
+       to implement DW_CFA_set_loc.
+       (struct dwarf2_frame_cache): Add ADDR_SIZE member.
+       (dwarf2_frame_cache): Set cache->addr_size.  Update calls to
+       execute_stack_op and execute_cfa_program.
+       (dwarf2_frame_prev_register): Update calls to execute_stack_op.
+       (size_of_encoded_value): Remove.
+       (read_encoded_value): Add PTR_LEN and FUNC_BASE parameters.
+       Remove call to size_of_encoded_value.  Implement DW_EH_PE_funcrel.
+       (add_cie): Set cie->unit backlink.
+       (decode_frame_entry_1): Set cie->addr_size.  Update calls to
+       read_encoded_value.
+       (dwarf2_build_frame_info): Allocate UNIT on objfile obstack.
+
 2008-03-17  Markus Deuling  <deuling@de.ibm.com>
 
        * i386-tdep.c (i386_print_insn): Remove unnecessary call to
index c4cd9f3d3ef59a74203727cde66503747f8171c7..e48fad9cd0649ea24579e4c6417c1cab8af4d18e 100644 (file)
 #include "complaints.h"
 #include "dwarf2-frame.h"
 
+struct comp_unit;
+
 /* Call Frame Information (CFI).  */
 
 /* Common Information Entry (CIE).  */
 
 struct dwarf2_cie
 {
+  /* Computation Unit for this CIE.  */
+  struct comp_unit *unit;
+
   /* Offset into the .debug_frame section where this CIE was found.
      Used to identify this CIE.  */
   ULONGEST cie_pointer;
@@ -68,6 +73,9 @@ struct dwarf2_cie
   /* Encoding of addresses.  */
   gdb_byte encoding;
 
+  /* Target address size in bytes.  */
+  int addr_size;
+
   /* True if a 'z' augmentation existed.  */
   unsigned char saw_z_augmentation;
 
@@ -104,10 +112,44 @@ struct dwarf2_fde
   struct dwarf2_fde *next;
 };
 
+/* A minimal decoding of DWARF2 compilation units.  We only decode
+   what's needed to get to the call frame information.  */
+
+struct comp_unit
+{
+  /* Keep the bfd convenient.  */
+  bfd *abfd;
+
+  struct objfile *objfile;
+
+  /* Linked list of CIEs for this object.  */
+  struct dwarf2_cie *cie;
+
+  /* Pointer to the .debug_frame section loaded into memory.  */
+  gdb_byte *dwarf_frame_buffer;
+
+  /* Length of the loaded .debug_frame section.  */
+  unsigned long dwarf_frame_size;
+
+  /* Pointer to the .debug_frame section.  */
+  asection *dwarf_frame_section;
+
+  /* Base for DW_EH_PE_datarel encodings.  */
+  bfd_vma dbase;
+
+  /* Base for DW_EH_PE_textrel encodings.  */
+  bfd_vma tbase;
+};
+
 static struct dwarf2_fde *dwarf2_frame_find_fde (CORE_ADDR *pc);
 
 static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum,
                                       int eh_frame_p);
+
+static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
+                                    int ptr_len, gdb_byte *buf,
+                                    unsigned int *bytes_read_ptr,
+                                    CORE_ADDR func_base);
 \f
 
 /* Structure describing a frame state.  */
@@ -299,13 +341,14 @@ register %s (#%d) at 0x%s"),
 }
 
 static CORE_ADDR
-execute_stack_op (gdb_byte *exp, ULONGEST len,
+execute_stack_op (gdb_byte *exp, ULONGEST len, int addr_size,
                  struct frame_info *next_frame, CORE_ADDR initial)
 {
   struct dwarf_expr_context *ctx;
   CORE_ADDR result;
 
   ctx = new_dwarf_expr_context ();
+  ctx->addr_size = addr_size;
   ctx->baton = next_frame;
   ctx->read_reg = read_reg;
   ctx->read_mem = read_mem;
@@ -326,10 +369,11 @@ execute_stack_op (gdb_byte *exp, ULONGEST len,
 \f
 
 static void
-execute_cfa_program (gdb_byte *insn_ptr, gdb_byte *insn_end,
-                    struct frame_info *next_frame,
-                    struct dwarf2_frame_state *fs, int eh_frame_p)
+execute_cfa_program (struct dwarf2_fde *fde, gdb_byte *insn_ptr,
+                    gdb_byte *insn_end, struct frame_info *next_frame,
+                    struct dwarf2_frame_state *fs)
 {
+  int eh_frame_p = fde->eh_frame_p;
   CORE_ADDR pc = frame_pc_unwind (next_frame);
   int bytes_read;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
@@ -362,7 +406,12 @@ execute_cfa_program (gdb_byte *insn_ptr, gdb_byte *insn_end,
          switch (insn)
            {
            case DW_CFA_set_loc:
-             fs->pc = dwarf2_read_address (insn_ptr, insn_end, &bytes_read);
+             fs->pc = read_encoded_value (fde->cie->unit, fde->cie->encoding,
+                                          fde->cie->addr_size, insn_ptr,
+                                          &bytes_read, fde->initial_location);
+             /* Apply the objfile offset for relocatable objects.  */
+             fs->pc += ANOFFSET (fde->cie->unit->objfile->section_offsets,
+                                 SECT_OFF_TEXT (fde->cie->unit->objfile));
              insn_ptr += bytes_read;
              break;
 
@@ -813,6 +862,9 @@ struct dwarf2_frame_cache
 
   /* Return address register.  */
   struct dwarf2_frame_state_reg retaddr_reg;
+
+  /* Target address size in bytes.  */
+  int addr_size;
 };
 
 static struct dwarf2_frame_cache *
@@ -863,21 +915,21 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
   fs->data_align = fde->cie->data_alignment_factor;
   fs->code_align = fde->cie->code_alignment_factor;
   fs->retaddr_column = fde->cie->return_address_register;
+  cache->addr_size = fde->cie->addr_size;
 
   /* Check for "quirks" - known bugs in producers.  */
   dwarf2_frame_find_quirks (fs, fde);
 
   /* First decode all the insns in the CIE.  */
-  execute_cfa_program (fde->cie->initial_instructions,
-                      fde->cie->end, next_frame, fs, fde->eh_frame_p);
+  execute_cfa_program (fde, fde->cie->initial_instructions,
+                      fde->cie->end, next_frame, fs);
 
   /* 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->instructions, fde->end, next_frame, fs,
-                      fde->eh_frame_p);
+  execute_cfa_program (fde, fde->instructions, fde->end, next_frame, fs);
 
   /* Caclulate the CFA.  */
   switch (fs->cfa_how)
@@ -892,7 +944,8 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
 
     case CFA_EXP:
       cache->cfa =
-       execute_stack_op (fs->cfa_exp, fs->cfa_exp_len, next_frame, 0);
+       execute_stack_op (fs->cfa_exp, fs->cfa_exp_len,
+                         cache->addr_size, next_frame, 0);
       break;
 
     default:
@@ -1089,7 +1142,7 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
       *lvalp = lval_memory;
       *addrp = execute_stack_op (cache->reg[regnum].loc.exp,
                                 cache->reg[regnum].exp_len,
-                                next_frame, cache->cfa);
+                                cache->addr_size, next_frame, cache->cfa);
       *realnump = -1;
       if (valuep)
        {
@@ -1117,7 +1170,8 @@ dwarf2_frame_prev_register (struct frame_info *next_frame, void **this_cache,
        store_unsigned_integer (valuep, register_size (gdbarch, regnum),
                                execute_stack_op (cache->reg[regnum].loc.exp,
                                                  cache->reg[regnum].exp_len,
-                                                 next_frame, cache->cfa));
+                                                 cache->addr_size, next_frame,
+                                                 cache->cfa));
       break;
 
     case DWARF2_FRAME_REG_UNSPECIFIED:
@@ -1261,35 +1315,6 @@ dwarf2_frame_base_sniffer (struct frame_info *next_frame)
   return NULL;
 }
 \f
-/* A minimal decoding of DWARF2 compilation units.  We only decode
-   what's needed to get to the call frame information.  */
-
-struct comp_unit
-{
-  /* Keep the bfd convenient.  */
-  bfd *abfd;
-
-  struct objfile *objfile;
-
-  /* Linked list of CIEs for this object.  */
-  struct dwarf2_cie *cie;
-
-  /* Pointer to the .debug_frame section loaded into memory.  */
-  gdb_byte *dwarf_frame_buffer;
-
-  /* Length of the loaded .debug_frame section.  */
-  unsigned long dwarf_frame_size;
-
-  /* Pointer to the .debug_frame section.  */
-  asection *dwarf_frame_section;
-
-  /* Base for DW_EH_PE_datarel encodings.  */
-  bfd_vma dbase;
-
-  /* Base for DW_EH_PE_textrel encodings.  */
-  bfd_vma tbase;
-};
-
 const struct objfile_data *dwarf2_frame_objfile_data;
 
 static unsigned int
@@ -1417,32 +1442,11 @@ encoding_for_size (unsigned int size)
     }
 }
 
-static unsigned int
-size_of_encoded_value (gdb_byte encoding)
-{
-  if (encoding == DW_EH_PE_omit)
-    return 0;
-
-  switch (encoding & 0x07)
-    {
-    case DW_EH_PE_absptr:
-      return TYPE_LENGTH (builtin_type_void_data_ptr);
-    case DW_EH_PE_udata2:
-      return 2;
-    case DW_EH_PE_udata4:
-      return 4;
-    case DW_EH_PE_udata8:
-      return 8;
-    default:
-      internal_error (__FILE__, __LINE__, _("Invalid or unsupported encoding"));
-    }
-}
-
 static CORE_ADDR
 read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
-                   gdb_byte *buf, unsigned int *bytes_read_ptr)
+                   int ptr_len, gdb_byte *buf, unsigned int *bytes_read_ptr,
+                   CORE_ADDR func_base)
 {
-  int ptr_len = size_of_encoded_value (DW_EH_PE_absptr);
   ptrdiff_t offset;
   CORE_ADDR base;
 
@@ -1470,12 +1474,7 @@ read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
       base = unit->tbase;
       break;
     case DW_EH_PE_funcrel:
-      /* FIXME: kettenis/20040501: For now just pretend
-         DW_EH_PE_funcrel is equivalent to DW_EH_PE_absptr.  For
-         reading the initial location of an FDE it should be treated
-         as such, and currently that's the only place where this code
-         is used.  */
-      base = 0;
+      base = func_base;
       break;
     case DW_EH_PE_aligned:
       base = 0;
@@ -1561,6 +1560,7 @@ add_cie (struct comp_unit *unit, struct dwarf2_cie *cie)
 {
   cie->next = unit->cie;
   unit->cie = cie;
+  cie->unit = unit;
 }
 
 /* Find the FDE for *PC.  Return a pointer to the FDE, and store the
@@ -1685,6 +1685,13 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p)
          depends on the target address size.  */
       cie->encoding = DW_EH_PE_absptr;
 
+      /* The target address size.  For .eh_frame FDEs this is considered
+        equal to the size of a target pointer.  For .dwarf_frame FDEs, 
+        this is supposed to be the target address size from the associated
+        CU header.  FIXME: We do not have a good way to determine the 
+        latter.  Always use the target pointer size for now.  */
+      cie->addr_size = gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+
       /* We'll determine the final value later, but we need to
         initialize it conservatively.  */
       cie->signal_frame = 0;
@@ -1773,7 +1780,8 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p)
            {
              /* Skip.  Avoid indirection since we throw away the result.  */
              gdb_byte encoding = (*buf++) & ~DW_EH_PE_indirect;
-             read_encoded_value (unit, encoding, buf, &bytes_read);
+             read_encoded_value (unit, encoding, cie->addr_size,
+                                 buf, &bytes_read, 0);
              buf += bytes_read;
              augmentation++;
            }
@@ -1837,11 +1845,13 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p)
       gdb_assert (fde->cie != NULL);
 
       fde->initial_location =
-       read_encoded_value (unit, fde->cie->encoding, buf, &bytes_read);
+       read_encoded_value (unit, fde->cie->encoding, fde->cie->addr_size,
+                           buf, &bytes_read, 0);
       buf += bytes_read;
 
       fde->address_range =
-       read_encoded_value (unit, fde->cie->encoding & 0x0f, buf, &bytes_read);
+       read_encoded_value (unit, fde->cie->encoding & 0x0f,
+                           fde->cie->addr_size, buf, &bytes_read, 0);
       buf += bytes_read;
 
       /* A 'z' augmentation in the CIE implies the presence of an
@@ -1975,14 +1985,16 @@ extern gdb_byte *dwarf2_read_section (struct objfile *objfile, asection *sectp);
 void
 dwarf2_build_frame_info (struct objfile *objfile)
 {
-  struct comp_unit unit;
+  struct comp_unit *unit;
   gdb_byte *frame_ptr;
 
   /* Build a minimal decoding of the DWARF2 compilation unit.  */
-  unit.abfd = objfile->obfd;
-  unit.objfile = objfile;
-  unit.dbase = 0;
-  unit.tbase = 0;
+  unit = (struct comp_unit *) obstack_alloc (&objfile->objfile_obstack,
+                                            sizeof (struct comp_unit));
+  unit->abfd = objfile->obfd;
+  unit->objfile = objfile;
+  unit->dbase = 0;
+  unit->tbase = 0;
 
   /* First add the information from the .eh_frame section.  That way,
      the FDEs from that section are searched last.  */
@@ -1990,43 +2002,43 @@ dwarf2_build_frame_info (struct objfile *objfile)
     {
       asection *got, *txt;
 
-      unit.cie = NULL;
-      unit.dwarf_frame_buffer = dwarf2_read_section (objfile,
-                                                    dwarf_eh_frame_section);
+      unit->cie = NULL;
+      unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
+                                                     dwarf_eh_frame_section);
 
-      unit.dwarf_frame_size = bfd_get_section_size (dwarf_eh_frame_section);
-      unit.dwarf_frame_section = dwarf_eh_frame_section;
+      unit->dwarf_frame_size = bfd_get_section_size (dwarf_eh_frame_section);
+      unit->dwarf_frame_section = dwarf_eh_frame_section;
 
       /* FIXME: kettenis/20030602: This is the DW_EH_PE_datarel base
         that is used for the i386/amd64 target, which currently is
         the only target in GCC that supports/uses the
         DW_EH_PE_datarel encoding.  */
-      got = bfd_get_section_by_name (unit.abfd, ".got");
+      got = bfd_get_section_by_name (unit->abfd, ".got");
       if (got)
-       unit.dbase = got->vma;
+       unit->dbase = got->vma;
 
       /* GCC emits the DW_EH_PE_textrel encoding type on sh and ia64
          so far.  */
-      txt = bfd_get_section_by_name (unit.abfd, ".text");
+      txt = bfd_get_section_by_name (unit->abfd, ".text");
       if (txt)
-       unit.tbase = txt->vma;
+       unit->tbase = txt->vma;
 
-      frame_ptr = unit.dwarf_frame_buffer;
-      while (frame_ptr < unit.dwarf_frame_buffer + unit.dwarf_frame_size)
-       frame_ptr = decode_frame_entry (&unit, frame_ptr, 1);
+      frame_ptr = unit->dwarf_frame_buffer;
+      while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
+       frame_ptr = decode_frame_entry (unit, frame_ptr, 1);
     }
 
   if (dwarf_frame_section)
     {
-      unit.cie = NULL;
-      unit.dwarf_frame_buffer = dwarf2_read_section (objfile,
-                                                    dwarf_frame_section);
-      unit.dwarf_frame_size = bfd_get_section_size (dwarf_frame_section);
-      unit.dwarf_frame_section = dwarf_frame_section;
-
-      frame_ptr = unit.dwarf_frame_buffer;
-      while (frame_ptr < unit.dwarf_frame_buffer + unit.dwarf_frame_size)
-       frame_ptr = decode_frame_entry (&unit, frame_ptr, 0);
+      unit->cie = NULL;
+      unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
+                                                     dwarf_frame_section);
+      unit->dwarf_frame_size = bfd_get_section_size (dwarf_frame_section);
+      unit->dwarf_frame_section = dwarf_frame_section;
+
+      frame_ptr = unit->dwarf_frame_buffer;
+      while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
+       frame_ptr = decode_frame_entry (unit, frame_ptr, 0);
     }
 }
 
index 1102cf07b6ef99bca057856664296ef2f0b4aae6..a099878f5e5697484b4985f0591ab3f12587639e 100644 (file)
@@ -32,7 +32,7 @@
 
 static void execute_stack_op (struct dwarf_expr_context *,
                              gdb_byte *, gdb_byte *);
-static struct type *unsigned_address_type (void);
+static struct type *unsigned_address_type (int);
 
 /* Create a new context for the expression evaluator.  */
 
@@ -192,20 +192,17 @@ read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r)
   return buf;
 }
 
-/* Read an address from BUF, and verify that it doesn't extend past
-   BUF_END.  The address is returned, and *BYTES_READ is set to the
-   number of bytes read from BUF.  */
+/* Read an address of size ADDR_SIZE from BUF, and verify that it
+   doesn't extend past BUF_END.  */
 
 CORE_ADDR
-dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read)
+dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int addr_size)
 {
   CORE_ADDR result;
 
-  if (buf_end - buf < gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
+  if (buf_end - buf < addr_size)
     error (_("dwarf2_read_address: Corrupted DWARF expression."));
 
-  *bytes_read = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
-
   /* For most architectures, calling extract_unsigned_integer() alone
      is sufficient for extracting an address.  However, some
      architectures (e.g. MIPS) use signed addresses and using
@@ -229,21 +226,18 @@ dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read)
      address being returned.  */
 
   result = value_as_address (value_from_longest 
-                             (unsigned_address_type (),
-                              extract_unsigned_integer 
-                                (buf,
-                                 gdbarch_addr_bit (current_gdbarch)
-                                   / TARGET_CHAR_BIT)));
-
+                             (unsigned_address_type (addr_size),
+                              extract_unsigned_integer (buf, addr_size)));
   return result;
 }
 
-/* Return the type of an address, for unsigned arithmetic.  */
+/* Return the type of an address of size ADDR_SIZE,
+   for unsigned arithmetic.  */
 
 static struct type *
-unsigned_address_type (void)
+unsigned_address_type (int addr_size)
 {
-  switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
+  switch (addr_size)
     {
     case 2:
       return builtin_type_uint16;
@@ -257,12 +251,13 @@ unsigned_address_type (void)
     }
 }
 
-/* Return the type of an address, for signed arithmetic.  */
+/* Return the type of an address of size ADDR_SIZE,
+   for signed arithmetic.  */
 
 static struct type *
-signed_address_type (void)
+signed_address_type (int addr_size)
 {
-  switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT)
+  switch (addr_size)
     {
     case 2:
       return builtin_type_int16;
@@ -292,7 +287,6 @@ execute_stack_op (struct dwarf_expr_context *ctx,
       CORE_ADDR result;
       ULONGEST uoffset, reg;
       LONGEST offset;
-      int bytes_read;
 
       switch (op)
        {
@@ -332,8 +326,8 @@ execute_stack_op (struct dwarf_expr_context *ctx,
          break;
 
        case DW_OP_addr:
-         result = dwarf2_read_address (op_ptr, op_end, &bytes_read);
-         op_ptr += bytes_read;
+         result = dwarf2_read_address (op_ptr, op_end, ctx->addr_size);
+         op_ptr += ctx->addr_size;
          break;
 
        case DW_OP_const1u:
@@ -550,34 +544,20 @@ execute_stack_op (struct dwarf_expr_context *ctx,
            {
            case DW_OP_deref:
              {
-               gdb_byte *buf = alloca (gdbarch_addr_bit (current_gdbarch)
-                                         / TARGET_CHAR_BIT);
-               int bytes_read;
-
-               (ctx->read_mem) (ctx->baton, buf, result,
-                                gdbarch_addr_bit (current_gdbarch)
-                                  / TARGET_CHAR_BIT);
-               result = dwarf2_read_address (buf,
-                                             buf + (gdbarch_addr_bit
-                                                      (current_gdbarch)
-                                                    / TARGET_CHAR_BIT),
-                                             &bytes_read);
+               gdb_byte *buf = alloca (ctx->addr_size);
+               (ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size);
+               result = dwarf2_read_address (buf, buf + ctx->addr_size,
+                                             ctx->addr_size);
              }
              break;
 
            case DW_OP_deref_size:
              {
-               gdb_byte *buf
-                  = alloca (gdbarch_addr_bit (current_gdbarch)
-                             / TARGET_CHAR_BIT);
-               int bytes_read;
-
-               (ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
-               result = dwarf2_read_address (buf,
-                                             buf + (gdbarch_addr_bit
-                                                     (current_gdbarch)
-                                                    / TARGET_CHAR_BIT),
-                                             &bytes_read);
+               int addr_size = *op_ptr++;
+               gdb_byte *buf = alloca (addr_size);
+               (ctx->read_mem) (ctx->baton, buf, result, addr_size);
+               result = dwarf2_read_address (buf, buf + addr_size,
+                                             addr_size);
              }
              break;
 
@@ -628,8 +608,10 @@ execute_stack_op (struct dwarf_expr_context *ctx,
            first = dwarf_expr_fetch (ctx, 0);
            dwarf_expr_pop (ctx);
 
-           val1 = value_from_longest (unsigned_address_type (), first);
-           val2 = value_from_longest (unsigned_address_type (), second);
+           val1 = value_from_longest
+                    (unsigned_address_type (ctx->addr_size), first);
+           val2 = value_from_longest
+                    (unsigned_address_type (ctx->addr_size), second);
 
            switch (op)
              {
@@ -662,7 +644,8 @@ execute_stack_op (struct dwarf_expr_context *ctx,
                 break;
              case DW_OP_shra:
                binop = BINOP_RSH;
-               val1 = value_from_longest (signed_address_type (), first);
+               val1 = value_from_longest
+                        (signed_address_type (ctx->addr_size), first);
                break;
              case DW_OP_xor:
                binop = BINOP_BITWISE_XOR;
index 306ccb05b5c8faafdb63799a66317d054bde9a9a..463c45261d6ce7cea85620ee2e49a14782e0dcdd 100644 (file)
@@ -34,6 +34,9 @@ struct dwarf_expr_context
      number of elements allocated to the stack.  */
   int stack_len, stack_allocated;
 
+  /* Target address size in bytes.  */
+  int addr_size;
+
   /* An opaque argument provided by the caller, which will be passed
      to all of the callback functions.  */
   void *baton;
@@ -136,6 +139,6 @@ CORE_ADDR dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
 gdb_byte *read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r);
 gdb_byte *read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r);
 CORE_ADDR dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end,
-                              int *bytes_read);
+                              int addr_size);
 
 #endif /* dwarf2expr.h */
index 7deb08e25baf1507cc2422b01d3b82e478202e45..4f4c0cab6b187314646c93f7733178c0e3bc6cc2 100644 (file)
@@ -54,11 +54,12 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
   CORE_ADDR low, high;
   gdb_byte *loc_ptr, *buf_end;
   int length;
-  unsigned int addr_size = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+  struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu);
+  unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets,
-                                   SECT_OFF_TEXT (baton->objfile));
+  CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
+                                   SECT_OFF_TEXT (objfile));
   CORE_ADDR base_address = baton->base_address + base_offset;
 
   loc_ptr = baton->data;
@@ -66,10 +67,10 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
 
   while (1)
     {
-      low = dwarf2_read_address (loc_ptr, buf_end, &length);
-      loc_ptr += length;
-      high = dwarf2_read_address (loc_ptr, buf_end, &length);
-      loc_ptr += length;
+      low = dwarf2_read_address (loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
+      high = dwarf2_read_address (loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
 
       /* An end-of-list entry.  */
       if (low == 0 && high == 0)
@@ -189,7 +190,7 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
 static struct value *
 dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
                          gdb_byte *data, unsigned short size,
-                         struct objfile *objfile)
+                         struct dwarf2_per_cu_data *per_cu)
 {
   struct gdbarch *arch = get_frame_arch (frame);
   struct value *retval;
@@ -205,9 +206,10 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
     }
 
   baton.frame = frame;
-  baton.objfile = objfile;
+  baton.objfile = dwarf2_per_cu_objfile (per_cu);
 
   ctx = new_dwarf_expr_context ();
+  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = dwarf_expr_read_reg;
   ctx->read_mem = dwarf_expr_read_mem;
@@ -318,7 +320,8 @@ needs_frame_tls_address (void *baton, CORE_ADDR offset)
    requires a frame to evaluate.  */
 
 static int
-dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
+dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
+                            struct dwarf2_per_cu_data *per_cu)
 {
   struct needs_frame_baton baton;
   struct dwarf_expr_context *ctx;
@@ -327,6 +330,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
   baton.needs_frame = 0;
 
   ctx = new_dwarf_expr_context ();
+  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = needs_frame_read_reg;
   ctx->read_mem = needs_frame_read_mem;
@@ -429,7 +433,7 @@ locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
   struct value *val;
   val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
-                                 dlbaton->objfile);
+                                 dlbaton->per_cu);
 
   return val;
 }
@@ -439,7 +443,8 @@ static int
 locexpr_read_needs_frame (struct symbol *symbol)
 {
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
-  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size);
+  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size,
+                                     dlbaton->per_cu);
 }
 
 /* Print a natural-language description of SYMBOL to STREAM.  */
@@ -448,6 +453,7 @@ locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
 {
   /* FIXME: be more extensive.  */
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
+  int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
 
   if (dlbaton->size == 1
       && dlbaton->data[0] >= DW_OP_reg0
@@ -477,14 +483,14 @@ locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
       && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
     if (dlbaton->data[0] == DW_OP_addr)
       {
-       int bytes_read;
+       struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
        CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1],
                                                &dlbaton->data[dlbaton->size - 1],
-                                               &bytes_read);
+                                               addr_size);
        fprintf_filtered (stream, 
                          "a thread-local variable at offset %s in the "
                          "thread-local storage for `%s'",
-                         paddr_nz (offset), dlbaton->objfile->name);
+                         paddr_nz (offset), objfile->name);
        return 1;
       }
   
@@ -546,7 +552,7 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
     }
   else
     val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
-                                   dlbaton->objfile);
+                                   dlbaton->per_cu);
 
   return val;
 }
index 22c66bd8394383f7328707e0412b7396e6df19c2..632568e1e803306647c77fa222244a0871894dee 100644 (file)
 #define DWARF2LOC_H
 
 struct symbol_ops;
+struct objfile;
+struct dwarf2_per_cu_data;
 
 /* This header is private to the DWARF-2 reader.  It is shared between
    dwarf2read.c and dwarf2loc.c.  */
 
+/* Return the OBJFILE associated with the compilation unit CU.  */
+struct objfile *dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *cu);
+
+/* Return the address size given in the compilation unit header for CU.  */
+CORE_ADDR dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *cu);
+
 /* The symbol location baton types used by the DWARF-2 reader (i.e.
    SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol).  "struct
    dwarf2_locexpr_baton" is for a symbol with a single location
@@ -39,8 +47,9 @@ struct dwarf2_locexpr_baton
   /* Length of the location expression.  */
   unsigned long size;
 
-  /* The objfile containing the symbol whose location we're computing.  */
-  struct objfile *objfile;
+  /* The compilation unit containing the symbol whose location
+     we're computing.  */
+  struct dwarf2_per_cu_data *per_cu;
 };
 
 struct dwarf2_loclist_baton
@@ -55,12 +64,9 @@ struct dwarf2_loclist_baton
   /* Length of the location list.  */
   unsigned long size;
 
-  /* The objfile containing the symbol whose location we're computing.  */
-  /* Used (only???) by thread local variables.  The objfile in which
-     this symbol is defined.  To find a thread-local variable (e.g., a
-     variable declared with the `__thread' storage class), we may need
-     to know which object file it's in.  */
-  struct objfile *objfile;
+  /* The compilation unit containing the symbol whose location
+     we're computing.  */
+  struct dwarf2_per_cu_data *per_cu;
 };
 
 extern const struct symbol_ops dwarf2_locexpr_funcs;
index af9585b8c8079ee2761046f21e61e7ddeb722ec7..7059ad2fc04ce7265745b1fb63edd2405a8f6534 100644 (file)
@@ -9818,13 +9818,6 @@ static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
                             struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
-
-  /* Save the master objfile, so that we can report and look up the
-     correct file containing this variable.  */
-  if (objfile->separate_debug_objfile_backlink)
-    objfile = objfile->separate_debug_objfile_backlink;
-
   if (attr_form_is_section_offset (attr)
       /* ".debug_loc" may not exist at all, or the offset may be outside
         the section.  If so, fall through to the complaint in the
@@ -9835,7 +9828,8 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 
       baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_loclist_baton));
-      baton->objfile = objfile;
+      baton->per_cu = cu->per_cu;
+      gdb_assert (baton->per_cu);
 
       /* We don't know how long the location list is, but make sure we
         don't run off the edge of the section.  */
@@ -9855,7 +9849,8 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 
       baton = obstack_alloc (&cu->objfile->objfile_obstack,
                             sizeof (struct dwarf2_locexpr_baton));
-      baton->objfile = objfile;
+      baton->per_cu = cu->per_cu;
+      gdb_assert (baton->per_cu);
 
       if (attr_form_is_block (attr))
        {
@@ -9880,6 +9875,43 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
     }
 }
 
+/* Return the OBJFILE associated with the compilation unit CU.  */
+
+struct objfile *
+dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu)
+{
+  struct objfile *objfile = per_cu->psymtab->objfile;
+
+  /* Return the master objfile, so that we can report and look up the
+     correct file containing this variable.  */
+  if (objfile->separate_debug_objfile_backlink)
+    objfile = objfile->separate_debug_objfile_backlink;
+
+  return objfile;
+}
+
+/* Return the address size given in the compilation unit header for CU.  */
+
+CORE_ADDR
+dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
+{
+  if (per_cu->cu)
+    return per_cu->cu->header.addr_size;
+  else
+    {
+      /* If the CU is not currently read in, we re-read its header.  */
+      struct objfile *objfile = per_cu->psymtab->objfile;
+      struct dwarf2_per_objfile *per_objfile
+       = objfile_data (objfile, dwarf2_objfile_data_key);
+      gdb_byte *info_ptr = per_objfile->info_buffer + per_cu->offset;
+
+      struct comp_unit_head cu_header;
+      memset (&cu_header, 0, sizeof cu_header);
+      read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
+      return cu_header.addr_size;
+    }
+}
+
 /* Locate the compilation unit from CU's objfile which contains the
    DIE at OFFSET.  Raises an error on failure.  */