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. I hope this is a much easier patch to digest; my apologies about the size of the previous patch. For those who follow the debian patchset, this was previously incorported into the pthreads patch. Cheers, Carlos. --- 2002-09-19 Carlos O'Donell <[EMAIL PROTECTED]> 2000-07-31 David Huggins-Daines <[EMAIL PROTECTED]> * 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.
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),