bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Hidden visibility for obstack symbols


From: Bruno Haible
Subject: Re: Hidden visibility for obstack symbols
Date: Fri, 02 Dec 2022 17:38:12 +0100

Florian Weimer wrote:
> Someone reported that ls in coreutils exported _obstack* symbols.  This
> is because ls uses the obstack module from gnulib (I assume).  Due to
> the way ELF linking works by default, this promotes the symbols to
> global visibility, so that there is a single definition in the entire
> process.  This is always a bit iffy (glibc supports it explicitly for
> malloc-related symbols, though), but in case of obstack it's really not
> great because the gnulib ABI is different from the glibc ABI:
> 
> $ gdb /usr/bin/ls
> […]
> (gdb) ptype _obstack_begin
> type = int (struct obstack *, size_t, size_t, void *(*)(size_t), 
>     void (*)(void *))
> $ gdb /lib64/libc.so.6
> […]
> (gdb) ptype _obstack_begin
> type = int (struct obstack *, int, int, void *(*)(long), 
>     void (*)(void *))
> 
> This is on x86-64, so the types aren't equivalent.
> 
> Would it be possible to give the obstack symbols hidden visibility?

I would suggest to do something about it *only* if it is an actual problem.

I claim that it is not an actual problem:

$ nm --dynamic /bin/ls | grep -v ' U '
                 w __cxa_finalize@GLIBC_2.2.5
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
00000000000106e0 T _obstack_allocated_p
00000000000220a0 D obstack_alloc_failed_handler
000000000000fc80 T _obstack_begin
000000000000fca0 T _obstack_begin_1
0000000000010720 T _obstack_free
00000000000107b0 T _obstack_memory_used
000000000000fcc0 T _obstack_newchunk

Among these symbols:
* _obstack_allocated_p is irrelevant, since it is only present for debugging,
  not even declared in <obstack.h>.

The remaining symbols are (with prototypes and parameter names):

extern void _obstack_newchunk (struct obstack *, int length);
extern int _obstack_begin (struct obstack *, int size, int alignment,
                           void *(*)(long size), void (*)(void *));
extern int _obstack_begin_1 (struct obstack *, int size, int alignment,
                             void *(*)(void *, long size),
                             void (*)(void *, void *), void *);
extern int _obstack_memory_used (struct obstack *) __attribute_pure__;
extern void _obstack_free (struct obstack *, void *);
extern void (*obstack_alloc_failed_handler) (void);

For arguments of type 'int' and with names 'length', 'size', 'alignment',
the valid values are in the range 0..INT_MAX. Similarly, the return value
of _obstack_memory_used must be in the range 0..INT_MAX.

For 32-bit platforms, such arguments are passed in the same location,
whether it's declared as 'int' or 'size_t'. Likewise for a return value.

For 64-bit platforms:
* On the Linux platforms with CPU aarch64, powerpc64, s390x, x86_64,
  32-bit values are passed in a 64-bit register. Whether sign-extended
  or zero-extended, does not matter, since the value is in the range
  0..INT_MAX.
* On the Linux platforms with CPU alpha, ia64, loongarch64, mips64,
  riscv64, sparc64,
  32-bit values are passed as a 64-bit value in the stack argument
  sequence (part of which can be mapped to registers). Again, whether
  it's sign-extended or zero-extended, does not matter, since the value
  is in the range 0..INT_MAX.

Finally, there are the ABIs mips-n32 and x86_64-x32. Here, 32-bit values
are passed as 32-bit, and 64-bit values as 64-bit. So, for these ABIs
there would be a problem. But there are no distros that use these ABIs
for the coreutils package.
  - Porting to x86_64-x32 essentially stopped in 2012; there have
    already been discussions whether to deprecate this ABI. [1]
  - For mips-n32, I can see that distros prefer to ship mips-32
    binaries. For example:
      $ file /bin/ls
      /bin/ls: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), 
dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 2.6.32, 
BuildID[sha1]=7f52495c14dbba5d1918cb3450fcc47a44f275bd, stripped
    If it was an n32 binary, this output would show /lib32/ld.so.1, not 
/lib/ld.so.1.

Bruno

[1] https://en.wikipedia.org/wiki/X32_ABI






reply via email to

[Prev in Thread] Current Thread [Next in Thread]