From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4105 invoked by alias); 14 Jan 2008 15:55:22 -0000 Received: (qmail 4069 invoked by uid 22791); 14 Jan 2008 15:55:19 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate7.de.ibm.com (HELO mtagate7.de.ibm.com) (195.212.29.156) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 14 Jan 2008 15:54:50 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate7.de.ibm.com (8.13.8/8.13.8) with ESMTP id m0EFskcH069994 for ; Mon, 14 Jan 2008 15:54:46 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m0EFslvI2904118 for ; Mon, 14 Jan 2008 16:54:47 +0100 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m0EFskZA011388 for ; Mon, 14 Jan 2008 16:54:46 +0100 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id m0EFskPB011384; Mon, 14 Jan 2008 16:54:46 +0100 Message-Id: <200801141554.m0EFskPB011384@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Mon, 14 Jan 2008 16:54:46 +0100 Subject: Re: [rfc] Make DWARF-2 "address size" explicit To: jimb@codesourcery.com (Jim Blandy) Date: Mon, 14 Jan 2008 15:55:00 -0000 From: "Ulrich Weigand" Cc: gdb-patches@sourceware.org In-Reply-To: from "Jim Blandy" at Dec 17, 2007 11:51:12 AM X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-01/txt/msg00329.txt.bz2 Hi Jim, > This is certainly a step in the right direction. However, the proper > value to use for addr_size is the one that comes from the header of > the compilation unit containing the expression. (The fact that > there's no compilation unit associated with the frame information is > an existing problem.) > > I had a patch to carry that through from a long while back. A fellow > from Intel has been working on updating it; I've encouraged him to > post it here. > > http://sourceware.org/ml/gdb-patches/2006-05/msg00226.html Thanks for pointing this out! I've updated my patch to retrieve the address size from the CU header, based on your patch. However, the implementation details are a bit different (e.g. because there is no dwarf2_pinfo any more): I use an (opaque) struct dwarf2_cu * in the location list / location expression batons, and provide a number of accessor functions to retrieve CU-associated information: dwarf2_cu_objfile dwarf2_cu_base_address dwarf2_cu_addr_size Apart from that, the behaviour should be identical, with one exception: what address size to use for CFI. Your patch uses size_of_encoded_value (DW_EH_PE_absptr) which basically boils down to: gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT This would be an effective change in behaviour to what we have now, which is: gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT My patch uses in effect gdbarch_addr_bit (get_frame_arch (frame)) / TARGET_CHAR_BIT which does not change behaviour. However, it might well be that the original code is simply wrong and we *should* be using ...ptr_bit instead of ...addr_bit. What do you think? Tested on i386-linux with no regressions. Bye, Ulrich ChangeLog: * dwarf2expr.h (struct dwarf_expr_context): Add ADDR_SIZE member. (dwarf2_read_address): Update prototype. * dwarf2expr.c (unsigned_address_type): Add ADDR_SIZE parameter. (signed_address_type): Likewise. (dwarf2_read_address): Replace BYTES_READ parameter with ADDR_SIZE. (execute_stack_op): Update calls to unsigned_address_type, signed_address_type and dwarf2_read_address. Fix implementation of DW_OP_deref_size. * dwarf2-frame.c (execute_stack_op): Set ctx->addr_size. (execute_cfa_program): Update calls to dwarf2_read_address. * dwarfloc.h (dwarf2_cu_objfile): Add prototype. (dwarf2_cu_addr_size, dwarf2_cu_base_address): Likewise. (struct dwarf2_locexpr_baton): Replace OBJFILE with CU. (struct dwarf2_loclist_baton): Likewise. Remove BASE_ADDRESS. * dwarf2loc.c (find_location_expression): Update calls to dwarf2_read_address. Use dwarf2_cu_objfile, dwarf2_cu_addr_size, and dwarf2_cu_base_address to retrieve CU parameters. (locexpr_describe_location): Likewise. (dwarf2_evaluate_loc_desc): Replace OBJFILE with CU parameter. Set ctx->addr_size to dwarf2_cu_addr_size (cu). (dwarf2_loc_desc_needs_frame): Add CU parameter. Set ctx->addr_size to dwarf2_cu_addr_size (cu). (locexpr_read_variable): Update dwarf2_evaluate_loc_desc call. (loclist_read_variable): Likewise. (locexpr_read_needs_frame): Update dwarf2_loc_desc_needs_frame call. * dwarf2read.c (dwarf2_symbol_mark_computed): Set baton->cu instead of baton->objfile. Do not set baton->base_address. (dwarf2_cu_obfile): New function. (dwarf2_cu_addr_size, dwarf2_cu_base_address): Likewise. diff -urNp gdb-orig/gdb/dwarf2expr.c gdb-head/gdb/dwarf2expr.c --- gdb-orig/gdb/dwarf2expr.c 2008-01-14 15:01:05.000000000 +0100 +++ gdb-head/gdb/dwarf2expr.c 2008-01-14 15:15:06.000000000 +0100 @@ -32,7 +32,7 @@ static void execute_stack_op (struct dwarf_expr_context *, gdb_byte *, gdb_byte *); -static struct type *unsigned_address_type (void); +static struct type *unsigned_address_type (int); /* Create a new context for the expression evaluator. */ @@ -192,20 +192,17 @@ read_sleb128 (gdb_byte *buf, gdb_byte *b return buf; } -/* Read an address from BUF, and verify that it doesn't extend past - BUF_END. The address is returned, and *BYTES_READ is set to the - number of bytes read from BUF. */ +/* Read an address of size ADDR_SIZE from BUF, and verify that it + doesn't extend past BUF_END. */ CORE_ADDR -dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read) +dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int addr_size) { CORE_ADDR result; - if (buf_end - buf < gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT) + if (buf_end - buf < addr_size) error (_("dwarf2_read_address: Corrupted DWARF expression.")); - *bytes_read = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT; - /* For most architectures, calling extract_unsigned_integer() alone is sufficient for extracting an address. However, some architectures (e.g. MIPS) use signed addresses and using @@ -229,21 +226,18 @@ dwarf2_read_address (gdb_byte *buf, gdb_ address being returned. */ result = value_as_address (value_from_longest - (unsigned_address_type (), - extract_unsigned_integer - (buf, - gdbarch_addr_bit (current_gdbarch) - / TARGET_CHAR_BIT))); - + (unsigned_address_type (addr_size), + extract_unsigned_integer (buf, addr_size))); return result; } -/* Return the type of an address, for unsigned arithmetic. */ +/* Return the type of an address of size ADDR_SIZE, + for unsigned arithmetic. */ static struct type * -unsigned_address_type (void) +unsigned_address_type (int addr_size) { - switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT) + switch (addr_size) { case 2: return builtin_type_uint16; @@ -257,12 +251,13 @@ unsigned_address_type (void) } } -/* Return the type of an address, for signed arithmetic. */ +/* Return the type of an address of size ADDR_SIZE, + for signed arithmetic. */ static struct type * -signed_address_type (void) +signed_address_type (int addr_size) { - switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT) + switch (addr_size) { case 2: return builtin_type_int16; @@ -292,7 +287,6 @@ execute_stack_op (struct dwarf_expr_cont CORE_ADDR result; ULONGEST uoffset, reg; LONGEST offset; - int bytes_read; switch (op) { @@ -332,8 +326,8 @@ execute_stack_op (struct dwarf_expr_cont break; case DW_OP_addr: - result = dwarf2_read_address (op_ptr, op_end, &bytes_read); - op_ptr += bytes_read; + result = dwarf2_read_address (op_ptr, op_end, ctx->addr_size); + op_ptr += ctx->addr_size; break; case DW_OP_const1u: @@ -550,34 +544,20 @@ execute_stack_op (struct dwarf_expr_cont { case DW_OP_deref: { - gdb_byte *buf = alloca (gdbarch_addr_bit (current_gdbarch) - / TARGET_CHAR_BIT); - int bytes_read; - - (ctx->read_mem) (ctx->baton, buf, result, - gdbarch_addr_bit (current_gdbarch) - / TARGET_CHAR_BIT); - result = dwarf2_read_address (buf, - buf + (gdbarch_addr_bit - (current_gdbarch) - / TARGET_CHAR_BIT), - &bytes_read); + gdb_byte *buf = alloca (ctx->addr_size); + (ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size); + result = dwarf2_read_address (buf, buf + ctx->addr_size, + ctx->addr_size); } break; case DW_OP_deref_size: { - gdb_byte *buf - = alloca (gdbarch_addr_bit (current_gdbarch) - / TARGET_CHAR_BIT); - int bytes_read; - - (ctx->read_mem) (ctx->baton, buf, result, *op_ptr++); - result = dwarf2_read_address (buf, - buf + (gdbarch_addr_bit - (current_gdbarch) - / TARGET_CHAR_BIT), - &bytes_read); + int addr_size = *op_ptr++; + gdb_byte *buf = alloca (addr_size); + (ctx->read_mem) (ctx->baton, buf, result, addr_size); + result = dwarf2_read_address (buf, buf + addr_size, + addr_size); } break; @@ -628,8 +608,10 @@ execute_stack_op (struct dwarf_expr_cont first = dwarf_expr_fetch (ctx, 0); dwarf_expr_pop (ctx); - val1 = value_from_longest (unsigned_address_type (), first); - val2 = value_from_longest (unsigned_address_type (), second); + val1 = value_from_longest + (unsigned_address_type (ctx->addr_size), first); + val2 = value_from_longest + (unsigned_address_type (ctx->addr_size), second); switch (op) { @@ -662,7 +644,8 @@ execute_stack_op (struct dwarf_expr_cont break; case DW_OP_shra: binop = BINOP_RSH; - val1 = value_from_longest (signed_address_type (), first); + val1 = value_from_longest + (signed_address_type (ctx->addr_size), first); break; case DW_OP_xor: binop = BINOP_BITWISE_XOR; diff -urNp gdb-orig/gdb/dwarf2expr.h gdb-head/gdb/dwarf2expr.h --- gdb-orig/gdb/dwarf2expr.h 2008-01-14 15:01:05.000000000 +0100 +++ gdb-head/gdb/dwarf2expr.h 2008-01-14 15:15:06.000000000 +0100 @@ -34,6 +34,9 @@ struct dwarf_expr_context number of elements allocated to the stack. */ int stack_len, stack_allocated; + /* Target address size in bytes. */ + int addr_size; + /* An opaque argument provided by the caller, which will be passed to all of the callback functions. */ void *baton; @@ -136,6 +139,6 @@ CORE_ADDR dwarf_expr_fetch (struct dwarf gdb_byte *read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r); gdb_byte *read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r); CORE_ADDR dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, - int *bytes_read); + int addr_size); #endif /* dwarf2expr.h */ diff -urNp gdb-orig/gdb/dwarf2-frame.c gdb-head/gdb/dwarf2-frame.c --- gdb-orig/gdb/dwarf2-frame.c 2008-01-14 15:01:05.000000000 +0100 +++ gdb-head/gdb/dwarf2-frame.c 2008-01-14 15:15:06.000000000 +0100 @@ -302,10 +302,12 @@ static CORE_ADDR execute_stack_op (gdb_byte *exp, ULONGEST len, struct frame_info *next_frame, CORE_ADDR initial) { + struct gdbarch *gdbarch = get_frame_arch (next_frame); struct dwarf_expr_context *ctx; CORE_ADDR result; ctx = new_dwarf_expr_context (); + ctx->addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; ctx->baton = next_frame; ctx->read_reg = read_reg; ctx->read_mem = read_mem; @@ -331,8 +333,8 @@ execute_cfa_program (gdb_byte *insn_ptr, struct dwarf2_frame_state *fs, int eh_frame_p) { CORE_ADDR pc = frame_pc_unwind (next_frame); - int bytes_read; struct gdbarch *gdbarch = get_frame_arch (next_frame); + int addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; while (insn_ptr < insn_end && fs->pc <= pc) { @@ -362,8 +364,8 @@ execute_cfa_program (gdb_byte *insn_ptr, switch (insn) { case DW_CFA_set_loc: - fs->pc = dwarf2_read_address (insn_ptr, insn_end, &bytes_read); - insn_ptr += bytes_read; + fs->pc = dwarf2_read_address (insn_ptr, insn_end, addr_size); + insn_ptr += addr_size; break; case DW_CFA_advance_loc1: diff -urNp gdb-orig/gdb/dwarf2loc.c gdb-head/gdb/dwarf2loc.c --- gdb-orig/gdb/dwarf2loc.c 2008-01-14 15:01:05.000000000 +0100 +++ gdb-head/gdb/dwarf2loc.c 2008-01-14 15:59:19.000000000 +0100 @@ -54,22 +54,23 @@ find_location_expression (struct dwarf2_ CORE_ADDR low, high; gdb_byte *loc_ptr, *buf_end; int length; - unsigned int addr_size = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT; + struct objfile *objfile = dwarf2_cu_objfile (baton->cu); + unsigned int addr_size = dwarf2_cu_addr_size (baton->cu); CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); /* Adjust base_address for relocatable objects. */ - CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets, - SECT_OFF_TEXT (baton->objfile)); - CORE_ADDR base_address = baton->base_address + base_offset; + CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile)); + CORE_ADDR base_address = dwarf2_cu_base_address (baton->cu) + base_offset; loc_ptr = baton->data; buf_end = baton->data + baton->size; while (1) { - low = dwarf2_read_address (loc_ptr, buf_end, &length); - loc_ptr += length; - high = dwarf2_read_address (loc_ptr, buf_end, &length); - loc_ptr += length; + low = dwarf2_read_address (loc_ptr, buf_end, addr_size); + loc_ptr += addr_size; + high = dwarf2_read_address (loc_ptr, buf_end, addr_size); + loc_ptr += addr_size; /* An end-of-list entry. */ if (low == 0 && high == 0) @@ -189,7 +190,7 @@ dwarf_expr_tls_address (void *baton, COR static struct value * dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, gdb_byte *data, unsigned short size, - struct objfile *objfile) + struct dwarf2_cu *cu) { struct gdbarch *arch = get_frame_arch (frame); struct value *retval; @@ -205,9 +206,10 @@ dwarf2_evaluate_loc_desc (struct symbol } baton.frame = frame; - baton.objfile = objfile; + baton.objfile = dwarf2_cu_objfile (cu); ctx = new_dwarf_expr_context (); + ctx->addr_size = dwarf2_cu_addr_size (cu); ctx->baton = &baton; ctx->read_reg = dwarf_expr_read_reg; ctx->read_mem = dwarf_expr_read_mem; @@ -318,7 +320,8 @@ needs_frame_tls_address (void *baton, CO requires a frame to evaluate. */ static int -dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size) +dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size, + struct dwarf2_cu *cu) { struct needs_frame_baton baton; struct dwarf_expr_context *ctx; @@ -327,6 +330,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *d baton.needs_frame = 0; ctx = new_dwarf_expr_context (); + ctx->addr_size = dwarf2_cu_addr_size (cu); ctx->baton = &baton; ctx->read_reg = needs_frame_read_reg; ctx->read_mem = needs_frame_read_mem; @@ -429,7 +433,7 @@ locexpr_read_variable (struct symbol *sy struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); struct value *val; val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size, - dlbaton->objfile); + dlbaton->cu); return val; } @@ -439,7 +443,8 @@ static int locexpr_read_needs_frame (struct symbol *symbol) { struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); - return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size); + return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size, + dlbaton->cu); } /* Print a natural-language description of SYMBOL to STREAM. */ @@ -448,6 +453,7 @@ locexpr_describe_location (struct symbol { /* FIXME: be more extensive. */ struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); + int addr_size = dwarf2_cu_addr_size (dlbaton->cu); if (dlbaton->size == 1 && dlbaton->data[0] >= DW_OP_reg0 @@ -477,14 +483,14 @@ locexpr_describe_location (struct symbol && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address) if (dlbaton->data[0] == DW_OP_addr) { - int bytes_read; + struct objfile *objfile = dwarf2_cu_objfile (dlbaton->cu); CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1], &dlbaton->data[dlbaton->size - 1], - &bytes_read); + addr_size); fprintf_filtered (stream, "a thread-local variable at offset %s in the " "thread-local storage for `%s'", - paddr_nz (offset), dlbaton->objfile->name); + paddr_nz (offset), objfile->name); return 1; } @@ -545,8 +551,7 @@ loclist_read_variable (struct symbol *sy set_value_optimized_out (val, 1); } else - val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, - dlbaton->objfile); + val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, dlbaton->cu); return val; } diff -urNp gdb-orig/gdb/dwarf2loc.h gdb-head/gdb/dwarf2loc.h --- gdb-orig/gdb/dwarf2loc.h 2008-01-14 15:01:05.000000000 +0100 +++ gdb-head/gdb/dwarf2loc.h 2008-01-14 15:44:51.000000000 +0100 @@ -21,10 +21,21 @@ #define DWARF2LOC_H struct symbol_ops; +struct objfile; +struct dwarf2_cu; /* This header is private to the DWARF-2 reader. It is shared between dwarf2read.c and dwarf2loc.c. */ +/* Return the OBJFILE associated with the compilation unit CU. */ +struct objfile *dwarf2_cu_objfile (struct dwarf2_cu *cu); + +/* Return the address size given in the compilation unit header for CU. */ +CORE_ADDR dwarf2_cu_addr_size (struct dwarf2_cu *cu); + +/* Return the base address given in the compilation unit header for CU. */ +CORE_ADDR dwarf2_cu_base_address (struct dwarf2_cu *cu); + /* The symbol location baton types used by the DWARF-2 reader (i.e. SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol). "struct dwarf2_locexpr_baton" is for a symbol with a single location @@ -39,28 +50,22 @@ struct dwarf2_locexpr_baton /* Length of the location expression. */ unsigned long size; - /* The objfile containing the symbol whose location we're computing. */ - struct objfile *objfile; + /* The compilation unit containing the symbol whose location + we're computing. */ + struct dwarf2_cu *cu; }; struct dwarf2_loclist_baton { - /* The initial base address for the location list, based on the compilation - unit. */ - CORE_ADDR base_address; - /* Pointer to the start of the location list. */ gdb_byte *data; /* Length of the location list. */ unsigned long size; - /* The objfile containing the symbol whose location we're computing. */ - /* Used (only???) by thread local variables. The objfile in which - this symbol is defined. To find a thread-local variable (e.g., a - variable declared with the `__thread' storage class), we may need - to know which object file it's in. */ - struct objfile *objfile; + /* The compilation unit containing the symbol whose location + we're computing. */ + struct dwarf2_cu *cu; }; extern const struct symbol_ops dwarf2_locexpr_funcs; diff -urNp gdb-orig/gdb/dwarf2read.c gdb-head/gdb/dwarf2read.c --- gdb-orig/gdb/dwarf2read.c 2008-01-14 15:01:05.000000000 +0100 +++ gdb-head/gdb/dwarf2read.c 2008-01-14 16:07:52.000000000 +0100 @@ -9804,13 +9804,6 @@ static void dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, struct dwarf2_cu *cu) { - struct objfile *objfile = cu->objfile; - - /* Save the master objfile, so that we can report and look up the - correct file containing this variable. */ - if (objfile->separate_debug_objfile_backlink) - objfile = objfile->separate_debug_objfile_backlink; - if (attr_form_is_section_offset (attr) /* ".debug_loc" may not exist at all, or the offset may be outside the section. If so, fall through to the complaint in the @@ -9821,13 +9814,12 @@ dwarf2_symbol_mark_computed (struct attr baton = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (struct dwarf2_loclist_baton)); - baton->objfile = objfile; + baton->cu = cu; /* We don't know how long the location list is, but make sure we don't run off the edge of the section. */ baton->size = dwarf2_per_objfile->loc_size - DW_UNSND (attr); baton->data = dwarf2_per_objfile->loc_buffer + DW_UNSND (attr); - baton->base_address = cu->header.base_address; if (cu->header.base_known == 0) complaint (&symfile_complaints, _("Location list used without specifying the CU base address.")); @@ -9841,7 +9833,7 @@ dwarf2_symbol_mark_computed (struct attr baton = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (struct dwarf2_locexpr_baton)); - baton->objfile = objfile; + baton->cu = cu; if (attr_form_is_block (attr)) { @@ -9866,6 +9858,37 @@ dwarf2_symbol_mark_computed (struct attr } } +/* Return the OBJFILE associated with the compilation unit CU. */ + +struct objfile * +dwarf2_cu_objfile (struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + + /* Return the master objfile, so that we can report and look up the + correct file containing this variable. */ + if (objfile->separate_debug_objfile_backlink) + objfile = objfile->separate_debug_objfile_backlink; + + return objfile; +} + +/* Return the address size given in the compilation unit header for CU. */ + +CORE_ADDR +dwarf2_cu_addr_size (struct dwarf2_cu *cu) +{ + return cu->header.addr_size; +} + +/* Return the base address given in the compilation unit header for CU. */ + +CORE_ADDR +dwarf2_cu_base_address (struct dwarf2_cu *cu) +{ + return cu->header.base_address; +} + /* Locate the compilation unit from CU's objfile which contains the DIE at OFFSET. Raises an error on failure. */ -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com