From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11146 invoked by alias); 4 Jan 2005 18:32:50 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 11048 invoked from network); 4 Jan 2005 18:32:38 -0000 Received: from unknown (HELO rwcrmhc11.comcast.net) (204.127.198.35) by sourceware.org with SMTP; 4 Jan 2005 18:32:38 -0000 Received: from lucon.org ([24.6.212.230]) by comcast.net (rwcrmhc11) with ESMTP id <2005010418323801300cdio9e>; Tue, 4 Jan 2005 18:32:38 +0000 Received: by lucon.org (Postfix, from userid 1000) id D302D640F4; Tue, 4 Jan 2005 10:32:37 -0800 (PST) Date: Tue, 04 Jan 2005 18:32:00 -0000 From: "H. J. Lu" To: binutils@sources.redhat.com Subject: PATCH: Check if DW_OP_fbreg has DW_AT_frame_base Message-ID: <20050104183237.GA28216@lucon.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i X-SW-Source: 2005-01/txt/msg00021.txt.bz2 DW_OP_fbreg needs DW_AT_frame_base. But gcc generates it without DW_AT_frame_base: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19124 This patch checks if DW_OP_fbreg has DW_AT_frame_base. H.J. --- 2005-01-04 H.J. Lu * readelf.c (have_frame_base): New. (decode_location_expression): Return 1 if DW_AT_frame_base is needed. (debug_info): Add a have_frame_base pointer. (read_and_display_attr_value): Set have_frame_base. Record if a location list has DW_AT_frame_base. Display if a location expression has no DW_AT_frame_base but needs one. (process_debug_info): Clear have_frame_base. (display_debug_loc): Display if a location expression has no DW_AT_frame_base but needs one. Display if start >= end. (process_object): Free the have_frame_base pointer in debug_info. --- binutils/readelf.c.frame 2005-01-04 09:20:26.000000000 -0800 +++ binutils/readelf.c 2005-01-04 09:59:00.158542184 -0800 @@ -168,6 +168,7 @@ int do_debug_loc; int do_arch; int do_notes; int is_32bit_elf; +int have_frame_base; struct group_list { @@ -7551,7 +7552,7 @@ display_block (unsigned char *data, unsi return data; } -static void +static int decode_location_expression (unsigned char * data, unsigned int pointer_size, unsigned long length, @@ -7561,6 +7562,7 @@ decode_location_expression (unsigned cha int bytes_read; unsigned long uvalue; unsigned char *end = data + length; + int need_frame_base = 0; while (data < end) { @@ -7823,6 +7825,7 @@ decode_location_expression (unsigned cha data += bytes_read; break; case DW_OP_fbreg: + need_frame_base = 1; printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1)); data += bytes_read; break; @@ -7879,13 +7882,15 @@ decode_location_expression (unsigned cha else printf (_("(Unknown location op)")); /* No way to tell where the next op is, so just bail. */ - return; + return need_frame_base; } /* Separate the ops. */ if (data < end) printf ("; "); } + + return need_frame_base; } /* Decode a DW_AT_ranges attribute for 64bit DWARF3 . */ @@ -8010,6 +8015,7 @@ typedef struct unsigned long cu_offset; /* This is an array of offsets to the location list table. */ unsigned long *loc_offsets; + int *have_frame_base; unsigned int num_loc_offsets; unsigned int max_loc_offsets; } @@ -8221,6 +8227,7 @@ read_and_display_attr_value (unsigned lo switch (attribute) { case DW_AT_frame_base: + have_frame_base = 1; case DW_AT_location: case DW_AT_data_member_location: case DW_AT_vtable_elem_location: @@ -8242,9 +8249,13 @@ read_and_display_attr_value (unsigned lo debug_info_p->loc_offsets = xrealloc (debug_info_p->loc_offsets, max * sizeof (*debug_info_p->loc_offsets)); + debug_info_p->have_frame_base + = xrealloc (debug_info_p->have_frame_base, + max * sizeof (*debug_info_p->have_frame_base)); debug_info_p->max_loc_offsets = max; } debug_info_p->loc_offsets [num] = uvalue; + debug_info_p->have_frame_base [num] = have_frame_base; debug_info_p->num_loc_offsets++; } break; @@ -8401,6 +8412,7 @@ read_and_display_attr_value (unsigned lo break; case DW_AT_frame_base: + have_frame_base = 1; case DW_AT_location: case DW_AT_data_member_location: case DW_AT_vtable_elem_location: @@ -8412,9 +8424,16 @@ read_and_display_attr_value (unsigned lo case DW_AT_lower_bound: if (block_start) { + int need_frame_base; + printf ("("); - decode_location_expression (block_start, pointer_size, uvalue, cu_offset); + need_frame_base = decode_location_expression (block_start, + pointer_size, + uvalue, + cu_offset); printf (")"); + if (need_frame_base && !have_frame_base) + printf (_(" [without DW_AT_frame_base]")); } else if (form == DW_FORM_data4 || form == DW_FORM_data8) printf (_("(location list)")); @@ -8692,6 +8711,7 @@ process_debug_info (Elf_Internal_Shdr *s debug_information [unit].pointer_size = compunit.cu_pointer_size; debug_information [unit].loc_offsets = NULL; + debug_information [unit].have_frame_base = NULL; debug_information [unit].max_loc_offsets = 0; debug_information [unit].num_loc_offsets = 0; } @@ -8779,6 +8799,18 @@ process_debug_info (Elf_Internal_Shdr *s abbrev_number, get_TAG_name (entry->tag)); + switch (entry->tag) + { + default: + break; + case DW_TAG_entry_point: + case DW_TAG_inlined_subroutine: + case DW_TAG_subprogram: + /* Assuming that there is no DW_AT_frame_base. */ + have_frame_base = 0; + break; + } + for (attr = entry->first_attr; attr; attr = attr->next) tags = read_and_display_attr (attr->attribute, attr->form, @@ -9468,12 +9500,15 @@ display_debug_loc (Elf_Internal_Shdr *se unsigned long offset; unsigned int pointer_size; unsigned long cu_offset; + int need_frame_base; + int has_frame_base; pointer_size = debug_information [i].pointer_size; cu_offset = debug_information [i].cu_offset; for (j = 0; j < debug_information [i].num_loc_offsets; j++) { + has_frame_base = debug_information [i].have_frame_base [j]; offset = debug_information [i].loc_offsets [j]; next = section_begin + offset; @@ -9512,13 +9547,21 @@ display_debug_loc (Elf_Internal_Shdr *se printf (" %8.8lx %8.8lx %8.8lx (", offset, begin, end); - decode_location_expression (start, pointer_size, length, - cu_offset); - printf (")\n"); + need_frame_base = decode_location_expression (start, + pointer_size, + length, + cu_offset); + putchar (')'); + + if (need_frame_base && !has_frame_base) + printf (_(" [without DW_AT_frame_base]")); + + if (begin == end) + fputs (_(" (start == end)"), stdout); + else if (begin > end) + fputs (_(" (start > end)"), stdout); - if (begin >= end) - warn ("Bad location list at %8.8lx from %8.8lx to %8.8lx\n", - offset, begin, end); + putchar ('\n'); start += length; } @@ -11748,8 +11791,11 @@ process_object (char *file_name, FILE *f if (debug_information) { for (i = 0; i < num_debug_info_entries; i++) - if (debug_information [i].loc_offsets != NULL) - free (debug_information [i].loc_offsets); + if (!debug_information [i].max_loc_offsets) + { + free (debug_information [i].loc_offsets); + free (debug_information [i].have_frame_base); + } free (debug_information); debug_information = NULL; num_debug_info_entries = 0;