1 --- libc/sysdeps/hppa/dl-machine.h Wed Nov 14 09:47:09 2001
2 +++ libc/sysdeps/hppa/dl-machine.h Wed Nov 14 09:46:02 2001
7 +# define VALID_ELF_OSABI(osabi) ((osabi == ELFOSABI_SYSV) || (osabi == ELFOSABI_LINUX))
8 +# define VALID_ELF_ABIVERSION(ver) (ver == 0)
9 +# define VALID_ELF_HEADER(hdr,exp,size) \
10 + memcmp (hdr,exp,size-2) == 0 \
11 + && VALID_ELF_OSABI (hdr[EI_OSABI]) \
12 + && VALID_ELF_ABIVERSION (hdr[EI_ABIVERSION])
14 /* These must match the definition of the stub in bfd/elf32-hppa.c. */
15 -#define SIZEOF_PLT_STUB (4*4)
16 +#define SIZEOF_PLT_STUB (7*4)
17 #define GOT_FROM_PLT_STUB (4*4)
19 /* A PLABEL is a function descriptor. Properly they consist of just
21 return ehdr->e_machine == EM_PARISC;
25 /* Return the link-time address of _DYNAMIC. */
26 static inline Elf32_Addr
27 +elf_machine_dynamic (void) __attribute__ ((const));
29 +static inline Elf32_Addr
30 elf_machine_dynamic (void)
35 - /* Use this method if GOT address not yet set up. */
40 "1: addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8),%0\n"
41 " ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
42 - : "=r" (dynamic) : : "r1");
44 - /* This works because we already have our GOT address available. */
45 - dynamic = (Elf32_Addr) &_DYNAMIC;
47 + : "=r" (dynamic) : : "r1");
52 /* Return the run-time load address of the shared object. */
53 static inline Elf32_Addr
54 +elf_machine_load_address (void) __attribute__ ((const));
56 +static inline Elf32_Addr
57 elf_machine_load_address (void)
59 - Elf32_Addr dynamic, dynamic_linkaddress;
65 "1: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%0\n"
66 -" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%1\n"
67 -" addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%0\n"
68 -" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%%r1),%0\n"
69 - : "=r" (dynamic_linkaddress), "=r" (dynamic) : : "r1");
70 +" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
71 + : "=r" (dynamic) : : "r1");
73 - return dynamic - dynamic_linkaddress;
74 + return dynamic - elf_machine_dynamic ();
77 /* Fixup a PLT entry to bounce directly to the function at VALUE. */
79 fptr = (struct hppa_fptr *) (reloc->r_offset + l_addr);
82 - /* Relocate the pointer to the stub. */
83 - fptr->func += l_addr;
84 - /* Instead of the LTP value, we put the reloc offset
85 - here. The trampoline code will load the proper
86 - LTP and pass the reloc offset to the fixup
88 - fptr->gp = iplt - jmprel;
94 } sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}};
95 + const Elf32_Rela *last_rel;
97 + last_rel = (const Elf32_Rela *) end_jmprel - 1;
99 + /* The stub is immediately after the last .plt
100 + entry. Rely on .plt relocs being ordered. */
101 + if (last_rel->r_offset == 0)
104 /* Find our .got section. It's right after the
106 - got = (Elf32_Addr *) (fptr->func + GOT_FROM_PLT_STUB);
107 + got = (Elf32_Addr *) (last_rel->r_offset + l_addr
108 + + 8 + SIZEOF_PLT_STUB);
110 - /* Sanity check to see if the address we are
111 - going to check below is within a reasonable
112 - approximation of the bounds of the PLT (or,
113 - at least, is at an address that won't fault
114 - on read). Then check for the magic signature
116 - if (fptr->func < (Elf32_Addr) fptr + sizeof(*fptr))
121 - + ((l->l_info[DT_PLTRELSZ]->d_un.d_val / sizeof (Elf32_Rela))
124 + /* Check the magic signature. */
125 if (got[-2] != sig.i[0] || got[-1] != sig.i[1])
126 return 0; /* No lazy linking for you! */
129 + /* Relocate the pointer to the stub. */
130 + fptr->func = (Elf32_Addr) got - GOT_FROM_PLT_STUB;
132 + /* Instead of the LTP value, we put the reloc offset
133 + here. The trampoline code will load the proper
134 + LTP and pass the reloc offset to the fixup
136 + fptr->gp = iplt - jmprel;
140 @@ -271,22 +272,24 @@
141 " stw %r25,-40(%sp)\n" /* argc */ \
142 " stw %r24,-44(%sp)\n" /* argv */ \
144 - /* We need the LTP, and we need it now. */ \
145 - /* $PIC_pcrel$0 points 8 bytes past the current instruction, \
146 - just like a branch reloc. This sequence gets us the runtime \
147 - address of _DYNAMIC. */ \
148 + /* We need the LTP, and we need it now. \
149 + $PIC_pcrel$0 points 8 bytes past the current instruction, \
150 + just like a branch reloc. This sequence gets us the \
151 + runtime address of _DYNAMIC. */ \
153 " depi 0,31,2,%r19\n" /* clear priviledge bits */ \
154 "0: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%r19\n" \
155 " ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%r26\n" \
157 - /* Also get the link time address from the first entry of the GOT. */ \
158 + /* The link time address is stored in the first entry of the \
160 " addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%r19\n" \
161 " ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r20\n" \
163 " sub %r26,%r20,%r20\n" /* Calculate load offset */ \
165 - /* Rummage through the dynamic entries, looking for DT_PLTGOT. */ \
166 + /* Rummage through the dynamic entries, looking for \
168 " ldw,ma 8(%r26),%r19\n" \
169 "1: cmpib,=,n 3,%r19,2f\n" /* tag == DT_PLTGOT? */ \
170 " cmpib,<>,n 0,%r19,1b\n" \
172 | 32 bytes of magic | \
173 |---------------------------------| \
174 | 32 bytes argument/sp save area | \
175 - |---------------------------------| ((current->mm->env_end) + 63 & ~63) \
176 - | N bytes of slack | \
177 + |---------------------------------| ((current->mm->env_end) \
178 + | N bytes of slack | + 63 & ~63) \
179 |---------------------------------| \
180 | envvar and arg strings | \
181 |---------------------------------| \
183 " bl _dl_init,%r2\n" \
184 " ldo 4(%r23),%r23\n" /* delay slot */ \
186 - /* Reload argc, argv to the registers start.S expects them in (feh) */ \
187 + /* Reload argc, argv to the registers start.S expects. */ \
188 " ldw -40(%sp),%r25\n" \
189 " ldw -44(%sp),%r24\n" \
192 " .word 0xdeadbeef\n" \
195 - /* %r3 contains a function pointer, we need to mask out the lower \
196 - * bits and load the gp and jump address. */ \
197 + /* %r3 contains a function pointer, we need to mask out the \
198 + lower bits and load the gp and jump address. */ \
199 " depi 0,31,2,%r3\n" \
200 " ldw 0(%r3),%r2\n" \
201 " addil LT'__dl_fini_plabel,%r19\n" \
202 @@ -409,43 +412,41 @@
203 Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp. */
204 #define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
205 extern void tramp_name (void); \
207 - /* Trampoline for " #tramp_name " */ \n\
208 - .globl " #tramp_name " \n\
209 - .type " #tramp_name ",@function \n\
210 -" #tramp_name ": \n\
211 - /* Save return pointer */ \n\
212 - stw %r2,-20(%sp) \n\
213 - /* Save argument registers in the call stack frame. */ \n\
214 - stw %r26,-36(%sp) \n\
215 - stw %r25,-40(%sp) \n\
216 - stw %r24,-44(%sp) \n\
217 - stw %r23,-48(%sp) \n\
218 - /* Build a call frame. */ \n\
219 - stwm %sp,64(%sp) \n\
221 - /* Set up args to fixup func. */ \n\
222 - ldw 8+4(%r20),%r26 /* got[1] == struct link_map * */ \n\
223 - copy %r19,%r25 /* reloc offset */ \n\
225 - /* Call the real address resolver. */ \n\
226 - bl " #fixup_name ",%r2 \n\
227 - copy %r21,%r19 /* delay slot, set fixup func ltp */ \n\
229 - ldwm -64(%sp),%sp \n\
230 - /* Arguments. */ \n\
231 - ldw -36(%sp),%r26 \n\
232 - ldw -40(%sp),%r25 \n\
233 - ldw -44(%sp),%r24 \n\
234 - ldw -48(%sp),%r23 \n\
235 - /* Return pointer. */ \n\
236 - ldw -20(%sp),%r2 \n\
237 - /* Call the real function. */ \n\
238 - ldw 0(%r28),%r22 \n\
240 - ldw 4(%r28),%r19 \n\
243 + asm (".globl " #tramp_name "\n" \
244 + " .type " #tramp_name ",@function\n" \
245 + #tramp_name ":\n" \
246 + /* Save return pointer */ \
247 + " stw %r2,-20(%sp)\n" \
248 + /* Save argument registers in the call stack frame. */ \
249 + " stw %r26,-36(%sp)\n" \
250 + " stw %r25,-40(%sp)\n" \
251 + " stw %r24,-44(%sp)\n" \
252 + " stw %r23,-48(%sp)\n" \
253 + /* Build a call frame, and save structure pointer. */ \
254 + " stwm %r28,64(%sp)\n" \
256 + /* Set up args to fixup func. */ \
257 + " ldw 8+4(%r20),%r26\n" /* got[1] == struct link_map * */ \
258 + " copy %r19,%r25\n" /* reloc offset */ \
260 + /* Call the real address resolver. */ \
261 + " bl " #fixup_name ",%r2\n" \
262 + " copy %r21,%r19\n" /* delay slot, set fixup func ltp */ \
264 + " ldw 0(%r28),%r22\n" /* load up the returned func ptr */ \
265 + " ldw 4(%r28),%r19\n" \
266 + " ldwm -64(%sp),%r28\n" \
268 + " ldw -36(%sp),%r26\n" \
269 + " ldw -40(%sp),%r25\n" \
270 + " ldw -44(%sp),%r24\n" \
271 + " ldw -48(%sp),%r23\n" \
272 + /* Call the real function. */ \
273 + " bv %r0(%r22)\n" \
274 + /* Return pointer. */ \
275 + " ldw -20(%sp),%r2\n" \
279 #define ELF_MACHINE_RUNTIME_TRAMPOLINE \
280 TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
281 @@ -570,15 +571,15 @@
282 probably haven't relocated the necessary values by this
283 point so we have to find them ourselves. */
287 -0: addil L'__boot_ldso_fptr - ($PIC_pcrel$0 - 8),%0 \n\
288 - ldo R'__boot_ldso_fptr - ($PIC_pcrel$0 - 12)(%%r1),%1 \n\
289 - addil L'__fptr_root - ($PIC_pcrel$0 - 16),%0 \n\
290 - ldo R'__fptr_root - ($PIC_pcrel$0 - 20)(%%r1),%2 \n\
291 - addil L'__fptr_count - ($PIC_pcrel$0 - 24),%0 \n\
292 - ldo R'__fptr_count - ($PIC_pcrel$0 - 28)(%%r1),%3"
294 + asm ("bl 0f,%0\n\t"
295 + "depi 0,31,2,%0\n\t"
296 + "0:\taddil L'__boot_ldso_fptr - ($PIC_pcrel$0 - 8),%0\n\t"
297 + "ldo R'__boot_ldso_fptr - ($PIC_pcrel$0 - 12)(%%r1),%1\n\t"
298 + "addil L'__fptr_root - ($PIC_pcrel$0 - 16),%0\n\t"
299 + "ldo R'__fptr_root - ($PIC_pcrel$0 - 20)(%%r1),%2\n\t"
300 + "addil L'__fptr_count - ($PIC_pcrel$0 - 24),%0\n\t"
301 + "ldo R'__fptr_count - ($PIC_pcrel$0 - 28)(%%r1),%3"
304 "=r" (p_boot_ldso_fptr),