This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

2.6.2 postponed .. (was Re: [Gcl-devel] RE ld from 2.14.90.0.8 puts no value into undefined symbols)


[  To sum up for people unfamiliar with gcl, gcl loads compiled lisp
objects into its .data section, relocates the code there, and makes
the region executable.  Certain undefined symbols, like _setjmp,
__moddi3, etc, can wind up being undefined in the compiled lisp
object, hence the main program needs to know how to relocate them.
This was done earlier by relocating them to the proper place in the
.plt table, which was in turn determined by the value of the symbol in
the symbol table of the main executable. ]

Greetings, and thanks so much for this!

Alas, I tested, and this is not the problem.  This define did not
change between .7 and .8.  This however did:

elf32-i386.c

@@ -3005,11 +3028,16 @@
       if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
 	{
 	  /* Mark the symbol as undefined, rather than as defined in
-	     the .plt section.  Leave the value alone.  This is a clue
+	     the .plt section.  Leave the value if there were any
+	     relocations where pointer equality matters (this is a clue
 	     for the dynamic linker, to make function pointer
 	     comparisons work between an application and shared
-	     library.  */
+	     library), otherwise set it to zero.  If a function is only
+	     called from a binary, there is no need to slow down
+	     shared libraries because of that.  */
 	  sym->st_shndx = SHN_UNDEF;
+	  if ((h->elf_link_hash_flags & ELF_LINK_POINTER_EQUALITY_NEEDED) == 0)
+	    sym->st_value = 0;
 	}
     }
 
Oh the pain the pain....

Even if this is changed later, .8 is out and will cause problems for
gcl and friends wherever it is found.

I have a workaround, but its quite ugly.  It has to go into stable,
and it needs further testing, so I'm going to postpone the 2.6.2
release for another week.

The workaround idea is this -- make a little list of undefined symbols
with nm from the .o files in o/, remove those defined elsewhere by
gcl, make a little homebrew plt substitute like

typedef struct {
  const char *n;
  const void *f;
} Plt;

#define join(a_,b_) a_ ## b_
#define Join(a_,b_) join(a_,b_)
#define MY_PLT(a_) {#a_,a_}

