Update.
2004-04-04 Carlos O'Donell <carlos@baldric.uwo.ca> * sysdeps/hppa/Dist: Add bits/link.h elf/entry.h. * sysdeps/hppa/bits/link.h: New file. * sysdeps/hppa/dl-machine.h (__hppa_init_bootstrap_fdesc_table): Initialze the fdesc table for the generic code. (elf_machine_dynamic): Use asm version. (elf_machine_load_addresss): Simplify asm by calling elf_machine_dynamic. (elf_machine_fixup_plt): Correct comment. (elf_machine_profile_fixup_plt): New. (elf_machine_runtime_setup): Check PLT exists, if lazy=1 process normally, else relocate all the absolute entries. (RTLD_START): Fix comments. (TRAMPOLINE_TEMPLATE): Reformat assembly, add return pointer for calls to profile_fixup. (ELF_MACHINE_SIZEOF_JMP_SLOT, DL_STATIC_FUNCTION_ADDRESS, DL_PLATFORM_INIT): Define. (DL_FUNCTION_ADDRESS): Remove. (dl_platform_init): New. (elf_machine_rela): Use generic fdesc code, and process all COPY relocations. Use __attribute__((always_inline)). (elf_machine_rela_relative): Add sanity checks, remove IPLT processing, print error message in default case. Use __attribute__((always_inline)). (elf_machine_lazy_rel): Use __attribute__((always_inline)). 2004-04-05 Carlos O'Donell <carlos@baldric.uwo.ca> * sysdeps/hppa/fpu/feupdateenv.c (feupdateenv): Use only sw[0] and call feraiseexcept. 2003-11-15 Randolph Chung <tausq@debian.org> * gmon/gmon.c (__monstartup): Round kcountsize to multiples of the froms[] array so the array is properly aligned. 2004-04-05 H.J. Lu <hongjiu.lu@intel.com> * Makeconfig (libgcc_eh): Add -Wl,. * configure.in: Add -lgcc_s for --as-needed check. 2004-04-16 Kaz Kojima <kkojima@rr.iij4u.or.jp> * sysdeps/sh/elf/configure.in: New file. * iconvdata/gconv-modules: Add PT154 and RK1048 entries. * iconvdata/tst-tables.sh: Add PT154 and RK1048. * iconvdata/Makefile (modules): Add PT154 anhd RK1048. (distribute): Add pt154.c and rk1048.c. (gen-8bit-gap-modules): Add pt154 and rk1048. * icondata/pt154.c: New file. * iconvdata/rk1048.c: New file.
This commit is contained in:
parent
5339290658
commit
69ac9d0793
57
ChangeLog
57
ChangeLog
@ -1,5 +1,62 @@
|
||||
2004-04-04 Carlos O'Donell <carlos@baldric.uwo.ca>
|
||||
|
||||
* sysdeps/hppa/Dist: Add bits/link.h elf/entry.h.
|
||||
|
||||
* sysdeps/hppa/bits/link.h: New file.
|
||||
|
||||
* sysdeps/hppa/dl-machine.h (__hppa_init_bootstrap_fdesc_table):
|
||||
Initialze the fdesc table for the generic code.
|
||||
(elf_machine_dynamic): Use asm version.
|
||||
(elf_machine_load_addresss): Simplify asm by calling
|
||||
elf_machine_dynamic.
|
||||
(elf_machine_fixup_plt): Correct comment.
|
||||
(elf_machine_profile_fixup_plt): New.
|
||||
(elf_machine_runtime_setup): Check PLT exists, if lazy=1 process
|
||||
normally, else relocate all the absolute entries.
|
||||
(RTLD_START): Fix comments.
|
||||
(TRAMPOLINE_TEMPLATE): Reformat assembly, add return pointer for
|
||||
calls to profile_fixup.
|
||||
(ELF_MACHINE_SIZEOF_JMP_SLOT, DL_STATIC_FUNCTION_ADDRESS,
|
||||
DL_PLATFORM_INIT): Define.
|
||||
(DL_FUNCTION_ADDRESS): Remove.
|
||||
(dl_platform_init): New.
|
||||
(elf_machine_rela): Use generic fdesc code, and process all COPY
|
||||
relocations. Use __attribute__((always_inline)).
|
||||
(elf_machine_rela_relative): Add sanity checks, remove IPLT
|
||||
processing, print error message in default case. Use
|
||||
__attribute__((always_inline)).
|
||||
(elf_machine_lazy_rel): Use __attribute__((always_inline)).
|
||||
|
||||
2004-04-05 Carlos O'Donell <carlos@baldric.uwo.ca>
|
||||
|
||||
* sysdeps/hppa/fpu/feupdateenv.c (feupdateenv): Use only sw[0]
|
||||
and call feraiseexcept.
|
||||
|
||||
2003-11-15 Randolph Chung <tausq@debian.org>
|
||||
|
||||
* gmon/gmon.c (__monstartup): Round kcountsize to multiples of
|
||||
the froms[] array so the array is properly aligned.
|
||||
|
||||
2004-04-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* Makeconfig (libgcc_eh): Add -Wl,.
|
||||
|
||||
* configure.in: Add -lgcc_s for --as-needed check.
|
||||
|
||||
2004-04-16 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
||||
|
||||
* sysdeps/sh/elf/configure.in: New file.
|
||||
|
||||
2004-04-17 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* iconvdata/gconv-modules: Add PT154 and RK1048 entries.
|
||||
* iconvdata/tst-tables.sh: Add PT154 and RK1048.
|
||||
* iconvdata/Makefile (modules): Add PT154 anhd RK1048.
|
||||
(distribute): Add pt154.c and rk1048.c.
|
||||
(gen-8bit-gap-modules): Add pt154 and rk1048.
|
||||
* icondata/pt154.c: New file.
|
||||
* iconvdata/rk1048.c: New file.
|
||||
|
||||
* rt/tst-timer4.c: Disable some tests, mark errors better.
|
||||
|
||||
2004-04-16 Ulrich Drepper <drepper@redhat.com>
|
||||
|
@ -114,7 +114,7 @@ __monstartup (lowpc, highpc)
|
||||
p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
||||
p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
||||
p->textsize = p->highpc - p->lowpc;
|
||||
p->kcountsize = p->textsize / HISTFRACTION;
|
||||
p->kcountsize = ROUNDUP(p->textsize / HISTFRACTION, sizeof(*p->froms));
|
||||
p->hashfraction = HASHFRACTION;
|
||||
p->log_hashfraction = -1;
|
||||
/* The following test must be kept in sync with the corresponding
|
||||
|
@ -1,5 +1,6 @@
|
||||
2004-04-17 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* SUPPORTED (SUPPORTED-LOCALES): Add kk_KZ/PT154.
|
||||
* locales/kk_KZ: New file.
|
||||
* charmaps/PT154: New file.
|
||||
* charmaps/RK1048: New file.
|
||||
|
@ -1,3 +1,5 @@
|
||||
libgcc-compat.c
|
||||
dl-symaddr.c
|
||||
dl-fptr.c
|
||||
bits/link.h
|
||||
elf/entry.h
|
||||
|
6
sysdeps/hppa/bits/link.h
Normal file
6
sysdeps/hppa/bits/link.h
Normal file
@ -0,0 +1,6 @@
|
||||
/* Used to store the function descriptor table */
|
||||
struct link_map_machine
|
||||
{
|
||||
size_t fptr_table_len;
|
||||
ElfW(Addr) *fptr_table;
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
/* Machine-dependent ELF dynamic relocation inline functions. PA-RISC version.
|
||||
Copyright (C) 1995-1997,1999,2000,2001,2002, 2003
|
||||
Copyright (C) 1995-1997,1999-2003
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by David Huggins-Daines <dhd@debian.org>
|
||||
This file is part of the GNU C Library.
|
||||
@ -25,40 +25,52 @@
|
||||
#define ELF_MACHINE_NAME "hppa"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <link.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <dl-fptr.h>
|
||||
#include <abort-instr.h>
|
||||
|
||||
/* These must match the definition of the stub in bfd/elf32-hppa.c. */
|
||||
#define SIZEOF_PLT_STUB (4*4)
|
||||
# define VALID_ELF_OSABI(osabi) ((osabi == ELFOSABI_SYSV) || (osabi == ELFOSABI_LINUX))
|
||||
# define VALID_ELF_ABIVERSION(ver) (ver == 0)
|
||||
# define VALID_ELF_HEADER(hdr,exp,size) \
|
||||
memcmp (hdr,exp,size-2) == 0 \
|
||||
&& VALID_ELF_OSABI (hdr[EI_OSABI]) \
|
||||
&& VALID_ELF_ABIVERSION (hdr[EI_ABIVERSION])
|
||||
|
||||
/* These two definitions must match the definition of the stub in
|
||||
bfd/elf32-hppa.c (see plt_stub[]).
|
||||
|
||||
a. Define the size of the *entire* stub we place at the end of the PLT
|
||||
table (right up against the GOT).
|
||||
|
||||
b. Define the number of bytes back from the GOT to the entry point of
|
||||
the PLT stub. You see the PLT stub must be entered in the middle
|
||||
so it can depwi to find it's own address (long jump stub)
|
||||
|
||||
c. Define the size of a single PLT entry so we can jump over the
|
||||
last entry to get the stub address */
|
||||
|
||||
#define SIZEOF_PLT_STUB (7*4)
|
||||
#define GOT_FROM_PLT_STUB (4*4)
|
||||
#define PLT_ENTRY_SIZE (2*4)
|
||||
|
||||
/* A PLABEL is a function descriptor. Properly they consist of just
|
||||
FUNC and GP. But we want to traverse a binary tree too. See
|
||||
dl-fptr.c for the code (it may be made common between HPPA and
|
||||
IA-64 in the future).
|
||||
|
||||
We call these 'fptr' to make it easier to steal code from IA-64. */
|
||||
|
||||
/* ld.so currently has 12 PLABEL32 relocs. We'll keep this constant
|
||||
large for now in case we require more, as the rest of these will be
|
||||
used by the dynamic program itself (libc.so has quite a few
|
||||
PLABEL32 relocs in it). */
|
||||
#define HPPA_BOOT_FPTR_SIZE 256
|
||||
|
||||
struct hppa_fptr
|
||||
/* Initialize the function descriptor table before relocations */
|
||||
static inline void
|
||||
__hppa_init_bootstrap_fdesc_table (struct link_map *map)
|
||||
{
|
||||
Elf32_Addr func;
|
||||
Elf32_Addr gp;
|
||||
struct hppa_fptr *next;
|
||||
};
|
||||
ElfW(Addr) *boot_table;
|
||||
|
||||
extern struct hppa_fptr __boot_ldso_fptr[];
|
||||
extern struct hppa_fptr *__fptr_root;
|
||||
extern int __fptr_count;
|
||||
/* Careful: this will be called before got has been relocated... */
|
||||
ELF_MACHINE_LOAD_ADDRESS(boot_table,_dl_boot_fptr_table);
|
||||
|
||||
extern Elf32_Addr __hppa_make_fptr (const struct link_map *, Elf32_Addr,
|
||||
struct hppa_fptr **, struct hppa_fptr *);
|
||||
map->l_mach.fptr_table_len = ELF_MACHINE_BOOT_FPTR_TABLE_LEN;
|
||||
map->l_mach.fptr_table = boot_table;
|
||||
}
|
||||
|
||||
#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
|
||||
__hppa_init_bootstrap_fdesc_table (&bootstrap_map);
|
||||
|
||||
/* Return nonzero iff ELF header is compatible with the running host. */
|
||||
static inline int
|
||||
@ -67,55 +79,52 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr)
|
||||
return ehdr->e_machine == EM_PARISC;
|
||||
}
|
||||
|
||||
|
||||
/* Return the link-time address of _DYNAMIC. */
|
||||
static inline Elf32_Addr
|
||||
elf_machine_dynamic (void) __attribute__ ((const));
|
||||
|
||||
static inline Elf32_Addr
|
||||
elf_machine_dynamic (void)
|
||||
{
|
||||
Elf32_Addr dynamic;
|
||||
|
||||
#if 0
|
||||
/* Use this method if GOT address not yet set up. */
|
||||
asm (
|
||||
" b,l 1f,%0\n"
|
||||
asm ("b,l 1f,%0\n"
|
||||
" depi 0,31,2,%0\n"
|
||||
"1: addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8),%0\n"
|
||||
" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
|
||||
: "=r" (dynamic) : : "r1");
|
||||
#else
|
||||
/* This works because we already have our GOT address available. */
|
||||
dynamic = (Elf32_Addr) &_DYNAMIC;
|
||||
#endif
|
||||
: "=r" (dynamic) : : "r1");
|
||||
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
/* Return the run-time load address of the shared object. */
|
||||
static inline Elf32_Addr
|
||||
elf_machine_load_address (void) __attribute__ ((const));
|
||||
|
||||
static inline Elf32_Addr
|
||||
elf_machine_load_address (void)
|
||||
{
|
||||
Elf32_Addr dynamic, dynamic_linkaddress;
|
||||
Elf32_Addr dynamic;
|
||||
|
||||
asm (
|
||||
" b,l 1f,%0\n"
|
||||
" depi 0,31,2,%0\n"
|
||||
"1: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%0\n"
|
||||
" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%1\n"
|
||||
" addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%0\n"
|
||||
" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%%r1),%0\n"
|
||||
: "=r" (dynamic_linkaddress), "=r" (dynamic) : : "r1");
|
||||
" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
|
||||
: "=r" (dynamic) : : "r1");
|
||||
|
||||
return dynamic - dynamic_linkaddress;
|
||||
return dynamic - elf_machine_dynamic ();
|
||||
}
|
||||
|
||||
/* Fixup a PLT entry to bounce directly to the function at VALUE. */
|
||||
/* Fixup a PLT entry to bounce directly to the function at VALUE.
|
||||
Optimized non-profile version. */
|
||||
static inline Elf32_Addr
|
||||
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
|
||||
const Elf32_Rela *reloc,
|
||||
Elf32_Addr *reloc_addr, Elf32_Addr value)
|
||||
{
|
||||
/* l is the link_map for the caller, t is the link_map for the object
|
||||
* being called */
|
||||
/* 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
|
||||
@ -123,6 +132,20 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
|
||||
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);
|
||||
}
|
||||
|
||||
/* Return the final value of a plt relocation. */
|
||||
static inline Elf32_Addr
|
||||
elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
|
||||
@ -138,110 +161,158 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
|
||||
static inline int
|
||||
elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
{
|
||||
Elf32_Addr *got = NULL;
|
||||
Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type, r_sym;
|
||||
const Elf32_Rela *reloc;
|
||||
struct fdesc *fptr;
|
||||
static union {
|
||||
unsigned char c[8];
|
||||
Elf32_Addr i[2];
|
||||
} sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}};
|
||||
|
||||
/* If we don't have a PLT we can just skip all this... */
|
||||
if (__builtin_expect (l->l_info[DT_JMPREL] == NULL,0))
|
||||
return lazy;
|
||||
|
||||
/* All paths use these values */
|
||||
l_addr = l->l_addr;
|
||||
jmprel = D_PTR(l, l_info[DT_JMPREL]);
|
||||
end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val;
|
||||
|
||||
extern void _dl_runtime_resolve (void);
|
||||
extern void _dl_runtime_profile (void);
|
||||
Elf32_Addr jmprel = D_PTR(l, l_info[DT_JMPREL]);
|
||||
|
||||
if (lazy && jmprel)
|
||||
|
||||
/* Linking lazily */
|
||||
if (lazy)
|
||||
{
|
||||
Elf32_Addr *got = NULL;
|
||||
Elf32_Addr l_addr;
|
||||
Elf32_Addr end_jmprel;
|
||||
Elf32_Addr iplt;
|
||||
/* FIXME: Search for the got, but backwards through the relocs, technically we should
|
||||
find it on the first try. However, assuming the relocs got out of order the
|
||||
routine is made a bit more robust by searching them all in case of failure. */
|
||||
for (iplt = (end_jmprel - sizeof(Elf32_Rela)); iplt >= jmprel; iplt -= sizeof (Elf32_Rela))
|
||||
{
|
||||
|
||||
reloc = (const Elf32_Rela *) iplt;
|
||||
r_type = ELF32_R_TYPE (reloc->r_info);
|
||||
r_sym = ELF32_R_SYM (reloc->r_info);
|
||||
|
||||
/* Relocate all the PLT slots. */
|
||||
l_addr = l->l_addr;
|
||||
end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val;
|
||||
got = (Elf32_Addr *) (reloc->r_offset + l_addr + PLT_ENTRY_SIZE + SIZEOF_PLT_STUB);
|
||||
|
||||
/* If we aren't an IPLT, and we aren't NONE then it's a bad reloc */
|
||||
if (__builtin_expect (r_type != R_PARISC_IPLT, 0))
|
||||
{
|
||||
if (__builtin_expect (r_type != R_PARISC_NONE, 0))
|
||||
_dl_reloc_bad_type (l, r_type, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for the plt_stub that binutils placed here for us
|
||||
to use with _dl_runtime_resolve */
|
||||
if (got[-2] != sig.i[0] || got[-1] != sig.i[1])
|
||||
{
|
||||
got = NULL; /* Not the stub... keep looking */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Found the GOT! */
|
||||
register Elf32_Addr ltp __asm__ ("%r19");
|
||||
/* Identify this shared object. */
|
||||
got[1] = (Elf32_Addr) l;
|
||||
|
||||
/* This function will be called to perform the relocation. */
|
||||
if (__builtin_expect (!profile, 1))
|
||||
{
|
||||
/* If a static application called us, then _dl_runtime_resolve is not
|
||||
a function descriptor, but the *real* address of the function... */
|
||||
if((unsigned long) &_dl_runtime_resolve & 3)
|
||||
{
|
||||
got[-2] = (Elf32_Addr) ((struct fdesc *)
|
||||
((unsigned long) &_dl_runtime_resolve & ~3))->ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Static executable! */
|
||||
got[-2] = (Elf32_Addr) &_dl_runtime_resolve;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_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
|
||||
started. */
|
||||
GL(dl_profile_map) = l;
|
||||
}
|
||||
|
||||
if((unsigned long) &_dl_runtime_resolve & 3)
|
||||
{
|
||||
got[-2] = (Elf32_Addr) ((struct fdesc *)
|
||||
((unsigned long) &_dl_runtime_profile & ~3))->ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Static executable */
|
||||
got[-2] = (Elf32_Addr) &_dl_runtime_profile;
|
||||
}
|
||||
}
|
||||
/* Plunk in the gp of this function descriptor so we
|
||||
can make the call to _dl_runtime_xxxxxx */
|
||||
got[-1] = ltp;
|
||||
break;
|
||||
/* Done looking for the GOT, and stub is setup */
|
||||
} /* else we found the GOT */
|
||||
} /* for, walk the relocs backwards */
|
||||
|
||||
if(!got)
|
||||
return 0; /* No lazy linking for you! */
|
||||
|
||||
/* Process all the relocs, now that we know the GOT... */
|
||||
for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela))
|
||||
{
|
||||
const Elf32_Rela *reloc;
|
||||
Elf32_Word r_type;
|
||||
Elf32_Word r_sym;
|
||||
struct hppa_fptr *fptr;
|
||||
|
||||
reloc = (const Elf32_Rela *) iplt;
|
||||
r_type = ELF32_R_TYPE (reloc->r_info);
|
||||
r_sym = ELF32_R_SYM (reloc->r_info);
|
||||
|
||||
if (__builtin_expect (r_type == R_PARISC_IPLT, 1))
|
||||
{
|
||||
fptr = (struct hppa_fptr *) (reloc->r_offset + l_addr);
|
||||
fptr = (struct fdesc *) (reloc->r_offset + l_addr);
|
||||
if (r_sym != 0)
|
||||
{
|
||||
/* Relocate the pointer to the stub. */
|
||||
fptr->func += l_addr;
|
||||
fptr->ip = (Elf32_Addr) got - GOT_FROM_PLT_STUB;
|
||||
|
||||
/* Instead of the LTP value, we put the reloc offset
|
||||
here. The trampoline code will load the proper
|
||||
LTP and pass the reloc offset to the fixup
|
||||
function. */
|
||||
fptr->gp = iplt - jmprel;
|
||||
if (!got)
|
||||
{
|
||||
static union {
|
||||
unsigned char c[8];
|
||||
Elf32_Addr i[2];
|
||||
} sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}};
|
||||
|
||||
/* Find our .got section. It's right after the
|
||||
stub. */
|
||||
got = (Elf32_Addr *) (fptr->func + GOT_FROM_PLT_STUB);
|
||||
|
||||
/* Sanity check to see if the address we are
|
||||
going to check below is within a reasonable
|
||||
approximation of the bounds of the PLT (or,
|
||||
at least, is at an address that won't fault
|
||||
on read). Then check for the magic signature
|
||||
above. */
|
||||
if (fptr->func < (Elf32_Addr) fptr + sizeof(*fptr))
|
||||
return 0;
|
||||
if (fptr->func >
|
||||
((Elf32_Addr) fptr
|
||||
+ SIZEOF_PLT_STUB
|
||||
+ ((l->l_info[DT_PLTRELSZ]->d_un.d_val / sizeof (Elf32_Rela))
|
||||
* 8)))
|
||||
return 0;
|
||||
if (got[-2] != sig.i[0] || got[-1] != sig.i[1])
|
||||
return 0; /* No lazy linking for you! */
|
||||
}
|
||||
}
|
||||
} /* r_sym != 0 */
|
||||
else
|
||||
{
|
||||
/* Relocate this *ABS* entry. */
|
||||
fptr->func = reloc->r_addend + l_addr;
|
||||
fptr->ip = reloc->r_addend + l_addr;
|
||||
fptr->gp = D_PTR (l, l_info[DT_PLTGOT]);
|
||||
}
|
||||
}
|
||||
else if (__builtin_expect (r_type != R_PARISC_NONE, 0))
|
||||
_dl_reloc_bad_type (l, r_type, 1);
|
||||
}
|
||||
} /* r_type == R_PARISC_IPLT */
|
||||
} /* for all the relocations */
|
||||
} /* if lazy */
|
||||
else
|
||||
{
|
||||
for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela))
|
||||
{
|
||||
reloc = (const Elf32_Rela *) iplt;
|
||||
r_type = ELF32_R_TYPE (reloc->r_info);
|
||||
r_sym = ELF32_R_SYM (reloc->r_info);
|
||||
|
||||
if (got)
|
||||
{
|
||||
register Elf32_Addr ltp __asm__ ("%r19");
|
||||
/* Identify this shared object. */
|
||||
got[1] = (Elf32_Addr) l;
|
||||
|
||||
/* This function will be called to perform the relocation. */
|
||||
if (__builtin_expect (!profile, 1))
|
||||
got[-2] =
|
||||
(Elf32_Addr) ((struct hppa_fptr *)
|
||||
((unsigned long) &_dl_runtime_resolve & ~3))->func;
|
||||
else
|
||||
{
|
||||
if (_dl_name_match_p (GL(dl_profile), l))
|
||||
{
|
||||
/* This is the object we are looking for. Say that
|
||||
we really want profiling and the timers are
|
||||
started. */
|
||||
GL(dl_profile_map) = l;
|
||||
}
|
||||
got[-2] =
|
||||
(Elf32_Addr) ((struct hppa_fptr *)
|
||||
((unsigned long) &_dl_runtime_profile & ~3))->func;
|
||||
}
|
||||
got[-1] = ltp;
|
||||
}
|
||||
}
|
||||
if (__builtin_expect ((r_type == R_PARISC_IPLT) && (r_sym == 0), 1))
|
||||
{
|
||||
fptr = (struct fdesc *) (reloc->r_offset + l_addr);
|
||||
/* Relocate this *ABS* entry, set only the gp, the rest is set later
|
||||
when elf_machine_rela_relative is called (WITHOUT the linkmap) */
|
||||
fptr->gp = D_PTR (l, l_info[DT_PLTGOT]);
|
||||
} /* r_type == R_PARISC_IPLT */
|
||||
} /* for all the relocations */
|
||||
}
|
||||
return lazy;
|
||||
}
|
||||
|
||||
@ -251,7 +322,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||
|
||||
#define RTLD_START \
|
||||
/* Set up dp for any non-PIC lib constructors that may be called. */ \
|
||||
static struct link_map * \
|
||||
static struct link_map * __attribute__((used)) \
|
||||
set_dp (struct link_map *map) \
|
||||
{ \
|
||||
register Elf32_Addr dp asm ("%r27"); \
|
||||
@ -272,22 +343,24 @@ asm ( \
|
||||
" stw %r25,-40(%sp)\n" /* argc */ \
|
||||
" stw %r24,-44(%sp)\n" /* argv */ \
|
||||
\
|
||||
/* We need the LTP, and we need it now. */ \
|
||||
/* $PIC_pcrel$0 points 8 bytes past the current instruction, \
|
||||
just like a branch reloc. This sequence gets us the runtime \
|
||||
address of _DYNAMIC. */ \
|
||||
/* We need the LTP, and we need it now. \
|
||||
$PIC_pcrel$0 points 8 bytes past the current instruction, \
|
||||
just like a branch reloc. This sequence gets us the \
|
||||
runtime address of _DYNAMIC. */ \
|
||||
" bl 0f,%r19\n" \
|
||||
" depi 0,31,2,%r19\n" /* clear priviledge bits */ \
|
||||
"0: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%r19\n" \
|
||||
" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%r26\n" \
|
||||
\
|
||||
/* Also get the link time address from the first entry of the GOT. */ \
|
||||
/* The link time address is stored in the first entry of the \
|
||||
GOT. */ \
|
||||
" addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%r19\n" \
|
||||
" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r20\n" \
|
||||
\
|
||||
" sub %r26,%r20,%r20\n" /* Calculate load offset */ \
|
||||
\
|
||||
/* Rummage through the dynamic entries, looking for DT_PLTGOT. */ \
|
||||
/* Rummage through the dynamic entries, looking for \
|
||||
DT_PLTGOT. */ \
|
||||
" ldw,ma 8(%r26),%r19\n" \
|
||||
"1: cmpib,=,n 3,%r19,2f\n" /* tag == DT_PLTGOT? */ \
|
||||
" cmpib,<>,n 0,%r19,1b\n" \
|
||||
@ -307,8 +380,8 @@ asm ( \
|
||||
| 32 bytes of magic | \
|
||||
|---------------------------------| \
|
||||
| 32 bytes argument/sp save area | \
|
||||
|---------------------------------| ((current->mm->env_end) + 63 & ~63) \
|
||||
| N bytes of slack | \
|
||||
|---------------------------------| ((current->mm->env_end) \
|
||||
| N bytes of slack | + 63 & ~63) \
|
||||
|---------------------------------| \
|
||||
| envvar and arg strings | \
|
||||
|---------------------------------| \
|
||||
@ -354,7 +427,7 @@ asm ( \
|
||||
" ldw 0(%r20),%r20\n" \
|
||||
\
|
||||
" ldw -40(%sp),%r25\n" /* argc */ \
|
||||
" comib,= 0,%r20,.Lnofix\n" /* FIXME: will be mispredicted */ \
|
||||
" comib,= 0,%r20,.Lnofix\n" /* FIXME: Mispredicted branch */\
|
||||
" ldw -44(%sp),%r24\n" /* argv (delay slot) */ \
|
||||
\
|
||||
" sub %r25,%r20,%r25\n" \
|
||||
@ -376,7 +449,7 @@ asm ( \
|
||||
" bl _dl_init_internal,%r2\n" \
|
||||
" ldo 4(%r23),%r23\n" /* delay slot */ \
|
||||
\
|
||||
/* Reload argc, argv to the registers start.S expects them in (feh) */ \
|
||||
/* Reload argc, argv to the registers start.S expects. */ \
|
||||
" ldw -40(%sp),%r25\n" \
|
||||
" ldw -44(%sp),%r24\n" \
|
||||
\
|
||||
@ -388,8 +461,8 @@ asm ( \
|
||||
" .word 0xdeadbeef\n" \
|
||||
" .previous\n" \
|
||||
\
|
||||
/* %r3 contains a function pointer, we need to mask out the lower \
|
||||
* bits and load the gp and jump address. */ \
|
||||
/* %r3 contains a function pointer, we need to mask out the \
|
||||
lower bits and load the gp and jump address. */ \
|
||||
" depi 0,31,2,%r3\n" \
|
||||
" ldw 0(%r3),%r2\n" \
|
||||
" addil LT'__dl_fini_plabel,%r19\n" \
|
||||
@ -404,46 +477,57 @@ asm ( \
|
||||
/* 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 ( "\
|
||||
/* Trampoline for " #tramp_name " */ \n\
|
||||
.globl " #tramp_name " \n\
|
||||
.type " #tramp_name ",@function \n\
|
||||
" #tramp_name ": \n\
|
||||
/* Save return pointer */ \n\
|
||||
stw %r2,-20(%sp) \n\
|
||||
/* Save argument registers in the call stack frame. */ \n\
|
||||
stw %r26,-36(%sp) \n\
|
||||
stw %r25,-40(%sp) \n\
|
||||
stw %r24,-44(%sp) \n\
|
||||
stw %r23,-48(%sp) \n\
|
||||
/* Build a call frame. */ \n\
|
||||
stwm %sp,64(%sp) \n\
|
||||
\n\
|
||||
/* Set up args to fixup func. */ \n\
|
||||
ldw 8+4(%r20),%r26 /* got[1] == struct link_map * */ \n\
|
||||
copy %r19,%r25 /* reloc offset */ \n\
|
||||
\n\
|
||||
/* Call the real address resolver. */ \n\
|
||||
bl " #fixup_name ",%r2 \n\
|
||||
copy %r21,%r19 /* delay slot, set fixup func ltp */ \n\
|
||||
\n\
|
||||
ldwm -64(%sp),%sp \n\
|
||||
/* Arguments. */ \n\
|
||||
ldw -36(%sp),%r26 \n\
|
||||
ldw -40(%sp),%r25 \n\
|
||||
ldw -44(%sp),%r24 \n\
|
||||
ldw -48(%sp),%r23 \n\
|
||||
/* Return pointer. */ \n\
|
||||
ldw -20(%sp),%r2 \n\
|
||||
/* Call the real function. */ \n\
|
||||
ldw 0(%r28),%r22 \n\
|
||||
bv %r0(%r22) \n\
|
||||
ldw 4(%r28),%r19 \n\
|
||||
");
|
||||
|
||||
#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" \
|
||||
/* 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" \
|
||||
);
|
||||
|
||||
#ifndef PROF
|
||||
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
|
||||
TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
|
||||
@ -454,7 +538,6 @@ asm ( \
|
||||
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_NOCOPY iff TYPE should not be allowed to resolve to one
|
||||
@ -464,22 +547,35 @@ asm ( \
|
||||
* ELF_RTYPE_CLASS_PLT) \
|
||||
| (((type) == R_PARISC_COPY) * ELF_RTYPE_CLASS_COPY))
|
||||
|
||||
/* Used by ld.so for ... something ... */
|
||||
/* Used by the runtime in fixup to figure out if reloc is *really* PLT */
|
||||
#define ELF_MACHINE_JMP_SLOT R_PARISC_IPLT
|
||||
#define ELF_MACHINE_SIZEOF_JMP_SLOT PLT_ENTRY_SIZE
|
||||
|
||||
/* We only use RELA. */
|
||||
#define ELF_MACHINE_NO_REL 1
|
||||
|
||||
/* Return the address of the entry point. */
|
||||
#define ELF_MACHINE_START_ADDRESS(map, start) \
|
||||
DL_FUNCTION_ADDRESS (map, start)
|
||||
DL_STATIC_FUNCTION_ADDRESS (map, start)
|
||||
|
||||
/* We define an initialization functions. This is called very early in
|
||||
* _dl_sysdep_start. */
|
||||
#define DL_PLATFORM_INIT dl_platform_init ()
|
||||
|
||||
static inline void __attribute__ ((unused))
|
||||
dl_platform_init (void)
|
||||
{
|
||||
if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
|
||||
/* Avoid an empty string which would disturb us. */
|
||||
GLRO(dl_platform) = NULL;
|
||||
}
|
||||
|
||||
#endif /* !dl_machine_h */
|
||||
|
||||
/* These are only actually used where RESOLVE_MAP is defined, anyway. */
|
||||
#ifdef RESOLVE_MAP
|
||||
|
||||
static inline void
|
||||
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,
|
||||
void *const reloc_addr_arg)
|
||||
@ -490,14 +586,14 @@ 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 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)
|
||||
because rtld.c contains the common defn for _dl_rtld_map, which is
|
||||
incompatible with a weak decl in the same file. */
|
||||
weak_extern (GL(dl_rtld_map));
|
||||
#endif
|
||||
# endif
|
||||
|
||||
/* RESOLVE_MAP will return a null value for undefined syms, and
|
||||
non-null for all other syms. In particular, relocs with no
|
||||
@ -505,13 +601,13 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
resolved to MAP. (The first entry in a symbol table is all
|
||||
zeros, and an all zero Elf32_Sym has a binding of STB_LOCAL.)
|
||||
See RESOLVE_MAP definition in elf/dl-reloc.c */
|
||||
#ifdef RTLD_BOOTSTRAP
|
||||
# ifdef RTLD_BOOTSTRAP
|
||||
/* RESOLVE_MAP in rtld.c doesn't have the local sym test. */
|
||||
sym_map = (ELF32_ST_BIND (sym->st_info) != STB_LOCAL
|
||||
? RESOLVE_MAP (&sym, version, r_type) : map);
|
||||
#else
|
||||
# else
|
||||
sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||
#endif
|
||||
# endif
|
||||
if (sym_map)
|
||||
{
|
||||
value = sym ? sym_map->l_addr + sym->st_value : 0;
|
||||
@ -523,15 +619,6 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
switch (r_type)
|
||||
{
|
||||
case R_PARISC_DIR32:
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
/* All hell breaks loose if we try to relocate these twice,
|
||||
because any initialized variables in ld.so that refer to
|
||||
other ones will have their values reset. In particular,
|
||||
__fptr_next will be reset, sometimes causing endless loops in
|
||||
__hppa_make_fptr(). So don't do that. */
|
||||
if (map == &GL(dl_rtld_map))
|
||||
return;
|
||||
#endif
|
||||
/* .eh_frame can have unaligned relocs. */
|
||||
if ((unsigned long) reloc_addr_arg & 3)
|
||||
{
|
||||
@ -552,51 +639,26 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
if (sym == NULL
|
||||
|| sym_map == NULL
|
||||
|| ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
|
||||
break;
|
||||
|
||||
/* Okay, we need to make ourselves a PLABEL then. See the IA64
|
||||
code for an explanation of how this works. */
|
||||
#ifndef RTLD_BOOTSTRAP
|
||||
value = __hppa_make_fptr (sym_map, value, &__fptr_root, NULL);
|
||||
#else
|
||||
{
|
||||
struct hppa_fptr *p_boot_ldso_fptr;
|
||||
struct hppa_fptr **p_fptr_root;
|
||||
int *p_fptr_count;
|
||||
unsigned long dot;
|
||||
|
||||
/* Go from the top of __boot_ldso_fptr. As on IA64, we
|
||||
probably haven't relocated the necessary values by this
|
||||
point so we have to find them ourselves. */
|
||||
|
||||
asm ("bl 0f,%0 \n\
|
||||
depi 0,31,2,%0 \n\
|
||||
0: addil L'__boot_ldso_fptr - ($PIC_pcrel$0 - 8),%0 \n\
|
||||
ldo R'__boot_ldso_fptr - ($PIC_pcrel$0 - 12)(%%r1),%1 \n\
|
||||
addil L'__fptr_root - ($PIC_pcrel$0 - 16),%0 \n\
|
||||
ldo R'__fptr_root - ($PIC_pcrel$0 - 20)(%%r1),%2 \n\
|
||||
addil L'__fptr_count - ($PIC_pcrel$0 - 24),%0 \n\
|
||||
ldo R'__fptr_count - ($PIC_pcrel$0 - 28)(%%r1),%3"
|
||||
:
|
||||
"=r" (dot),
|
||||
"=r" (p_boot_ldso_fptr),
|
||||
"=r" (p_fptr_root),
|
||||
"=r" (p_fptr_count));
|
||||
|
||||
value = __hppa_make_fptr (sym_map, value, p_fptr_root,
|
||||
&p_boot_ldso_fptr[--*p_fptr_count]);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
break;
|
||||
}
|
||||
/* Set bit 30 to indicate to $$dyncall that this is a PLABEL.
|
||||
We have to do this outside of the generic function descriptor
|
||||
code, since it doesn't know about our requirement for setting
|
||||
protection bits */
|
||||
value = (Elf32_Addr)((unsigned int)_dl_make_fptr (sym_map, sym, value) | 2);
|
||||
break;
|
||||
|
||||
case R_PARISC_IPLT:
|
||||
if (__builtin_expect (sym_map != NULL, 1))
|
||||
elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr, value);
|
||||
else
|
||||
{
|
||||
{
|
||||
elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we get here, it's a (weak) undefined sym. */
|
||||
elf_machine_fixup_plt (NULL, map, reloc, reloc_addr, value);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case R_PARISC_COPY:
|
||||
@ -606,20 +668,20 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
break;
|
||||
if (__builtin_expect (sym->st_size > refsym->st_size, 0)
|
||||
|| (__builtin_expect (sym->st_size < refsym->st_size, 0)
|
||||
&& __builtin_expect (GL(dl_verbose), 0)))
|
||||
&& __builtin_expect (GLRO(dl_verbose), 0)))
|
||||
{
|
||||
const char *strtab;
|
||||
|
||||
strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
_dl_error_printf ("\
|
||||
%s: Symbol `%s' has different size in shared object, consider re-linking\n",
|
||||
_dl_error_printf ("%s: Symbol `%s' has different size in shared object, "
|
||||
"consider re-linking\n",
|
||||
rtld_progname ?: "<program name unknown>",
|
||||
strtab + refsym->st_name);
|
||||
}
|
||||
memcpy (reloc_addr_arg, (void *) value,
|
||||
MIN (sym->st_size, refsym->st_size));
|
||||
return;
|
||||
|
||||
|
||||
case R_PARISC_NONE: /* Alright, Wilbur. */
|
||||
return;
|
||||
|
||||
@ -630,25 +692,27 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||
*reloc_addr = value;
|
||||
}
|
||||
|
||||
#define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \
|
||||
elf_machine_rel_relative (map, l_addr, relative, \
|
||||
(void *) (l_addr + relative->r_offset))
|
||||
|
||||
/* hppa doesn't have an R_PARISC_RELATIVE reloc, but uses relocs with
|
||||
ELF32_R_SYM (info) == 0 for a similar purpose. */
|
||||
static inline void
|
||||
elf_machine_rela_relative (struct link_map *map, Elf32_Addr l_addr,
|
||||
auto void __attribute__((always_inline))
|
||||
elf_machine_rela_relative (Elf32_Addr l_addr,
|
||||
const Elf32_Rela *reloc,
|
||||
void *const reloc_addr_arg)
|
||||
{
|
||||
Elf32_Addr *const reloc_addr = reloc_addr_arg;
|
||||
unsigned long const r_type = ELF32_R_TYPE (reloc->r_info);
|
||||
Elf32_Addr *const reloc_addr = reloc_addr_arg;
|
||||
static char msgbuf[] = { "Unknown" };
|
||||
struct link_map map;
|
||||
Elf32_Addr value;
|
||||
|
||||
value = l_addr + reloc->r_addend;
|
||||
|
||||
if (ELF32_R_SYM (reloc->r_info) != 0)
|
||||
asm volatile ("iitlbp %r0,(%r0)"); /* Crash. */
|
||||
if (ELF32_R_SYM (reloc->r_info) != 0){
|
||||
_dl_error_printf ("%s: In elf_machine_rela_relative "
|
||||
"ELF32_R_SYM (reloc->r_info) != 0. Aborting.",
|
||||
rtld_progname ?: "<program name unknown>");
|
||||
ABORT_INSTRUCTION; /* Crash. */
|
||||
}
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
@ -668,21 +732,22 @@ elf_machine_rela_relative (struct link_map *map, Elf32_Addr l_addr,
|
||||
case R_PARISC_PLABEL32:
|
||||
break;
|
||||
|
||||
case R_PARISC_IPLT:
|
||||
elf_machine_fixup_plt (NULL, map, reloc, reloc_addr, value);
|
||||
return;
|
||||
case R_PARISC_IPLT: /* elf_machine_runtime_setup already set gp */
|
||||
break;
|
||||
|
||||
case R_PARISC_NONE:
|
||||
return;
|
||||
|
||||
default:
|
||||
_dl_reloc_bad_type (map, r_type, 0);
|
||||
default: /* Bad reloc, map unknown (really it's the current map) */
|
||||
map.l_name = msgbuf;
|
||||
_dl_reloc_bad_type (&map, r_type, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
*reloc_addr = value;
|
||||
}
|
||||
|
||||
static inline void
|
||||
auto void __attribute__((always_inline))
|
||||
elf_machine_lazy_rel (struct link_map *map,
|
||||
Elf32_Addr l_addr, const Elf32_Rela *reloc)
|
||||
{
|
||||
|
@ -27,11 +27,10 @@ feupdateenv (const fenv_t *envp)
|
||||
|
||||
/* Get the current exception status. */
|
||||
__asm__ ("fstd %%fr0,0(%1)" : "=m" (*sw) : "r" (sw));
|
||||
sw[0] &= FE_ALL_EXCEPT;
|
||||
envp->__status_word = envp->__status_word | sw[0];
|
||||
|
||||
/* Install new environment. */
|
||||
fesetenv (envp);
|
||||
/* Raise the saved exceptions */
|
||||
feraiseexcept(sw[0] & FE_ALL_EXCEPT);
|
||||
|
||||
/* Success. */
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user