bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* Hidden visibility for obstack symbols
@ 2022-12-02 15:27 Florian Weimer
  2022-12-02 16:38 ` Bruno Haible
  0 siblings, 1 reply; 2+ messages in thread
From: Florian Weimer @ 2022-12-02 15:27 UTC (permalink / raw)
  To: bug-gnulib

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?

Eventually, we need to fix this on the glibc side, either by deprecating
the interfaces and turning them into a compat interface eventually, or
by switching to size_t in these interfaces.  But in the interim, I think
we should use hidden visibility for the gnulib variants.

(ls loads third-party code via NSS modules, and those modules could
reasonably assume that the glibc obstack symbols follow the glibc ABI.)

Thanks,
Florian



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Hidden visibility for obstack symbols
  2022-12-02 15:27 Hidden visibility for obstack symbols Florian Weimer
@ 2022-12-02 16:38 ` Bruno Haible
  0 siblings, 0 replies; 2+ messages in thread
From: Bruno Haible @ 2022-12-02 16:38 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Florian Weimer

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





^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-12-02 16:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-02 15:27 Hidden visibility for obstack symbols Florian Weimer
2022-12-02 16:38 ` Bruno Haible

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).