mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 11:20:07 +00:00
Handle __gmon_start__ as undefined weak on hppa.
[BZ libc/19170] * sysdeps/hppa/crti.S: Declare PREINIT_FUNCTION weak_extern when PREINIT_FUNCTION_WEAK is nonzero. (gmon_initializer): New function. Put procedure label for it in .init_array section. (_init): Don't call PREINIT_FUNCTION. * sysdeps/hppa/crtn.S (__gmon_start__): Remove. * sysdeps/hppa/dl-lookupcfg.h (DL_FIXUP_MAKE_VALUE): Create null fixup value when map argument is null.
This commit is contained in:
parent
800a496acb
commit
b3f7fb12f5
10
ChangeLog
10
ChangeLog
@ -1,5 +1,15 @@
|
|||||||
2017-12-02 John David Anglin <danglin@gcc.gnu.org>
|
2017-12-02 John David Anglin <danglin@gcc.gnu.org>
|
||||||
|
|
||||||
|
[BZ libc/19170]
|
||||||
|
* sysdeps/hppa/crti.S: Declare PREINIT_FUNCTION weak_extern when
|
||||||
|
PREINIT_FUNCTION_WEAK is nonzero.
|
||||||
|
(gmon_initializer): New function. Put procedure label for it in
|
||||||
|
.init_array section.
|
||||||
|
(_init): Don't call PREINIT_FUNCTION.
|
||||||
|
* sysdeps/hppa/crtn.S (__gmon_start__): Remove.
|
||||||
|
* sysdeps/hppa/dl-lookupcfg.h (DL_FIXUP_MAKE_VALUE): Create null fixup
|
||||||
|
value when map argument is null.
|
||||||
|
|
||||||
* sysdeps/hppa/dl-fptr.c (elf_machine_resolve): Remove unnecessary
|
* sysdeps/hppa/dl-fptr.c (elf_machine_resolve): Remove unnecessary
|
||||||
depi instruction from PIC pc-relative sequence.
|
depi instruction from PIC pc-relative sequence.
|
||||||
* sysdeps/hppa/dl-fptr.h (ELF_MACHINE_LOAD_ADDRESS): Likewise.
|
* sysdeps/hppa/dl-fptr.h (ELF_MACHINE_LOAD_ADDRESS): Likewise.
|
||||||
|
@ -49,6 +49,95 @@
|
|||||||
# define PREINIT_FUNCTION_WEAK 1
|
# define PREINIT_FUNCTION_WEAK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PREINIT_FUNCTION_WEAK
|
||||||
|
weak_extern (PREINIT_FUNCTION)
|
||||||
|
#else
|
||||||
|
.hidden PREINIT_FUNCTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* If we have working .init_array support, we want to keep the .init
|
||||||
|
section empty (apart from the mandatory prologue/epilogue. This
|
||||||
|
ensures that the default unwind conventions (return-pointer in b0,
|
||||||
|
frame state in ar.pfs, etc.) will do the Right Thing. To ensure
|
||||||
|
an empty .init section, we register gmon_initializer() via the
|
||||||
|
.init_array.
|
||||||
|
|
||||||
|
--davidm 02/10/29 */
|
||||||
|
|
||||||
|
#if PREINIT_FUNCTION_WEAK
|
||||||
|
/* This blob of assembly code is one simple C function:
|
||||||
|
|
||||||
|
static void
|
||||||
|
__attribute__ ((used))
|
||||||
|
gmon_initializer (void)
|
||||||
|
{
|
||||||
|
extern void weak_function __gmon_start__ (void);
|
||||||
|
|
||||||
|
if (__gmon_start__)
|
||||||
|
(*__gmon_start__)();
|
||||||
|
}
|
||||||
|
|
||||||
|
In a final executable, PLABEL32 relocations for function pointers are
|
||||||
|
resolved at link time. Typically, binutils/ld resolves __gmon_start__
|
||||||
|
using an external shared library. __gmon_start__ is always called if
|
||||||
|
it is found at link time. If __gmon_start__ is not found at runtime
|
||||||
|
due to a library update, then the function pointer will point at a null
|
||||||
|
function descriptor and calling it will cause a segmentation fault.
|
||||||
|
So, we call __canonicalize_funcptr_for_compare to obtain the canonicalized
|
||||||
|
address of __gmon_start__ and skip calling __gmon_start__ if it is zero.
|
||||||
|
|
||||||
|
*/
|
||||||
|
.type __canonicalize_funcptr_for_compare,@function
|
||||||
|
.type $$dyncall,@function
|
||||||
|
|
||||||
|
.section .data.rel.ro,"aw",@progbits
|
||||||
|
.align 4
|
||||||
|
.LC0:
|
||||||
|
.type __gmon_start__,@function
|
||||||
|
.word P%__gmon_start__
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 4
|
||||||
|
.type gmon_initializer,@function
|
||||||
|
gmon_initializer:
|
||||||
|
.PROC
|
||||||
|
.CALLINFO FRAME=64,CALLS,SAVE_RP,ENTRY_GR=4
|
||||||
|
.ENTRY
|
||||||
|
stw %r2,-20(%r30)
|
||||||
|
stwm %r4,64(%r30)
|
||||||
|
stw %r3,-60(%r30)
|
||||||
|
addil LT'.LC0,%r19
|
||||||
|
ldw RT'.LC0(%r1),%r28
|
||||||
|
ldw 0(%r28),%r3
|
||||||
|
comib,= 0,%r3,1f
|
||||||
|
copy %r19,%r4
|
||||||
|
stw %r19,-32(%r30)
|
||||||
|
bl __canonicalize_funcptr_for_compare,%r2
|
||||||
|
copy %r3,%r26
|
||||||
|
comib,= 0,%r28,1f
|
||||||
|
copy %r4,%r19
|
||||||
|
copy %r3,%r22
|
||||||
|
.CALL ARGW0=GR
|
||||||
|
bl $$dyncall,%r31
|
||||||
|
copy %r31,%r2
|
||||||
|
1:
|
||||||
|
ldw -84(%r30),%r2
|
||||||
|
ldw -60(%r30),%r3
|
||||||
|
bv %r0(%r2)
|
||||||
|
ldwm -64(%r30),%r4
|
||||||
|
.EXIT
|
||||||
|
.PROCEND
|
||||||
|
.size gmon_initializer, .-gmon_initializer
|
||||||
|
|
||||||
|
# undef PREINIT_FUNCTION
|
||||||
|
# define PREINIT_FUNCTION gmon_initializer
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.section .init_array, "aw"
|
||||||
|
.word P% PREINIT_FUNCTION
|
||||||
|
|
||||||
|
|
||||||
/* _init prologue. */
|
/* _init prologue. */
|
||||||
.section .init, "ax", %progbits
|
.section .init, "ax", %progbits
|
||||||
.align 4
|
.align 4
|
||||||
@ -58,14 +147,6 @@ _init:
|
|||||||
stw %rp,-20(%sp)
|
stw %rp,-20(%sp)
|
||||||
stwm %r4,64(%sp)
|
stwm %r4,64(%sp)
|
||||||
stw %r19,-32(%sp)
|
stw %r19,-32(%sp)
|
||||||
#if PREINIT_FUNCTION_WEAK
|
|
||||||
bl PREINIT_FUNCTION,%rp
|
|
||||||
copy %r19,%r4 /* delay slot */
|
|
||||||
#else
|
|
||||||
bl PREINIT_FUNCTION,%rp
|
|
||||||
copy %r19,%r4 /* delay slot */
|
|
||||||
#endif
|
|
||||||
copy %r4,%r19
|
|
||||||
|
|
||||||
/* _fini prologue. */
|
/* _fini prologue. */
|
||||||
.section .fini,"ax",%progbits
|
.section .fini,"ax",%progbits
|
||||||
|
@ -38,27 +38,6 @@
|
|||||||
/* crtn.S puts function epilogues in the .init and .fini sections
|
/* crtn.S puts function epilogues in the .init and .fini sections
|
||||||
corresponding to the prologues in crti.S. */
|
corresponding to the prologues in crti.S. */
|
||||||
|
|
||||||
/* Note that we cannot have a weak undefined __gmon_start__, because
|
|
||||||
that would require this to be PIC, and the linker is currently not
|
|
||||||
able to generate a proper procedure descriptor for _init. Sad but
|
|
||||||
true. Anyway, HPPA is one of those horrible architectures where
|
|
||||||
making the comparison and indirect call is quite expensive (see the
|
|
||||||
comment in sysdeps/generic/initfini.c). */
|
|
||||||
.text
|
|
||||||
.align 4
|
|
||||||
.weak __gmon_start__
|
|
||||||
.type __gmon_start__,@function
|
|
||||||
__gmon_start__:
|
|
||||||
.proc
|
|
||||||
.callinfo
|
|
||||||
.entry
|
|
||||||
bv,n %r0(%r2)
|
|
||||||
.exit
|
|
||||||
.procend
|
|
||||||
|
|
||||||
/* Here is the tail end of _init. We put __gmon_start before this so
|
|
||||||
that the assembler creates the .PARISC.unwind section for us, ie.
|
|
||||||
with the right attributes. */
|
|
||||||
.section .init, "ax", @progbits
|
.section .init, "ax", @progbits
|
||||||
ldw -84(%sp),%rp
|
ldw -84(%sp),%rp
|
||||||
copy %r4,%r19
|
copy %r4,%r19
|
||||||
|
@ -73,7 +73,8 @@ void attribute_hidden _dl_unmap (struct link_map *map);
|
|||||||
|
|
||||||
/* Construct a fixup value from the address and linkmap */
|
/* Construct a fixup value from the address and linkmap */
|
||||||
#define DL_FIXUP_MAKE_VALUE(map, addr) \
|
#define DL_FIXUP_MAKE_VALUE(map, addr) \
|
||||||
((struct fdesc) { (addr), (map)->l_info[DT_PLTGOT]->d_un.d_ptr })
|
(map) ? ((struct fdesc) { (addr), (map)->l_info[DT_PLTGOT]->d_un.d_ptr }) \
|
||||||
|
: ((struct fdesc) { 0, 0 })
|
||||||
|
|
||||||
/* Extract the code address from a fixup value */
|
/* Extract the code address from a fixup value */
|
||||||
#define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
|
#define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
|
||||||
|
Loading…
Reference in New Issue
Block a user