public inbox for frysk@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Cagney <cagney@redhat.com>
To: Sami Wagiaalla <swagiaal@redhat.com>, Roland McGrath <roland@redhat.com>
Cc: frysk <frysk@sourceware.org>
Subject: Re: elfutils import
Date: Thu, 30 Aug 2007 20:35:00 -0000	[thread overview]
Message-ID: <46D72A3D.2030804@redhat.com> (raw)
In-Reply-To: <46D5DAD1.8050807@redhat.com>

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

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




[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 5565 bytes --]

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)

  reply	other threads:[~2007-08-30 20:35 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-22 21:45 Sami Wagiaalla
2007-08-22 21:52 ` Roland McGrath
2007-08-27 19:29   ` Sami Wagiaalla
2007-08-27 20:21     ` Roland McGrath
2007-08-29 20:45       ` Sami Wagiaalla
2007-08-30 20:35         ` Andrew Cagney [this message]
2007-08-28 13:25     ` Andrew Cagney
2007-08-27 18:23 ` Sami Wagiaalla

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46D72A3D.2030804@redhat.com \
    --to=cagney@redhat.com \
    --cc=frysk@sourceware.org \
    --cc=roland@redhat.com \
    --cc=swagiaal@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).