[parisc-linux] [PATCH] Fixup dl-machine for HPPA
Carlos O'Donell
carlos@baldric.uwo.ca
Tue, 19 Nov 2002 01:06:42 -0500
--l5oECiFRo5dp+2y7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
libc-alpha,
The following fixes dl-machine.h for hppa.
These fixes have been in debian-glibc for a long time
and have received heavy testing.
Cheers,
Carlos.
Round 2...
sysdeps/hppa/dl-machine.h | 193 +++++++++++++++++++++++++++++------------------------------
1 files changed, 97 insertions(+), 96 deletions(-)
--
2000-07-31 David Huggins-Daines <dhd@debian.org>
* sysdeps/hppa/dl-machine.h:
Cleanup assembly, define VALID_ELF_*,
(elf_machine_dynamic): Cleanup assembly.
(elf_machine_load_address): Likewise.
(elf_machine_runtime_setup): Fix relocations.
(set_dp): Cleanup assembly.
(elf_machine_rela): Likewise.
--l5oECiFRo5dp+2y7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=01-glibc23-hppa-dl-machine
diff -urN libc/sysdeps/hppa/dl-machine.h libc/sysdeps/hppa/dl-machine.h
--- libc/sysdeps/hppa/dl-machine.h Wed Nov 14 09:47:09 2001
+++ libc/sysdeps/hppa/dl-machine.h Wed Nov 14 09:46:02 2001
@@ -28,8 +28,15 @@
#include <link.h>
#include <assert.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 must match the definition of the stub in bfd/elf32-hppa.c. */
-#define SIZEOF_PLT_STUB (4*4)
+#define SIZEOF_PLT_STUB (7*4)
#define GOT_FROM_PLT_STUB (4*4)
/* A PLABEL is a function descriptor. Properly they consist of just
@@ -66,45 +73,41 @@
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. */
@@ -167,41 +170,39 @@
fptr = (struct hppa_fptr *) (reloc->r_offset + l_addr);
if (r_sym != 0)
{
- /* Relocate the pointer to the stub. */
- fptr->func += l_addr;
- /* 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}};
+ const Elf32_Rela *last_rel;
+
+ last_rel = (const Elf32_Rela *) end_jmprel - 1;
+
+ /* The stub is immediately after the last .plt
+ entry. Rely on .plt relocs being ordered. */
+ if (last_rel->r_offset == 0)
+ return 0;
/* Find our .got section. It's right after the
stub. */
- got = (Elf32_Addr *) (fptr->func + GOT_FROM_PLT_STUB);
+ got = (Elf32_Addr *) (last_rel->r_offset + l_addr
+ + 8 + SIZEOF_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;
+ /* Check the magic signature. */
if (got[-2] != sig.i[0] || got[-1] != sig.i[1])
return 0; /* No lazy linking for you! */
}
+
+ /* Relocate the pointer to the stub. */
+ fptr->func = (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;
}
else
{
@@ -271,22 +272,24 @@
" 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" \
@@ -306,8 +309,8 @@
| 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 | \
|---------------------------------| \
@@ -375,7 +378,7 @@
" bl _dl_init,%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" \
\
@@ -387,8 +390,8 @@
" .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" \
@@ -409,43 +409,41 @@
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\
-");
-
+ asm (".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" /* got[1] == struct link_map * */ \
+ " copy %r19,%r25\n" /* reloc offset */ \
+ \
+ /* Call the real address resolver. */ \
+ " bl " #fixup_name ",%r2\n" \
+ " copy %r21,%r19\n" /* delay slot, set fixup func ltp */ \
+ \
+ " 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); \
@@ -570,15 +568,15 @@
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"
- :
+ asm ("bl 0f,%0\n\t"
+ "depi 0,31,2,%0\n\t"
+ "0:\taddil L'__boot_ldso_fptr - ($PIC_pcrel$0 - 8),%0\n\t"
+ "ldo R'__boot_ldso_fptr - ($PIC_pcrel$0 - 12)(%%r1),%1\n\t"
+ "addil L'__fptr_root - ($PIC_pcrel$0 - 16),%0\n\t"
+ "ldo R'__fptr_root - ($PIC_pcrel$0 - 20)(%%r1),%2\n\t"
+ "addil L'__fptr_count - ($PIC_pcrel$0 - 24),%0\n\t"
+ "ldo R'__fptr_count - ($PIC_pcrel$0 - 28)(%%r1),%3"
+ :
"=r" (dot),
"=r" (p_boot_ldso_fptr),
"=r" (p_fptr_root),
--l5oECiFRo5dp+2y7--