Package: glibc / 2.24-11+deb9u4

hppa/submitted-gmon-start.diff Patch series | download
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
2015-11-15  Helge Deller  <deller@gmx.de>
	    John David Anglin  <danglin@gcc.gnu.org>

	PR libc/19170
	* sysdeps/hppa/crti.S (gmon_initializer): New.  Use .init_array support
	to call gmon_initializer.  Only call __gmon_start__ when symbol is
	defined at runtime.
	* sysdeps/hppa/crtn.S (__gmon_start__): Delete.
	* sysdeps/hppa/dl-lookupcfg.h (DL_FIXUP_MAKE_VALUE): Provide null
	function descriptor when MAP argument is null.
	* sysdeps/hppa/dl-trampoline.S (_dl_runtime_resolve): Return directly
	to previous function when function is undefined.

diff --git a/sysdeps/hppa/crti.S b/sysdeps/hppa/crti.S
index 98f1af5..568a999 100644
--- a/sysdeps/hppa/crti.S
+++ b/sysdeps/hppa/crti.S
@@ -49,6 +49,95 @@
 # define PREINIT_FUNCTION_WEAK 1
 #endif
 
+#if PREINIT_FUNCTION_WEAK
+	weak_extern (PREINIT_FUNCTION)
+#else
+	.hidden PREINIT_FUNCTION
+#endif
+
+
+/* If we have working .init_array support, we want to keep the .init
+   section empty (apart from the mandatory prologue/epilogue.  This
+   ensures that the default unwind conventions (return-pointer in b0,
+   frame state in ar.pfs, etc.)  will do the Right Thing.  To ensure
+   an empty .init section, we register gmon_initializer() via the
+   .init_array.
+
+    --davidm 02/10/29 */
+
+#if PREINIT_FUNCTION_WEAK
+/* This blob of assembly code is one simple C function:
+
+static void
+__attribute__ ((used))
+gmon_initializer (void)
+{
+  extern void weak_function __gmon_start__ (void);
+
+  if (__gmon_start__)
+    (*__gmon_start__)();
+}
+
+In a final executable, PLABEL32 relocations for function pointers are
+resolved at link time.  Typically, binutils/ld resolves __gmon_start__
+using an external shared library.  __gmon_start__ is always called if
+it is found at link time.  If __gmon_start__ is not found at runtime
+due to a library update, then the function pointer will point at a null
+function descriptor and calling it will cause a segmentation fault.
+So, we call __canonicalize_funcptr_for_compare to obtain the canonicalized
+address of __gmon_start__ and skip calling __gmon_start__ if it is zero.
+
+ */
+	.type __canonicalize_funcptr_for_compare,@function
+	.type $$dyncall,@function
+
+	.section .data.rel.ro,"aw",@progbits
+	.align 4
+.LC0:
+	.type __gmon_start__,@function
+	.word P%__gmon_start__
+
+	.text
+	.align 4
+	.type gmon_initializer,@function
+gmon_initializer:
+	.PROC
+	.CALLINFO FRAME=64,CALLS,SAVE_RP,ENTRY_GR=4
+	.ENTRY
+	stw %r2,-20(%r30)
+	stwm %r4,64(%r30)
+	stw %r3,-60(%r30)
+	addil LT'.LC0,%r19
+	ldw RT'.LC0(%r1),%r28
+	ldw 0(%r28),%r3
+	comib,= 0,%r3,1f
+	copy %r19,%r4
+	stw %r19,-32(%r30)
+	bl __canonicalize_funcptr_for_compare,%r2
+	copy %r3,%r26
+	comib,= 0,%r28,1f
+	copy %r4,%r19
+	copy %r3,%r22
+	.CALL ARGW0=GR
+	bl $$dyncall,%r31
+	copy %r31,%r2
+1:
+	ldw -84(%r30),%r2
+	ldw -60(%r30),%r3
+	bv %r0(%r2)
+	ldwm -64(%r30),%r4
+	.EXIT
+	.PROCEND
+	.size gmon_initializer, .-gmon_initializer
+
+# undef PREINIT_FUNCTION
+# define PREINIT_FUNCTION gmon_initializer
+#endif
+
+	.section .init_array, "aw"
+	.word P% PREINIT_FUNCTION
+
+
 /* _init prologue.  */
 	.section .init, "ax", %progbits
 	.align 4
