mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-28 20:23:35 +08:00
2006-05-15 Carlos O'Donell <carlos@systemhalted.org>
* sysdeps/hppa/dl-machine.h: Include tls.h (elf_machine_fixup_plt): Returns fdesc. (elf_machine_profile_fixup_plt): Remove. (elf_machine_plt_value): Returns fdesc. (elf_machine_runtime_setup): Check that dl_profile != NULL. (ARCH_LA_PLTENT, ARCH_LA_PLTEXIT): Define. (RTLD_START): Use iitlbp with sr0. (elf_machine_type_class): Include TLS relocs. (reassemble_21, reassemble_14): Define. (elf_machine_rela): Add DIR21L, DIR14R, PLABEL21L, PLABEL14R, TLS_DTPMOD32, TLS_TPREL32, TLS_DTPOFF32 support. (TRAMPOLINE_TEMPLATE): Move to ... * sysdeps/hppa/dl-trampoline.S: ... here. * sysdeps/hppa/abort-instr.h: Use iitlbp with sr0. * sysdeps/hppa/dl-lookupcfg.h: Inlcude dl-fptr.h. (DL_FIXUP_VALUE_TYPE, DL_FIXUP_MAKE_VALUE, DL_FIXUP_VALUE_CODE_ADDR, DL_FIXUP_VALUE_ADD, DL_FIXUP_ADDR_VALUE): Define. * sysdeps/hppa/sysdep.h: Use "!" as a separator. Cleanup comments. * sysdeps/hppa/bits/link.h (La_hppa_regs, La_hppa_retval): Define. Define prototypes for la_hppa_gnu_pltenter and la_hppa_gnu_pltexit.
This commit is contained in:
parent
42e36d16b3
commit
084442fce3
@ -1,3 +1,26 @@
|
||||
2006-05-15 Carlos O'Donell <carlos@systemhalted.org>
|
||||
|
||||
* sysdeps/hppa/dl-machine.h: Include tls.h
|
||||
(elf_machine_fixup_plt): Returns fdesc.
|
||||
(elf_machine_profile_fixup_plt): Remove.
|
||||
(elf_machine_plt_value): Returns fdesc.
|
||||
(elf_machine_runtime_setup): Check that dl_profile != NULL.
|
||||
(ARCH_LA_PLTENT, ARCH_LA_PLTEXIT): Define.
|
||||
(RTLD_START): Use iitlbp with sr0.
|
||||
(elf_machine_type_class): Include TLS relocs.
|
||||
(reassemble_21, reassemble_14): Define.
|
||||
(elf_machine_rela): Add DIR21L, DIR14R, PLABEL21L, PLABEL14R,
|
||||
TLS_DTPMOD32, TLS_TPREL32, TLS_DTPOFF32 support.
|
||||
(TRAMPOLINE_TEMPLATE): Move to ...
|
||||
* sysdeps/hppa/dl-trampoline.S: ... here.
|
||||
* sysdeps/hppa/abort-instr.h: Use iitlbp with sr0.
|
||||
* sysdeps/hppa/dl-lookupcfg.h: Inlcude dl-fptr.h.
|
||||
(DL_FIXUP_VALUE_TYPE, DL_FIXUP_MAKE_VALUE, DL_FIXUP_VALUE_CODE_ADDR,
|
||||
DL_FIXUP_VALUE_ADD, DL_FIXUP_ADDR_VALUE): Define.
|
||||
* sysdeps/hppa/sysdep.h: Use "!" as a separator. Cleanup comments.
|
||||
* sysdeps/hppa/bits/link.h (La_hppa_regs, La_hppa_retval): Define.
|
||||
Define prototypes for la_hppa_gnu_pltenter and la_hppa_gnu_pltexit.
|
||||
|
||||
2006-04-27 Carlos O'Donell <carlos@systemhalted.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/hppa/bits/fcntl.h: Include uio.h, and
|
||||
|
@ -3,4 +3,4 @@
|
||||
We go with iitlbp because it has a history of being used to crash
|
||||
programs. */
|
||||
|
||||
#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%r0)")
|
||||
#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%sr0, %r0)")
|
||||
|
@ -0,0 +1,57 @@
|
||||
/* Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _LINK_H
|
||||
# error "Never include <bits/link.h> directly; use <link.h> instead."
|
||||
#endif
|
||||
|
||||
/* Registers for entry into PLT on hppa. */
|
||||
typedef struct La_hppa_regs
|
||||
{
|
||||
uint32_t lr_reg[4];
|
||||
double lr_fpreg[4];
|
||||
uint32_t lr_sp;
|
||||
uint32_t lr_ra;
|
||||
} La_hppa_regs;
|
||||
|
||||
/* Return values for calls from PLT on hppa. */
|
||||
typedef struct La_hppa_retval
|
||||
{
|
||||
uint32_t lrv_r28;
|
||||
uint32_t lrv_r29;
|
||||
double lr_fr4;
|
||||
} La_hppa_retval;
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
extern Elf32_Addr la_hppa_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
La_hppa_regs *__regs,
|
||||
unsigned int *__flags,
|
||||
const char *__symname,
|
||||
long int *__framesizep);
|
||||
extern unsigned int la_hppa_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
|
||||
uintptr_t *__refcook,
|
||||
uintptr_t *__defcook,
|
||||
const La_hppa_regs *__inregs,
|
||||
La_hppa_retval *__outregs,
|
||||
const char *symname);
|
||||
|
||||
__END_DECLS
|
@ -20,6 +20,8 @@
|
||||
#define ELF_FUNCTION_PTR_IS_SPECIAL
|
||||
#define DL_UNMAP_IS_SPECIAL
|
||||
|
||||
#include <dl-fptr.h>
|
||||
|
||||
/* Forward declaration. */
|
||||
struct link_map;
|
||||
|
||||
@ -63,3 +65,16 @@ void _dl_unmap (struct link_map *map);
|
||||
((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
|
||||
#define DL_DT_FINI_ADDRESS(map, addr) \
|
||||
((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
|
||||
|
||||
/* The type of the return value of fixup/profile_fixup */
|
||||
#define DL_FIXUP_VALUE_TYPE struct fdesc
|
||||
|
||||
/* Construct a fixup value from the address and linkmap */
|
||||
#define DL_FIXUP_MAKE_VALUE(map, addr) \
|
||||
((struct fdesc) { (addr), (map)->l_info[DT_PLTGOT]->d_un.d_ptr })
|
||||
|
||||
/* Extract the code address from a fixup value */
|
||||
#define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
|
||||
#define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
|
||||
#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <errno.h>
|
||||
#include <dl-fptr.h>
|
||||
#include <abort-instr.h>
|
||||
#include <tls.h>
|
||||
|
||||
# define VALID_ELF_OSABI(osabi) ((osabi == ELFOSABI_SYSV) || (osabi == ELFOSABI_LINUX))
|
||||
# define VALID_ELF_ABIVERSION(ver) (ver == 0)
|
||||
@ -116,43 +117,28 @@ elf_machine_load_address (void)
|
||||
return dynamic - elf_machine_dynamic ();
|
||||
}
|
||||
|
||||
/* Fixup a PLT entry to bounce directly to the function at VALUE.
|
||||
Optimized non-profile version. */
|
||||
static inline Elf32_Addr
|
||||
/* Fixup a PLT entry to bounce directly to the function at VALUE. */
|
||||
static inline struct fdesc __attribute__ ((always_inline))
|
||||
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
|
||||
const Elf32_Rela *reloc,
|
||||
Elf32_Addr *reloc_addr, Elf32_Addr value)
|
||||
Elf32_Addr *reloc_addr, struct fdesc value)
|
||||
{
|
||||
/* map is the link_map for the caller, t is the link_map for the object
|
||||
being called */
|
||||
reloc_addr[1] = D_PTR (t, l_info[DT_PLTGOT]);
|
||||
reloc_addr[0] = value;
|
||||
/* Return the PLT slot rather than the function value so that the
|
||||
trampoline can load the new LTP. */
|
||||
return (Elf32_Addr) reloc_addr;
|
||||
}
|
||||
|
||||
/* Fixup a PLT entry to bounce directly to the function at VALUE. */
|
||||
#define ELF_MACHINE_PROFILE_FIXUP_PLT elf_machine_profile_fixup_plt
|
||||
static inline Elf32_Addr
|
||||
elf_machine_profile_fixup_plt (struct link_map *map, lookup_t t,
|
||||
const Elf32_Rela *reloc,
|
||||
Elf32_Addr *reloc_addr, Elf32_Addr value)
|
||||
{
|
||||
if(__builtin_expect (t == NULL, 1))
|
||||
return (Elf32_Addr) reloc_addr;
|
||||
/* Return the PLT slot rather than the function value so that the
|
||||
trampoline can load the new LTP. */
|
||||
return (Elf32_Addr) elf_machine_fixup_plt(map, t, reloc, reloc_addr, value);
|
||||
reloc_addr[1] = value.gp;
|
||||
/* Need to ensure that the gp is visible before the code
|
||||
entry point is updated */
|
||||
((volatile Elf32_Addr *) reloc_addr)[0] = value.ip;
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Return the final value of a plt relocation. */
|
||||
static inline Elf32_Addr
|
||||
static inline struct fdesc
|
||||
elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
|
||||
Elf32_Addr value)
|
||||
struct fdesc value)
|
||||
{
|
||||
/* We are rela only */
|
||||
return value + reloc->r_addend;
|
||||
/* We are rela only, return a function descriptor as a plt entry. */
|
||||
return (struct fdesc) { value.ip + reloc->r_addend, value.gp };
|
||||
}
|
||||
|
||||
/* Set up the loaded object described by L so its unrelocated PLT
|
||||
@ -181,7 +167,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
|
||||
extern void _dl_runtime_resolve (void);
|
||||
extern void _dl_runtime_profile (void);
|
||||
|
||||
|
||||
/* Linking lazily */
|
||||
if (lazy)
|
||||
{
|
||||
@ -215,9 +201,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
{
|
||||
/* Found the GOT! */
|
||||
register Elf32_Addr ltp __asm__ ("%r19");
|
||||
/* Identify this shared object. */
|
||||
|
||||
/* Identify this shared object. Second entry in the got. */
|
||||
got[1] = (Elf32_Addr) l;
|
||||
|
||||
|
||||
/* This function will be called to perform the relocation. */
|
||||
if (__builtin_expect (!profile, 1))
|
||||
{
|
||||
@ -236,7 +223,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_dl_name_match_p (GLRO(dl_profile), l))
|
||||
if (GLRO(dl_profile) != NULL
|
||||
&& _dl_name_match_p (GLRO(dl_profile), l))
|
||||
{
|
||||
/* This is the object we are looking for. Say that
|
||||
we really want profiling and the timers are
|
||||
@ -316,6 +304,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
return lazy;
|
||||
}
|
||||
|
||||
|
||||
/* Names of the architecture-specific auditing callback functions. */
|
||||
#define ARCH_LA_PLTENTER hppa_gnu_pltenter
|
||||
#define ARCH_LA_PLTEXIT hppa_gnu_pltexit
|
||||
|
||||
/* Initial entry point code for the dynamic linker.
|
||||
The C function `_dl_start' is the real entry point;
|
||||
its return value is the user program's entry point. */
|
||||
@ -367,7 +360,7 @@ asm ( \
|
||||
" ldw,ma 8(%r26),%r19\n" \
|
||||
\
|
||||
/* Uh oh! We didn't find one. Abort. */ \
|
||||
" iitlbp %r0,(%r0)\n" \
|
||||
" iitlbp %r0,(%sr0,%r0)\n" \
|
||||
\
|
||||
"2: ldw -4(%r26),%r19\n" /* Found it, load value. */ \
|
||||
" add %r19,%r20,%r19\n" /* And add the load offset. */ \
|
||||
@ -471,85 +464,28 @@ asm ( \
|
||||
" ldw 4(%r3),%r19\n" /* load the object's gp */ \
|
||||
" bv %r0(%r2)\n" \
|
||||
" depi 2,31,2,%r23\n" /* delay slot */ \
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
/* This code gets called via the .plt stub, and is used in
|
||||
dl-runtime.c to call the `fixup' function and then redirect to the
|
||||
address it returns.
|
||||
|
||||
WARNING: This template is also used by gcc's __cffc, and expects
|
||||
that the "bl" for fixup() exist at a particular offset.
|
||||
Do not change this template without changing gcc, while the prefix
|
||||
"bl" should fix everything so gcc finds the right spot, it will
|
||||
slow down __cffc when it attempts to call fixup to resolve function
|
||||
descriptor references. Please refer to gcc/gcc/config/pa/fptr.c
|
||||
|
||||
Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp. */
|
||||
#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
|
||||
extern void tramp_name (void); \
|
||||
asm ( \
|
||||
" .text\n" \
|
||||
/* FAKE bl to provide gcc's __cffc with fixup's address */ \
|
||||
" bl " #fixup_name ",%r2\n" /* Runtime address of fixup */ \
|
||||
" .globl " #tramp_name "\n" \
|
||||
" .type " #tramp_name ",@function\n" \
|
||||
#tramp_name ":\n" \
|
||||
" .proc\n" \
|
||||
" .callinfo frame=64,calls,save_rp\n" \
|
||||
" .entry\n" \
|
||||
/* Save return pointer */ \
|
||||
" stw %r2,-20(%sp)\n" \
|
||||
/* Save argument registers in the call stack frame. */ \
|
||||
" stw %r26,-36(%sp)\n" \
|
||||
" stw %r25,-40(%sp)\n" \
|
||||
" stw %r24,-44(%sp)\n" \
|
||||
" stw %r23,-48(%sp)\n" \
|
||||
/* Build a call frame, and save structure pointer. */ \
|
||||
" stwm %r28,64(%sp)\n" \
|
||||
\
|
||||
/* Set up args to fixup func. */ \
|
||||
" ldw 8+4(%r20),%r26\n" /* (1) got[1] == struct link_map */ \
|
||||
" copy %r19,%r25\n" /* (2) reloc offset */ \
|
||||
" copy %r2,%r24\n" /* (3) profile_fixup needs rp */ \
|
||||
\
|
||||
/* Call the real address resolver. */ \
|
||||
" bl " #fixup_name ",%r2\n" \
|
||||
" copy %r21,%r19\n" /* set fixup func ltp (DELAY SLOT)*/ \
|
||||
\
|
||||
" ldw 0(%r28),%r22\n" /* load up the returned func ptr */ \
|
||||
" ldw 4(%r28),%r19\n" \
|
||||
" ldwm -64(%sp),%r28\n" \
|
||||
/* Arguments. */ \
|
||||
" ldw -36(%sp),%r26\n" \
|
||||
" ldw -40(%sp),%r25\n" \
|
||||
" ldw -44(%sp),%r24\n" \
|
||||
" ldw -48(%sp),%r23\n" \
|
||||
/* Call the real function. */ \
|
||||
" bv %r0(%r22)\n" \
|
||||
/* Return pointer. */ \
|
||||
" ldw -20(%sp),%r2\n" \
|
||||
" .exit\n" \
|
||||
" .procend\n");
|
||||
|
||||
#ifndef PROF
|
||||
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
|
||||
#else
|
||||
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
|
||||
strong_alias (_dl_runtime_resolve, _dl_runtime_profile);
|
||||
#endif
|
||||
|
||||
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
|
||||
PLT entries should not be allowed to define the value.
|
||||
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
|
||||
a TLS variable, so references should not be allowed to define the value.
|
||||
ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
|
||||
of the main executable's symbols, as for a COPY reloc. */
|
||||
#define elf_machine_type_class(type) \
|
||||
((((type) == R_PARISC_IPLT || (type) == R_PARISC_EPLT) \
|
||||
* ELF_RTYPE_CLASS_PLT) \
|
||||
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
|
||||
# define elf_machine_type_class(type) \
|
||||
((((type) == R_PARISC_IPLT \
|
||||
|| (type) == R_PARISC_EPLT \
|
||||
|| (type) == R_PARISC_TLS_DTPMOD32 \
|
||||
|| (type) == R_PARISC_TLS_DTPOFF32 \
|
||||
|| (type) == R_PARISC_TLS_TPREL32) \
|
||||
* ELF_RTYPE_CLASS_PLT) \
|
||||
| (((type) == R_PARISC_COPY) * ELF_RTYPE_CLASS_COPY))
|
||||
#else
|
||||
#define elf_machine_type_class(type) \
|
||||
((((type) == R_PARISC_IPLT \
|
||||
|| (type) == R_PARISC_EPLT) \
|
||||
* ELF_RTYPE_CLASS_PLT) \
|
||||
| (((type) == R_PARISC_COPY) * ELF_RTYPE_CLASS_COPY))
|
||||
#endif
|
||||
|
||||
/* Used by the runtime in fixup to figure out if reloc is *really* PLT */
|
||||
#define ELF_MACHINE_JMP_SLOT R_PARISC_IPLT
|
||||
@ -579,9 +515,22 @@ dl_platform_init (void)
|
||||
/* These are only actually used where RESOLVE_MAP is defined, anyway. */
|
||||
#ifdef RESOLVE_MAP
|
||||
|
||||
#define reassemble_21(as21) \
|
||||
( (((as21) & 0x100000) >> 20) \
|
||||
| (((as21) & 0x0ffe00) >> 8) \
|
||||
| (((as21) & 0x000180) << 7) \
|
||||
| (((as21) & 0x00007c) << 14) \
|
||||
| (((as21) & 0x000003) << 12))
|
||||
|
||||
#define reassemble_14(as14) \
|
||||
( (((as14) & 0x1fff) << 1) \
|
||||
| (((as14) & 0x2000) >> 13))
|
||||
|
||||
auto void __attribute__((always_inline))
|
||||
elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
const Elf32_Sym *sym, const struct r_found_version *version,
|
||||
elf_machine_rela (struct link_map *map,
|
||||
const Elf32_Rela *reloc,
|
||||
const Elf32_Sym *sym,
|
||||
const struct r_found_version *version,
|
||||
void *const reloc_addr_arg)
|
||||
{
|
||||
Elf32_Addr *const reloc_addr = reloc_addr_arg;
|
||||
@ -590,7 +539,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
struct link_map *sym_map;
|
||||
Elf32_Addr value;
|
||||
|
||||
# if !defined RTLD_BOOTSTRAP && !defined SHARED
|
||||
# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC && !defined SHARED
|
||||
/* This is defined in rtld.c, but nowhere in the static libc.a; make the
|
||||
reference weak so static programs can still link. This declaration
|
||||
cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
|
||||
@ -612,6 +561,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
# else
|
||||
sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||
# endif
|
||||
|
||||
if (sym_map)
|
||||
{
|
||||
value = sym ? sym_map->l_addr + sym->st_value : 0;
|
||||
@ -635,6 +585,27 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
}
|
||||
break;
|
||||
|
||||
case R_PARISC_DIR21L:
|
||||
{
|
||||
unsigned int insn = *(unsigned int *)reloc_addr;
|
||||
value = sym_map->l_addr + sym->st_value
|
||||
+ ((reloc->r_addend + 0x1000) & -0x2000);
|
||||
value = value >> 11;
|
||||
insn = (insn &~ 0x1fffff) | reassemble_21 (value);
|
||||
*(unsigned int *)reloc_addr = insn;
|
||||
}
|
||||
return;
|
||||
|
||||
case R_PARISC_DIR14R:
|
||||
{
|
||||
unsigned int insn = *(unsigned int *)reloc_addr;
|
||||
value = ((sym_map->l_addr + sym->st_value) & 0x7ff)
|
||||
+ (((reloc->r_addend & 0x1fff) ^ 0x1000) - 0x1000);
|
||||
insn = (insn &~ 0x3fff) | reassemble_14 (value);
|
||||
*(unsigned int *)reloc_addr = insn;
|
||||
}
|
||||
return;
|
||||
|
||||
case R_PARISC_PLABEL32:
|
||||
/* Easy rule: If there is a symbol and it is global, then we
|
||||
need to make a dynamic function descriptor. Otherwise we
|
||||
@ -653,15 +624,42 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
value = (Elf32_Addr)((unsigned int)_dl_make_fptr (sym_map, sym, value) | 2);
|
||||
break;
|
||||
|
||||
case R_PARISC_PLABEL21L:
|
||||
case R_PARISC_PLABEL14R:
|
||||
{
|
||||
unsigned int insn = *(unsigned int *)reloc_addr;
|
||||
|
||||
if (__builtin_expect (sym == NULL, 0))
|
||||
break;
|
||||
|
||||
value = (Elf32_Addr)((unsigned int)_dl_make_fptr (sym_map, sym, value) | 2);
|
||||
|
||||
if (r_type == R_PARISC_PLABEL21L)
|
||||
{
|
||||
value >>= 11;
|
||||
insn = (insn &~ 0x1fffff) | reassemble_21 (value);
|
||||
}
|
||||
else
|
||||
{
|
||||
value &= 0x7ff;
|
||||
insn = (insn &~ 0x3fff) | reassemble_14 (value);
|
||||
}
|
||||
|
||||
*(unsigned int *)reloc_addr = insn;
|
||||
}
|
||||
return;
|
||||
|
||||
case R_PARISC_IPLT:
|
||||
if (__builtin_expect (sym_map != NULL, 1))
|
||||
{
|
||||
elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr, value);
|
||||
elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr,
|
||||
DL_FIXUP_MAKE_VALUE(sym_map, value));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we get here, it's a (weak) undefined sym. */
|
||||
elf_machine_fixup_plt (NULL, map, reloc, reloc_addr, value);
|
||||
elf_machine_fixup_plt (NULL, map, reloc, reloc_addr,
|
||||
DL_FIXUP_MAKE_VALUE(map, value));
|
||||
}
|
||||
return;
|
||||
|
||||
@ -685,6 +683,28 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
memcpy (reloc_addr_arg, (void *) value,
|
||||
MIN (sym->st_size, refsym->st_size));
|
||||
return;
|
||||
|
||||
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP)
|
||||
case R_PARISC_TLS_DTPMOD32:
|
||||
value = sym_map->l_tls_modid;
|
||||
break;
|
||||
|
||||
case R_PARISC_TLS_DTPOFF32:
|
||||
/* During relocation all TLS symbols are defined and used.
|
||||
Therefore the offset is already correct. */
|
||||
if (sym != NULL)
|
||||
*reloc_addr = sym->st_value;
|
||||
return;
|
||||
|
||||
case R_PARISC_TLS_TPREL32:
|
||||
/* The offset is negative, forward from the thread pointer */
|
||||
if (sym != NULL)
|
||||
{
|
||||
CHECK_STATIC_TLS (map, sym_map);
|
||||
value = sym_map->l_tls_offset + sym->st_value + reloc->r_addend;
|
||||
}
|
||||
break;
|
||||
#endif /* use TLS */
|
||||
|
||||
case R_PARISC_NONE: /* Alright, Wilbur. */
|
||||
return;
|
||||
|
197
sysdeps/hppa/dl-trampoline.S
Normal file
197
sysdeps/hppa/dl-trampoline.S
Normal file
@ -0,0 +1,197 @@
|
||||
/* PLT trampolines. hppa version.
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
/* This code gets called via the .plt stub, and is used in
|
||||
dl-runtime.c to call the `_dl_fixup' function and then redirect
|
||||
to the address it returns. `_dl_fixup' takes two
|
||||
arguments, however `_dl_profile_fixup' takes a number of
|
||||
parameters for use with library auditing (LA).
|
||||
|
||||
WARNING: This template is also used by gcc's __cffc, and expects
|
||||
that the "bl" for _dl_runtime_resolve exist at a particular offset.
|
||||
Do not change this template without changing gcc, while the prefix
|
||||
"bl" should fix everything so gcc finds the right spot, it will
|
||||
slow down __cffc when it attempts to call fixup to resolve function
|
||||
descriptor references. Please refer to gcc/gcc/config/pa/fptr.c
|
||||
|
||||
Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp. */
|
||||
|
||||
/* FAKE bl to provide gcc's __cffc with fixup loc. */
|
||||
.text
|
||||
bl _dl_fixup, %r2
|
||||
.text
|
||||
.align 4
|
||||
.global _dl_runtime_resolve
|
||||
.type _dl_runtime_resolve,@function
|
||||
_dl_runtime_resolve:
|
||||
.PROC
|
||||
.CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
|
||||
.ENTRY
|
||||
/* SAVE_RP says we do */
|
||||
stw %rp, -20(%sp)
|
||||
|
||||
/* Save static link register */
|
||||
stw %r29,-16(%sp)
|
||||
/* Save argument registers in the call stack frame. */
|
||||
stw %r26,-36(%sp)
|
||||
stw %r25,-40(%sp)
|
||||
stw %r24,-44(%sp)
|
||||
stw %r23,-48(%sp)
|
||||
|
||||
/* Build a call frame, and save structure pointer. */
|
||||
copy %sp, %r26 /* Copy previous sp */
|
||||
/* Save function result address (on entry) */
|
||||
stwm %r28,128(%sp)
|
||||
|
||||
/* Save floating point argument registers */
|
||||
ldo -56(%sp),%r26
|
||||
fstd,ma %fr4,-8(%r26)
|
||||
fstd,ma %fr5,-8(%r26)
|
||||
fstd,ma %fr6,-8(%r26)
|
||||
fstd %fr7,0(%r26)
|
||||
|
||||
/* Fillin some frame info to follow ABI */
|
||||
stw %r21,-32(%sp) /* PIC register value */
|
||||
stw %r26,-4(%sp) /* Previous sp */
|
||||
|
||||
/* Set up args to fixup func, needs only two arguments */
|
||||
ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */
|
||||
copy %r19,%r25 /* (2) reloc offset */
|
||||
|
||||
/* Call the real address resolver. */
|
||||
bl _dl_fixup,%rp
|
||||
copy %r21,%r19 /* set fixup func ltp */
|
||||
|
||||
/* Load up the returned func descriptor */
|
||||
copy %ret0, %r22
|
||||
copy %ret1, %r19
|
||||
|
||||
/* Reload arguments fp args */
|
||||
ldo -80(%sp),%r26
|
||||
fldd,ma 8(%r26),%fr7
|
||||
fldd,ma 8(%r26),%fr6
|
||||
fldd,ma 8(%r26),%fr5
|
||||
fldd 0(%r26),%fr4
|
||||
|
||||
/* Adjust sp, and restore function result address*/
|
||||
ldwm -128(%sp),%r28
|
||||
|
||||
/* Reload static link register */
|
||||
ldw -16(%sp),%r29
|
||||
/* Reload general args */
|
||||
ldw -36(%sp),%r26
|
||||
ldw -40(%sp),%r25
|
||||
ldw -44(%sp),%r24
|
||||
ldw -48(%sp),%r23
|
||||
|
||||
/* Jump to new function, but return to previous function */
|
||||
bv %r0(%r22)
|
||||
ldw -20(%sp),%rp
|
||||
.EXIT
|
||||
.PROCEND
|
||||
.size _dl_runtime_resolve, . - _dl_runtime_resolve
|
||||
|
||||
|
||||
/* FIXME:
|
||||
Need to largely rewrite the bottom half of
|
||||
this code in order to save and restore the
|
||||
LA struct from the stack along with
|
||||
interpreted parameters.
|
||||
*/
|
||||
.text
|
||||
.align 4
|
||||
.global _dl_runtime_profile
|
||||
.type _dl_runtime_profile,@function
|
||||
_dl_runtime_profile:
|
||||
.PROC
|
||||
.CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
|
||||
.ENTRY
|
||||
|
||||
/* SAVE_RP says we do */
|
||||
stw %rp, -20(%sp)
|
||||
|
||||
/* Save static link register */
|
||||
stw %r29,-16(%sp)
|
||||
/* Save argument registers in the call stack frame. */
|
||||
stw %r26,-36(%sp)
|
||||
stw %r25,-40(%sp)
|
||||
stw %r24,-44(%sp)
|
||||
stw %r23,-48(%sp)
|
||||
|
||||
/* Build a call frame, and save structure pointer. */
|
||||
copy %sp, %r26 /* Copy previous sp */
|
||||
/* Save function result address (on entry) */
|
||||
stwm %r28,128(%sp)
|
||||
|
||||
/* Save floating point argument registers */
|
||||
ldo -56(%sp),%r26
|
||||
fstd,ma %fr4,-8(%r26)
|
||||
fstd,ma %fr5,-8(%r26)
|
||||
fstd,ma %fr6,-8(%r26)
|
||||
fstd %fr7,0(%r26)
|
||||
|
||||
/* Fillin some frame info to follow ABI */
|
||||
stw %r21,-32(%sp) /* PIC register value */
|
||||
stw %r26,-4(%sp) /* Previous sp */
|
||||
|
||||
/* Set up args to fixup func, needs five arguments */
|
||||
ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */
|
||||
copy %r19,%r25 /* (2) reloc offset */
|
||||
copy %rp,%r24 /* (3) profile_fixup needs rp */
|
||||
copy %r0,%r23 /* (4) regs */
|
||||
ldo -56(%sp), %r1
|
||||
stw %r1, -52(%sp) /* (5) long int *framesizep */
|
||||
|
||||
/* Call the real address resolver. */
|
||||
bl _dl_profile_fixup,%rp
|
||||
copy %r21,%r19 /* set fixup func ltp */
|
||||
|
||||
/* Load up the returned func descriptor */
|
||||
copy %ret0, %r22
|
||||
copy %ret1, %r19
|
||||
|
||||
/* Reload arguments fp args */
|
||||
ldo -80(%sp),%r26
|
||||
fldd,ma 8(%r26),%fr7
|
||||
fldd,ma 8(%r26),%fr6
|
||||
fldd,ma 8(%r26),%fr5
|
||||
fldd 0(%r26),%fr4
|
||||
|
||||
/* Adjust sp, and restore function result address*/
|
||||
ldwm -128(%sp),%r28
|
||||
|
||||
/* Reload static link register */
|
||||
ldw -16(%sp),%r29
|
||||
/* Reload general args */
|
||||
ldw -36(%sp),%r26
|
||||
ldw -40(%sp),%r25
|
||||
ldw -44(%sp),%r24
|
||||
ldw -48(%sp),%r23
|
||||
|
||||
/* Jump to new function, but return to previous function */
|
||||
bv %r0(%r22)
|
||||
ldw -20(%sp),%rp
|
||||
.EXIT
|
||||
.PROCEND
|
||||
.size _dl_runtime_profile, . - _dl_runtime_profile
|
||||
|
||||
|
||||
|
@ -22,9 +22,8 @@
|
||||
#include <sys/syscall.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifndef ASM_LINE_SEP
|
||||
#define ASM_LINE_SEP ;
|
||||
#endif
|
||||
#undef ASM_LINE_SEP
|
||||
#define ASM_LINE_SEP !
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
|
||||
@ -51,13 +50,9 @@
|
||||
#define END(name) \
|
||||
.PROCEND
|
||||
|
||||
|
||||
/* If compiled for profiling, call `mcount' at the start of each function. */
|
||||
/* GCC does everything for us. */
|
||||
#ifdef PROF
|
||||
/* The mcount code relies on a normal frame pointer being on the stack
|
||||
to locate our caller, so push one just for its benefit. */
|
||||
#define CALL_MCOUNT \
|
||||
XXX ASM_LINE_SEP
|
||||
#define CALL_MCOUNT
|
||||
#else
|
||||
#define CALL_MCOUNT /* Do nothing. */
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user