Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback
@ 2012-03-05 22:34 Joel Brobecker
  2012-03-06 20:25 ` Tom Tromey
  2012-03-07 17:10 ` [patch] Fix CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback] Jan Kratochvil
  0 siblings, 2 replies; 20+ messages in thread
From: Joel Brobecker @ 2012-03-05 22:34 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 5202 bytes --]

Hello,

I am investigating an issue we're seeing with GCC 4.7 where the compiler
produces a DW_OP_GNU_deref_type like this:

        .byte   0x5     # DW_AT_GNU_call_site_value
        .byte   0x91    # DW_OP_fbreg
        .sleb128 0
        .byte   0xf6    # DW_OP_GNU_deref_type
        .byte   0x4
        .uleb128 0x25

This is what we get when GDB tries to print the parameter value's
at entry:

    file_1.export_1 (param_1=99.0, param_1@entry=<error reading variable: Could not find type for DW_OP_GNU_const_type>, str=...) at file_1.adb:3

I think I tracked the problem down, but I am unsure of where the problem
should be fixed. So, here's what happens:

GDB finds the DW_OP_GNU_deref_type operand, and starts evaluating it.
This is in dwarf2expr.c:

        case DW_OP_GNU_deref_type:
          {
            [...]
            if (op == DW_OP_GNU_deref_type)
              {
                op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
                type = dwarf_get_base_type (ctx, type_die, 0);
              }

Here, read_uleb128 returns 0x25, as expected, and the associated
die should be:

        .uleb128 0x2    # (DIE (0x25) DW_TAG_base_type)
        .byte   0x4     # DW_AT_byte_size
        .byte   0x4     # DW_AT_encoding
        .long   .LASF3  # DW_AT_name: "FLOAT_32"

However, dwarf_get_base_type fails to find it, and it's fairly easy
to figure out why: dwarf_get_base_type just calls ctx->funcs->get_base_type,
which is dwarf_expr_get_base_type. And the latter is merely a wrapper
around dwarf2_get_die_type:

> static struct type *
> dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
> {
>   struct dwarf_expr_baton *debaton = ctx->baton;
>
>   return dwarf2_get_die_type (die_offset, debaton->per_cu);
> }

And dwarf2_get_die_type (through get_die_type_at_offset) try to locate
the DIE by searching through the debug_types_type_hash by using that
same offset (0x25).

However, 0x25 is the offset within the unit, whereas the DIE was actually
inserted using the absolute offset. So the lookup fails.

First of all, I am a little surprised that an error like this would
have slipped in, and I am really wondering whether I might be missing
something. I looked at http://www.dwarfstd.org/doc/040408.1.html, to
see if maybe the offset was supposed to be relocated, but it does not
appear to be the case, the text is very explicit with the fact that
the value should be an offset to the start of the CU.

The fix seems relatively simple: Add the CU's offset to the deref's
offset. But where should this be done? There are several places:

  (1) when calling dwarf_get_base_type (making dwarf_get_base_type
      require an absolute offset rather than a relative one)

  (2) Inside dwarf_get_base_type, when calling ctx->funcs->get_base_type;
      The description of that callback is unclear as to whether the
      offset is expected to be absolute or not

  (3) Inside dwarf_expr_get_base_type, when calling dwarf2_get_die_type
      (dwarf_expr_get_base_type is the ctx->funcs->get_base_type callback);

  (4) Inside dwarf2_get_die_type, when calling get_die_type_at_offset

As unbelievable as option (4) might seem (this is an exported routine
from dwarf2read.c), it almost seems like the correct one. The function's
description reads:

> /* Return the type of the DIE at DIE_OFFSET in the CU named by
>    PER_CU.  */
>
> struct type *
> dwarf2_get_die_type (unsigned int die_offset,
>                      struct dwarf2_per_cu_data *per_cu)

It seems to me that DIE_OFFSET is expected to be a relative offset.
I've audited the uses of that function, and it is used exclusively
in dwarf2loc.c, either by dwarf_expr_get_base_type, or by
disassemble_dwarf_expression, when disassembling various DW_OP_GNU_*
operands, including our DW_OP_GNU_deref_type operand. And I also
checked dwarf_expr_get_base_type, and it's only used to get the base
type of the same DW_OP_GNU_* operands.

I tested the change, and lo and behold, on x86_64-linux, I get the
following fixes:

* gdb.arch:
+------------+------------+----------------------------------------------------+
|       FAIL | PASS       | amd64-entry-value.exp: entry: bt                   |
|       FAIL | PASS       | amd64-entry-value.exp: entry: p j                  |
|       FAIL | PASS       | amd64-entry-value.exp: entry: p j@entry            |
|       FAIL | PASS       | amd64-entry-value.exp: entry_stack: bt at entry    |
|       FAIL | PASS       | amd64-entry-value.exp: entry_stack: bt             |
|       FAIL | PASS       | amd64-entry-value.exp: entry_stack: p d9@entry     |
|       FAIL | PASS       | amd64-entry-value.exp: entry_stack: p da@entry     |
|       FAIL | PASS       | amd64-entry-value.exp: tailcall: bt                |
|       FAIL | PASS       | amd64-entry-value.exp: tailcall: p j               |
|       FAIL | PASS       | amd64-entry-value.exp: tailcall: p j@entry         |
+------------+------------+----------------------------------------------------+

(and it also fixes my problem).  Thoughts?

gdb/ChangeLog:

        * dwarf2read.c (dwarf2_get_die_type): Pass absolute offset
        in call to get_die_type_at_offset.

Thanks,
-- 
Joel

[-- Attachment #2: 0001-Pass-absolute-die-offset-in-call-to-get_die_type_at_.patch --]
[-- Type: text/x-diff, Size: 907 bytes --]

From f074ef5b5e92d638e46a9e55c6b52a89ebe80141 Mon Sep 17 00:00:00 2001
From: Joel Brobecker <brobecker@adacore.com>
Date: Mon, 5 Mar 2012 14:25:41 -0800
Subject: [PATCH] Pass absolute die offset in call to get_die_type_at_offset

gdb/ChangeLog:

        * dwarf2read.c (dwarf2_get_die_type): Pass absolute offset
        in call to get_die_type_at_offset.
---
 gdb/dwarf2read.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 3fa28b1..307d98e 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14269,7 +14269,7 @@ dwarf2_get_die_type (unsigned int die_offset,
 		     struct dwarf2_per_cu_data *per_cu)
 {
   dw2_setup (per_cu->objfile);
-  return get_die_type_at_offset (die_offset, per_cu);
+  return get_die_type_at_offset (per_cu->offset + die_offset, per_cu);
 }
 
 /* Follow the signature attribute ATTR in SRC_DIE.
-- 
1.7.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback
  2012-03-05 22:34 RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback Joel Brobecker
@ 2012-03-06 20:25 ` Tom Tromey
  2012-03-06 23:46   ` Joel Brobecker
  2012-03-07 17:10 ` [patch] Fix CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback] Jan Kratochvil
  1 sibling, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2012-03-06 20:25 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

>>>>> "Joel" == Joel Brobecker <brobecker@adacore.com> writes:

Joel>         * dwarf2read.c (dwarf2_get_die_type): Pass absolute offset
Joel>         in call to get_die_type_at_offset.

Thanks for finding this.
I agree with your analysis and this patch.

Tom


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback
  2012-03-06 20:25 ` Tom Tromey
@ 2012-03-06 23:46   ` Joel Brobecker
  0 siblings, 0 replies; 20+ messages in thread
From: Joel Brobecker @ 2012-03-06 23:46 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

> >>>>> "Joel" == Joel Brobecker <brobecker@adacore.com> writes:
> 
> Joel>         * dwarf2read.c (dwarf2_get_die_type): Pass absolute offset
> Joel>         in call to get_die_type_at_offset.
> 
> I agree with your analysis and this patch.

Thanks for the review, Tom. I just checked the patch in. I'm sure
Jan will let me know if it causes any regression :-).

-- 
Joel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [patch] Fix CU relative vs. absolute offsets  [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-05 22:34 RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback Joel Brobecker
  2012-03-06 20:25 ` Tom Tromey
@ 2012-03-07 17:10 ` Jan Kratochvil
  2012-03-07 17:13   ` [patch 2/2] typedef-checking for " Jan Kratochvil
  2012-03-07 18:57   ` [patch] Fix CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback] Joel Brobecker
  1 sibling, 2 replies; 20+ messages in thread
From: Jan Kratochvil @ 2012-03-07 17:10 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On Mon, 05 Mar 2012 23:34:29 +0100, Joel Brobecker wrote:
> I tested the change, and lo and behold, on x86_64-linux, I get the
> following fixes:
> 
> * gdb.arch:
> +------------+------------+----------------------------------------------------+
> |       FAIL | PASS       | amd64-entry-value.exp: entry: bt                   |

I do not understand how it can happen.  amd64-entry-value.exp uses precompiled
amd64-entry-value.s (unless you use runtest COMPILE=1) and sure it fully
PASSed+PASSes for me.

There are more issues of this kind.

I will re-review the patch later but it seems to me these fixes are needed.

No regressions on {x86_64,x86_64-m32,i686}-fedora17-linux-gnu and with
-gdwarf-4 -fdebug-types-section.

It looks as if some of the GDB features have never worked in real world - just
in the testcase which have single CU. :-)


Thanks,
Jan


2012-03-07  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix CU relative vs. absolute DIE offsets.
	* dwarf2loc.h (dwarf2_fetch_die_location_block): Rename parameter
	offset to offset_in_cu.
	* dwarf2read.c (process_enumeration_scope): Add CU offset to
	TYPE_OFFSET.
	(dwarf2_fetch_die_location_block): Rename parameter offset to
	offset_in_cu.  New variable offset, add CU offset to OFFSET_IN_CU.

--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -61,7 +61,7 @@ const gdb_byte *dwarf2_find_location_expression
    CORE_ADDR pc);
 
 struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block
-  (unsigned int offset, struct dwarf2_per_cu_data *per_cu,
+  (unsigned int offset_in_cu, struct dwarf2_per_cu_data *per_cu,
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton);
 
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -8031,7 +8031,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
 	= lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile,
 					    cu->per_cu->debug_types_section,
 					    cu->per_cu->offset);
-      if (type_sig->type_offset != die->offset)
+      if (type_sig->per_cu.offset + type_sig->type_offset
+	  != die->offset)
 	return;
     }
 
@@ -14202,11 +14203,12 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr,
    dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE.  */
 
 struct dwarf2_locexpr_baton
-dwarf2_fetch_die_location_block (unsigned int offset,
+dwarf2_fetch_die_location_block (unsigned int offset_in_cu,
 				 struct dwarf2_per_cu_data *per_cu,
 				 CORE_ADDR (*get_frame_pc) (void *baton),
 				 void *baton)
 {
+  unsigned int offset = per_cu->offset + offset_in_cu;
   struct dwarf2_cu *cu;
   struct die_info *die;
   struct attribute *attr;


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [patch 2/2] typedef-checking for CU relative vs. absolute offsets  [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 17:10 ` [patch] Fix CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback] Jan Kratochvil
@ 2012-03-07 17:13   ` Jan Kratochvil
  2012-03-07 18:58     ` Doug Evans
                       ` (2 more replies)
  2012-03-07 18:57   ` [patch] Fix CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback] Joel Brobecker
  1 sibling, 3 replies; 20+ messages in thread
From: Jan Kratochvil @ 2012-03-07 17:13 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On Wed, 07 Mar 2012 18:09:40 +0100, Jan Kratochvil wrote:
> There are more issues of this kind.

This is not maintainable IMO in its current form.

typedef struct { unsigned int co; } cu_offset;
typedef struct { unsigned int so; } sect_offset;

OK with the patch?

I will write the ChangeLog only after some agreement of it.


Thanks,
Jan


--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -342,7 +342,7 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset)
     }
   else if (p->location == DWARF_VALUE_IMPLICIT_POINTER)
     {
-      p->v.ptr.die = ctx->len;
+      p->v.ptr.die.co = ctx->len;
       p->v.ptr.offset = value_as_long (dwarf_expr_fetch (ctx, 0));
     }
   else if (p->location == DWARF_VALUE_REGISTER)
@@ -464,7 +464,7 @@ base_types_equal_p (struct type *t1, struct type *t2)
    size.  */
 
 static struct type *
-dwarf_get_base_type (struct dwarf_expr_context *ctx, ULONGEST die, int size)
+dwarf_get_base_type (struct dwarf_expr_context *ctx, cu_offset die, int size)
 {
   struct type *result;
 
@@ -869,7 +869,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	      error (_("DWARF-2 expression error: DW_OP_GNU_implicit_pointer "
 		       "is not allowed in frame context"));
 
-	    /* The referred-to DIE.  */
+	    /* The referred-to DIE of cu_offset kind.  */
 	    ctx->len = extract_unsigned_integer (op_ptr, ctx->ref_addr_size,
 						 byte_order);
 	    op_ptr += ctx->ref_addr_size;
@@ -1031,9 +1031,10 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	    if (op == DW_OP_GNU_deref_type)
 	      {
-		ULONGEST type_die;
+		cu_offset type_die;
 
-		op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+		op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
+		type_die.co = uoffset;
 		type = dwarf_get_base_type (ctx, type_die, 0);
 	      }
 	    else
@@ -1335,15 +1336,23 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  goto no_push;
 
 	case DW_OP_call2:
-	  result = extract_unsigned_integer (op_ptr, 2, byte_order);
-	  op_ptr += 2;
-	  ctx->funcs->dwarf_call (ctx, result);
+	  {
+	    cu_offset offset;
+
+	    offset.co = extract_unsigned_integer (op_ptr, 2, byte_order);
+	    op_ptr += 2;
+	    ctx->funcs->dwarf_call (ctx, offset);
+	  }
 	  goto no_push;
 
 	case DW_OP_call4:
-	  result = extract_unsigned_integer (op_ptr, 4, byte_order);
-	  op_ptr += 4;
-	  ctx->funcs->dwarf_call (ctx, result);
+	  {
+	    cu_offset offset;
+
+	    offset.co = extract_unsigned_integer (op_ptr, 4, byte_order);
+	    op_ptr += 4;
+	    ctx->funcs->dwarf_call (ctx, offset);
+	  }
 	  goto no_push;
 	
 	case DW_OP_GNU_entry_value:
@@ -1386,12 +1395,13 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_GNU_const_type:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 	    int n;
 	    const gdb_byte *data;
 	    struct type *type;
 
-	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
+	    type_die.co = uoffset;
 	    n = *op_ptr++;
 	    data = op_ptr;
 	    op_ptr += n;
@@ -1403,11 +1413,12 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 
 	case DW_OP_GNU_regval_type:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 	    struct type *type;
 
 	    op_ptr = read_uleb128 (op_ptr, op_end, &reg);
-	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
+	    type_die.co = uoffset;
 
 	    type = dwarf_get_base_type (ctx, type_die, 0);
 	    result = (ctx->funcs->read_reg) (ctx->baton, reg);
@@ -1420,12 +1431,13 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	case DW_OP_GNU_convert:
 	case DW_OP_GNU_reinterpret:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 	    struct type *type;
 
-	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
+	    type_die.co = uoffset;
 
-	    if (type_die == 0)
+	    if (type_die.co == 0)
 	      type = address_type;
 	    else
 	      type = dwarf_get_base_type (ctx, type_die, 0);
@@ -1506,7 +1518,7 @@ ctx_no_get_tls_address (void *baton, CORE_ADDR offset)
 /* Stub dwarf_expr_context_funcs.dwarf_call implementation.  */
 
 void
-ctx_no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+ctx_no_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
 {
   error (_("%s is invalid in this context"), "DW_OP_call*");
 }
@@ -1514,7 +1526,7 @@ ctx_no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 /* Stub dwarf_expr_context_funcs.get_base_type implementation.  */
 
 struct type *
-ctx_no_get_base_type (struct dwarf_expr_context *ctx, size_t die)
+ctx_no_get_base_type (struct dwarf_expr_context *ctx, cu_offset die)
 {
   error (_("Support for typed DWARF is not supported in this context"));
 }
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -25,6 +25,18 @@
 
 struct dwarf_expr_context;
 
+/* Offset relative to the start of its containing CU (compilation unit).  */
+typedef struct
+{
+  unsigned int co;
+} cu_offset;
+
+/* Offset relative to the start of its .debug_info or .debug_types section.  */
+typedef struct
+{
+  unsigned int so;
+} sect_offset;
+
 /* Virtual method table for struct dwarf_expr_context below.  */
 
 struct dwarf_expr_context_funcs
@@ -53,14 +65,14 @@ struct dwarf_expr_context_funcs
   /* Execute DW_AT_location expression for the DWARF expression subroutine in
      the DIE at DIE_OFFSET in the CU from CTX.  Do not touch STACK while it
      being passed to and returned from the called DWARF subroutine.  */
-  void (*dwarf_call) (struct dwarf_expr_context *ctx, size_t die_offset);
+  void (*dwarf_call) (struct dwarf_expr_context *ctx, cu_offset die_offset);
 
   /* Return the base type given by the indicated DIE.  This can throw
      an exception if the DIE is invalid or does not represent a base
      type.  If can also be NULL in the special case where the
      callbacks are not performing evaluation, and thus it is
      meaningful to substitute a stub type of the correct size.  */
-  struct type *(*get_base_type) (struct dwarf_expr_context *ctx, size_t die);
+  struct type *(*get_base_type) (struct dwarf_expr_context *ctx, cu_offset die);
 
   /* Push on DWARF stack an entry evaluated for DW_TAG_GNU_call_site's
      DWARF_REG/FB_OFFSET at the caller of specified BATON.  If DWARF register
@@ -160,7 +172,7 @@ struct dwarf_expr_context
 
   /* For DWARF_VALUE_LITERAL, the current literal value's length and
      data.  For DWARF_VALUE_IMPLICIT_POINTER, LEN is the offset of the
-     target DIE.  */
+     target DIE of cu_offset kind.  */
   ULONGEST len;
   const gdb_byte *data;
 
@@ -231,7 +243,7 @@ struct dwarf_expr_piece
     struct
     {
       /* The referent DIE from DW_OP_GNU_implicit_pointer.  */
-      ULONGEST die;
+      cu_offset die;
       /* The byte offset into the resulting data.  */
       LONGEST offset;
     } ptr;
@@ -275,8 +287,9 @@ void ctx_no_get_frame_base (void *baton, const gdb_byte **start,
 CORE_ADDR ctx_no_get_frame_cfa (void *baton);
 CORE_ADDR ctx_no_get_frame_pc (void *baton);
 CORE_ADDR ctx_no_get_tls_address (void *baton, CORE_ADDR offset);
-void ctx_no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset);
-struct type *ctx_no_get_base_type (struct dwarf_expr_context *ctx, size_t die);
+void ctx_no_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset);
+struct type *ctx_no_get_base_type (struct dwarf_expr_context *ctx,
+				   cu_offset die);
 void ctx_no_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
 					int dwarf_reg, CORE_ADDR fb_offset,
 					int deref_size);
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -282,7 +282,7 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
    call and return.  */
 
 static void
-per_cu_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset,
+per_cu_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset,
 		   struct dwarf2_per_cu_data *per_cu,
 		   CORE_ADDR (*get_frame_pc) (void *baton),
 		   void *baton)
@@ -301,7 +301,7 @@ per_cu_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset,
 /* Helper interface of per_cu_dwarf_call for dwarf2_evaluate_loc_desc.  */
 
 static void
-dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
 {
   struct dwarf_expr_baton *debaton = ctx->baton;
 
@@ -312,7 +312,8 @@ dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 /* Callback function for dwarf2_evaluate_loc_desc.  */
 
 static struct type *
-dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
+dwarf_expr_get_base_type (struct dwarf_expr_context *ctx,
+			  cu_offset die_offset)
 {
   struct dwarf_expr_baton *debaton = ctx->baton;
 
@@ -2219,7 +2220,7 @@ needs_frame_tls_address (void *baton, CORE_ADDR offset)
 /* Helper interface of per_cu_dwarf_call for dwarf2_loc_desc_needs_frame.  */
 
 static void
-needs_frame_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+needs_frame_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
 {
   struct needs_frame_baton *nf_baton = ctx->baton;
 
@@ -3012,11 +3013,13 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
 	  {
 	    struct dwarf2_locexpr_baton block;
 	    int size = (op == DW_OP_call2 ? 2 : 4);
+	    cu_offset offset;
 
 	    uoffset = extract_unsigned_integer (op_ptr, size, byte_order);
 	    op_ptr += size;
 
-	    block = dwarf2_fetch_die_location_block (uoffset, per_cu,
+	    offset.co = uoffset;
+	    block = dwarf2_fetch_die_location_block (offset, per_cu,
 						     get_ax_pc, expr);
 
 	    /* DW_OP_call_ref is currently not supported.  */
@@ -3515,43 +3518,48 @@ disassemble_dwarf_expression (struct ui_file *stream,
 	case DW_OP_GNU_deref_type:
 	  {
 	    int addr_size = *data++;
-	    ULONGEST offset;
+	    cu_offset offset;
 	    struct type *type;
 
-	    data = read_uleb128 (data, end, &offset);
+	    data = read_uleb128 (data, end, &ul);
+	    offset.co = ul;
 	    type = dwarf2_get_die_type (offset, per_cu);
 	    fprintf_filtered (stream, "<");
 	    type_print (type, "", stream, -1);
-	    fprintf_filtered (stream, " [0x%s]> %d", phex_nz (offset, 0),
+	    fprintf_filtered (stream, " [0x%s]> %d", phex_nz (offset.co, 0),
 			      addr_size);
 	  }
 	  break;
 
 	case DW_OP_GNU_const_type:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 	    struct type *type;
 
-	    data = read_uleb128 (data, end, &type_die);
+	    data = read_uleb128 (data, end, &ul);
+	    type_die.co = ul;
 	    type = dwarf2_get_die_type (type_die, per_cu);
 	    fprintf_filtered (stream, "<");
 	    type_print (type, "", stream, -1);
-	    fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die, 0));
+	    fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die.co, 0));
 	  }
 	  break;
 
 	case DW_OP_GNU_regval_type:
 	  {
-	    ULONGEST type_die, reg;
+	    ULONGEST reg;
+	    cu_offset type_die;
 	    struct type *type;
 
 	    data = read_uleb128 (data, end, &reg);
-	    data = read_uleb128 (data, end, &type_die);
+	    data = read_uleb128 (data, end, &ul);
+	    type_die.co = ul;
 
 	    type = dwarf2_get_die_type (type_die, per_cu);
 	    fprintf_filtered (stream, "<");
 	    type_print (type, "", stream, -1);
-	    fprintf_filtered (stream, " [0x%s]> [$%s]", phex_nz (type_die, 0),
+	    fprintf_filtered (stream, " [0x%s]> [$%s]",
+			      phex_nz (type_die.co, 0),
 			      locexpr_regname (arch, reg));
 	  }
 	  break;
@@ -3559,11 +3567,12 @@ disassemble_dwarf_expression (struct ui_file *stream,
 	case DW_OP_GNU_convert:
 	case DW_OP_GNU_reinterpret:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 
-	    data = read_uleb128 (data, end, &type_die);
+	    data = read_uleb128 (data, end, &ul);
+	    type_die.co = ul;
 
-	    if (type_die == 0)
+	    if (type_die.co == 0)
 	      fprintf_filtered (stream, "<0>");
 	    else
 	      {
@@ -3572,7 +3581,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
 		type = dwarf2_get_die_type (type_die, per_cu);
 		fprintf_filtered (stream, "<");
 		type_print (type, "", stream, -1);
-		fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die, 0));
+		fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die.co, 0));
 	      }
 	  }
 	  break;
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -20,6 +20,8 @@
 #if !defined (DWARF2LOC_H)
 #define DWARF2LOC_H
 
+#include "dwarf2expr.h"
+
 struct symbol_computed_ops;
 struct objfile;
 struct dwarf2_per_cu_data;
@@ -61,11 +63,11 @@ const gdb_byte *dwarf2_find_location_expression
    CORE_ADDR pc);
 
 struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block
-  (unsigned int offset_in_cu, struct dwarf2_per_cu_data *per_cu,
+  (cu_offset offset_in_cu, struct dwarf2_per_cu_data *per_cu,
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton);
 
-struct type *dwarf2_get_die_type (unsigned int die_offset,
+struct type *dwarf2_get_die_type (cu_offset die_offset,
 				  struct dwarf2_per_cu_data *per_cu);
 
 /* Evaluate a location description, starting at DATA and with length
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -213,7 +213,7 @@ struct dwarf2_per_objfile
      To keep things simple we allocate both lazily.  */
   htab_t debug_info_type_hash;
 
-  /* Table mapping type .debug_types DIE offsets to types.
+  /* Table mapping type .debug_types DIE sect_offset to types.
      This is NULL if not allocated yet.  */
   htab_t debug_types_type_hash;
 };
@@ -257,7 +257,7 @@ struct comp_unit_head
   short version;
   unsigned char addr_size;
   unsigned char signed_addr_p;
-  unsigned int abbrev_offset;
+  sect_offset abbrev_offset;
 
   /* Size of file offsets; either 4 or 8.  */
   unsigned int offset_size;
@@ -267,11 +267,11 @@ struct comp_unit_head
 
   /* Offset to the first byte of this compilation unit header in the
      .debug_info section, for resolving relative reference dies.  */
-  unsigned int offset;
+  sect_offset offset;
 
   /* Offset to first die in this cu from the start of the cu.
      This will be the first byte following the compilation unit header.  */
-  unsigned int first_die_offset;
+  cu_offset first_die_offset;
 };
 
 /* Type used for delaying computation of method physnames.
@@ -335,7 +335,8 @@ struct dwarf2_cu
   /* Storage for the abbrev table.  */
   struct obstack abbrev_obstack;
 
-  /* Hash table holding all the loaded partial DIEs.  */
+  /* Hash table holding all the loaded partial DIEs with partial_die->offset.so
+     as hash.  */
   htab_t partial_dies;
 
   /* Storage for things with the same lifetime as this read-in compilation
@@ -354,7 +355,8 @@ struct dwarf2_cu
   /* How many compilation units ago was this CU last referenced?  */
   int last_used;
 
-  /* A hash table of die offsets for following references.  */
+  /* A hash table of DIE cu_offset for following references with
+     die_info->offset.so as hash.  */
   htab_t die_hash;
 
   /* Full DIEs if read in.  */
@@ -396,7 +398,7 @@ struct dwarf2_per_cu_data
      - if it doesn't, GDB will fall over anyway.
      NOTE: Unlike comp_unit_head.length, this length includes
      initial_length_size.  */
-  unsigned int offset;
+  sect_offset offset;
   unsigned int length : 29;
 
   /* Flag indicating this compilation unit will be read in before
@@ -442,8 +444,8 @@ struct signatured_type
 {
   ULONGEST signature;
 
-  /* Offset in .debug_types of the type defined by this TU.  */
-  unsigned int type_offset;
+  /* Offset in this TU of the type defined by this TU.  */
+  cu_offset type_offset;
 
   /* The CU(/TU) of this type.  */
   struct dwarf2_per_cu_data per_cu;
@@ -520,7 +522,7 @@ struct line_header
 struct partial_die_info
   {
     /* Offset of this DIE.  */
-    unsigned int offset;
+    sect_offset offset;
 
     /* DWARF-2 tag for this DIE.  */
     ENUM_BITFIELD(dwarf_tag) tag : 16;
@@ -574,7 +576,7 @@ struct partial_die_info
     /* If HAS_SPECIFICATION, the offset of the DIE referred to by
        DW_AT_specification (or DW_AT_abstract_origin or
        DW_AT_extension).  */
-    unsigned int spec_offset;
+    sect_offset spec_offset;
 
     /* Pointers to this DIE's parent, first child, and next sibling,
        if any.  */
@@ -638,7 +640,7 @@ struct die_info
     unsigned int abbrev;
 
     /* Offset in .debug_info or .debug_types section.  */
-    unsigned int offset;
+    sect_offset offset;
 
     /* The dies in a compilation unit form an n-ary tree.  PARENT
        points to this die's parent; CHILD points to the first child of
@@ -900,7 +902,7 @@ static gdb_byte *read_partial_die (struct partial_die_info *,
 				   gdb_byte *, gdb_byte *,
 				   struct dwarf2_cu *);
 
-static struct partial_die_info *find_partial_die (unsigned int,
+static struct partial_die_info *find_partial_die (sect_offset,
 						  struct dwarf2_cu *);
 
 static void fixup_partial_die (struct partial_die_info *,
@@ -1151,7 +1153,7 @@ static void store_in_ref_table (struct die_info *,
 
 static int is_ref_attr (struct attribute *);
 
-static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+static sect_offset dwarf2_get_ref_die_offset (struct attribute *);
 
 static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int);
 
@@ -1169,8 +1171,7 @@ static struct die_info *follow_die_sig (struct die_info *,
 
 static struct signatured_type *lookup_signatured_type_at_offset
     (struct objfile *objfile,
-     struct dwarf2_section_info *section,
-     unsigned int offset);
+     struct dwarf2_section_info *section, sect_offset offset);
 
 static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu);
 
@@ -1214,7 +1215,7 @@ static hashval_t partial_die_hash (const void *item);
 static int partial_die_eq (const void *item_lhs, const void *item_rhs);
 
 static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
-  (unsigned int offset, struct objfile *objfile);
+  (sect_offset offset, struct objfile *objfile);
 
 static void init_one_comp_unit (struct dwarf2_cu *cu,
 				struct dwarf2_per_cu_data *per_cu);
@@ -1248,7 +1249,7 @@ static void dwarf2_mark (struct dwarf2_cu *);
 
 static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
 
-static struct type *get_die_type_at_offset (unsigned int,
+static struct type *get_die_type_at_offset (sect_offset,
 					    struct dwarf2_per_cu_data *per_cu);
 
 static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
@@ -1880,7 +1881,7 @@ create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list,
 
       the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
 			       struct dwarf2_per_cu_data);
-      the_cu->offset = offset;
+      the_cu->offset.so = offset;
       the_cu->length = length;
       the_cu->objfile = objfile;
       the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
@@ -1925,9 +1926,9 @@ create_signatured_type_table_from_index (struct objfile *objfile,
       type_sig = OBSTACK_ZALLOC (&objfile->objfile_obstack,
 				 struct signatured_type);
       type_sig->signature = signature;
-      type_sig->type_offset = type_offset;
+      type_sig->type_offset.co = type_offset;
       type_sig->per_cu.debug_types_section = section;
-      type_sig->per_cu.offset = offset;
+      type_sig->per_cu.offset.so = offset;
       type_sig->per_cu.objfile = objfile;
       type_sig->per_cu.v.quick
 	= OBSTACK_ZALLOC (&objfile->objfile_obstack,
@@ -2229,7 +2230,7 @@ dw2_get_file_names (struct objfile *objfile,
   else
     sec = &dwarf2_per_objfile->info;
   dwarf2_read_section (objfile, sec);
-  info_ptr = sec->buffer + this_cu->offset;
+  info_ptr = sec->buffer + this_cu->offset.so;
 
   info_ptr = read_and_check_comp_unit_head (&cu.header, sec, info_ptr,
 					    this_cu->debug_types_section != NULL);
@@ -2955,14 +2956,13 @@ dwarf2_build_psymtabs (struct objfile *objfile)
 /* Return TRUE if OFFSET is within CU_HEADER.  */
 
 static inline int
-offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset)
+offset_in_cu_p (const struct comp_unit_head *cu_header, sect_offset offset)
 {
-  unsigned int bottom = cu_header->offset;
-  unsigned int top = (cu_header->offset
-		      + cu_header->length
-		      + cu_header->initial_length_size);
+  sect_offset bottom = { cu_header->offset.so };
+  sect_offset top = { (cu_header->offset.so + cu_header->length
+		       + cu_header->initial_length_size) };
 
-  return (offset >= bottom && offset < top);
+  return (offset.so >= bottom.so && offset.so < top.so);
 }
 
 /* Read in the comp unit header information from the debug_info at info_ptr.
@@ -2982,8 +2982,8 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
   info_ptr += bytes_read;
   cu_header->version = read_2_bytes (abfd, info_ptr);
   info_ptr += 2;
-  cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header,
-					  &bytes_read);
+  cu_header->abbrev_offset.so = read_offset (abfd, info_ptr, cu_header,
+					     &bytes_read);
   info_ptr += bytes_read;
   cu_header->addr_size = read_1_byte (abfd, info_ptr);
   info_ptr += 1;
@@ -3012,22 +3012,22 @@ error_check_comp_unit_head (struct comp_unit_head *header,
 	   "(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
 	   filename);
 
-  if (header->abbrev_offset
+  if (header->abbrev_offset.so
       >= dwarf2_section_size (dwarf2_per_objfile->objfile,
 			      &dwarf2_per_objfile->abbrev))
     error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
 	   "(offset 0x%lx + 6) [in module %s]"),
-	   (long) header->abbrev_offset, (long) header->offset,
+	   (long) header->abbrev_offset.so, (long) header->offset.so,
 	   filename);
 
   /* Cast to unsigned long to use 64-bit arithmetic when possible to
      avoid potential 32-bit overflow.  */
-  if (((unsigned long) header->offset
+  if (((unsigned long) header->offset.so
        + header->length + header->initial_length_size)
       > section->size)
     error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
 	   "(offset 0x%lx + 0) [in module %s]"),
-	   (long) header->length, (long) header->offset,
+	   (long) header->length, (long) header->offset.so,
 	   filename);
 }
 
@@ -3044,7 +3044,7 @@ read_and_check_comp_unit_head (struct comp_unit_head *header,
   gdb_byte *beg_of_comp_unit = info_ptr;
   bfd *abfd = section->asection->owner;
 
-  header->offset = beg_of_comp_unit - section->buffer;
+  header->offset.so = beg_of_comp_unit - section->buffer;
 
   info_ptr = read_comp_unit_head (header, info_ptr, abfd);
 
@@ -3053,7 +3053,7 @@ read_and_check_comp_unit_head (struct comp_unit_head *header,
   if (is_debug_types_section)
     info_ptr += 8 /*signature*/ + header->offset_size;
 
-  header->first_die_offset = info_ptr - beg_of_comp_unit;
+  header->first_die_offset.co = info_ptr - beg_of_comp_unit;
 
   error_check_comp_unit_head (header, section);
 
@@ -3067,12 +3067,12 @@ static gdb_byte *
 read_and_check_type_unit_head (struct comp_unit_head *header,
 			       struct dwarf2_section_info *section,
 			       gdb_byte *info_ptr,
-			       ULONGEST *signature, unsigned int *type_offset)
+			       ULONGEST *signature, cu_offset *type_offset)
 {
   gdb_byte *beg_of_comp_unit = info_ptr;
   bfd *abfd = section->asection->owner;
 
-  header->offset = beg_of_comp_unit - section->buffer;
+  header->offset.so = beg_of_comp_unit - section->buffer;
 
   info_ptr = read_comp_unit_head (header, info_ptr, abfd);
 
@@ -3082,10 +3082,10 @@ read_and_check_type_unit_head (struct comp_unit_head *header,
     *signature = read_8_bytes (abfd, info_ptr);
   info_ptr += 8;
   if (type_offset != NULL)
-    *type_offset = read_offset_1 (abfd, info_ptr, header->offset_size);
+    type_offset->co = read_offset_1 (abfd, info_ptr, header->offset_size);
   info_ptr += header->offset_size;
 
-  header->first_die_offset = info_ptr - beg_of_comp_unit;
+  header->first_die_offset.co = info_ptr - beg_of_comp_unit;
 
   error_check_comp_unit_head (header, section);
 
@@ -3241,15 +3241,15 @@ create_debug_types_hash_table (struct objfile *objfile)
       end_ptr = info_ptr + section->size;
       while (info_ptr < end_ptr)
 	{
-	  unsigned int offset;
-	  unsigned int type_offset;
+	  sect_offset offset;
+	  cu_offset type_offset;
 	  ULONGEST signature;
 	  struct signatured_type *type_sig;
 	  void **slot;
 	  gdb_byte *ptr = info_ptr;
 	  struct comp_unit_head header;
 
-	  offset = ptr - section->buffer;
+	  offset.so = ptr - section->buffer;
 
 	  /* We need to read the type's signature in order to build the hash
 	     table, but we don't need anything else just yet.  */
@@ -3281,7 +3281,7 @@ create_debug_types_hash_table (struct objfile *objfile)
 	      complaint (&symfile_complaints,
 			 _("debug type entry at offset 0x%x is duplicate to the "
 			   "entry at offset 0x%x, signature 0x%s"),
-			 offset, dup_sig->per_cu.offset,
+			 offset.so, dup_sig->per_cu.offset.so,
 			 phex (signature, sizeof (signature)));
 	      gdb_assert (signature == dup_sig->signature);
 	    }
@@ -3289,7 +3289,8 @@ create_debug_types_hash_table (struct objfile *objfile)
 
 	  if (dwarf2_die_debug)
 	    fprintf_unfiltered (gdb_stdlog, "  offset 0x%x, signature 0x%s\n",
-				offset, phex (signature, sizeof (signature)));
+				offset.so,
+				phex (signature, sizeof (signature)));
 
 	  info_ptr = info_ptr + header.initial_length_size + header.length;
 	}
@@ -3395,7 +3396,7 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
   struct objfile *objfile = this_cu->objfile;
   bfd *abfd = objfile->obfd;
   gdb_byte *buffer = section->buffer;
-  gdb_byte *info_ptr = buffer + this_cu->offset;
+  gdb_byte *info_ptr = buffer + this_cu->offset.so;
   unsigned int buffer_size = section->size;
   gdb_byte *beg_of_comp_unit = info_ptr;
   struct die_info *comp_unit_die;
@@ -3450,7 +3451,7 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
   if (is_debug_types_section)
     {
       /* LENGTH has not been set yet for type units.  */
-      gdb_assert (this_cu->offset == cu.header.offset);
+      gdb_assert (this_cu->offset.so == cu.header.offset.so);
       this_cu->length = cu.header.length + cu.header.initial_length_size;
     }
   else if (comp_unit_die->tag == DW_TAG_partial_unit)
@@ -3657,7 +3658,7 @@ load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
   gdb_assert (! this_cu->debug_types_section);
 
   gdb_assert (section->readin);
-  info_ptr = section->buffer + this_cu->offset;
+  info_ptr = section->buffer + this_cu->offset.so;
 
   if (this_cu->cu == NULL)
     {
@@ -3687,7 +3688,7 @@ load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
   else
     {
       cu = this_cu->cu;
-      info_ptr += cu->header.first_die_offset;
+      info_ptr += cu->header.first_die_offset.co;
     }
 
   /* Read the abbrevs for this compilation unit into a table.  */
@@ -3742,9 +3743,9 @@ create_all_comp_units (struct objfile *objfile)
     {
       unsigned int length, initial_length_size;
       struct dwarf2_per_cu_data *this_cu;
-      unsigned int offset;
+      sect_offset offset;
 
-      offset = info_ptr - dwarf2_per_objfile->info.buffer;
+      offset.so = info_ptr - dwarf2_per_objfile->info.buffer;
 
       /* Read just enough information to find out where the next
 	 compilation unit is.  */
@@ -3946,7 +3947,7 @@ partial_die_parent_scope (struct partial_die_info *pdi,
 	 ignoring them.  */
       complaint (&symfile_complaints,
 		 _("unhandled containing DIE tag %d for DIE at %d"),
-		 parent->tag, pdi->offset);
+		 parent->tag, pdi->offset.so);
       parent->scope = grandparent_scope;
     }
 
@@ -3976,9 +3977,10 @@ partial_die_full_name (struct partial_die_info *pdi,
 	  struct attribute attr;
 	  struct dwarf2_cu *ref_cu = cu;
 
+	  /* DW_FORM_ref_addr is using section offset.  */
 	  attr.name = 0;
 	  attr.form = DW_FORM_ref_addr;
-	  attr.u.addr = pdi->offset;
+	  attr.u.addr = pdi->offset.so;
 	  die = follow_die_ref (NULL, &attr, &ref_cu);
 
 	  return xstrdup (dwarf2_full_name (NULL, die, ref_cu));
@@ -4369,7 +4371,7 @@ skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
 	    complaint (&symfile_complaints,
 		       _("ignoring absolute DW_AT_sibling"));
 	  else
-	    return buffer + dwarf2_get_ref_die_offset (&attr);
+	    return buffer + dwarf2_get_ref_die_offset (&attr).so;
 	}
 
       /* If it isn't DW_AT_sibling, skip this attribute.  */
@@ -4653,7 +4655,7 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
   struct objfile *objfile = per_cu->objfile;
   bfd *abfd = objfile->obfd;
   struct dwarf2_cu *cu;
-  unsigned int offset;
+  sect_offset offset;
   gdb_byte *info_ptr, *beg_of_comp_unit;
   struct cleanup *free_cu_cleanup = NULL;
   struct attribute *attr;
@@ -4665,7 +4667,7 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
   offset = per_cu->offset;
 
   dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
-  info_ptr = dwarf2_per_objfile->info.buffer + offset;
+  info_ptr = dwarf2_per_objfile->info.buffer + offset.so;
   beg_of_comp_unit = info_ptr;
 
   if (per_cu->cu == NULL)
@@ -4692,7 +4694,7 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
 
       /* Complete the cu_header.  */
       cu->header.offset = offset;
-      cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
+      cu->header.first_die_offset.co = info_ptr - beg_of_comp_unit;
 
       /* Link this CU into read_in_chain.  */
       per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
@@ -4701,7 +4703,7 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
   else
     {
       cu = per_cu->cu;
-      info_ptr += cu->header.first_die_offset;
+      info_ptr += cu->header.first_die_offset.co;
     }
 
   cu->dies = read_comp_unit (info_ptr, cu);
@@ -5334,7 +5336,7 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
 	  complaint (&symfile_complaints,
 		     _("Computed physname <%s> does not match demangled <%s> "
 		       "(from linkage <%s>) - DIE at 0x%x [in module %s]"),
-		     physname, canon, mangled, die->offset, objfile->name);
+		     physname, canon, mangled, die->offset.so, objfile->name);
 
 	  /* Prefer DW_AT_linkage_name (in the CANON form) - when it
 	     is available here - over computed PHYSNAME.  It is safer
@@ -5471,7 +5473,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
 	    complaint (&symfile_complaints,
 		       _("child DW_TAG_imported_declaration expected "
 			 "- DIE at 0x%x [in module %s]"),
-		       child_die->offset, objfile->name);
+		       child_die->offset.so, objfile->name);
 	    continue;
 	  }
 
@@ -5492,7 +5494,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
 	    complaint (&symfile_complaints,
 		       _("child DW_TAG_imported_declaration has unknown "
 			 "imported name - DIE at 0x%x [in module %s]"),
-		       child_die->offset, objfile->name);
+		       child_die->offset.so, objfile->name);
 	    continue;
 	  }
 
@@ -5799,8 +5801,8 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *child_die;
   unsigned die_children_count;
   /* CU offsets which were referenced by children of the current DIE.  */
-  unsigned *offsets;
-  unsigned *offsets_end, *offsetp;
+  sect_offset *offsets;
+  sect_offset *offsets_end, *offsetp;
   /* Parent of DIE - referenced by DW_AT_abstract_origin.  */
   struct die_info *origin_die;
   /* Iterator of the ORIGIN_DIE children.  */
@@ -5830,7 +5832,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
 	   && origin_die->tag == DW_TAG_subprogram))
     complaint (&symfile_complaints,
 	       _("DIE 0x%x and its abstract origin 0x%x have different tags"),
-	       die->offset, origin_die->offset);
+	       die->offset.so, origin_die->offset.so);
 
   child_die = die->child;
   die_children_count = 0;
@@ -5873,13 +5875,13 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
 		   && child_origin_die->tag == DW_TAG_subprogram))
 	    complaint (&symfile_complaints,
 		       _("Child DIE 0x%x and its abstract origin 0x%x have "
-			 "different tags"), child_die->offset,
-		       child_origin_die->offset);
+			 "different tags"), child_die->offset.so,
+		       child_origin_die->offset.so);
 	  if (child_origin_die->parent != origin_die)
 	    complaint (&symfile_complaints,
 		       _("Child DIE 0x%x and its abstract origin 0x%x have "
-			 "different parents"), child_die->offset,
-		       child_origin_die->offset);
+			 "different parents"), child_die->offset.so,
+		       child_origin_die->offset.so);
 	  else
 	    *offsets_end++ = child_origin_die->offset;
 	}
@@ -5888,20 +5890,20 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
   qsort (offsets, offsets_end - offsets, sizeof (*offsets),
 	 unsigned_int_compar);
   for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
-    if (offsetp[-1] == *offsetp)
+    if (offsetp[-1].so == offsetp->so)
       complaint (&symfile_complaints,
 		 _("Multiple children of DIE 0x%x refer "
 		   "to DIE 0x%x as their abstract origin"),
-		 die->offset, *offsetp);
+		 die->offset.so, offsetp->so);
 
   offsetp = offsets;
   origin_child_die = origin_die->child;
   while (origin_child_die && origin_child_die->tag)
     {
       /* Is ORIGIN_CHILD_DIE referenced by any of the DIE children?  */
-      while (offsetp < offsets_end && *offsetp < origin_child_die->offset)
+      while (offsetp < offsets_end && offsetp->so < origin_child_die->offset.so)
 	offsetp++;
-      if (offsetp >= offsets_end || *offsetp > origin_child_die->offset)
+      if (offsetp >= offsets_end || offsetp->so > origin_child_die->offset.so)
 	{
 	  /* Found that ORIGIN_CHILD_DIE is really not referenced.  */
 	  process_die (origin_child_die, origin_cu);
@@ -5952,7 +5954,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (name == NULL)
     {
       complaint (&symfile_complaints,
-                 _("missing name for subprogram DIE at %d"), die->offset);
+                 _("missing name for subprogram DIE at %d"), die->offset.so);
       return;
     }
 
@@ -5963,8 +5965,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
       if (!attr || !DW_UNSND (attr))
 	complaint (&symfile_complaints,
 		   _("cannot get low and high bounds "
-		     "for subprogram DIE at %d"),
-		   die->offset);
+		     "for subprogram DIE at 0x%x"),
+		   die->offset.so);
       return;
     }
 
@@ -6176,7 +6178,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       complaint (&symfile_complaints,
 		 _("missing DW_AT_low_pc for DW_TAG_GNU_call_site "
 		   "DIE 0x%x [in module %s]"),
-		 die->offset, objfile->name);
+		 die->offset.so, objfile->name);
       return;
     }
   pc = DW_ADDR (attr) + baseaddr;
@@ -6192,7 +6194,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
       complaint (&symfile_complaints,
 		 _("Duplicate PC %s for DW_TAG_GNU_call_site "
 		   "DIE 0x%x [in module %s]"),
-		 paddress (gdbarch, pc), die->offset, objfile->name);
+		 paddress (gdbarch, pc), die->offset.so, objfile->name);
       return;
     }
 
@@ -6207,7 +6209,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 	  complaint (&symfile_complaints,
 		     _("Tag %d is not DW_TAG_GNU_call_site_parameter in "
 		       "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		     child_die->tag, child_die->offset, objfile->name);
+		     child_die->tag, child_die->offset.so, objfile->name);
 	  continue;
 	}
 
@@ -6265,7 +6267,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 	    complaint (&symfile_complaints,
 		       _("Cannot find function owning DW_TAG_GNU_call_site "
 			 "DIE 0x%x [in module %s]"),
-		       die->offset, objfile->name);
+		       die->offset.so, objfile->name);
 	}
     }
 
@@ -6302,7 +6304,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 	    complaint (&symfile_complaints,
 		       _("DW_AT_GNU_call_site_target target DIE has invalid "
 		         "physname, for referencing DIE 0x%x [in module %s]"),
-		       die->offset, objfile->name);
+		       die->offset.so, objfile->name);
 	  else
 	    SET_FIELD_PHYSNAME (call_site->target, (char *) target_physname);
 	}
@@ -6315,7 +6317,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 	    complaint (&symfile_complaints,
 		       _("DW_AT_GNU_call_site_target target DIE has invalid "
 		         "low pc, for referencing DIE 0x%x [in module %s]"),
-		       die->offset, objfile->name);
+		       die->offset.so, objfile->name);
 	  else
 	    SET_FIELD_PHYSADDR (call_site->target, lowpc + baseaddr);
 	}
@@ -6324,7 +6326,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
     complaint (&symfile_complaints,
 	       _("DW_TAG_GNU_call_site DW_AT_GNU_call_site_target is neither "
 		 "block nor reference, for DIE 0x%x [in module %s]"),
-	       die->offset, objfile->name);
+	       die->offset.so, objfile->name);
 
   call_site->per_cu = cu->per_cu;
 
@@ -6353,7 +6355,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 	  complaint (&symfile_complaints,
 		     _("No DW_FORM_block* DW_AT_location for "
 		       "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		     child_die->offset, objfile->name);
+		     child_die->offset.so, objfile->name);
 	  continue;
 	}
       parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data,
@@ -6367,7 +6369,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 		     _("Only single DW_OP_reg or DW_OP_fbreg is supported "
 		       "for DW_FORM_block* DW_AT_location for "
 		       "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		     child_die->offset, objfile->name);
+		     child_die->offset.so, objfile->name);
 	  continue;
 	}
 
@@ -6377,7 +6379,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 	  complaint (&symfile_complaints,
 		     _("No DW_FORM_block* DW_AT_GNU_call_site_value for "
 		       "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		     child_die->offset, objfile->name);
+		     child_die->offset.so, objfile->name);
 	  continue;
 	}
       parameter->value = DW_BLOCK (attr)->data;
@@ -6395,7 +6397,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 	    complaint (&symfile_complaints,
 		       _("No DW_FORM_block* DW_AT_GNU_call_site_data_value for "
 			 "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		       child_die->offset, objfile->name);
+		       child_die->offset.so, objfile->name);
 	  else
 	    {
 	      parameter->data_value = DW_BLOCK (attr)->data;
@@ -7436,9 +7438,9 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
 	{
 	  /* GCC does this, as of 2008-08-25; PR debug/37237.  */
 	  complaint (&symfile_complaints,
-		     _("Member function \"%s\" (offset %d) is virtual "
+		     _("Member function \"%s\" (offset 0x%x) is virtual "
 		       "but the vtable offset is not specified"),
-		     fieldname, die->offset);
+		     fieldname, die->offset.so);
 	  ALLOCATE_CPLUS_STRUCT_TYPE (type);
 	  TYPE_CPLUS_DYNAMIC (type) = 1;
 	}
@@ -8031,8 +8033,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
 	= lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile,
 					    cu->per_cu->debug_types_section,
 					    cu->per_cu->offset);
-      if (type_sig->per_cu.offset + type_sig->type_offset
-	  != die->offset)
+      if (type_sig->per_cu.offset.so + type_sig->type_offset.co
+	  != die->offset.so)
 	return;
     }
 
@@ -8358,7 +8360,7 @@ read_module_type (struct die_info *die, struct dwarf2_cu *cu)
   if (!module_name)
     complaint (&symfile_complaints,
 	       _("DW_TAG_module has no name, offset 0x%x"),
-               die->offset);
+               die->offset.so);
   type = init_type (TYPE_CODE_MODULE, 0, 0, module_name, objfile);
 
   /* determine_prefix uses TYPE_TAG_NAME.  */
@@ -8814,7 +8816,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
       complaint (&symfile_complaints,
 		 _("Self-referential DW_TAG_typedef "
 		   "- DIE at 0x%x [in module %s]"),
-		 die->offset, objfile->name);
+		 die->offset.so, objfile->name);
       TYPE_TARGET_TYPE (this_type) = NULL;
     }
   return this_type;
@@ -9082,7 +9084,7 @@ die_hash (const void *item)
 {
   const struct die_info *die = item;
 
-  return die->offset;
+  return die->offset.so;
 }
 
 /* Trivial comparison function for die_info structures: two DIEs
@@ -9094,7 +9096,7 @@ die_eq (const void *item_lhs, const void *item_rhs)
   const struct die_info *die_lhs = item_lhs;
   const struct die_info *die_rhs = item_rhs;
 
-  return die_lhs->offset == die_rhs->offset;
+  return die_lhs->offset.so == die_rhs->offset.so;
 }
 
 /* Read a whole compilation unit into a linked list of dies.  */
@@ -9243,13 +9245,14 @@ read_full_die (const struct die_reader_specs *reader,
 	       struct die_info **diep, gdb_byte *info_ptr,
 	       int *has_children)
 {
-  unsigned int abbrev_number, bytes_read, i, offset;
+  unsigned int abbrev_number, bytes_read, i;
+  sect_offset offset;
   struct abbrev_info *abbrev;
   struct die_info *die;
   struct dwarf2_cu *cu = reader->cu;
   bfd *abfd = reader->abfd;
 
-  offset = info_ptr - reader->buffer;
+  offset.so = info_ptr - reader->buffer;
   abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
   info_ptr += bytes_read;
   if (!abbrev_number)
@@ -9309,7 +9312,7 @@ dwarf2_read_abbrevs (struct dwarf2_cu *cu)
 
   dwarf2_read_section (dwarf2_per_objfile->objfile,
 		       &dwarf2_per_objfile->abbrev);
-  abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset;
+  abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset.so;
   abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
   abbrev_ptr += bytes_read;
 
@@ -9596,7 +9599,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
 	complaint (&symfile_complaints,
 		   _("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
 		     "- DIE at 0x%x [in module %s]"),
-		   part_die->offset, objfile->name);
+		   part_die->offset.so, objfile->name);
 
       /* If we're at the second level, and we're an enumerator, and
 	 our parent has no specification (meaning possibly lives in a
@@ -9670,7 +9673,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
 	  void **slot;
 
 	  slot = htab_find_slot_with_hash (cu->partial_dies, part_die,
-					   part_die->offset, INSERT);
+					   part_die->offset.so, INSERT);
 	  *slot = part_die;
 	}
 
@@ -9736,7 +9739,7 @@ read_partial_die (struct partial_die_info *part_die,
 
   memset (part_die, 0, sizeof (struct partial_die_info));
 
-  part_die->offset = info_ptr - buffer;
+  part_die->offset.so = info_ptr - buffer;
 
   info_ptr += abbrev_len;
 
@@ -9829,7 +9832,7 @@ read_partial_die (struct partial_die_info *part_die,
 	    complaint (&symfile_complaints,
 		       _("ignoring absolute DW_AT_sibling"));
 	  else
-	    part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr);
+	    part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr).so;
 	  break;
         case DW_AT_byte_size:
           part_die->has_byte_size = 1;
@@ -9882,7 +9885,7 @@ read_partial_die (struct partial_die_info *part_die,
 		     _("DW_AT_low_pc %s is zero "
 		       "for DIE at 0x%x [in module %s]"),
 		     paddress (gdbarch, part_die->lowpc),
-		     part_die->offset, objfile->name);
+		     part_die->offset.so, objfile->name);
 	}
       /* dwarf2_get_pc_bounds has also the strict low < high requirement.  */
       else if (part_die->lowpc >= part_die->highpc)
@@ -9894,7 +9897,7 @@ read_partial_die (struct partial_die_info *part_die,
 		       "for DIE at 0x%x [in module %s]"),
 		     paddress (gdbarch, part_die->lowpc),
 		     paddress (gdbarch, part_die->highpc),
-		     part_die->offset, objfile->name);
+		     part_die->offset.so, objfile->name);
 	}
       else
 	part_die->has_pc_info = 1;
@@ -9906,13 +9909,13 @@ read_partial_die (struct partial_die_info *part_die,
 /* Find a cached partial DIE at OFFSET in CU.  */
 
 static struct partial_die_info *
-find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu)
+find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu)
 {
   struct partial_die_info *lookup_die = NULL;
   struct partial_die_info part_die;
 
   part_die.offset = offset;
-  lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, offset);
+  lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, offset.so);
 
   return lookup_die;
 }
@@ -9923,7 +9926,7 @@ find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu)
    DW_FORM_ref_sig8).  */
 
 static struct partial_die_info *
-find_partial_die (unsigned int offset, struct dwarf2_cu *cu)
+find_partial_die (sect_offset offset, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   struct dwarf2_per_cu_data *per_cu = NULL;
@@ -9970,8 +9973,8 @@ find_partial_die (unsigned int offset, struct dwarf2_cu *cu)
 	  make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
 	}
       info_ptr = (dwarf2_per_objfile->info.buffer
-		  + per_cu->cu->header.offset
-		  + per_cu->cu->header.first_die_offset);
+		  + per_cu->cu->header.offset.so
+		  + per_cu->cu->header.first_die_offset.co);
       abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
       info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
 				   objfile->obfd,
@@ -9992,7 +9995,7 @@ find_partial_die (unsigned int offset, struct dwarf2_cu *cu)
     internal_error (__FILE__, __LINE__,
 		    _("could not find partial DIE 0x%x "
 		      "in cache [from module %s]\n"),
-		    offset, bfd_get_filename (objfile->obfd));
+		    offset.so, bfd_get_filename (objfile->obfd));
   return pd;
 }
 
@@ -10237,19 +10240,19 @@ read_attribute_value (struct attribute *attr, unsigned form,
       info_ptr += bytes_read;
       break;
     case DW_FORM_ref1:
-      DW_ADDR (attr) = cu->header.offset + read_1_byte (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset.so + read_1_byte (abfd, info_ptr);
       info_ptr += 1;
       break;
     case DW_FORM_ref2:
-      DW_ADDR (attr) = cu->header.offset + read_2_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset.so + read_2_bytes (abfd, info_ptr);
       info_ptr += 2;
       break;
     case DW_FORM_ref4:
-      DW_ADDR (attr) = cu->header.offset + read_4_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset.so + read_4_bytes (abfd, info_ptr);
       info_ptr += 4;
       break;
     case DW_FORM_ref8:
-      DW_ADDR (attr) = cu->header.offset + read_8_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = cu->header.offset.so + read_8_bytes (abfd, info_ptr);
       info_ptr += 8;
       break;
     case DW_FORM_ref_sig8:
@@ -10261,7 +10264,7 @@ read_attribute_value (struct attribute *attr, unsigned form,
       info_ptr += 8;
       break;
     case DW_FORM_ref_udata:
-      DW_ADDR (attr) = (cu->header.offset
+      DW_ADDR (attr) = (cu->header.offset.so
 			+ read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
       info_ptr += bytes_read;
       break;
@@ -12222,7 +12225,7 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
 
   if (is_ref_attr (attr))
     {
-      unsigned int offset = dwarf2_get_ref_die_offset (attr);
+      sect_offset offset = dwarf2_get_ref_die_offset (attr);
 
       this_type = get_die_type_at_offset (offset, cu->per_cu);
     }
@@ -12230,17 +12233,17 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
     {
       struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
       struct dwarf2_cu *sig_cu;
-      unsigned int offset;
+      sect_offset offset;
 
       /* sig_type will be NULL if the signatured type is missing from
 	 the debug info.  */
       if (sig_type == NULL)
 	error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
 		 "at 0x%x [in module %s]"),
-	       die->offset, objfile->name);
+	       die->offset.so, objfile->name);
 
       gdb_assert (sig_type->per_cu.debug_types_section);
-      offset = sig_type->per_cu.offset + sig_type->type_offset;
+      offset.so = sig_type->per_cu.offset.so + sig_type->type_offset.co;
       this_type = get_die_type_at_offset (offset, &sig_type->per_cu);
     }
   else
@@ -12272,8 +12275,8 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
       /* read_type_die already issued a complaint.  */
       message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
 			    objfile->name,
-			    cu->header.offset,
-			    die->offset);
+			    cu->header.offset.so,
+			    die->offset.so);
       saved = obstack_copy0 (&objfile->objfile_obstack,
 			     message, strlen (message));
       xfree (message);
@@ -13856,13 +13859,13 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
 
   print_spaces (indent, f);
   fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n",
-	   dwarf_tag_name (die->tag), die->abbrev, die->offset);
+	   dwarf_tag_name (die->tag), die->abbrev, die->offset.so);
 
   if (die->parent != NULL)
     {
       print_spaces (indent, f);
       fprintf_unfiltered (f, "  parent at offset: 0x%x\n",
-			  die->parent->offset);
+			  die->parent->offset.so);
     }
 
   print_spaces (indent, f);
@@ -13919,7 +13922,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
 	case DW_FORM_ref_sig8:
 	  if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL)
 	    fprintf_unfiltered (f, "signatured type, offset: 0x%x",
-			  DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset);
+			 DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset.so);
 	  else
 	    fprintf_unfiltered (f, "signatured type, offset: unknown");
 	  break;
@@ -14008,11 +14011,14 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu)
 {
   void **slot;
 
-  slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset, INSERT);
+  slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset.so, INSERT);
 
   *slot = die;
 }
 
+/* DW_ADDR is always stored already as sect_offset; despite for the forms
+   besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file.  */
+
 static int
 is_ref_attr (struct attribute *attr)
 {
@@ -14030,16 +14036,19 @@ is_ref_attr (struct attribute *attr)
     }
 }
 
-static unsigned int
+static sect_offset
 dwarf2_get_ref_die_offset (struct attribute *attr)
 {
+  sect_offset retval = { DW_ADDR (attr) };
+
   if (is_ref_attr (attr))
-    return DW_ADDR (attr);
+    return retval;
 
+  retval.so = 0;
   complaint (&symfile_complaints,
 	     _("unsupported die ref attribute form: '%s'"),
 	     dwarf_form_name (attr->form));
-  return 0;
+  return retval;
 }
 
 /* Return the constant value held by ATTR.  Return DEFAULT_VALUE if
@@ -14136,7 +14145,7 @@ follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr,
    Returns NULL if OFFSET is invalid.  */
 
 static struct die_info *
-follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
+follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
 {
   struct die_info temp_die;
   struct dwarf2_cu *target_cu, *cu = *ref_cu;
@@ -14174,7 +14183,7 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
 
   *ref_cu = target_cu;
   temp_die.offset = offset;
-  return htab_find_with_hash (target_cu->die_hash, &temp_die, offset);
+  return htab_find_with_hash (target_cu->die_hash, &temp_die, offset.so);
 }
 
 /* Follow reference attribute ATTR of SRC_DIE.
@@ -14185,7 +14194,7 @@ static struct die_info *
 follow_die_ref (struct die_info *src_die, struct attribute *attr,
 		struct dwarf2_cu **ref_cu)
 {
-  unsigned int offset = dwarf2_get_ref_die_offset (attr);
+  sect_offset offset = dwarf2_get_ref_die_offset (attr);
   struct dwarf2_cu *cu = *ref_cu;
   struct die_info *die;
 
@@ -14193,7 +14202,7 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr,
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
 	   "at 0x%x [in module %s]"),
-	   offset, src_die->offset, cu->objfile->name);
+	   offset.so, src_die->offset.so, cu->objfile->name);
 
   return die;
 }
@@ -14203,12 +14212,12 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr,
    dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE.  */
 
 struct dwarf2_locexpr_baton
-dwarf2_fetch_die_location_block (unsigned int offset_in_cu,
+dwarf2_fetch_die_location_block (cu_offset offset_in_cu,
 				 struct dwarf2_per_cu_data *per_cu,
 				 CORE_ADDR (*get_frame_pc) (void *baton),
 				 void *baton)
 {
-  unsigned int offset = per_cu->offset + offset_in_cu;
+  sect_offset offset = { per_cu->offset.so + offset_in_cu.co };
   struct dwarf2_cu *cu;
   struct die_info *die;
   struct attribute *attr;
@@ -14223,7 +14232,7 @@ dwarf2_fetch_die_location_block (unsigned int offset_in_cu,
   die = follow_die_offset (offset, &cu);
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
-	   offset, per_cu->objfile->name);
+	   offset.so, per_cu->objfile->name);
 
   attr = dwarf2_attr (die, DW_AT_location, cu);
   if (!attr)
@@ -14251,7 +14260,7 @@ dwarf2_fetch_die_location_block (unsigned int offset_in_cu,
       if (!attr_form_is_block (attr))
 	error (_("Dwarf Error: DIE at 0x%x referenced in module %s "
 		 "is neither DW_FORM_block* nor DW_FORM_exprloc"),
-	       offset, per_cu->objfile->name);
+	       offset.so, per_cu->objfile->name);
 
       retval.data = DW_BLOCK (attr)->data;
       retval.size = DW_BLOCK (attr)->size;
@@ -14267,11 +14276,15 @@ dwarf2_fetch_die_location_block (unsigned int offset_in_cu,
    PER_CU.  */
 
 struct type *
-dwarf2_get_die_type (unsigned int die_offset,
+dwarf2_get_die_type (cu_offset die_offset,
 		     struct dwarf2_per_cu_data *per_cu)
 {
+  sect_offset die_offset_sect;
+
   dw2_setup (per_cu->objfile);
-  return get_die_type_at_offset (per_cu->offset + die_offset, per_cu);
+
+  die_offset_sect.so = per_cu->offset.so + die_offset.co;
+  return get_die_type_at_offset (die_offset_sect, per_cu);
 }
 
 /* Follow the signature attribute ATTR in SRC_DIE.
@@ -14293,7 +14306,7 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
   if (sig_type == NULL)
     error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
 	     "at 0x%x [in module %s]"),
-	   src_die->offset, objfile->name);
+	   src_die->offset.so, objfile->name);
 
   /* If necessary, add it to the queue and load its DIEs.  */
 
@@ -14303,8 +14316,8 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
   gdb_assert (sig_type->per_cu.cu != NULL);
 
   sig_cu = sig_type->per_cu.cu;
-  temp_die.offset = sig_cu->header.offset + sig_type->type_offset;
-  die = htab_find_with_hash (sig_cu->die_hash, &temp_die, temp_die.offset);
+  temp_die.offset.so = sig_type->per_cu.offset.so + sig_type->type_offset.co;
+  die = htab_find_with_hash (sig_cu->die_hash, &temp_die, temp_die.offset.so);
   if (die)
     {
       *ref_cu = sig_cu;
@@ -14313,7 +14326,7 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
 
   error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced "
 	 "from DIE at 0x%x [in module %s]"),
-	 sig_type->type_offset, src_die->offset, objfile->name);
+	 temp_die.offset.so, src_die->offset.so, objfile->name);
 }
 
 /* Given an offset of a signatured type, return its signatured_type.  */
@@ -14321,9 +14334,9 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
 static struct signatured_type *
 lookup_signatured_type_at_offset (struct objfile *objfile,
 				  struct dwarf2_section_info *section,
-				  unsigned int offset)
+				  sect_offset offset)
 {
-  gdb_byte *info_ptr = section->buffer + offset;
+  gdb_byte *info_ptr = section->buffer + offset.so;
   unsigned int length, initial_length_size;
   unsigned int sig_offset;
   struct signatured_type find_entry, *type_sig;
@@ -14339,7 +14352,7 @@ lookup_signatured_type_at_offset (struct objfile *objfile,
   /* This is only used to lookup previously recorded types.
      If we didn't find it, it's our bug.  */
   gdb_assert (type_sig != NULL);
-  gdb_assert (offset == type_sig->per_cu.offset);
+  gdb_assert (offset.so == type_sig->per_cu.offset.so);
 
   return type_sig;
 }
@@ -14351,7 +14364,7 @@ load_full_type_unit (struct dwarf2_per_cu_data *per_cu)
 {
   struct objfile *objfile = per_cu->objfile;
   struct dwarf2_section_info *sect = per_cu->debug_types_section;
-  unsigned int offset = per_cu->offset;
+  sect_offset offset = per_cu->offset;
   struct signatured_type *type_sig;
 
   dwarf2_read_section (objfile, sect);
@@ -14385,7 +14398,7 @@ read_signatured_type (struct signatured_type *type_sig)
   struct dwarf2_section_info *section = type_sig->per_cu.debug_types_section;
 
   dwarf2_read_section (objfile, section);
-  types_ptr = section->buffer + type_sig->per_cu.offset;
+  types_ptr = section->buffer + type_sig->per_cu.offset.so;
 
   gdb_assert (type_sig->per_cu.cu == NULL);
 
@@ -15735,7 +15748,7 @@ per_cu_header_read_in (struct comp_unit_head *cu_headerp,
 
   objfile = per_cu->objfile;
   per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
-  info_ptr = per_objfile->info.buffer + per_cu->offset;
+  info_ptr = per_objfile->info.buffer + per_cu->offset.so;
 
   memset (cu_headerp, 0, sizeof (*cu_headerp));
   read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd);
@@ -15802,7 +15815,7 @@ dwarf2_per_cu_text_offset (struct dwarf2_per_cu_data *per_cu)
    the DIE at OFFSET.  Raises an error on failure.  */
 
 static struct dwarf2_per_cu_data *
-dwarf2_find_containing_comp_unit (unsigned int offset,
+dwarf2_find_containing_comp_unit (sect_offset offset,
 				  struct objfile *objfile)
 {
   struct dwarf2_per_cu_data *this_cu;
@@ -15814,29 +15827,30 @@ dwarf2_find_containing_comp_unit (unsigned int offset,
     {
       int mid = low + (high - low) / 2;
 
-      if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset)
+      if (dwarf2_per_objfile->all_comp_units[mid]->offset.so >= offset.so)
 	high = mid;
       else
 	low = mid + 1;
     }
   gdb_assert (low == high);
-  if (dwarf2_per_objfile->all_comp_units[low]->offset > offset)
+  if (dwarf2_per_objfile->all_comp_units[low]->offset.so > offset.so)
     {
       if (low == 0)
 	error (_("Dwarf Error: could not find partial DIE containing "
 	       "offset 0x%lx [in module %s]"),
-	       (long) offset, bfd_get_filename (objfile->obfd));
+	       (long) offset.so, bfd_get_filename (objfile->obfd));
 
-      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset <= offset);
+      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset.so
+		  <= offset.so);
       return dwarf2_per_objfile->all_comp_units[low-1];
     }
   else
     {
       this_cu = dwarf2_per_objfile->all_comp_units[low];
       if (low == dwarf2_per_objfile->n_comp_units - 1
-	  && offset >= this_cu->offset + this_cu->length)
-	error (_("invalid dwarf2 offset %u"), offset);
-      gdb_assert (offset < this_cu->offset + this_cu->length);
+	  && offset.so >= this_cu->offset.so + this_cu->length)
+	error (_("invalid dwarf2 offset %u"), offset.so);
+      gdb_assert (offset.so < this_cu->offset.so + this_cu->length);
       return this_cu;
     }
 }
@@ -16030,7 +16044,7 @@ dwarf2_free_objfile (struct objfile *objfile)
 
 struct dwarf2_offset_and_type
 {
-  unsigned int offset;
+  sect_offset offset;
   struct type *type;
 };
 
@@ -16041,7 +16055,7 @@ offset_and_type_hash (const void *item)
 {
   const struct dwarf2_offset_and_type *ofs = item;
 
-  return ofs->offset;
+  return ofs->offset.so;
 }
 
 /* Equality function for a dwarf2_offset_and_type.  */
@@ -16052,7 +16066,7 @@ offset_and_type_eq (const void *item_lhs, const void *item_rhs)
   const struct dwarf2_offset_and_type *ofs_lhs = item_lhs;
   const struct dwarf2_offset_and_type *ofs_rhs = item_rhs;
 
-  return ofs_lhs->offset == ofs_rhs->offset;
+  return ofs_lhs->offset.so == ofs_rhs->offset.so;
 }
 
 /* Set the type associated with DIE to TYPE.  Save it in CU's hash
@@ -16113,11 +16127,11 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
   ofs.offset = die->offset;
   ofs.type = type;
   slot = (struct dwarf2_offset_and_type **)
-    htab_find_slot_with_hash (*type_hash_ptr, &ofs, ofs.offset, INSERT);
+    htab_find_slot_with_hash (*type_hash_ptr, &ofs, ofs.offset.so, INSERT);
   if (*slot)
     complaint (&symfile_complaints,
 	       _("A problem internal to GDB: DIE 0x%x has type already set"),
-	       die->offset);
+	       die->offset.so);
   *slot = obstack_alloc (&objfile->objfile_obstack, sizeof (**slot));
   **slot = ofs;
   return type;
@@ -16127,7 +16141,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
    table, or return NULL if the die does not have a saved type.  */
 
 static struct type *
-get_die_type_at_offset (unsigned int offset,
+get_die_type_at_offset (sect_offset offset,
 			struct dwarf2_per_cu_data *per_cu)
 {
   struct dwarf2_offset_and_type *slot, ofs;
@@ -16141,7 +16155,7 @@ get_die_type_at_offset (unsigned int offset,
     return NULL;
 
   ofs.offset = offset;
-  slot = htab_find_with_hash (type_hash, &ofs, ofs.offset);
+  slot = htab_find_with_hash (type_hash, &ofs, ofs.offset.so);
   if (slot)
     return slot->type;
   else
@@ -16235,7 +16249,7 @@ partial_die_hash (const void *item)
 {
   const struct partial_die_info *part_die = item;
 
-  return part_die->offset;
+  return part_die->offset.so;
 }
 
 /* Trivial comparison function for partial_die_info structures: two DIEs
@@ -16247,7 +16261,7 @@ partial_die_eq (const void *item_lhs, const void *item_rhs)
   const struct partial_die_info *part_die_lhs = item_lhs;
   const struct partial_die_info *part_die_rhs = item_rhs;
 
-  return part_die_lhs->offset == part_die_rhs->offset;
+  return part_die_lhs->offset.so == part_die_rhs->offset.so;
 }
 
 static struct cmd_list_element *set_dwarf2_cmdlist;
@@ -16855,9 +16869,9 @@ write_one_signatured_type (void **slot, void *d)
 		  psymtab->n_static_syms, info->cu_index,
 		  1);
 
-  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->per_cu.offset);
+  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->per_cu.offset.so);
   obstack_grow (info->types_list, val, 8);
-  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset);
+  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset.co);
   obstack_grow (info->types_list, val, 8);
   store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature);
   obstack_grow (info->types_list, val, 8);
@@ -16970,7 +16984,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
       gdb_assert (*slot == NULL);
       *slot = map;
 
-      store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->offset);
+      store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->offset.so);
       obstack_grow (&cu_list, val, 8);
       store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->length);
       obstack_grow (&cu_list, val, 8);


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] Fix CU relative vs. absolute offsets  [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 17:10 ` [patch] Fix CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback] Jan Kratochvil
  2012-03-07 17:13   ` [patch 2/2] typedef-checking for " Jan Kratochvil
@ 2012-03-07 18:57   ` Joel Brobecker
  2012-03-07 19:47     ` Joel Brobecker
  1 sibling, 1 reply; 20+ messages in thread
From: Joel Brobecker @ 2012-03-07 18:57 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches

> I do not understand how it can happen.  amd64-entry-value.exp uses precompiled
> amd64-entry-value.s (unless you use runtest COMPILE=1) and sure it fully
> PASSed+PASSes for me.

I did not run with COMPILE=1, so I think what might be happening is
that the linker might be putting your pre-compiled CU first?

> It looks as if some of the GDB features have never worked in real world - just
> in the testcase which have single CU. :-)

That was my guess first I first saw the testcase using them in our
testsuite. But then, I saw that we do a link, so I thought for sure
we have multi-CU exes. But maybe we used to get lucky as explained
in the total blind guess above?

> 2012-03-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
> 
> 	Fix CU relative vs. absolute DIE offsets.
> 	* dwarf2loc.h (dwarf2_fetch_die_location_block): Rename parameter
> 	offset to offset_in_cu.
> 	* dwarf2read.c (process_enumeration_scope): Add CU offset to
> 	TYPE_OFFSET.
> 	(dwarf2_fetch_die_location_block): Rename parameter offset to
> 	offset_in_cu.  New variable offset, add CU offset to OFFSET_IN_CU.
> 
> --- a/gdb/dwarf2loc.h
> +++ b/gdb/dwarf2loc.h
> @@ -61,7 +61,7 @@ const gdb_byte *dwarf2_find_location_expression
>     CORE_ADDR pc);
>  
>  struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block
> -  (unsigned int offset, struct dwarf2_per_cu_data *per_cu,
> +  (unsigned int offset_in_cu, struct dwarf2_per_cu_data *per_cu,
>     CORE_ADDR (*get_frame_pc) (void *baton),
>     void *baton);

I like these renames...

I don't really know the code well enough to give an opinion on
the correctness of the patch, though. I can test them against our
version of GCC 4.7. Will do that and report.

-- 
Joel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 17:13   ` [patch 2/2] typedef-checking for " Jan Kratochvil
@ 2012-03-07 18:58     ` Doug Evans
  2012-03-07 19:10       ` Jan Kratochvil
  2012-03-08 21:54       ` Tom Tromey
  2012-03-07 19:07     ` Joel Brobecker
  2012-03-08 21:53     ` Tom Tromey
  2 siblings, 2 replies; 20+ messages in thread
From: Doug Evans @ 2012-03-07 18:58 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Joel Brobecker, gdb-patches

On Wed, Mar 7, 2012 at 9:12 AM, Jan Kratochvil
<jan.kratochvil@redhat.com> wrote:
> On Wed, 07 Mar 2012 18:09:40 +0100, Jan Kratochvil wrote:
>> There are more issues of this kind.
>
> This is not maintainable IMO in its current form.
>
> typedef struct { unsigned int co; } cu_offset;
> typedef struct { unsigned int so; } sect_offset;
>
> OK with the patch?

The problem stems from "offset" being ambiguous.
I'd rather just pick a better (clearer) name and be consistent.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 17:13   ` [patch 2/2] typedef-checking for " Jan Kratochvil
  2012-03-07 18:58     ` Doug Evans
@ 2012-03-07 19:07     ` Joel Brobecker
  2012-03-07 19:16       ` Jan Kratochvil
  2012-03-08 21:53     ` Tom Tromey
  2 siblings, 1 reply; 20+ messages in thread
From: Joel Brobecker @ 2012-03-07 19:07 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches

> This is not maintainable IMO in its current form.
> 
> typedef struct { unsigned int co; } cu_offset;
> typedef struct { unsigned int so; } sect_offset;

[brainstorming]

I like the idea of having distinct types. If we were using Ada,
we would have been able to define distinct scalar types for our
offsets, and the compiler would catch invalid uses. It's a bit
more of a pain in C because the use of a struct makes it harder
to use, but it's certainly better to catch these errors at compile
time.  I do find "co" and "so" a little too short and confusing,
though.  So, here is another suggestion:

typedef struct { unsigned int val; } cu_offset;
typedef struct { unsigned int val; } sect_offset;

?

Would that be enough? Or maybe you really want different field names
to make the writer aware of which offset he really has. In that case,
perhaps field names that are a little more explicit? For instance:
"rel_off" and "abs_off" (for "relative" vs "absolute")?

-- 
Joel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 18:58     ` Doug Evans
@ 2012-03-07 19:10       ` Jan Kratochvil
  2012-03-07 19:29         ` Jan Kratochvil
  2012-03-08 21:54       ` Tom Tromey
  1 sibling, 1 reply; 20+ messages in thread
From: Jan Kratochvil @ 2012-03-07 19:10 UTC (permalink / raw)
  To: Doug Evans; +Cc: Joel Brobecker, gdb-patches

On Wed, 07 Mar 2012 19:58:17 +0100, Doug Evans wrote:
> The problem stems from "offset" being ambiguous.
> I'd rather just pick a better (clearer) name and be consistent.

I have to strongly disagree, without automatic checking this bug will creep in
again. Even with testcases it does not get found as they rarely excersise
multiple CUs.

Plus these advanced DWARF features are used only for -O2 -g builds and so bugs
there have low chance to be reported - everyone expects -O2 -g debug info is
not good.


I find the other possibility some static checker instead, to have just some:
typedef unsigned int cu_offset; typedef unsigned int sect_offset;
No idea which static checker can find it.


Thanks,
Jan


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 19:07     ` Joel Brobecker
@ 2012-03-07 19:16       ` Jan Kratochvil
  0 siblings, 0 replies; 20+ messages in thread
From: Jan Kratochvil @ 2012-03-07 19:16 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On Wed, 07 Mar 2012 20:07:03 +0100, Joel Brobecker wrote:
> Or maybe you really want different field names
> to make the writer aware of which offset he really has.

Exactly.


> In that case,
> perhaps field names that are a little more explicit? For instance:
> "rel_off" and "abs_off" (for "relative" vs "absolute")?

Not so fine with rel vs. abs (I find the sect vs. CU distinction more clear,
both are relative) and not so fine with _off (too long).  But I do not mind
the naming.


Regards,
Jan


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 19:10       ` Jan Kratochvil
@ 2012-03-07 19:29         ` Jan Kratochvil
  0 siblings, 0 replies; 20+ messages in thread
From: Jan Kratochvil @ 2012-03-07 19:29 UTC (permalink / raw)
  To: Doug Evans; +Cc: Joel Brobecker, gdb-patches

On Wed, 07 Mar 2012 20:09:36 +0100, Jan Kratochvil wrote:
> I find the other possibility some static checker instead,

And sure the third one C++ again.


Regards,
Jan


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] Fix CU relative vs. absolute offsets  [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 18:57   ` [patch] Fix CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback] Joel Brobecker
@ 2012-03-07 19:47     ` Joel Brobecker
  2012-03-08 19:40       ` [commit] " Jan Kratochvil
  0 siblings, 1 reply; 20+ messages in thread
From: Joel Brobecker @ 2012-03-07 19:47 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches

> I don't really know the code well enough to give an opinion on
> the correctness of the patch, though. I can test them against our
> version of GCC 4.7. Will do that and report.

FWIW: I didn't see any regression with our testsuite and GCC 4.7.

-- 
Joel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [commit] [patch] Fix CU relative vs. absolute offsets  [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 19:47     ` Joel Brobecker
@ 2012-03-08 19:40       ` Jan Kratochvil
  0 siblings, 0 replies; 20+ messages in thread
From: Jan Kratochvil @ 2012-03-08 19:40 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On Wed, 07 Mar 2012 20:46:55 +0100, Joel Brobecker wrote:
> FWIW: I didn't see any regression with our testsuite and GCC 4.7.

Checked it in, with a new testcase for one part of it.

The part
-      if (type_sig->type_offset != die->offset)
+      if (type_sig->per_cu.offset + type_sig->type_offset
+         != die->offset)

comes from:
	Re: [1/4] RFC: skip DIEs which only declare an enum
	http://sourceware.org/ml/gdb-patches/2011-07/msg00428.html
and while it has no new testcase:
(1) after changing it the debug output clearly shows it is right:
    type_sig->type_offset=0x25 != die->offset=0x82e
    type_sig->type_offset=0x3c != die->offset=0x7ce
    ->
    type_sig->type_offset=0x821 != die->offset=0x82e
    type_sig->type_offset=0x7d4 != die->offset=0x7ce
(2) it is also shown in the [patch 2/2] enforcing
    proper .debug_*-section vs.  CU relative offset types.

For the dwarf2_fetch_die_location_block part it was even easy to write
a testcase showing now FAIL->PASS.


Thanks,
Jan


http://sourceware.org/ml/gdb-cvs/2012-03/msg00134.html

--- src/gdb/ChangeLog	2012/03/08 19:08:09	1.13979
+++ src/gdb/ChangeLog	2012/03/08 19:37:04	1.13980
@@ -1,5 +1,15 @@
 2012-03-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
+	Fix CU relative vs. absolute DIE offsets.
+	* dwarf2loc.h (dwarf2_fetch_die_location_block): Rename parameter
+	offset to offset_in_cu.
+	* dwarf2read.c (process_enumeration_scope): Add CU offset to
+	TYPE_OFFSET.
+	(dwarf2_fetch_die_location_block): Rename parameter offset to
+	offset_in_cu.  New variable offset, add CU offset to OFFSET_IN_CU.
+
+2012-03-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
 	* libunwind-frame.c: Rename to ...
 	* ia64-libunwind-tdep.c: ... here.
 	* libunwind-frame.h: Rename to ...
--- src/gdb/testsuite/ChangeLog	2012/03/08 07:42:50	1.3127
+++ src/gdb/testsuite/ChangeLog	2012/03/08 19:37:07	1.3128
@@ -1,5 +1,11 @@
 2012-03-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
+	Fix CU relative vs. absolute DIE offsets.
+	* gdb.dwarf2/dw2-op-call.S: New compilation unit preceding the existing
+	one.
+
+2012-03-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
 	Fix false FAIL on distros with relro linkage as default.
 	* gdb.reverse/solib-precsave.exp: Try to compile the test using
 	-Wl,-z,norelro first.
--- src/gdb/dwarf2loc.h	2012/01/05 21:53:14	1.29
+++ src/gdb/dwarf2loc.h	2012/03/08 19:37:07	1.30
@@ -61,7 +61,7 @@
    CORE_ADDR pc);
 
 struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block
-  (unsigned int offset, struct dwarf2_per_cu_data *per_cu,
+  (unsigned int offset_in_cu, struct dwarf2_per_cu_data *per_cu,
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton);
 
--- src/gdb/dwarf2read.c	2012/03/06 23:41:50	1.619
+++ src/gdb/dwarf2read.c	2012/03/08 19:37:07	1.620
@@ -8031,7 +8031,8 @@
 	= lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile,
 					    cu->per_cu->debug_types_section,
 					    cu->per_cu->offset);
-      if (type_sig->type_offset != die->offset)
+      if (type_sig->per_cu.offset + type_sig->type_offset
+	  != die->offset)
 	return;
     }
 
@@ -14202,11 +14203,12 @@
    dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE.  */
 
 struct dwarf2_locexpr_baton
-dwarf2_fetch_die_location_block (unsigned int offset,
+dwarf2_fetch_die_location_block (unsigned int offset_in_cu,
 				 struct dwarf2_per_cu_data *per_cu,
 				 CORE_ADDR (*get_frame_pc) (void *baton),
 				 void *baton)
 {
+  unsigned int offset = per_cu->offset + offset_in_cu;
   struct dwarf2_cu *cu;
   struct die_info *die;
   struct attribute *attr;
--- src/gdb/testsuite/gdb.dwarf2/dw2-op-call.S	2012/01/04 08:17:51	1.5
+++ src/gdb/testsuite/gdb.dwarf2/dw2-op-call.S	2012/03/08 19:37:08	1.6
@@ -23,6 +23,23 @@
 array3:	.2byte	3
 
 	.section .debug_info
+.Lcu0_begin:
+	/* CU header */
+	.4byte	.Lcu0_end - .Lcu0_start		/* Length of Compilation Unit */
+.Lcu0_start:
+	.2byte	2				/* DWARF Version */
+	.4byte	.Labbrev1_begin			/* Offset into abbrev section */
+	.byte	4				/* Pointer size */
+
+	/* CU die */
+	.uleb128 1				/* Abbrev: DW_TAG_compile_unit */
+	.ascii	"file0.txt\0"			/* DW_AT_name */
+	.ascii	"GNU C 3.3.3\0"			/* DW_AT_producer */
+	.byte	2				/* DW_LANG_C (C) */
+
+	.byte	0				/* End of children of CU */
+.Lcu0_end:
+
 .Lcu1_begin:
 	/* CU header */
 	.4byte	.Lcu1_end - .Lcu1_start		/* Length of Compilation Unit */


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets  [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 17:13   ` [patch 2/2] typedef-checking for " Jan Kratochvil
  2012-03-07 18:58     ` Doug Evans
  2012-03-07 19:07     ` Joel Brobecker
@ 2012-03-08 21:53     ` Tom Tromey
  2012-03-09 19:40       ` cu_offset vs. sect_offset field names bikeshedding [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets] Jan Kratochvil
  2 siblings, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2012-03-08 21:53 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Joel Brobecker, gdb-patches

>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:

Jan> This is not maintainable IMO in its current form.
Jan> typedef struct { unsigned int co; } cu_offset;
Jan> typedef struct { unsigned int so; } sect_offset;

Jan> OK with the patch?

I read through the thread.

I think this patch is a good idea.  I find that it does not clutter up
the code very much (which was my main concern), and it adds type-safety
to an area where we've clearly already had review and/or reasoning
failures.

Tom


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-07 18:58     ` Doug Evans
  2012-03-07 19:10       ` Jan Kratochvil
@ 2012-03-08 21:54       ` Tom Tromey
  2012-03-08 21:56         ` Doug Evans
  1 sibling, 1 reply; 20+ messages in thread
From: Tom Tromey @ 2012-03-08 21:54 UTC (permalink / raw)
  To: Doug Evans; +Cc: Jan Kratochvil, Joel Brobecker, gdb-patches

>>>>> "Doug" == Doug Evans <dje@google.com> writes:

Doug> I'd rather just pick a better (clearer) name and be consistent.

Could you say why?
I'm curious to know what you think the downside is.

Tom


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback]
  2012-03-08 21:54       ` Tom Tromey
@ 2012-03-08 21:56         ` Doug Evans
  0 siblings, 0 replies; 20+ messages in thread
From: Doug Evans @ 2012-03-08 21:56 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Jan Kratochvil, Joel Brobecker, gdb-patches

On Thu, Mar 8, 2012 at 1:54 PM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Doug" == Doug Evans <dje@google.com> writes:
>
> Doug> I'd rather just pick a better (clearer) name and be consistent.
>
> Could you say why?
> I'm curious to know what you think the downside is.

No point.
Just go with what you want and I'll live with it.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* cu_offset vs. sect_offset field names bikeshedding  [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets]
  2012-03-08 21:53     ` Tom Tromey
@ 2012-03-09 19:40       ` Jan Kratochvil
  2012-03-09 19:52         ` Joel Brobecker
  2012-03-09 19:56         ` cu_offset vs. sect_offset field names bikeshedding [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets] Tom Tromey
  0 siblings, 2 replies; 20+ messages in thread
From: Jan Kratochvil @ 2012-03-09 19:40 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Joel Brobecker, gdb-patches

Hi,

On Thu, 08 Mar 2012 22:53:08 +0100, Tom Tromey wrote:
> I think this patch is a good idea.  I find that it does not clutter up
> the code very much (which was my main concern), and it adds type-safety
> to an area where we've clearly already had review and/or reasoning
> failures.

that's great, thanks for the agreement.

Now just how to call them:

> >>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
> Jan> typedef struct { unsigned int co; } cu_offset;
> Jan> typedef struct { unsigned int so; } sect_offset;

I find 'cu_offset' + 'sect_offset' names for the types are OK, any objective?

I do not find 'co' + 'so' great myself.

'val' + 'val' I do not find acceptable, it needs to differ, otherwise the
expressions are a mess, the type of variable is not immediately visible.

'rel_off' + 'abs_off'?  It no longer matches 'cu_offset' + 'sect_offset'.
Moreover rel + abs I do not find so great, cu + sect I find better.

'rel_off' would be 7 characters, 23 lines of 143 lines of the patch would need
reindentation overflowing 80 characters.

	field length | overflown lines of patch
	3	3
	4	7
	5	13
	6	15
	7	23
	8	27
	9	31
	10	35
	11	41
	12	45
	13	47
	14	47
	15	49

Another proposal is 'cu_o' and 'sect_o' or even 'cu_off' or 'sect_off'.


Regards,
Jan


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: cu_offset vs. sect_offset field names bikeshedding  [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets]
  2012-03-09 19:40       ` cu_offset vs. sect_offset field names bikeshedding [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets] Jan Kratochvil
@ 2012-03-09 19:52         ` Joel Brobecker
  2012-03-19 20:02           ` [commit] [patch 2/2] typedef-checking for CU relative vs. absolute offsets Jan Kratochvil
  2012-03-09 19:56         ` cu_offset vs. sect_offset field names bikeshedding [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets] Tom Tromey
  1 sibling, 1 reply; 20+ messages in thread
From: Joel Brobecker @ 2012-03-09 19:52 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Tom Tromey, gdb-patches

FWIW:

> > >>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
> > Jan> typedef struct { unsigned int co; } cu_offset;
> > Jan> typedef struct { unsigned int so; } sect_offset;
> 
> I find 'cu_offset' + 'sect_offset' names for the types are OK, any
> objecti[on]?

Seems fine to me.

> Another proposal is 'cu_o' and 'sect_o' or even 'cu_off' or 'sect_off'.

I would personally go with the second option (cu_off and sect_off).
And I would be OK if the change was done mechanically and re-indenting
wasn't performed.

-- 
Joel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: cu_offset vs. sect_offset field names bikeshedding  [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets]
  2012-03-09 19:40       ` cu_offset vs. sect_offset field names bikeshedding [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets] Jan Kratochvil
  2012-03-09 19:52         ` Joel Brobecker
@ 2012-03-09 19:56         ` Tom Tromey
  1 sibling, 0 replies; 20+ messages in thread
From: Tom Tromey @ 2012-03-09 19:56 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Joel Brobecker, gdb-patches

>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:

>> >>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
Jan> typedef struct { unsigned int co; } cu_offset;
Jan> typedef struct { unsigned int so; } sect_offset;

Jan> I find 'cu_offset' + 'sect_offset' names for the types are OK, any
Jan> objective?

I think they are ok too.  DWARF doesn't provide these terms exactly, but
pretty close, e.g.:

    For DW_OP_call2 and DW_OP_call4, the operand is the 2- or 4-byte
    unsigned offset, respectively, of a debugging information entry in the
    current compilation unit.

and

    The operand is used as the offset of a debugging information entry
    in a .debug_info or .debug_types section

Tom


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [commit] [patch 2/2] typedef-checking for CU relative vs. absolute offsets
  2012-03-09 19:52         ` Joel Brobecker
@ 2012-03-19 20:02           ` Jan Kratochvil
  0 siblings, 0 replies; 20+ messages in thread
From: Jan Kratochvil @ 2012-03-19 20:02 UTC (permalink / raw)
  To: Joel Brobecker, Tom Tromey; +Cc: gdb-patches

On Fri, 09 Mar 2012 20:51:50 +0100, Joel Brobecker wrote:
> > Another proposal is 'cu_o' and 'sect_o' or even 'cu_off' or 'sect_off'.
> 
> I would personally go with the second option (cu_off and sect_off).

On Fri, 09 Mar 2012 20:55:52 +0100, Tom Tromey wrote:
> I think they are ok too.  DWARF doesn't provide these terms exactly, but
> pretty close, e.g.:

Checked in.


Thanks,
Jan


http://sourceware.org/ml/gdb-cvs/2012-03/msg00238.html

--- src/gdb/ChangeLog	2012/03/19 18:23:51	1.14028
+++ src/gdb/ChangeLog	2012/03/19 19:59:15	1.14029
@@ -1,5 +1,56 @@
 2012-03-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
+	Code cleanupp: Use cu_offset and sect_offset compile time type checking.
+	* dwarf2expr.c (add_piece, dwarf_get_base_type, execute_stack_op)
+	(ctx_no_dwarf_call, ctx_no_get_base_type): Use cu_offset and
+	sect_offset.
+	* dwarf2expr.h (cu_offset, sect_offset): New types.
+	(struct dwarf_expr_context_funcs) <dwarf_call>
+	(struct dwarf_expr_context_funcs) <get_base_type>: Use cu_offset and
+	sect_offset.
+	(struct dwarf_expr_context) <len>: Improve the comment.
+	(struct dwarf_expr_piece, ctx_no_dwarf_call, ctx_no_get_base_type): Use
+	cu_offset and sect_offset.
+	* dwarf2loc.c (per_cu_dwarf_call, dwarf_expr_dwarf_call)
+	(dwarf_expr_get_base_type, needs_frame_dwarf_call)
+	(dwarf2_compile_expr_to_ax, disassemble_dwarf_expression): Likewise.
+	* dwarf2loc.h: Include dwarf2expr.h.
+	(dwarf2_fetch_die_location_block, dwarf2_get_die_type): Use cu_offset
+	and sect_offset.
+	* dwarf2read.c (struct dwarf2_per_objfile) <debug_types_type_hash>:
+	Improve the comment.
+	(struct comp_unit_head, struct dwarf2_cu, struct dwarf2_per_cu_data)
+	(struct signatured_type, struct line_header, struct partial_die_info)
+	(struct die_info, find_partial_die, dwarf2_get_ref_die_offset)
+	(lookup_signatured_type_at_offset, dwarf2_find_containing_comp_unit)
+	(get_die_type_at_offset, create_cus_from_index)
+	(create_signatured_type_table_from_index, dw2_get_file_names)
+	(offset_in_cu_p, read_comp_unit_head, error_check_comp_unit_head)
+	(read_and_check_comp_unit_head, read_and_check_type_unit_head)
+	(create_debug_types_hash_table, process_psymtab_comp_unit)
+	(load_partial_comp_unit, create_all_comp_units)
+	(partial_die_parent_scope, partial_die_full_name, skip_one_die)
+	(load_full_comp_unit, dwarf2_physname, read_import_statement)
+	(inherit_abstract_dies, read_func_scope, read_call_site_scope)
+	(dwarf2_add_member_fn, process_enumeration_scope, read_module_type)
+	(read_typedef, die_hash, die_eq, read_full_die, dwarf2_read_abbrevs)
+	(load_partial_dies, read_partial_die, find_partial_die_in_comp_unit)
+	(find_partial_die, read_attribute_value, lookup_die_type)
+	(dump_die_shallow, store_in_ref_table): Use cu_offset and sect_offset.
+	(is_ref_attr): New function comment.
+	(dwarf2_get_ref_die_offset): New function comment, new variable retval.
+	Use cu_offset and sect_offset.
+	(follow_die_offset, follow_die_ref, dwarf2_fetch_die_location_block)
+	(dwarf2_get_die_type, follow_die_sig, lookup_signatured_type_at_offset)
+	(load_full_type_unit, read_signatured_type, per_cu_header_read_in)
+	(dwarf2_find_containing_comp_unit, struct dwarf2_offset_and_type)
+	(offset_and_type_hash, offset_and_type_eq, set_die_type)
+	(get_die_type_at_offset, partial_die_hash, partial_die_eq)
+	(write_one_signatured_type, write_psymtabs_to_index): Use cu_offset and
+	sect_offset.
+
+2012-03-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
 	Code cleanup.
 	* python/py-auto-load.c (source_section_scripts): New variable back_to.
 	Turn fclose and xfree calls into make_cleanup_fclose and make_cleanup
--- src/gdb/dwarf2expr.c	2012/03/01 21:13:58	1.79
+++ src/gdb/dwarf2expr.c	2012/03/19 19:59:18	1.80
@@ -342,7 +342,7 @@
     }
   else if (p->location == DWARF_VALUE_IMPLICIT_POINTER)
     {
-      p->v.ptr.die = ctx->len;
+      p->v.ptr.die.cu_off = ctx->len;
       p->v.ptr.offset = value_as_long (dwarf_expr_fetch (ctx, 0));
     }
   else if (p->location == DWARF_VALUE_REGISTER)
@@ -464,7 +464,7 @@
    size.  */
 
 static struct type *
-dwarf_get_base_type (struct dwarf_expr_context *ctx, ULONGEST die, int size)
+dwarf_get_base_type (struct dwarf_expr_context *ctx, cu_offset die, int size)
 {
   struct type *result;
 
@@ -869,7 +869,7 @@
 	      error (_("DWARF-2 expression error: DW_OP_GNU_implicit_pointer "
 		       "is not allowed in frame context"));
 
-	    /* The referred-to DIE.  */
+	    /* The referred-to DIE of cu_offset kind.  */
 	    ctx->len = extract_unsigned_integer (op_ptr, ctx->ref_addr_size,
 						 byte_order);
 	    op_ptr += ctx->ref_addr_size;
@@ -1031,9 +1031,10 @@
 
 	    if (op == DW_OP_GNU_deref_type)
 	      {
-		ULONGEST type_die;
+		cu_offset type_die;
 
-		op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+		op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
+		type_die.cu_off = uoffset;
 		type = dwarf_get_base_type (ctx, type_die, 0);
 	      }
 	    else
@@ -1335,15 +1336,23 @@
 	  goto no_push;
 
 	case DW_OP_call2:
-	  result = extract_unsigned_integer (op_ptr, 2, byte_order);
-	  op_ptr += 2;
-	  ctx->funcs->dwarf_call (ctx, result);
+	  {
+	    cu_offset offset;
+
+	    offset.cu_off = extract_unsigned_integer (op_ptr, 2, byte_order);
+	    op_ptr += 2;
+	    ctx->funcs->dwarf_call (ctx, offset);
+	  }
 	  goto no_push;
 
 	case DW_OP_call4:
-	  result = extract_unsigned_integer (op_ptr, 4, byte_order);
-	  op_ptr += 4;
-	  ctx->funcs->dwarf_call (ctx, result);
+	  {
+	    cu_offset offset;
+
+	    offset.cu_off = extract_unsigned_integer (op_ptr, 4, byte_order);
+	    op_ptr += 4;
+	    ctx->funcs->dwarf_call (ctx, offset);
+	  }
 	  goto no_push;
 	
 	case DW_OP_GNU_entry_value:
@@ -1386,12 +1395,13 @@
 
 	case DW_OP_GNU_const_type:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 	    int n;
 	    const gdb_byte *data;
 	    struct type *type;
 
-	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
+	    type_die.cu_off = uoffset;
 	    n = *op_ptr++;
 	    data = op_ptr;
 	    op_ptr += n;
@@ -1403,11 +1413,12 @@
 
 	case DW_OP_GNU_regval_type:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 	    struct type *type;
 
 	    op_ptr = read_uleb128 (op_ptr, op_end, &reg);
-	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
+	    type_die.cu_off = uoffset;
 
 	    type = dwarf_get_base_type (ctx, type_die, 0);
 	    result = (ctx->funcs->read_reg) (ctx->baton, reg);
@@ -1420,12 +1431,13 @@
 	case DW_OP_GNU_convert:
 	case DW_OP_GNU_reinterpret:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 	    struct type *type;
 
-	    op_ptr = read_uleb128 (op_ptr, op_end, &type_die);
+	    op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
+	    type_die.cu_off = uoffset;
 
-	    if (type_die == 0)
+	    if (type_die.cu_off == 0)
 	      type = address_type;
 	    else
 	      type = dwarf_get_base_type (ctx, type_die, 0);
@@ -1506,7 +1518,7 @@
 /* Stub dwarf_expr_context_funcs.dwarf_call implementation.  */
 
 void
-ctx_no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+ctx_no_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
 {
   error (_("%s is invalid in this context"), "DW_OP_call*");
 }
@@ -1514,7 +1526,7 @@
 /* Stub dwarf_expr_context_funcs.get_base_type implementation.  */
 
 struct type *
-ctx_no_get_base_type (struct dwarf_expr_context *ctx, size_t die)
+ctx_no_get_base_type (struct dwarf_expr_context *ctx, cu_offset die)
 {
   error (_("Support for typed DWARF is not supported in this context"));
 }
--- src/gdb/dwarf2expr.h	2012/01/04 08:17:00	1.43
+++ src/gdb/dwarf2expr.h	2012/03/19 19:59:18	1.44
@@ -25,6 +25,18 @@
 
 struct dwarf_expr_context;
 
+/* Offset relative to the start of its containing CU (compilation unit).  */
+typedef struct
+{
+  unsigned int cu_off;
+} cu_offset;
+
+/* Offset relative to the start of its .debug_info or .debug_types section.  */
+typedef struct
+{
+  unsigned int sect_off;
+} sect_offset;
+
 /* Virtual method table for struct dwarf_expr_context below.  */
 
 struct dwarf_expr_context_funcs
@@ -53,14 +65,14 @@
   /* Execute DW_AT_location expression for the DWARF expression subroutine in
      the DIE at DIE_OFFSET in the CU from CTX.  Do not touch STACK while it
      being passed to and returned from the called DWARF subroutine.  */
-  void (*dwarf_call) (struct dwarf_expr_context *ctx, size_t die_offset);
+  void (*dwarf_call) (struct dwarf_expr_context *ctx, cu_offset die_offset);
 
   /* Return the base type given by the indicated DIE.  This can throw
      an exception if the DIE is invalid or does not represent a base
      type.  If can also be NULL in the special case where the
      callbacks are not performing evaluation, and thus it is
      meaningful to substitute a stub type of the correct size.  */
-  struct type *(*get_base_type) (struct dwarf_expr_context *ctx, size_t die);
+  struct type *(*get_base_type) (struct dwarf_expr_context *ctx, cu_offset die);
 
   /* Push on DWARF stack an entry evaluated for DW_TAG_GNU_call_site's
      DWARF_REG/FB_OFFSET at the caller of specified BATON.  If DWARF register
@@ -160,7 +172,7 @@
 
   /* For DWARF_VALUE_LITERAL, the current literal value's length and
      data.  For DWARF_VALUE_IMPLICIT_POINTER, LEN is the offset of the
-     target DIE.  */
+     target DIE of cu_offset kind.  */
   ULONGEST len;
   const gdb_byte *data;
 
@@ -231,7 +243,7 @@
     struct
     {
       /* The referent DIE from DW_OP_GNU_implicit_pointer.  */
-      ULONGEST die;
+      cu_offset die;
       /* The byte offset into the resulting data.  */
       LONGEST offset;
     } ptr;
@@ -275,8 +287,9 @@
 CORE_ADDR ctx_no_get_frame_cfa (void *baton);
 CORE_ADDR ctx_no_get_frame_pc (void *baton);
 CORE_ADDR ctx_no_get_tls_address (void *baton, CORE_ADDR offset);
-void ctx_no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset);
-struct type *ctx_no_get_base_type (struct dwarf_expr_context *ctx, size_t die);
+void ctx_no_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset);
+struct type *ctx_no_get_base_type (struct dwarf_expr_context *ctx,
+				   cu_offset die);
 void ctx_no_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
 					int dwarf_reg, CORE_ADDR fb_offset,
 					int deref_size);
--- src/gdb/dwarf2loc.c	2012/03/13 01:16:07	1.141
+++ src/gdb/dwarf2loc.c	2012/03/19 19:59:19	1.142
@@ -284,7 +284,7 @@
    call and return.  */
 
 static void
-per_cu_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset,
+per_cu_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset,
 		   struct dwarf2_per_cu_data *per_cu,
 		   CORE_ADDR (*get_frame_pc) (void *baton),
 		   void *baton)
@@ -303,7 +303,7 @@
 /* Helper interface of per_cu_dwarf_call for dwarf2_evaluate_loc_desc.  */
 
 static void
-dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
 {
   struct dwarf_expr_baton *debaton = ctx->baton;
 
@@ -314,7 +314,8 @@
 /* Callback function for dwarf2_evaluate_loc_desc.  */
 
 static struct type *
-dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
+dwarf_expr_get_base_type (struct dwarf_expr_context *ctx,
+			  cu_offset die_offset)
 {
   struct dwarf_expr_baton *debaton = ctx->baton;
 
@@ -2221,7 +2222,7 @@
 /* Helper interface of per_cu_dwarf_call for dwarf2_loc_desc_needs_frame.  */
 
 static void
-needs_frame_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
+needs_frame_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
 {
   struct needs_frame_baton *nf_baton = ctx->baton;
 
@@ -3014,11 +3015,13 @@
 	  {
 	    struct dwarf2_locexpr_baton block;
 	    int size = (op == DW_OP_call2 ? 2 : 4);
+	    cu_offset offset;
 
 	    uoffset = extract_unsigned_integer (op_ptr, size, byte_order);
 	    op_ptr += size;
 
-	    block = dwarf2_fetch_die_location_block (uoffset, per_cu,
+	    offset.cu_off = uoffset;
+	    block = dwarf2_fetch_die_location_block (offset, per_cu,
 						     get_ax_pc, expr);
 
 	    /* DW_OP_call_ref is currently not supported.  */
@@ -3517,43 +3520,48 @@
 	case DW_OP_GNU_deref_type:
 	  {
 	    int addr_size = *data++;
-	    ULONGEST offset;
+	    cu_offset offset;
 	    struct type *type;
 
-	    data = read_uleb128 (data, end, &offset);
+	    data = read_uleb128 (data, end, &ul);
+	    offset.cu_off = ul;
 	    type = dwarf2_get_die_type (offset, per_cu);
 	    fprintf_filtered (stream, "<");
 	    type_print (type, "", stream, -1);
-	    fprintf_filtered (stream, " [0x%s]> %d", phex_nz (offset, 0),
+	    fprintf_filtered (stream, " [0x%s]> %d", phex_nz (offset.cu_off, 0),
 			      addr_size);
 	  }
 	  break;
 
 	case DW_OP_GNU_const_type:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 	    struct type *type;
 
-	    data = read_uleb128 (data, end, &type_die);
+	    data = read_uleb128 (data, end, &ul);
+	    type_die.cu_off = ul;
 	    type = dwarf2_get_die_type (type_die, per_cu);
 	    fprintf_filtered (stream, "<");
 	    type_print (type, "", stream, -1);
-	    fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die, 0));
+	    fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die.cu_off, 0));
 	  }
 	  break;
 
 	case DW_OP_GNU_regval_type:
 	  {
-	    ULONGEST type_die, reg;
+	    ULONGEST reg;
+	    cu_offset type_die;
 	    struct type *type;
 
 	    data = read_uleb128 (data, end, &reg);
-	    data = read_uleb128 (data, end, &type_die);
+	    data = read_uleb128 (data, end, &ul);
+	    type_die.cu_off = ul;
 
 	    type = dwarf2_get_die_type (type_die, per_cu);
 	    fprintf_filtered (stream, "<");
 	    type_print (type, "", stream, -1);
-	    fprintf_filtered (stream, " [0x%s]> [$%s]", phex_nz (type_die, 0),
+	    fprintf_filtered (stream, " [0x%s]> [$%s]",
+			      phex_nz (type_die.cu_off, 0),
 			      locexpr_regname (arch, reg));
 	  }
 	  break;
@@ -3561,11 +3569,12 @@
 	case DW_OP_GNU_convert:
 	case DW_OP_GNU_reinterpret:
 	  {
-	    ULONGEST type_die;
+	    cu_offset type_die;
 
-	    data = read_uleb128 (data, end, &type_die);
+	    data = read_uleb128 (data, end, &ul);
+	    type_die.cu_off = ul;
 
-	    if (type_die == 0)
+	    if (type_die.cu_off == 0)
 	      fprintf_filtered (stream, "<0>");
 	    else
 	      {
@@ -3574,7 +3583,7 @@
 		type = dwarf2_get_die_type (type_die, per_cu);
 		fprintf_filtered (stream, "<");
 		type_print (type, "", stream, -1);
-		fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die, 0));
+		fprintf_filtered (stream, " [0x%s]>", phex_nz (type_die.cu_off, 0));
 	      }
 	  }
 	  break;
--- src/gdb/dwarf2loc.h	2012/03/08 19:37:07	1.30
+++ src/gdb/dwarf2loc.h	2012/03/19 19:59:19	1.31
@@ -20,6 +20,8 @@
 #if !defined (DWARF2LOC_H)
 #define DWARF2LOC_H
 
+#include "dwarf2expr.h"
+
 struct symbol_computed_ops;
 struct objfile;
 struct dwarf2_per_cu_data;
@@ -61,11 +63,11 @@
    CORE_ADDR pc);
 
 struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block
-  (unsigned int offset_in_cu, struct dwarf2_per_cu_data *per_cu,
+  (cu_offset offset_in_cu, struct dwarf2_per_cu_data *per_cu,
    CORE_ADDR (*get_frame_pc) (void *baton),
    void *baton);
 
-struct type *dwarf2_get_die_type (unsigned int die_offset,
+struct type *dwarf2_get_die_type (cu_offset die_offset,
 				  struct dwarf2_per_cu_data *per_cu);
 
 /* Evaluate a location description, starting at DATA and with length
--- src/gdb/dwarf2read.c	2012/03/16 18:26:00	1.626
+++ src/gdb/dwarf2read.c	2012/03/19 19:59:19	1.627
@@ -216,7 +216,7 @@
      To keep things simple we allocate both lazily.  */
   htab_t debug_info_type_hash;
 
-  /* Table mapping type .debug_types DIE offsets to types.
+  /* Table mapping type .debug_types DIE sect_offset to types.
      This is NULL if not allocated yet.  */
   htab_t debug_types_type_hash;
 };
@@ -260,7 +260,7 @@
   short version;
   unsigned char addr_size;
   unsigned char signed_addr_p;
-  unsigned int abbrev_offset;
+  sect_offset abbrev_offset;
 
   /* Size of file offsets; either 4 or 8.  */
   unsigned int offset_size;
@@ -270,11 +270,11 @@
 
   /* Offset to the first byte of this compilation unit header in the
      .debug_info section, for resolving relative reference dies.  */
-  unsigned int offset;
+  sect_offset offset;
 
   /* Offset to first die in this cu from the start of the cu.
      This will be the first byte following the compilation unit header.  */
-  unsigned int first_die_offset;
+  cu_offset first_die_offset;
 };
 
 /* Type used for delaying computation of method physnames.
@@ -338,7 +338,8 @@
   /* Storage for the abbrev table.  */
   struct obstack abbrev_obstack;
 
-  /* Hash table holding all the loaded partial DIEs.  */
+  /* Hash table holding all the loaded partial DIEs
+     with partial_die->offset.SECT_OFF as hash.  */
   htab_t partial_dies;
 
   /* Storage for things with the same lifetime as this read-in compilation
@@ -357,7 +358,8 @@
   /* How many compilation units ago was this CU last referenced?  */
   int last_used;
 
-  /* A hash table of die offsets for following references.  */
+  /* A hash table of DIE cu_offset for following references with
+     die_info->offset.sect_off as hash.  */
   htab_t die_hash;
 
   /* Full DIEs if read in.  */
@@ -406,7 +408,7 @@
      - if it doesn't, GDB will fall over anyway.
      NOTE: Unlike comp_unit_head.length, this length includes
      initial_length_size.  */
-  unsigned int offset;
+  sect_offset offset;
   unsigned int length : 29;
 
   /* Flag indicating this compilation unit will be read in before
@@ -452,8 +454,8 @@
 {
   ULONGEST signature;
 
-  /* Offset in .debug_types of the type defined by this TU.  */
-  unsigned int type_offset;
+  /* Offset in this TU of the type defined by this TU.  */
+  cu_offset type_offset;
 
   /* The CU(/TU) of this type.  */
   struct dwarf2_per_cu_data per_cu;
@@ -530,7 +532,7 @@
 struct partial_die_info
   {
     /* Offset of this DIE.  */
-    unsigned int offset;
+    sect_offset offset;
 
     /* DWARF-2 tag for this DIE.  */
     ENUM_BITFIELD(dwarf_tag) tag : 16;
@@ -585,7 +587,7 @@
     /* If HAS_SPECIFICATION, the offset of the DIE referred to by
        DW_AT_specification (or DW_AT_abstract_origin or
        DW_AT_extension).  */
-    unsigned int spec_offset;
+    sect_offset spec_offset;
 
     /* Pointers to this DIE's parent, first child, and next sibling,
        if any.  */
@@ -649,7 +651,7 @@
     unsigned int abbrev;
 
     /* Offset in .debug_info or .debug_types section.  */
-    unsigned int offset;
+    sect_offset offset;
 
     /* The dies in a compilation unit form an n-ary tree.  PARENT
        points to this die's parent; CHILD points to the first child of
@@ -911,7 +913,7 @@
 				   gdb_byte *, gdb_byte *,
 				   struct dwarf2_cu *);
 
-static struct partial_die_info *find_partial_die (unsigned int,
+static struct partial_die_info *find_partial_die (sect_offset,
 						  struct dwarf2_cu *);
 
 static void fixup_partial_die (struct partial_die_info *,
@@ -1162,7 +1164,7 @@
 
 static int is_ref_attr (struct attribute *);
 
-static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+static sect_offset dwarf2_get_ref_die_offset (struct attribute *);
 
 static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int);
 
@@ -1180,8 +1182,7 @@
 
 static struct signatured_type *lookup_signatured_type_at_offset
     (struct objfile *objfile,
-     struct dwarf2_section_info *section,
-     unsigned int offset);
+     struct dwarf2_section_info *section, sect_offset offset);
 
 static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu);
 
@@ -1225,7 +1226,7 @@
 static int partial_die_eq (const void *item_lhs, const void *item_rhs);
 
 static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
-  (unsigned int offset, struct objfile *objfile);
+  (sect_offset offset, struct objfile *objfile);
 
 static void init_one_comp_unit (struct dwarf2_cu *cu,
 				struct dwarf2_per_cu_data *per_cu);
@@ -1259,7 +1260,7 @@
 
 static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
 
-static struct type *get_die_type_at_offset (unsigned int,
+static struct type *get_die_type_at_offset (sect_offset,
 					    struct dwarf2_per_cu_data *per_cu);
 
 static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
@@ -1891,7 +1892,7 @@
 
       the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
 			       struct dwarf2_per_cu_data);
-      the_cu->offset = offset;
+      the_cu->offset.sect_off = offset;
       the_cu->length = length;
       the_cu->objfile = objfile;
       the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
@@ -1936,9 +1937,9 @@
       type_sig = OBSTACK_ZALLOC (&objfile->objfile_obstack,
 				 struct signatured_type);
       type_sig->signature = signature;
-      type_sig->type_offset = type_offset;
+      type_sig->type_offset.cu_off = type_offset;
       type_sig->per_cu.debug_types_section = section;
-      type_sig->per_cu.offset = offset;
+      type_sig->per_cu.offset.sect_off = offset;
       type_sig->per_cu.objfile = objfile;
       type_sig->per_cu.v.quick
 	= OBSTACK_ZALLOC (&objfile->objfile_obstack,
@@ -2268,7 +2269,7 @@
   else
     sec = &dwarf2_per_objfile->info;
   dwarf2_read_section (objfile, sec);
-  info_ptr = sec->buffer + this_cu->offset;
+  info_ptr = sec->buffer + this_cu->offset.sect_off;
 
   info_ptr = read_and_check_comp_unit_head (&cu.header, sec, info_ptr,
 					    this_cu->debug_types_section != NULL);
@@ -2994,14 +2995,13 @@
 /* Return TRUE if OFFSET is within CU_HEADER.  */
 
 static inline int
-offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset)
+offset_in_cu_p (const struct comp_unit_head *cu_header, sect_offset offset)
 {
-  unsigned int bottom = cu_header->offset;
-  unsigned int top = (cu_header->offset
-		      + cu_header->length
-		      + cu_header->initial_length_size);
+  sect_offset bottom = { cu_header->offset.sect_off };
+  sect_offset top = { (cu_header->offset.sect_off + cu_header->length
+		       + cu_header->initial_length_size) };
 
-  return (offset >= bottom && offset < top);
+  return (offset.sect_off >= bottom.sect_off && offset.sect_off < top.sect_off);
 }
 
 /* Read in the comp unit header information from the debug_info at info_ptr.
@@ -3021,8 +3021,8 @@
   info_ptr += bytes_read;
   cu_header->version = read_2_bytes (abfd, info_ptr);
   info_ptr += 2;
-  cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header,
-					  &bytes_read);
+  cu_header->abbrev_offset.sect_off = read_offset (abfd, info_ptr, cu_header,
+					     &bytes_read);
   info_ptr += bytes_read;
   cu_header->addr_size = read_1_byte (abfd, info_ptr);
   info_ptr += 1;
@@ -3051,22 +3051,22 @@
 	   "(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
 	   filename);
 
-  if (header->abbrev_offset
+  if (header->abbrev_offset.sect_off
       >= dwarf2_section_size (dwarf2_per_objfile->objfile,
 			      &dwarf2_per_objfile->abbrev))
     error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
 	   "(offset 0x%lx + 6) [in module %s]"),
-	   (long) header->abbrev_offset, (long) header->offset,
+	   (long) header->abbrev_offset.sect_off, (long) header->offset.sect_off,
 	   filename);
 
   /* Cast to unsigned long to use 64-bit arithmetic when possible to
      avoid potential 32-bit overflow.  */
-  if (((unsigned long) header->offset
+  if (((unsigned long) header->offset.sect_off
        + header->length + header->initial_length_size)
       > section->size)
     error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
 	   "(offset 0x%lx + 0) [in module %s]"),
-	   (long) header->length, (long) header->offset,
+	   (long) header->length, (long) header->offset.sect_off,
 	   filename);
 }
 
@@ -3083,7 +3083,7 @@
   gdb_byte *beg_of_comp_unit = info_ptr;
   bfd *abfd = section->asection->owner;
 
-  header->offset = beg_of_comp_unit - section->buffer;
+  header->offset.sect_off = beg_of_comp_unit - section->buffer;
 
   info_ptr = read_comp_unit_head (header, info_ptr, abfd);
 
@@ -3092,7 +3092,7 @@
   if (is_debug_types_section)
     info_ptr += 8 /*signature*/ + header->offset_size;
 
-  header->first_die_offset = info_ptr - beg_of_comp_unit;
+  header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
 
   error_check_comp_unit_head (header, section);
 
@@ -3106,12 +3106,12 @@
 read_and_check_type_unit_head (struct comp_unit_head *header,
 			       struct dwarf2_section_info *section,
 			       gdb_byte *info_ptr,
-			       ULONGEST *signature, unsigned int *type_offset)
+			       ULONGEST *signature, cu_offset *type_offset)
 {
   gdb_byte *beg_of_comp_unit = info_ptr;
   bfd *abfd = section->asection->owner;
 
-  header->offset = beg_of_comp_unit - section->buffer;
+  header->offset.sect_off = beg_of_comp_unit - section->buffer;
 
   info_ptr = read_comp_unit_head (header, info_ptr, abfd);
 
@@ -3121,10 +3121,10 @@
     *signature = read_8_bytes (abfd, info_ptr);
   info_ptr += 8;
   if (type_offset != NULL)
-    *type_offset = read_offset_1 (abfd, info_ptr, header->offset_size);
+    type_offset->cu_off = read_offset_1 (abfd, info_ptr, header->offset_size);
   info_ptr += header->offset_size;
 
-  header->first_die_offset = info_ptr - beg_of_comp_unit;
+  header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
 
   error_check_comp_unit_head (header, section);
 
@@ -3280,15 +3280,15 @@
       end_ptr = info_ptr + section->size;
       while (info_ptr < end_ptr)
 	{
-	  unsigned int offset;
-	  unsigned int type_offset;
+	  sect_offset offset;
+	  cu_offset type_offset;
 	  ULONGEST signature;
 	  struct signatured_type *type_sig;
 	  void **slot;
 	  gdb_byte *ptr = info_ptr;
 	  struct comp_unit_head header;
 
-	  offset = ptr - section->buffer;
+	  offset.sect_off = ptr - section->buffer;
 
 	  /* We need to read the type's signature in order to build the hash
 	     table, but we don't need anything else just yet.  */
@@ -3320,7 +3320,7 @@
 	      complaint (&symfile_complaints,
 			 _("debug type entry at offset 0x%x is duplicate to the "
 			   "entry at offset 0x%x, signature 0x%s"),
-			 offset, dup_sig->per_cu.offset,
+			 offset.sect_off, dup_sig->per_cu.offset.sect_off,
 			 phex (signature, sizeof (signature)));
 	      gdb_assert (signature == dup_sig->signature);
 	    }
@@ -3328,7 +3328,8 @@
 
 	  if (dwarf2_die_debug)
 	    fprintf_unfiltered (gdb_stdlog, "  offset 0x%x, signature 0x%s\n",
-				offset, phex (signature, sizeof (signature)));
+				offset.sect_off,
+				phex (signature, sizeof (signature)));
 
 	  info_ptr = info_ptr + header.initial_length_size + header.length;
 	}
@@ -3434,7 +3435,7 @@
   struct objfile *objfile = this_cu->objfile;
   bfd *abfd = objfile->obfd;
   gdb_byte *buffer = section->buffer;
-  gdb_byte *info_ptr = buffer + this_cu->offset;
+  gdb_byte *info_ptr = buffer + this_cu->offset.sect_off;
   unsigned int buffer_size = section->size;
   gdb_byte *beg_of_comp_unit = info_ptr;
   struct die_info *comp_unit_die;
@@ -3489,7 +3490,7 @@
   if (is_debug_types_section)
     {
       /* LENGTH has not been set yet for type units.  */
-      gdb_assert (this_cu->offset == cu.header.offset);
+      gdb_assert (this_cu->offset.sect_off == cu.header.offset.sect_off);
       this_cu->length = cu.header.length + cu.header.initial_length_size;
     }
   else if (comp_unit_die->tag == DW_TAG_partial_unit)
@@ -3696,7 +3697,7 @@
   gdb_assert (! this_cu->debug_types_section);
 
   gdb_assert (section->readin);
-  info_ptr = section->buffer + this_cu->offset;
+  info_ptr = section->buffer + this_cu->offset.sect_off;
 
   if (this_cu->cu == NULL)
     {
@@ -3722,7 +3723,7 @@
   else
     {
       cu = this_cu->cu;
-      info_ptr += cu->header.first_die_offset;
+      info_ptr += cu->header.first_die_offset.cu_off;
     }
 
   /* Read the abbrevs for this compilation unit into a table.  */
@@ -3781,9 +3782,9 @@
     {
       unsigned int length, initial_length_size;
       struct dwarf2_per_cu_data *this_cu;
-      unsigned int offset;
+      sect_offset offset;
 
-      offset = info_ptr - dwarf2_per_objfile->info.buffer;
+      offset.sect_off = info_ptr - dwarf2_per_objfile->info.buffer;
 
       /* Read just enough information to find out where the next
 	 compilation unit is.  */
@@ -3985,7 +3986,7 @@
 	 ignoring them.  */
       complaint (&symfile_complaints,
 		 _("unhandled containing DIE tag %d for DIE at %d"),
-		 parent->tag, pdi->offset);
+		 parent->tag, pdi->offset.sect_off);
       parent->scope = grandparent_scope;
     }
 
@@ -4015,9 +4016,10 @@
 	  struct attribute attr;
 	  struct dwarf2_cu *ref_cu = cu;
 
+	  /* DW_FORM_ref_addr is using section offset.  */
 	  attr.name = 0;
 	  attr.form = DW_FORM_ref_addr;
-	  attr.u.addr = pdi->offset;
+	  attr.u.addr = pdi->offset.sect_off;
 	  die = follow_die_ref (NULL, &attr, &ref_cu);
 
 	  return xstrdup (dwarf2_full_name (NULL, die, ref_cu));
@@ -4412,7 +4414,7 @@
 	    complaint (&symfile_complaints,
 		       _("ignoring absolute DW_AT_sibling"));
 	  else
-	    return buffer + dwarf2_get_ref_die_offset (&attr);
+	    return buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
 	}
 
       /* If it isn't DW_AT_sibling, skip this attribute.  */
@@ -4696,7 +4698,7 @@
   struct objfile *objfile = per_cu->objfile;
   bfd *abfd = objfile->obfd;
   struct dwarf2_cu *cu;
-  unsigned int offset;
+  sect_offset offset;
   gdb_byte *info_ptr, *beg_of_comp_unit;
   struct cleanup *free_cu_cleanup = NULL;
   struct attribute *attr;
@@ -4708,7 +4710,7 @@
   offset = per_cu->offset;
 
   dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
-  info_ptr = dwarf2_per_objfile->info.buffer + offset;
+  info_ptr = dwarf2_per_objfile->info.buffer + offset.sect_off;
   beg_of_comp_unit = info_ptr;
 
   if (per_cu->cu == NULL)
@@ -4735,12 +4737,12 @@
 
       /* Complete the cu_header.  */
       cu->header.offset = offset;
-      cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
+      cu->header.first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
     }
   else
     {
       cu = per_cu->cu;
-      info_ptr += cu->header.first_die_offset;
+      info_ptr += cu->header.first_die_offset.cu_off;
     }
 
   cu->dies = read_comp_unit (info_ptr, cu);
@@ -5379,7 +5381,7 @@
 	  complaint (&symfile_complaints,
 		     _("Computed physname <%s> does not match demangled <%s> "
 		       "(from linkage <%s>) - DIE at 0x%x [in module %s]"),
-		     physname, canon, mangled, die->offset, objfile->name);
+		     physname, canon, mangled, die->offset.sect_off, objfile->name);
 
 	  /* Prefer DW_AT_linkage_name (in the CANON form) - when it
 	     is available here - over computed PHYSNAME.  It is safer
@@ -5516,7 +5518,7 @@
 	    complaint (&symfile_complaints,
 		       _("child DW_TAG_imported_declaration expected "
 			 "- DIE at 0x%x [in module %s]"),
-		       child_die->offset, objfile->name);
+		       child_die->offset.sect_off, objfile->name);
 	    continue;
 	  }
 
@@ -5537,7 +5539,7 @@
 	    complaint (&symfile_complaints,
 		       _("child DW_TAG_imported_declaration has unknown "
 			 "imported name - DIE at 0x%x [in module %s]"),
-		       child_die->offset, objfile->name);
+		       child_die->offset.sect_off, objfile->name);
 	    continue;
 	  }
 
@@ -5844,8 +5846,8 @@
   struct die_info *child_die;
   unsigned die_children_count;
   /* CU offsets which were referenced by children of the current DIE.  */
-  unsigned *offsets;
-  unsigned *offsets_end, *offsetp;
+  sect_offset *offsets;
+  sect_offset *offsets_end, *offsetp;
   /* Parent of DIE - referenced by DW_AT_abstract_origin.  */
   struct die_info *origin_die;
   /* Iterator of the ORIGIN_DIE children.  */
@@ -5875,7 +5877,7 @@
 	   && origin_die->tag == DW_TAG_subprogram))
     complaint (&symfile_complaints,
 	       _("DIE 0x%x and its abstract origin 0x%x have different tags"),
-	       die->offset, origin_die->offset);
+	       die->offset.sect_off, origin_die->offset.sect_off);
 
   child_die = die->child;
   die_children_count = 0;
@@ -5918,13 +5920,13 @@
 		   && child_origin_die->tag == DW_TAG_subprogram))
 	    complaint (&symfile_complaints,
 		       _("Child DIE 0x%x and its abstract origin 0x%x have "
-			 "different tags"), child_die->offset,
-		       child_origin_die->offset);
+			 "different tags"), child_die->offset.sect_off,
+		       child_origin_die->offset.sect_off);
 	  if (child_origin_die->parent != origin_die)
 	    complaint (&symfile_complaints,
 		       _("Child DIE 0x%x and its abstract origin 0x%x have "
-			 "different parents"), child_die->offset,
-		       child_origin_die->offset);
+			 "different parents"), child_die->offset.sect_off,
+		       child_origin_die->offset.sect_off);
 	  else
 	    *offsets_end++ = child_origin_die->offset;
 	}
@@ -5933,20 +5935,22 @@
   qsort (offsets, offsets_end - offsets, sizeof (*offsets),
 	 unsigned_int_compar);
   for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
-    if (offsetp[-1] == *offsetp)
+    if (offsetp[-1].sect_off == offsetp->sect_off)
       complaint (&symfile_complaints,
 		 _("Multiple children of DIE 0x%x refer "
 		   "to DIE 0x%x as their abstract origin"),
-		 die->offset, *offsetp);
+		 die->offset.sect_off, offsetp->sect_off);
 
   offsetp = offsets;
   origin_child_die = origin_die->child;
   while (origin_child_die && origin_child_die->tag)
     {
       /* Is ORIGIN_CHILD_DIE referenced by any of the DIE children?  */
-      while (offsetp < offsets_end && *offsetp < origin_child_die->offset)
+      while (offsetp < offsets_end
+	     && offsetp->sect_off < origin_child_die->offset.sect_off)
 	offsetp++;
-      if (offsetp >= offsets_end || *offsetp > origin_child_die->offset)
+      if (offsetp >= offsets_end
+	  || offsetp->sect_off > origin_child_die->offset.sect_off)
 	{
 	  /* Found that ORIGIN_CHILD_DIE is really not referenced.  */
 	  process_die (origin_child_die, origin_cu);
@@ -5997,7 +6001,8 @@
   if (name == NULL)
     {
       complaint (&symfile_complaints,
-                 _("missing name for subprogram DIE at %d"), die->offset);
+		 _("missing name for subprogram DIE at %d"),
+		 die->offset.sect_off);
       return;
     }
 
@@ -6009,7 +6014,7 @@
 	complaint (&symfile_complaints,
 		   _("cannot get low and high bounds "
 		     "for subprogram DIE at %d"),
-		   die->offset);
+		   die->offset.sect_off);
       return;
     }
 
@@ -6221,7 +6226,7 @@
       complaint (&symfile_complaints,
 		 _("missing DW_AT_low_pc for DW_TAG_GNU_call_site "
 		   "DIE 0x%x [in module %s]"),
-		 die->offset, objfile->name);
+		 die->offset.sect_off, objfile->name);
       return;
     }
   pc = DW_ADDR (attr) + baseaddr;
@@ -6237,7 +6242,7 @@
       complaint (&symfile_complaints,
 		 _("Duplicate PC %s for DW_TAG_GNU_call_site "
 		   "DIE 0x%x [in module %s]"),
-		 paddress (gdbarch, pc), die->offset, objfile->name);
+		 paddress (gdbarch, pc), die->offset.sect_off, objfile->name);
       return;
     }
 
@@ -6252,7 +6257,7 @@
 	  complaint (&symfile_complaints,
 		     _("Tag %d is not DW_TAG_GNU_call_site_parameter in "
 		       "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		     child_die->tag, child_die->offset, objfile->name);
+		     child_die->tag, child_die->offset.sect_off, objfile->name);
 	  continue;
 	}
 
@@ -6310,7 +6315,7 @@
 	    complaint (&symfile_complaints,
 		       _("Cannot find function owning DW_TAG_GNU_call_site "
 			 "DIE 0x%x [in module %s]"),
-		       die->offset, objfile->name);
+		       die->offset.sect_off, objfile->name);
 	}
     }
 
@@ -6347,7 +6352,7 @@
 	    complaint (&symfile_complaints,
 		       _("DW_AT_GNU_call_site_target target DIE has invalid "
 		         "physname, for referencing DIE 0x%x [in module %s]"),
-		       die->offset, objfile->name);
+		       die->offset.sect_off, objfile->name);
 	  else
 	    SET_FIELD_PHYSNAME (call_site->target, (char *) target_physname);
 	}
@@ -6360,7 +6365,7 @@
 	    complaint (&symfile_complaints,
 		       _("DW_AT_GNU_call_site_target target DIE has invalid "
 		         "low pc, for referencing DIE 0x%x [in module %s]"),
-		       die->offset, objfile->name);
+		       die->offset.sect_off, objfile->name);
 	  else
 	    SET_FIELD_PHYSADDR (call_site->target, lowpc + baseaddr);
 	}
@@ -6369,7 +6374,7 @@
     complaint (&symfile_complaints,
 	       _("DW_TAG_GNU_call_site DW_AT_GNU_call_site_target is neither "
 		 "block nor reference, for DIE 0x%x [in module %s]"),
-	       die->offset, objfile->name);
+	       die->offset.sect_off, objfile->name);
 
   call_site->per_cu = cu->per_cu;
 
@@ -6398,7 +6403,7 @@
 	  complaint (&symfile_complaints,
 		     _("No DW_FORM_block* DW_AT_location for "
 		       "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		     child_die->offset, objfile->name);
+		     child_die->offset.sect_off, objfile->name);
 	  continue;
 	}
       parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data,
@@ -6412,7 +6417,7 @@
 		     _("Only single DW_OP_reg or DW_OP_fbreg is supported "
 		       "for DW_FORM_block* DW_AT_location for "
 		       "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		     child_die->offset, objfile->name);
+		     child_die->offset.sect_off, objfile->name);
 	  continue;
 	}
 
@@ -6422,7 +6427,7 @@
 	  complaint (&symfile_complaints,
 		     _("No DW_FORM_block* DW_AT_GNU_call_site_value for "
 		       "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		     child_die->offset, objfile->name);
+		     child_die->offset.sect_off, objfile->name);
 	  continue;
 	}
       parameter->value = DW_BLOCK (attr)->data;
@@ -6440,7 +6445,7 @@
 	    complaint (&symfile_complaints,
 		       _("No DW_FORM_block* DW_AT_GNU_call_site_data_value for "
 			 "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
-		       child_die->offset, objfile->name);
+		       child_die->offset.sect_off, objfile->name);
 	  else
 	    {
 	      parameter->data_value = DW_BLOCK (attr)->data;
@@ -7491,7 +7496,7 @@
 	  complaint (&symfile_complaints,
 		     _("Member function \"%s\" (offset %d) is virtual "
 		       "but the vtable offset is not specified"),
-		     fieldname, die->offset);
+		     fieldname, die->offset.sect_off);
 	  ALLOCATE_CPLUS_STRUCT_TYPE (type);
 	  TYPE_CPLUS_DYNAMIC (type) = 1;
 	}
@@ -8084,8 +8089,8 @@
 	= lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile,
 					    cu->per_cu->debug_types_section,
 					    cu->per_cu->offset);
-      if (type_sig->per_cu.offset + type_sig->type_offset
-	  != die->offset)
+      if (type_sig->per_cu.offset.sect_off + type_sig->type_offset.cu_off
+	  != die->offset.sect_off)
 	return;
     }
 
@@ -8411,7 +8416,7 @@
   if (!module_name)
     complaint (&symfile_complaints,
 	       _("DW_TAG_module has no name, offset 0x%x"),
-               die->offset);
+               die->offset.sect_off);
   type = init_type (TYPE_CODE_MODULE, 0, 0, module_name, objfile);
 
   /* determine_prefix uses TYPE_TAG_NAME.  */
@@ -8867,7 +8872,7 @@
       complaint (&symfile_complaints,
 		 _("Self-referential DW_TAG_typedef "
 		   "- DIE at 0x%x [in module %s]"),
-		 die->offset, objfile->name);
+		 die->offset.sect_off, objfile->name);
       TYPE_TARGET_TYPE (this_type) = NULL;
     }
   return this_type;
@@ -9135,7 +9140,7 @@
 {
   const struct die_info *die = item;
 
-  return die->offset;
+  return die->offset.sect_off;
 }
 
 /* Trivial comparison function for die_info structures: two DIEs
@@ -9147,7 +9152,7 @@
   const struct die_info *die_lhs = item_lhs;
   const struct die_info *die_rhs = item_rhs;
 
-  return die_lhs->offset == die_rhs->offset;
+  return die_lhs->offset.sect_off == die_rhs->offset.sect_off;
 }
 
 /* Read a whole compilation unit into a linked list of dies.  */
@@ -9296,13 +9301,14 @@
 	       struct die_info **diep, gdb_byte *info_ptr,
 	       int *has_children)
 {
-  unsigned int abbrev_number, bytes_read, i, offset;
+  unsigned int abbrev_number, bytes_read, i;
+  sect_offset offset;
   struct abbrev_info *abbrev;
   struct die_info *die;
   struct dwarf2_cu *cu = reader->cu;
   bfd *abfd = reader->abfd;
 
-  offset = info_ptr - reader->buffer;
+  offset.sect_off = info_ptr - reader->buffer;
   abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
   info_ptr += bytes_read;
   if (!abbrev_number)
@@ -9362,7 +9368,8 @@
 
   dwarf2_read_section (dwarf2_per_objfile->objfile,
 		       &dwarf2_per_objfile->abbrev);
-  abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset;
+  abbrev_ptr = (dwarf2_per_objfile->abbrev.buffer
+		+ cu_header->abbrev_offset.sect_off);
   abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
   abbrev_ptr += bytes_read;
 
@@ -9649,7 +9656,7 @@
 	complaint (&symfile_complaints,
 		   _("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
 		     "- DIE at 0x%x [in module %s]"),
-		   part_die->offset, objfile->name);
+		   part_die->offset.sect_off, objfile->name);
 
       /* If we're at the second level, and we're an enumerator, and
 	 our parent has no specification (meaning possibly lives in a
@@ -9723,7 +9730,7 @@
 	  void **slot;
 
 	  slot = htab_find_slot_with_hash (cu->partial_dies, part_die,
-					   part_die->offset, INSERT);
+					   part_die->offset.sect_off, INSERT);
 	  *slot = part_die;
 	}
 
@@ -9789,7 +9796,7 @@
 
   memset (part_die, 0, sizeof (struct partial_die_info));
 
-  part_die->offset = info_ptr - buffer;
+  part_die->offset.sect_off = info_ptr - buffer;
 
   info_ptr += abbrev_len;
 
@@ -9882,7 +9889,7 @@
 	    complaint (&symfile_complaints,
 		       _("ignoring absolute DW_AT_sibling"));
 	  else
-	    part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr);
+	    part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
 	  break;
         case DW_AT_byte_size:
           part_die->has_byte_size = 1;
@@ -9940,7 +9947,7 @@
 		     _("DW_AT_low_pc %s is zero "
 		       "for DIE at 0x%x [in module %s]"),
 		     paddress (gdbarch, part_die->lowpc),
-		     part_die->offset, objfile->name);
+		     part_die->offset.sect_off, objfile->name);
 	}
       /* dwarf2_get_pc_bounds has also the strict low < high requirement.  */
       else if (part_die->lowpc >= part_die->highpc)
@@ -9952,7 +9959,7 @@
 		       "for DIE at 0x%x [in module %s]"),
 		     paddress (gdbarch, part_die->lowpc),
 		     paddress (gdbarch, part_die->highpc),
-		     part_die->offset, objfile->name);
+		     part_die->offset.sect_off, objfile->name);
 	}
       else
 	part_die->has_pc_info = 1;
@@ -9964,13 +9971,14 @@
 /* Find a cached partial DIE at OFFSET in CU.  */
 
 static struct partial_die_info *
-find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu)
+find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu)
 {
   struct partial_die_info *lookup_die = NULL;
   struct partial_die_info part_die;
 
   part_die.offset = offset;
-  lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, offset);
+  lookup_die = htab_find_with_hash (cu->partial_dies, &part_die,
+				    offset.sect_off);
 
   return lookup_die;
 }
@@ -9981,7 +9989,7 @@
    DW_FORM_ref_sig8).  */
 
 static struct partial_die_info *
-find_partial_die (unsigned int offset, struct dwarf2_cu *cu)
+find_partial_die (sect_offset offset, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
   struct dwarf2_per_cu_data *per_cu = NULL;
@@ -10028,8 +10036,8 @@
 	  make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
 	}
       info_ptr = (dwarf2_per_objfile->info.buffer
-		  + per_cu->cu->header.offset
-		  + per_cu->cu->header.first_die_offset);
+		  + per_cu->cu->header.offset.sect_off
+		  + per_cu->cu->header.first_die_offset.cu_off);
       abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
       info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
 				   objfile->obfd,
@@ -10050,7 +10058,7 @@
     internal_error (__FILE__, __LINE__,
 		    _("could not find partial DIE 0x%x "
 		      "in cache [from module %s]\n"),
-		    offset, bfd_get_filename (objfile->obfd));
+		    offset.sect_off, bfd_get_filename (objfile->obfd));
   return pd;
 }
 
@@ -10295,19 +10303,23 @@
       info_ptr += bytes_read;
       break;
     case DW_FORM_ref1:
-      DW_ADDR (attr) = cu->header.offset + read_1_byte (abfd, info_ptr);
+      DW_ADDR (attr) = (cu->header.offset.sect_off
+			+ read_1_byte (abfd, info_ptr));
       info_ptr += 1;
       break;
     case DW_FORM_ref2:
-      DW_ADDR (attr) = cu->header.offset + read_2_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = (cu->header.offset.sect_off
+			+ read_2_bytes (abfd, info_ptr));
       info_ptr += 2;
       break;
     case DW_FORM_ref4:
-      DW_ADDR (attr) = cu->header.offset + read_4_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = (cu->header.offset.sect_off
+			+ read_4_bytes (abfd, info_ptr));
       info_ptr += 4;
       break;
     case DW_FORM_ref8:
-      DW_ADDR (attr) = cu->header.offset + read_8_bytes (abfd, info_ptr);
+      DW_ADDR (attr) = (cu->header.offset.sect_off
+			+ read_8_bytes (abfd, info_ptr));
       info_ptr += 8;
       break;
     case DW_FORM_ref_sig8:
@@ -10319,7 +10331,7 @@
       info_ptr += 8;
       break;
     case DW_FORM_ref_udata:
-      DW_ADDR (attr) = (cu->header.offset
+      DW_ADDR (attr) = (cu->header.offset.sect_off
 			+ read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
       info_ptr += bytes_read;
       break;
@@ -12281,7 +12293,7 @@
 
   if (is_ref_attr (attr))
     {
-      unsigned int offset = dwarf2_get_ref_die_offset (attr);
+      sect_offset offset = dwarf2_get_ref_die_offset (attr);
 
       this_type = get_die_type_at_offset (offset, cu->per_cu);
     }
@@ -12289,17 +12301,18 @@
     {
       struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
       struct dwarf2_cu *sig_cu;
-      unsigned int offset;
+      sect_offset offset;
 
       /* sig_type will be NULL if the signatured type is missing from
 	 the debug info.  */
       if (sig_type == NULL)
 	error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
 		 "at 0x%x [in module %s]"),
-	       die->offset, objfile->name);
+	       die->offset.sect_off, objfile->name);
 
       gdb_assert (sig_type->per_cu.debug_types_section);
-      offset = sig_type->per_cu.offset + sig_type->type_offset;
+      offset.sect_off = (sig_type->per_cu.offset.sect_off
+			 + sig_type->type_offset.cu_off);
       this_type = get_die_type_at_offset (offset, &sig_type->per_cu);
     }
   else
@@ -12331,8 +12344,8 @@
       /* read_type_die already issued a complaint.  */
       message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
 			    objfile->name,
-			    cu->header.offset,
-			    die->offset);
+			    cu->header.offset.sect_off,
+			    die->offset.sect_off);
       saved = obstack_copy0 (&objfile->objfile_obstack,
 			     message, strlen (message));
       xfree (message);
@@ -13919,13 +13932,13 @@
 
   print_spaces (indent, f);
   fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n",
-	   dwarf_tag_name (die->tag), die->abbrev, die->offset);
+	   dwarf_tag_name (die->tag), die->abbrev, die->offset.sect_off);
 
   if (die->parent != NULL)
     {
       print_spaces (indent, f);
       fprintf_unfiltered (f, "  parent at offset: 0x%x\n",
-			  die->parent->offset);
+			  die->parent->offset.sect_off);
     }
 
   print_spaces (indent, f);
@@ -13982,7 +13995,7 @@
 	case DW_FORM_ref_sig8:
 	  if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL)
 	    fprintf_unfiltered (f, "signatured type, offset: 0x%x",
-			  DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset);
+			 DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset.sect_off);
 	  else
 	    fprintf_unfiltered (f, "signatured type, offset: unknown");
 	  break;
@@ -14071,11 +14084,15 @@
 {
   void **slot;
 
-  slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset, INSERT);
+  slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset.sect_off,
+				   INSERT);
 
   *slot = die;
 }
 
+/* DW_ADDR is always stored already as sect_offset; despite for the forms
+   besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file.  */
+
 static int
 is_ref_attr (struct attribute *attr)
 {
@@ -14093,16 +14110,22 @@
     }
 }
 
-static unsigned int
+/* Return DIE offset of ATTR.  Return 0 with complaint if ATTR is not of the
+   required kind.  */
+
+static sect_offset
 dwarf2_get_ref_die_offset (struct attribute *attr)
 {
+  sect_offset retval = { DW_ADDR (attr) };
+
   if (is_ref_attr (attr))
-    return DW_ADDR (attr);
+    return retval;
 
+  retval.sect_off = 0;
   complaint (&symfile_complaints,
 	     _("unsupported die ref attribute form: '%s'"),
 	     dwarf_form_name (attr->form));
-  return 0;
+  return retval;
 }
 
 /* Return the constant value held by ATTR.  Return DEFAULT_VALUE if
@@ -14199,7 +14222,7 @@
    Returns NULL if OFFSET is invalid.  */
 
 static struct die_info *
-follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
+follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
 {
   struct die_info temp_die;
   struct dwarf2_cu *target_cu, *cu = *ref_cu;
@@ -14237,7 +14260,7 @@
 
   *ref_cu = target_cu;
   temp_die.offset = offset;
-  return htab_find_with_hash (target_cu->die_hash, &temp_die, offset);
+  return htab_find_with_hash (target_cu->die_hash, &temp_die, offset.sect_off);
 }
 
 /* Follow reference attribute ATTR of SRC_DIE.
@@ -14248,7 +14271,7 @@
 follow_die_ref (struct die_info *src_die, struct attribute *attr,
 		struct dwarf2_cu **ref_cu)
 {
-  unsigned int offset = dwarf2_get_ref_die_offset (attr);
+  sect_offset offset = dwarf2_get_ref_die_offset (attr);
   struct dwarf2_cu *cu = *ref_cu;
   struct die_info *die;
 
@@ -14256,7 +14279,7 @@
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
 	   "at 0x%x [in module %s]"),
-	   offset, src_die->offset, cu->objfile->name);
+	   offset.sect_off, src_die->offset.sect_off, cu->objfile->name);
 
   return die;
 }
@@ -14266,12 +14289,12 @@
    dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE.  */
 
 struct dwarf2_locexpr_baton
-dwarf2_fetch_die_location_block (unsigned int offset_in_cu,
+dwarf2_fetch_die_location_block (cu_offset offset_in_cu,
 				 struct dwarf2_per_cu_data *per_cu,
 				 CORE_ADDR (*get_frame_pc) (void *baton),
 				 void *baton)
 {
-  unsigned int offset = per_cu->offset + offset_in_cu;
+  sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off };
   struct dwarf2_cu *cu;
   struct die_info *die;
   struct attribute *attr;
@@ -14286,7 +14309,7 @@
   die = follow_die_offset (offset, &cu);
   if (!die)
     error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
-	   offset, per_cu->objfile->name);
+	   offset.sect_off, per_cu->objfile->name);
 
   attr = dwarf2_attr (die, DW_AT_location, cu);
   if (!attr)
@@ -14314,7 +14337,7 @@
       if (!attr_form_is_block (attr))
 	error (_("Dwarf Error: DIE at 0x%x referenced in module %s "
 		 "is neither DW_FORM_block* nor DW_FORM_exprloc"),
-	       offset, per_cu->objfile->name);
+	       offset.sect_off, per_cu->objfile->name);
 
       retval.data = DW_BLOCK (attr)->data;
       retval.size = DW_BLOCK (attr)->size;
@@ -14330,11 +14353,15 @@
    PER_CU.  */
 
 struct type *
-dwarf2_get_die_type (unsigned int die_offset,
+dwarf2_get_die_type (cu_offset die_offset,
 		     struct dwarf2_per_cu_data *per_cu)
 {
+  sect_offset die_offset_sect;
+
   dw2_setup (per_cu->objfile);
-  return get_die_type_at_offset (per_cu->offset + die_offset, per_cu);
+
+  die_offset_sect.sect_off = per_cu->offset.sect_off + die_offset.cu_off;
+  return get_die_type_at_offset (die_offset_sect, per_cu);
 }
 
 /* Follow the signature attribute ATTR in SRC_DIE.
@@ -14356,7 +14383,7 @@
   if (sig_type == NULL)
     error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
 	     "at 0x%x [in module %s]"),
-	   src_die->offset, objfile->name);
+	   src_die->offset.sect_off, objfile->name);
 
   /* If necessary, add it to the queue and load its DIEs.  */
 
@@ -14366,8 +14393,10 @@
   gdb_assert (sig_type->per_cu.cu != NULL);
 
   sig_cu = sig_type->per_cu.cu;
-  temp_die.offset = sig_cu->header.offset + sig_type->type_offset;
-  die = htab_find_with_hash (sig_cu->die_hash, &temp_die, temp_die.offset);
+  temp_die.offset.sect_off = (sig_type->per_cu.offset.sect_off
+			      + sig_type->type_offset.cu_off);
+  die = htab_find_with_hash (sig_cu->die_hash, &temp_die,
+			     temp_die.offset.sect_off);
   if (die)
     {
       *ref_cu = sig_cu;
@@ -14376,7 +14405,7 @@
 
   error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced "
 	 "from DIE at 0x%x [in module %s]"),
-	 sig_type->type_offset, src_die->offset, objfile->name);
+	 temp_die.offset.sect_off, src_die->offset.sect_off, objfile->name);
 }
 
 /* Given an offset of a signatured type, return its signatured_type.  */
@@ -14384,9 +14413,9 @@
 static struct signatured_type *
 lookup_signatured_type_at_offset (struct objfile *objfile,
 				  struct dwarf2_section_info *section,
-				  unsigned int offset)
+				  sect_offset offset)
 {
-  gdb_byte *info_ptr = section->buffer + offset;
+  gdb_byte *info_ptr = section->buffer + offset.sect_off;
   unsigned int length, initial_length_size;
   unsigned int sig_offset;
   struct signatured_type find_entry, *type_sig;
@@ -14402,7 +14431,7 @@
   /* This is only used to lookup previously recorded types.
      If we didn't find it, it's our bug.  */
   gdb_assert (type_sig != NULL);
-  gdb_assert (offset == type_sig->per_cu.offset);
+  gdb_assert (offset.sect_off == type_sig->per_cu.offset.sect_off);
 
   return type_sig;
 }
@@ -14414,7 +14443,7 @@
 {
   struct objfile *objfile = per_cu->objfile;
   struct dwarf2_section_info *sect = per_cu->debug_types_section;
-  unsigned int offset = per_cu->offset;
+  sect_offset offset = per_cu->offset;
   struct signatured_type *type_sig;
 
   dwarf2_read_section (objfile, sect);
@@ -14448,7 +14477,7 @@
   struct dwarf2_section_info *section = type_sig->per_cu.debug_types_section;
 
   dwarf2_read_section (objfile, section);
-  types_ptr = section->buffer + type_sig->per_cu.offset;
+  types_ptr = section->buffer + type_sig->per_cu.offset.sect_off;
 
   gdb_assert (type_sig->per_cu.cu == NULL);
 
@@ -15799,7 +15828,7 @@
 
   objfile = per_cu->objfile;
   per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
-  info_ptr = per_objfile->info.buffer + per_cu->offset;
+  info_ptr = per_objfile->info.buffer + per_cu->offset.sect_off;
 
   memset (cu_headerp, 0, sizeof (*cu_headerp));
   read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd);
@@ -15866,7 +15895,7 @@
    the DIE at OFFSET.  Raises an error on failure.  */
 
 static struct dwarf2_per_cu_data *
-dwarf2_find_containing_comp_unit (unsigned int offset,
+dwarf2_find_containing_comp_unit (sect_offset offset,
 				  struct objfile *objfile)
 {
   struct dwarf2_per_cu_data *this_cu;
@@ -15878,29 +15907,32 @@
     {
       int mid = low + (high - low) / 2;
 
-      if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset)
+      if (dwarf2_per_objfile->all_comp_units[mid]->offset.sect_off
+	  >= offset.sect_off)
 	high = mid;
       else
 	low = mid + 1;
     }
   gdb_assert (low == high);
-  if (dwarf2_per_objfile->all_comp_units[low]->offset > offset)
+  if (dwarf2_per_objfile->all_comp_units[low]->offset.sect_off
+      > offset.sect_off)
     {
       if (low == 0)
 	error (_("Dwarf Error: could not find partial DIE containing "
 	       "offset 0x%lx [in module %s]"),
-	       (long) offset, bfd_get_filename (objfile->obfd));
+	       (long) offset.sect_off, bfd_get_filename (objfile->obfd));
 
-      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset <= offset);
+      gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset.sect_off
+		  <= offset.sect_off);
       return dwarf2_per_objfile->all_comp_units[low-1];
     }
   else
     {
       this_cu = dwarf2_per_objfile->all_comp_units[low];
       if (low == dwarf2_per_objfile->n_comp_units - 1
-	  && offset >= this_cu->offset + this_cu->length)
-	error (_("invalid dwarf2 offset %u"), offset);
-      gdb_assert (offset < this_cu->offset + this_cu->length);
+	  && offset.sect_off >= this_cu->offset.sect_off + this_cu->length)
+	error (_("invalid dwarf2 offset %u"), offset.sect_off);
+      gdb_assert (offset.sect_off < this_cu->offset.sect_off + this_cu->length);
       return this_cu;
     }
 }
@@ -16094,7 +16126,7 @@
 
 struct dwarf2_offset_and_type
 {
-  unsigned int offset;
+  sect_offset offset;
   struct type *type;
 };
 
@@ -16105,7 +16137,7 @@
 {
   const struct dwarf2_offset_and_type *ofs = item;
 
-  return ofs->offset;
+  return ofs->offset.sect_off;
 }
 
 /* Equality function for a dwarf2_offset_and_type.  */
@@ -16116,7 +16148,7 @@
   const struct dwarf2_offset_and_type *ofs_lhs = item_lhs;
   const struct dwarf2_offset_and_type *ofs_rhs = item_rhs;
 
-  return ofs_lhs->offset == ofs_rhs->offset;
+  return ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off;
 }
 
 /* Set the type associated with DIE to TYPE.  Save it in CU's hash
@@ -16177,11 +16209,12 @@
   ofs.offset = die->offset;
   ofs.type = type;
   slot = (struct dwarf2_offset_and_type **)
-    htab_find_slot_with_hash (*type_hash_ptr, &ofs, ofs.offset, INSERT);
+    htab_find_slot_with_hash (*type_hash_ptr, &ofs, ofs.offset.sect_off,
+			      INSERT);
   if (*slot)
     complaint (&symfile_complaints,
 	       _("A problem internal to GDB: DIE 0x%x has type already set"),
-	       die->offset);
+	       die->offset.sect_off);
   *slot = obstack_alloc (&objfile->objfile_obstack, sizeof (**slot));
   **slot = ofs;
   return type;
@@ -16191,7 +16224,7 @@
    table, or return NULL if the die does not have a saved type.  */
 
 static struct type *
-get_die_type_at_offset (unsigned int offset,
+get_die_type_at_offset (sect_offset offset,
 			struct dwarf2_per_cu_data *per_cu)
 {
   struct dwarf2_offset_and_type *slot, ofs;
@@ -16205,7 +16238,7 @@
     return NULL;
 
   ofs.offset = offset;
-  slot = htab_find_with_hash (type_hash, &ofs, ofs.offset);
+  slot = htab_find_with_hash (type_hash, &ofs, ofs.offset.sect_off);
   if (slot)
     return slot->type;
   else
@@ -16299,7 +16332,7 @@
 {
   const struct partial_die_info *part_die = item;
 
-  return part_die->offset;
+  return part_die->offset.sect_off;
 }
 
 /* Trivial comparison function for partial_die_info structures: two DIEs
@@ -16311,7 +16344,7 @@
   const struct partial_die_info *part_die_lhs = item_lhs;
   const struct partial_die_info *part_die_rhs = item_rhs;
 
-  return part_die_lhs->offset == part_die_rhs->offset;
+  return part_die_lhs->offset.sect_off == part_die_rhs->offset.sect_off;
 }
 
 static struct cmd_list_element *set_dwarf2_cmdlist;
@@ -16919,9 +16952,10 @@
 		  psymtab->n_static_syms, info->cu_index,
 		  1);
 
-  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->per_cu.offset);
+  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
+			  entry->per_cu.offset.sect_off);
   obstack_grow (info->types_list, val, 8);
-  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset);
+  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset.cu_off);
   obstack_grow (info->types_list, val, 8);
   store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature);
   obstack_grow (info->types_list, val, 8);
@@ -17034,7 +17068,8 @@
       gdb_assert (*slot == NULL);
       *slot = map;
 
-      store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->offset);
+      store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
+			      per_cu->offset.sect_off);
       obstack_grow (&cu_list, val, 8);
       store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->length);
       obstack_grow (&cu_list, val, 8);


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2012-03-19 20:02 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-05 22:34 RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback Joel Brobecker
2012-03-06 20:25 ` Tom Tromey
2012-03-06 23:46   ` Joel Brobecker
2012-03-07 17:10 ` [patch] Fix CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback] Jan Kratochvil
2012-03-07 17:13   ` [patch 2/2] typedef-checking for " Jan Kratochvil
2012-03-07 18:58     ` Doug Evans
2012-03-07 19:10       ` Jan Kratochvil
2012-03-07 19:29         ` Jan Kratochvil
2012-03-08 21:54       ` Tom Tromey
2012-03-08 21:56         ` Doug Evans
2012-03-07 19:07     ` Joel Brobecker
2012-03-07 19:16       ` Jan Kratochvil
2012-03-08 21:53     ` Tom Tromey
2012-03-09 19:40       ` cu_offset vs. sect_offset field names bikeshedding [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets] Jan Kratochvil
2012-03-09 19:52         ` Joel Brobecker
2012-03-19 20:02           ` [commit] [patch 2/2] typedef-checking for CU relative vs. absolute offsets Jan Kratochvil
2012-03-09 19:56         ` cu_offset vs. sect_offset field names bikeshedding [Re: [patch 2/2] typedef-checking for CU relative vs. absolute offsets] Tom Tromey
2012-03-07 18:57   ` [patch] Fix CU relative vs. absolute offsets [Re: RFC: problem with DW_OP_GNU_deref_type and dwarf's get_base_type callback] Joel Brobecker
2012-03-07 19:47     ` Joel Brobecker
2012-03-08 19:40       ` [commit] " Jan Kratochvil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox