From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28498 invoked by alias); 30 Aug 2007 20:35:56 -0000 Received: (qmail 28489 invoked by uid 22791); 30 Aug 2007 20:35:55 -0000 X-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,DK_POLICY_SIGNSOME,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 30 Aug 2007 20:35:50 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.1/8.13.1) with ESMTP id l7UKZmvl015113 for ; Thu, 30 Aug 2007 16:35:48 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [10.11.255.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l7UKZkXd024750; Thu, 30 Aug 2007 16:35:46 -0400 Received: from [127.0.0.1] (sebastian-int.corp.redhat.com [172.16.52.221]) by pobox.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l7UKZioE013568; Thu, 30 Aug 2007 16:35:45 -0400 Message-ID: <46D72A3D.2030804@redhat.com> Date: Thu, 30 Aug 2007 20:35:00 -0000 From: Andrew Cagney User-Agent: Thunderbird 1.5.0.12 (X11/20070530) MIME-Version: 1.0 To: Sami Wagiaalla , Roland McGrath CC: frysk Subject: Re: elfutils import References: <20070827202033.D62924D05BE@magilla.localdomain> <46D5DAD1.8050807@redhat.com> In-Reply-To: <46D5DAD1.8050807@redhat.com> Content-Type: multipart/mixed; boundary="------------000800050203060403090900" X-Virus-Checked: Checked by ClamAV on sourceware.org X-IsSubscribed: yes Mailing-List: contact frysk-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-owner@sourceware.org X-SW-Source: 2007-q3/txt/msg00373.txt.bz2 This is a multi-part message in MIME format. --------------000800050203060403090900 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1686 Sami Wagiaalla wrote: > Roland McGrath wrote: >> That diff was really not useful. Please post the diff between what you >> have in the frysk tree and the corresponding vanilla elfutils source. >> > Roland, > > My mistake. This branch (sami-elfutils_129-merge-20070827-branch) now > contains the vanila elfutils sources plus frysk changes to elfutils. I > attached a diff showing thos changes. > > Sami Thanks! Working through this I found these problems: > GLOBAL(large_global_at_small_global) > GLOBAL(small_global_at_large_global) > STORE(REG0,REG0) <---- HERE > NO_OP > SIZE(small_global_at_large_global) > NO_OP > SIZE(large_global_at_small_global) this isn't "stable" the first of those symbols is choose. > # A global symbol that has zero size. > GLOBAL(global_st_size_0) > LOAD_IMMED_BYTE (REG0, 0) > STORE (REG0, REG0) <---- HERE > NO_OP this symbol can be missed entirely because min_label is > global_st_size_0. > # A global symbol, with size, that contains a nested global and local > # symbols each also with sizes. > GLOBAL(global_outer) > STORE(REG0, REG0) > NO_OP > LOCAL(local_in_global) > STORE (REG0, REG0) <----- HERE > NO_OP > SIZE(local_in_global) > .Lglobal_outer: > STORE (REG0, REG0) > NO_OP > SIZE(global_outer) this isn't stable, the second of local_in_global and global_outer is chosen. I've attached a context diff of up-stream vs local (they are sufficiently different to make a unified diff harder to read). I'll see about mearing that !section and !file test. Andrew --------------000800050203060403090900 Content-Type: text/plain; name="diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diffs" Content-length: 5565 Index: frysk-imports/elfutils/libdwfl/dwfl_module_addrsym.c =================================================================== RCS file: /cvs/frysk/frysk-imports/elfutils/libdwfl/dwfl_module_addrsym.c,v retrieving revision 1.6.2.2 retrieving revision 1.6.2.3 diff -p -r1.6.2.2 -r1.6.2.3 *** frysk-imports/elfutils/libdwfl/dwfl_module_addrsym.c 28 Aug 2007 20:40:47 -0000 1.6.2.2 --- frysk-imports/elfutils/libdwfl/dwfl_module_addrsym.c 30 Aug 2007 19:07:03 -0000 1.6.2.3 *************** dwfl_module_addrsym (Dwfl_Module *mod, G *** 97,170 **** return shndx == addr_shndx; } ! /* Keep track of the closest symbol we have seen so far. ! Here we store only symbols with nonzero st_size. */ const char *closest_name = NULL; GElf_Word closest_shndx = SHN_UNDEF; - - /* Keep track of an eligible symbol with st_size == 0 as a fallback. */ - const char *sizeless_name = NULL; - GElf_Sym sizeless_sym = { 0, 0, 0, 0, 0, SHN_UNDEF }; - GElf_Word sizeless_shndx = SHN_UNDEF; - - /* Keep track of the lowest address a relevant sizeless symbol could have. */ - GElf_Addr min_label = addr; - - /* Look through the symbol table for a matching symbol. */ for (int i = 1; i < syments; ++i) { GElf_Sym sym; GElf_Word shndx; const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx); ! if (name != NULL ! && sym.st_value <= addr ! && (sym.st_size == 0 || addr - sym.st_value < sym.st_size)) { ! /* Even if we don't choose this symbol, its existence ! excludes any sizeless symbol (assembly label) that ! is inside its bounds. */ ! if (sym.st_value + sym.st_size > addr) ! min_label = sym.st_value + sym.st_size; ! ! /* This symbol is a better candidate than the current one ! if it's a named symbol, not a section or file symbol, ! and is closer to ADDR or is global when it was local. */ ! if (name[0] != '\0' ! && GELF_ST_TYPE (sym.st_info) != STT_SECTION ! && GELF_ST_TYPE (sym.st_info) != STT_FILE ! && (closest_name == NULL ! || closest_sym->st_value < sym.st_value ! || (GELF_ST_BIND (closest_sym->st_info) ! < GELF_ST_BIND (sym.st_info)))) { ! if (sym.st_size != 0) { ! *closest_sym = sym; ! closest_shndx = shndx; ! closest_name = name; } ! else if (same_section (&sym, shndx)) { ! /* Handwritten assembly symbols sometimes have no st_size. ! If no symbol with proper size includes the address, ! we'll use the closest one that is in the same section ! as ADDR. */ ! sizeless_sym = sym; ! sizeless_shndx = shndx; ! sizeless_name = name; } } } } ! /* If we found no proper sized symbol to use, fall back to the best ! candidate sizeless symbol we found, if any. */ ! if (closest_name == NULL ! && sizeless_name != NULL && sizeless_sym.st_value >= min_label) { ! *closest_sym = sizeless_sym; ! closest_shndx = sizeless_shndx; ! closest_name = sizeless_name; } if (shndxp != NULL) --- 97,176 ---- return shndx == addr_shndx; } ! /* Look through the symbol table for a matching symbol. */ const char *closest_name = NULL; + memset(closest_sym, 0, sizeof(*closest_sym)); GElf_Word closest_shndx = SHN_UNDEF; for (int i = 1; i < syments; ++i) { GElf_Sym sym; GElf_Word shndx; const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx); ! if (name != NULL && sym.st_value <= addr) { ! inline void closest (void) { ! *closest_sym = sym; ! closest_shndx = shndx; ! closest_name = name; ! } ! ! /* This symbol contains ADDR; but is it better than the ! previous candidate? */ ! if (addr < sym.st_value + sym.st_size) ! { ! if (addr >= closest_sym->st_value + closest_sym->st_size) ! { ! /* Ha! The previous candidate doesn't even contain ! ADDR; replace it. */ ! closest(); ! continue; ! } ! if (sym.st_value > closest_sym->st_value) { ! /* This candidate is closer to ADDR. */ ! closest (); ! continue; } ! if (sym.st_value == closest_sym->st_value ! && sym.st_size < closest_sym->st_size) { ! /* This candidate, while having an identical value, ! is at least smaller. */ ! closest (); ! continue; } + /* Discard this candidate, no better than the previous + sized symbol that contained ADDR. */ + continue; + } + + /* The current closest symbol contains ADDR, can't do better + than that. */ + if (addr < closest_sym->st_value + closest_sym->st_size) + continue; + + /* Save the symbol which is "closer". Use the end-address + so that a sized symbol that ends closer to an unsized + symbol wins (unsized symbols are typically created using + hand-written assembler). */ + if (sym.st_value + sym.st_size + >= closest_sym->st_value + closest_sym->st_size + && same_section (&sym, shndx)) + { + closest (); + continue; } } } ! /* If the closest symbol has a size doesn't contain ADDR, discard ! it. There must be a hole in the symbol table. */ ! if (closest_sym->st_size > 0 ! && addr >= closest_sym->st_value + closest_sym->st_size) { ! memset(closest_sym, 0, sizeof(*closest_sym)); ! return NULL; } if (shndxp != NULL) --------------000800050203060403090900--