[PATCH 2/2] powerpc: Move cache line size to rtld_global_ro
Florian Weimer
fweimer@redhat.com
Mon Aug 3 08:15:57 GMT 2020
* Joseph Myers:
>> Does this affect the statically linked test binaries built by
>> build-many-glibcs.py?
>
> Yes. I tested build-many-glibcs.py? for powerpc-linux-gnu with current
> default versions of everything (so binutils 2.35 branch in this case);
> running the math/atest-exp binary left from a --keep=all build produces
> that same assertion failure.
I can reproduce it:
(gdb) bt
#0 0x10007d74 in __libc_signal_restore_set (set=0xfffed708)
at ../sysdeps/unix/sysv/linux/internal-signals.h:104
#1 raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:47
#2 0x10000268 in abort () at abort.c:79
#3 0x1001c7b8 in __malloc_assert (
assertion=assertion@entry=0x10081ec4 "(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)",
file=file@entry=0x10081690 "malloc.c", line=line@entry=2394,
function=function@entry=0x100828b8 <__PRETTY_FUNCTION__.3> "sysmalloc") at malloc.c:298
#4 0x1001ee1c in sysmalloc (nb=nb@entry=64,
av=av@entry=0x100c03d4 <main_arena>) at malloc.c:2394
#5 0x10020614 in _int_malloc (av=av@entry=0x100c03d4 <main_arena>,
bytes=bytes@entry=53) at malloc.c:4169
#6 0x10021804 in __libc_malloc (bytes=53) at malloc.c:3078
#7 0x10060f44 in _dl_get_origin ()
at ../sysdeps/unix/sysv/linux/dl-origin.c:49
#8 0x100302f4 in _dl_non_dynamic_init () at dl-support.c:311
#9 0x10031908 in __libc_init_first (argc=argc@entry=2,
argv=argv@entry=0xfffeecd4, envp=0xfffeece0) at init-first.c:72
#10 0x100024dc in generic_start_main (main=0x100003d4 <main>,
argc=argc@entry=2, argv=argv@entry=0xfffeecd4,
auxvec=auxvec@entry=0xfffeed9c, init=0x10002be0 <__libc_csu_init>,
fini=0x10002d58 <__libc_csu_fini>, rtld_fini=rtld_fini@entry=0x0,
stack_end=stack_end@entry=0xfffeecd0) at ../csu/libc-start.c:250
#11 0x10002774 in __libc_start_main (argc=2, argv=0xfffeecd4,
ev=<optimized out>, auxvec=0xfffeed9c, rtld_fini=0x0,
stinfo=0x1007f3e0, stack_on_entry=0xfffeecd0)
at ../sysdeps/unix/sysv/linux/powerpc/libc-start.c:98
#12 0x00000000 in ?? ()
main_arena.top->mchunk_size gets overwritten during tcache_init:
#0 memset () at ../sysdeps/powerpc/powerpc32/memset.S:291
#1 0x10021660 in tcache_init () at malloc.c:3021
#2 0x10021af4 in __libc_malloc (bytes=bytes@entry=53) at malloc.c:3064
#3 0x10021d80 in malloc_hook_ini (sz=53, caller=<optimized out>) at hooks.c:32
#4 0x10021aa0 in __libc_malloc (bytes=53) at malloc.c:3053
#5 0x100614c4 in _dl_get_origin () at ../sysdeps/unix/sysv/linux/dl-origin.c:49
#6 0x10030874 in _dl_non_dynamic_init () at dl-support.c:311
#7 0x10031e88 in __libc_init_first (argc=argc@entry=2,
argv=argv@entry=0xfffeecd4, envp=0xfffeece0) at init-first.c:72
#8 0x100024dc in generic_start_main (main=0x100003d4 <main>, argc=argc@entry=2,
argv=argv@entry=0xfffeecd4, auxvec=auxvec@entry=0xfffeed9c,
init=0x10002be0 <__libc_csu_init>, fini=0x10002d58 <__libc_csu_fini>,
rtld_fini=rtld_fini@entry=0x0, stack_end=stack_end@entry=0xfffeecd0)
at ../csu/libc-start.c:250
#9 0x10002774 in __libc_start_main (argc=2, argv=0xfffeecd4,
ev=<optimized out>, auxvec=0xfffeed9c, rtld_fini=0x0, stinfo=0x1007f960,
stack_on_entry=0xfffeecd0)
at ../sysdeps/unix/sysv/linux/powerpc/libc-start.c:98
#10 0x00000000 in ?? ()
The memset goes wrong because it loads the cache line size as 1 here:
/* Load rtld_global_ro._dl_cache_line_size. */
__GLRO(rCLS, rGOT, _dl_cache_line_size,
RTLD_GLOBAL_RO_DL_CACHE_LINE_SIZE_OFFSET)
0x100259e4 <+576>: lis r8,4108
=> 0x100259e8 <+580>: lwz r8,3912(r8)
(gdb) print (void*)($r8 + 3912)
$24 = (void *) 0x100c0f48 <__libc_enable_secure_decided>
This is not the address that is seen by the debugger for
_dl_cache_line_size:
(gdb) print &_dl_cache_line_size
$26 = (int *) 0x100c0f44 <_dl_cache_line_size>
The symbol table looks pretty reasonable:
1461: 100c0f44 4 OBJECT GLOBAL DEFAULT 23 _dl_cache_line_size
1495: 100c0f40 4 OBJECT GLOBAL DEFAULT 23 _dl_platform
1512: 100c0f48 4 OBJECT GLOBAL DEFAULT 23 __libc_enable_secure_decided
2135: 100c0f4c 4 OBJECT GLOBAL DEFAULT 23 __libc_argv
For some reason, we have relocations with displacements in
string/memset.o:
244: 3d 00 00 00 lis r8,0
246: R_PPC_ADDR16_HA _dl_cache_line_size+0x4
248: 81 08 00 00 lwz r8,0(r8)
24a: R_PPC_ADDR16_LO _dl_cache_line_size+0x4
This is due to the definition of __GLRO:
#else
/* Position-dependent code does not require access to the GOT. */
# define __GLRO(rOUT, rGOT, member, offset) \
lis rOUT,(member+LOWORD)@ha; \
lwz rOUT,(member+LOWORD)@l(rOUT)
#endif /* PIC */
And LOWORD is 4 on big-endian PowerPC:
/* The 32-bit words of a 64-bit dword are at these offsets in memory. */
#if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
# define LOWORD 0
# define HIWORD 4
#else
# define LOWORD 4
# define HIWORD 0
#endif
I believe we should remove the “+LOWORD” part here:
diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h
index 2ba009e9..829eec26 100644
--- a/sysdeps/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/powerpc/powerpc32/sysdep.h
@@ -179,8 +179,8 @@ GOT_LABEL: ;
\
#else
/* Position-dependent code does not require access to the GOT. */
# define __GLRO(rOUT, rGOT, member, offset) \
- lis rOUT,(member+LOWORD)@ha; \
- lwz rOUT,(member+LOWORD)@l(rOUT)
+ lis rOUT,(member)@ha; \
+ lwz rOUT,(member)@l(rOUT)
#endif /* PIC */
#endif /* __ASSEMBLER__ */
It fixes math/atest-exp for me.
Tulio, I believe you constructed this macro from
sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S, where it
is needed because we are loading the lower 32 bits of a 64-bit value.
It's not correct for loading a 32-bit quantity.
Technically, this bug is not a release blocker. It's not a regression,
it's present in 2.31 as well. I will file a bug and post a proper patch.
Thanks,
Florian
More information about the Libc-alpha
mailing list