#include "undef1.h" /* headers containing undefined symbol definitions*/
/* Replace this with gcl's own hash structure at some point */
static int
build_symbol_table_bfd(void) {

  int u,v;
  asymbol **q;
  Plt mplt[]={
    #include "undef.h" /*the set of undefined symbols*/
  };

....
      if (q[u]->value || q[u]->flags != BSF_FUNCTION)
	h->u.def.value=q[u]->value+q[u]->section->vma;
      else {
	Plt *p=mplt,*pe=p+sizeof(mplt)/sizeof(*mplt);
	for (;p<pe && strcmp(p->n,q[u]->name);p++);
	if (p<pe) {
	  printf("foo %s\n",q[u]->name);
	  h->u.def.value=(unsigned long)p->f+q[u]->section->vma;
	} else
	  printf("missing %s\n",q[u]->name);
      }

I've tested that this fixes things, the hard part is going to be the
generation of undef.h and undef1.h in a platform independent way,
esp. as some hidden symbols need inclusion, like __moddi3 on i386.  In
fact, the plt search is never triggered, as the mere presence of the
table puts in a R_386_32 reloc for the symbol as opposed to/in
addition to a R_386_PC32, in which case the value for the symbol is
restored in the executable.  Not a bad idea to leave this search there
for future changes I suppose.  

It would be wonderful if this could be done in a robust fashion immune
to further binutils development. Advice appreciated.

Take care,


Peter Wood <peter.wood@worldonline.dk> writes:

> Hi Camm
> 
> I think it's a bug in BFD.  In a binutils downloaded via CVS today, in
> src/bfd/elf32-i386.c
> 
> #define elf_backend_want_plt_sym    1 /* was 0, breaks GCL -prw */
> 
> _Seems_ to fix this for me on a binutils from CVS (today).
> 
> I tested it with the following file.  First with my old (system) ld,
> (GNU ld version 2.13.2) then with the new ld _without_ the change,
> then with the new ld _with_ the change (GNU ld version 2.15.90 20040227)
> 
> *disclaimer*
> 
> 1) I haven't tested it with GCL, since I'm working with an _ancient_
> version of GCL which is completely irrelevant to current development.
> 
> 2) I have no idea why elf_backend_want_plt_sym was defined to 0, and I
> don't know the full consequences of changing it.  Hopefully, it was
> just an oversight and the BFD people won't mind changing it
> 
> Regards,
> Peter
> 
> /* dynatest.c : to test availability of plt symbols in executable image */
> 
> #include <stdio.h>
> 
> int main (){
> 
>   unsigned long secs = 1000000;
>   
>   printf("Sleeping\n");
>   usleep(secs);
>   return(0);
> }
> /* end */
> 
> WITH OLD ld:   gcc -o dynatest dynatest.c
> 
> objdump -x dynatest | grep -e UND
> 080482f8       F *UND*  00000067              usleep@@GLIBC_2.0
> 08048308  w    F *UND*  00000048              __register_frame_info@@GLIBC_2.0
> 00000000         *UND*  00000004              _fp_hw
> 08048318  w    F *UND*  0000005e              __deregister_frame_info@@GLIBC_2.0
> 08048328       F *UND*  000000d5              __libc_start_main@@GLIBC_2.0
> 08048338       F *UND*  00000033              printf@@GLIBC_2.0
> 00000000  w      *UND*  00000000              __gmon_start__
> 
> ==============================================
> WITH NEW ld (bad for GCL)
> 
> /home/prw/binutils-1077869339/bin/ld -dy -o --dynamic-linker /lib/ld-linux-so2 /lib/dynatest_new /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.3/crtbegin.o -L/usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.3 dynatest.o -lgcc -lc -lgcc /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.3/crtend.o /usr/lib/crtn.o 
> 
> objdump -x dynatest_new | grep -e UND
> 
> 00000000       F *UND*  00000067              usleep@@GLIBC_2.0
> 08048308  w    F *UND*  00000048              __register_frame_info@@GLIBC_2.0
> 00000000         *UND*  00000004              _fp_hw
> 08048318  w    F *UND*  0000005e              __deregister_frame_info@@GLIBC_2.0
> 00000000       F *UND*  000000d5              __libc_start_main@@GLIBC_2.0
> 00000000       F *UND*  00000033              printf@@GLIBC_2.0
> 00000000  w      *UND*  00000000              __gmon_start__
> 
> ===================================================
> WITH NEW ld WITH change to bfd/elf32-i386.c in binutils from cvs
> 
> #define elf_backend_want_plt_sym	1 /* was 0, breaks GCL -prw */
> 
> /home/prw/binutils-1077880238/bin/ld -dy --dynamic-linker /lib/ld-linux.so.2 -o dynatest_new /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.3/crtbegin.o -L/usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.3 dynatest.o -lgcc -lc -lgcc /usr/lib/gcc-lib/i586-pc-linux-gnu/2.95.3/crtend.o /usr/lib/crtn.o 
> 
> 
> objdump -x dynatest | grep -e UND
> 080482f8       F *UND*  00000067              usleep@@GLIBC_2.0
> 08048308  w    F *UND*  00000048              __register_frame_info@@GLIBC_2.0
> 00000000         *UND*  00000004              _fp_hw
> 08048318  w    F *UND*  0000005e              __deregister_frame_info@@GLIBC_2.0
> 08048328       F *UND*  000000d5              __libc_start_main@@GLIBC_2.0
> 08048338       F *UND*  00000033              printf@@GLIBC_2.0
> 00000000  w      *UND*  00000000              __gmon_start__
> 
> =============================================
> 
> 
> _______________________________________________
> Gcl-devel mailing list
> Gcl-devel@gnu.org
> http://mail.gnu.org/mailman/listinfo/gcl-devel
> 
> 

-- 
Camm Maguire			     			camm@enhanced.com
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah


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