This is the mail archive of the frysk@sourceware.org mailing list for the frysk project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: elfutils import


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



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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]