__hidden_ver1() macro handles USER_LABEL_PREFIX incorrectly ?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

__hidden_ver1() macro handles USER_LABEL_PREFIX incorrectly ?

Mike Frysinger
i'm playing with the blackfin target which defines USER_LABEL_PREFIX to "_"
and i seem to be ending up with symbols with too many _ prefixes ... i traced
it back to the libc_hidden_def() macro in libc-symbols.h

for example, this bit of code:
int __libc_close(int fd) { return fd; }
strong_alias(__libc_close,close)
libc_hidden_proto(close)
libc_hidden_def(close)

on a target where USER_LABEL_PREFIX is defined to "", we'd correctly end up
with global symbols __libc_close and close, and an internal hidden __GI_close

however, on an a target where USER_LABEL_PREFIX is defined to "_", we'd end up
with global symbols ___libc_close and _close, an internal hidden ___GI_close,
and an undefined reference to ____GI_close

i'm thinking it's because __hidden_ver1() is incorrectly using
__hidden_asmname() when defining the __EI_##name alias ... the alias name is
processed by gcc itself which will insert USER_LABEL_PREFIX, so calling
__hidden_asmname() which also inserts USER_LABEL_PREFIX for us generates an
alias to a double prefixed asmname

if i change __hidden_ver1() to call __hidden_asmname1() with an empty prefix
for the alias, my final object ends up with the correct prefixes ... sample
file along with patch are attached, tested against x86_64 and bfin elf
targets

current cvs:
$ gcc -c hidden-test.c && readelf -s hidden-test.o | grep close
     8: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 __libc_close
     9: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 close
    10: 0000000000000000    12 FUNC    GLOBAL HIDDEN    1 __GI_close
$ bfin-elf-gcc -c hidden-test.c && readelf -s hidden-test.o | grep close
     6: 00000000    14 FUNC    GLOBAL DEFAULT    1 ___libc_close
     7: 00000000    14 FUNC    GLOBAL HIDDEN    1 ___GI_close
     8: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND ____GI_close
with my simple patch:
$ gcc -DFIX -c hidden-test.c && readelf -s hidden-test.o | grep close
     8: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 __libc_close
     9: 0000000000000000    12 FUNC    GLOBAL DEFAULT    1 close
    10: 0000000000000000    12 FUNC    GLOBAL HIDDEN    1 __GI_close
$ bfin-elf-gcc -DFIX -c hidden-test.c && readelf -s hidden-test.o | grep close
     6: 00000000    14 FUNC    GLOBAL DEFAULT    1 ___libc_close
     7: 00000000    14 FUNC    GLOBAL DEFAULT    1 _close
     8: 00000000    14 FUNC    GLOBAL HIDDEN    1 ___GI_close
-mike

# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
  extern __typeof (name) aliasname __attribute__ ((alias (#name)));

#define __hidden_proto_hiddenattr(attrs...) \
  __attribute__ ((visibility ("hidden"), ##attrs))

#define __hidden_asmname(name) \
  __hidden_asmname1 (__USER_LABEL_PREFIX__, name)
#define __hidden_asmname1(prefix, name) __hidden_asmname2(prefix, name)
#define __hidden_asmname2(prefix, name) #prefix name

#ifndef FIX
#define __hidden_ver1(local, internal, name) \
  extern __typeof (name) __EI_##name __asm__(__hidden_asmname (#internal)); \
  extern __typeof (name) __EI_##name \
    __attribute__((alias (__hidden_asmname (#local))))
#else
#define __hidden_ver1(local, internal, name) \
  extern __typeof (name) __EI_##name __asm__(__hidden_asmname (#internal)); \
  extern __typeof (name) __EI_##name \
    __attribute__((alias (__hidden_asmname1 (,#local))))
#endif

#define hidden_proto(name, attrs...) \
  __hidden_proto (name, __GI_##name, ##attrs)
#define __hidden_proto(name, internal, attrs...) \
  extern __typeof (name) name __asm__ (__hidden_asmname (#internal)) \
  __hidden_proto_hiddenattr (attrs);
#define libc_hidden_proto(name, attrs...) hidden_proto (name, ##attrs)

#define hidden_def(name)      __hidden_ver1(__GI_##name, name, name);
#define libc_hidden_def(name) hidden_def (name)

int __libc_close(int fd) { return fd; }
strong_alias(__libc_close,close)
libc_hidden_proto(close)
libc_hidden_def(close)

2006-01-15  Mike Frysinger  <[hidden email]>

        * include/libc-symbols.h (__hidden_ver1): Use __hidden_asmname1() for
        __EI_ aliase names.

--- include/libc-symbols.h 6 Nov 2005 02:05:18 -0000 1.73
+++ include/libc-symbols.h 15 Jan 2006 22:14:30 -0000
@@ -570,7 +570,7 @@ for linking")
 #  define __hidden_ver1(local, internal, name) \
   extern __typeof (name) __EI_##name __asm__(__hidden_asmname (#internal)); \
   extern __typeof (name) __EI_##name \
- __attribute__((alias (__hidden_asmname (#local))))
+ __attribute__((alias (__hidden_asmname1 (,#local))))
 #  define hidden_ver(local, name) __hidden_ver1(local, __GI_##name, name);
 #  define hidden_data_ver(local, name) hidden_ver(local, name)
 #  define hidden_def(name) __hidden_ver1(__GI_##name, name, name);
Reply | Threaded
Open this post in threaded view
|

Re: __hidden_ver1() macro handles USER_LABEL_PREFIX incorrectly ?

Daniel Jacobowitz-2
On Sun, Jan 15, 2006 at 05:23:08PM -0500, Mike Frysinger wrote:
> i'm playing with the blackfin target which defines USER_LABEL_PREFIX to "_"
> and i seem to be ending up with symbols with too many _ prefixes ... i traced
> it back to the libc_hidden_def() macro in libc-symbols.h

My experience is that this is far from the only problem you're going to
have on a target with USER_LABEL_PREFIX and dynamic loading.  It's just
not worth it.  Turn it off for GNU/Linux ports.

Next example: dlsym.

--
Daniel Jacobowitz
CodeSourcery
Reply | Threaded
Open this post in threaded view
|

Re: __hidden_ver1() macro handles USER_LABEL_PREFIX incorrectly ?

Mike Frysinger
On Monday 16 January 2006 12:41, Daniel Jacobowitz wrote:
> On Sun, Jan 15, 2006 at 05:23:08PM -0500, Mike Frysinger wrote:
> > i'm playing with the blackfin target which defines USER_LABEL_PREFIX to
> > "_" and i seem to be ending up with symbols with too many _ prefixes ...
> > i traced it back to the libc_hidden_def() macro in libc-symbols.h
>
> My experience is that this is far from the only problem you're going to
> have on a target with USER_LABEL_PREFIX and dynamic loading.  It's just
> not worth it.  Turn it off for GNU/Linux ports.

i'm not terribly worried about that as i'm working with uClibc/static-only
code ... that is a good point though and i'll keep it in mind if i ever use
dynamic loading, thanks
-mike