@@ -58,14 +147,6 @@ _init:
 	stw	%rp,-20(%sp)
 	stwm	%r4,64(%sp)
 	stw	%r19,-32(%sp)
-#if PREINIT_FUNCTION_WEAK
-	bl	PREINIT_FUNCTION,%rp
-	copy	%r19,%r4	/* delay slot */
-#else
-	bl	PREINIT_FUNCTION,%rp
-	copy	%r19,%r4	/* delay slot */
-#endif
-	copy	%r4,%r19
 
 /* _fini prologue.  */
         .section .fini,"ax",%progbits
diff --git a/sysdeps/hppa/crtn.S b/sysdeps/hppa/crtn.S
index e0d345f..a410425 100644
--- a/sysdeps/hppa/crtn.S
+++ b/sysdeps/hppa/crtn.S
@@ -38,27 +38,6 @@
 /* crtn.S puts function epilogues in the .init and .fini sections
    corresponding to the prologues in crti.S. */
 
-/* Note that we cannot have a weak undefined __gmon_start__, because
-   that would require this to be PIC, and the linker is currently not
-   able to generate a proper procedure descriptor for _init.  Sad but
-   true.  Anyway, HPPA is one of those horrible architectures where
-   making the comparison and indirect call is quite expensive (see the
-   comment in sysdeps/generic/initfini.c). */
-        .text
-        .align 4
-        .weak   __gmon_start__
-        .type    __gmon_start__,@function
-__gmon_start__:
-	.proc
-	.callinfo
-	.entry
-        bv,n %r0(%r2)
-	.exit
-	.procend
-
-/* Here is the tail end of _init.  We put __gmon_start before this so
-   that the assembler creates the .PARISC.unwind section for us, ie.
-   with the right attributes.  */
 	.section .init, "ax", @progbits
 	ldw	-84(%sp),%rp
 	copy	%r4,%r19
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
index c36928c..dea1809 100644
--- a/sysdeps/hppa/dl-lookupcfg.h
+++ b/sysdeps/hppa/dl-lookupcfg.h
@@ -75,7 +75,9 @@ void attribute_hidden _dl_unmap (struct link_map *map);
 
 /* Construct a fixup value from the address and linkmap */
 #define DL_FIXUP_MAKE_VALUE(map, addr) \
-   ((struct fdesc) { (addr), (map)->l_info[DT_PLTGOT]->d_un.d_ptr })
+  (map) ? ((struct fdesc) { (addr), (map)->l_info[DT_PLTGOT]->d_un.d_ptr }) \
+	: ((struct fdesc) { 0, 0 })
+
 
 /* Extract the code address from a fixup value */
 #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
diff --git a/sysdeps/hppa/dl-trampoline.S b/sysdeps/hppa/dl-trampoline.S
index 22f484a..64f0966 100644
--- a/sysdeps/hppa/dl-trampoline.S
+++ b/sysdeps/hppa/dl-trampoline.S
@@ -82,6 +82,11 @@ _dl_runtime_resolve:
 	bl	_dl_fixup,%rp
 	copy	%r21,%r19		/* set fixup func ltp */
 
+	/* Sometimes a final executable may attempt to call an undefined
+	   weak function (e.g., __gmon_start__).  Return if the function
+	   was not resolved by _dl_fixup */
+	comib,=	0,%r28,1f
+
 	/* Load up the returned func descriptor */
 	copy	%r28, %r22
 	copy	%r29, %r19
@@ -107,6 +112,13 @@ _dl_runtime_resolve:
 	/* Jump to new function, but return to previous function */
 	bv	%r0(%r22)
 	ldw	-20(%sp),%rp
+
+1:
+	/* Return to previous function */
+	ldw	-148(%sp),%rp
+	bv	%r0(%rp)
+	ldo	-128(%sp),%sp
+
         .EXIT
         .PROCEND
 	cfi_endproc