aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-04-17 22:57:01 +0000
committerUlrich Drepper <drepper@redhat.com>2004-04-17 22:57:01 +0000
commit69ac9d0793dd675cf49fa3ce6796a0dce227c076 (patch)
tree6e57d02cf5268af95afdef4012fa0379332285c0
parent5339290658a4c9e8c8d9e6d95ae27705fdd59c10 (diff)
downloadglibc-69ac9d0793dd675cf49fa3ce6796a0dce227c076.tar.xz
glibc-69ac9d0793dd675cf49fa3ce6796a0dce227c076.zip
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.
-rw-r--r--ChangeLog57
-rw-r--r--gmon/gmon.c2
-rw-r--r--localedata/ChangeLog1
-rw-r--r--sysdeps/hppa/Dist2
-rw-r--r--sysdeps/hppa/bits/link.h6
-rw-r--r--sysdeps/hppa/dl-machine.h575
-rw-r--r--sysdeps/hppa/fpu/feupdateenv.c5
7 files changed, 389 insertions, 259 deletions
diff --git a/ChangeLog b/ChangeLog
index 373b4b2ce2..f20ed56998 100644
--- a/ChangeLog
+++ b/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>
diff --git a/gmon/gmon.c b/gmon/gmon.c
index 407993d571..dd4ee3a79d 100644
--- a/gmon/gmon.c
+++ b/gmon/gmon.c
@@ -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
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index c0ad189e0b..ec63b75cf1 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -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.
diff --git a/sysdeps/hppa/Dist b/sysdeps/hppa/Dist
index e26e411bc5..5a0df47c68 100644
--- a/sysdeps/hppa/Dist
+++ b/sysdeps/hppa/Dist
@@ -1,3 +1,5 @@
libgcc-compat.c
dl-symaddr.c
dl-fptr.c
+bits/link.h
+elf/entry.h
diff --git a/sysdeps/hppa/bits/link.h b/sysdeps/hppa/bits/link.h
new file mode 100644
index 0000000000..54842b2299
--- /dev/null
+++ b/sysdeps/hppa/bits/link.h
@@ -0,0 +1,6 @@
+/* Used to store the function descriptor table */
+struct link_map_machine
+ {
+ size_t fptr_table_len;
+ ElfW(Addr) *fptr_table;
+ };
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
index cd180e7f76..bc9ed107b8 100644
--- a/sysdeps/hppa/dl-machine.h
+++ b/sysdeps/hppa/dl-machine.h
@@ -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>
-
-/* These must match the definition of the stub in bfd/elf32-hppa.c. */
-#define SIZEOF_PLT_STUB (4*4)
+#include <errno.h>
+#include <dl-fptr.h>
+#include <abort-instr.h>
+
+# 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;
+
+ /* Careful: this will be called before got has been relocated... */
+ ELF_MACHINE_LOAD_ADDRESS(boot_table,_dl_boot_fptr_table);
-extern struct hppa_fptr __boot_ldso_fptr[];
-extern struct hppa_fptr *__fptr_root;
-extern int __fptr_count;
+ map->l_mach.fptr_table_len = ELF_MACHINE_BOOT_FPTR_TABLE_LEN;
+ map->l_mach.fptr_table = boot_table;
+}
-extern Elf32_Addr __hppa_make_fptr (const struct link_map *, Elf32_Addr,
- struct hppa_fptr **, struct hppa_fptr *);
+#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;
-
- /* Relocate all the PLT slots. */
- l_addr = l->l_addr;
- end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val;
+ /* 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);
+
+ 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);
- }
-
- 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;
- }
- }
+ } /* 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 (__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,=