This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


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

Attempts to add altivec-enabled *jmp() support - death by symbol versioning


Symbol versioning is presenting me with some nasty problems.

My original plan was just to version all of the functions which exposed a
jmp_buf et al, and change depending on configuration which version was the
default.  That's all well and good, except it causes a lot of symbols to
become versioned.  This is presenting two particular problems:

  - __sigsetjmp now belongs to a version that ld.so does not expose.  This
causes the linker to try to expose it (I think this is because it's marked
as a default version; might just be because it's versioned).  I worked
around this by extending versions.awk to handle 'local:' lines explicitly
and marking __sigsetjmp as local to ld.  I'll submit that patch along with
this one, unless it's a fundamentally Wrong Thing To Do.  It seems useful.

 - The bigger problem - longjmp is versioned.  Thus, longjmp is not weak
any more.  The copy in linuxthreads also has to be versioned, for the same
reason, and thus can also not be weak any more.  And thus, attempting to
link both libc and libpthread together fails:

/opt/mvista/rpm-ppc_7xxx/BUILD/glibc-2.2.1/objdir/linuxthreads/libpthread.so(*IND*+0x0):
	multiple definition of `longjmp@GLIBC_2.0'
/opt/mvista/rpm-ppc_7xxx/BUILD/glibc-2.2.1/objdir/libc.so(.text+0x13500):
	first defined here

/opt/mvista/rpm-ppc_7xxx/BUILD/glibc-2.2.1/objdir/linuxthreads/libpthread.so(*IND*+0x0): 
	multiple definition of `siglongjmp@GLIBC_2.0'
/opt/mvista/rpm-ppc_7xxx/BUILD/glibc-2.2.1/objdir/libc.so(.text+0x13500):
	first defined here

collect2: ld returned 1 exit status


I've gotten everything but this working with my original approach, and I'd
hate to abandon it now.  I think the semantic I would want would be a weak
version, but as far as I know there's no way to do that in ELF (at least
with current binutils...).  Though some comments in bfd suggest otherwise, I
can't think of a way to do it.

I can get what looks to me like the right effect in a limited case, by using
default versions:
000003bc  w   DF .text  0000000f  VER2        bar
000003cc g    DF .text  0000000f (VER1)       bar

and in the map:
VER2 {
  global:
    bar;
};

VER1 {
  global:
    bar;
} VER2;

and in the code:

weak_alias (foo, bar);
symbol_version (foo2, bar, VER1);


However, when VER2 (the one we want used by default) is not the default
version of the library, I don't see an explicit way to do this.  Thus I have
no way to handle the case in which the altivec version is used by default.

The specific problem is that I want anything linked against a version of
-lpthread compiled with altivec as a default to use
longjmp@GLIBC_ALTIVEC_2.2 from -lpthread; anything linked against a version
of -lpthread with altivec only as an option to use longjmp@GLIBC_2.0 by default.
But the only way we got away with having longjmp() in both libc and
libpthread was because the version in libc is weak, and if I provide a
matching two versions of longjmp in libc I get into a fix.

Any ideas?

-- 
Daniel Jacobowitz                           Debian GNU/Linux Developer
Monta Vista Software                              Debian Security Team


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