summaryrefslogtreecommitdiffstats
path: root/recipes/glibc/glibc-2.3.2/glibc23-01-hppa-dl-machine.patch
blob: f5f02d19927aaec7d056c44eaca8db2e38aa0f96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
--- 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 +412,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 +571,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),