[patch] libc: Do not export .cerror

Jilles Tjoelker jilles at stack.nl
Fri Aug 24 22:16:58 UTC 2012


For some reason, libc exports the symbol .cerror (HIDENAME(cerror)),
albeit in the FBSDprivate_1.0 version. It looks like there is no reason
for this since it is not used from other libraries. Given that it cannot
be accessed from C and its strange calling convention, it is rather
unlikely that other things rely on it. Perhaps it is from a time when
symbols could not be hidden. 

Not exporting .cerror causes it to be jumped to directly instead of via
the PLT.

The below patch is for i386 only and also takes advantage of .cerror's
new status by not saving and loading %ebx before jumping to it.
(Therefore, .cerror now saves and loads %ebx itself.) Where there was a
conditional jump to a jump to .cerror, the conditional jump has been
changed to jump to .cerror directly (many modern CPUs don't do static
prediction and in any case it is not much of a benefit anyway).

The patch decreases the size of libc.so.7 by a few kilobytes.

Similar changes could be made to other architectures, and there may be
more symbols that are exported but need not be.

Index: lib/libc/i386/Symbol.map
===================================================================
--- lib/libc/i386/Symbol.map	(revision 239195)
+++ lib/libc/i386/Symbol.map	(working copy)
@@ -63,7 +63,6 @@
 	__sys_vfork;
 	_vfork;
 	_end;
-	.cerror;
 	_brk;
 	.curbrk;
 	.minbrk;
Index: lib/libc/i386/SYS.h
===================================================================
--- lib/libc/i386/SYS.h	(revision 239195)
+++ lib/libc/i386/SYS.h	(working copy)
@@ -36,21 +36,21 @@
 #include <sys/syscall.h>
 #include <machine/asm.h>
 
-#define	SYSCALL(x)	2: PIC_PROLOGUE; jmp PIC_PLT(HIDENAME(cerror));	\
-			ENTRY(__CONCAT(__sys_,x));			\
+#define	SYSCALL(x)	ENTRY(__CONCAT(__sys_,x));			\
 			.weak CNAME(x);					\
 			.set CNAME(x),CNAME(__CONCAT(__sys_,x));	\
 			.weak CNAME(__CONCAT(_,x));			\
 			.set CNAME(__CONCAT(_,x)),CNAME(__CONCAT(__sys_,x)); \
-			mov __CONCAT($SYS_,x),%eax; KERNCALL; jb 2b
+			mov __CONCAT($SYS_,x),%eax; KERNCALL;		\
+ 			jb HIDENAME(cerror)
 
 #define	RSYSCALL(x)	SYSCALL(x); ret; END(__CONCAT(__sys_,x))
 
-#define	PSEUDO(x)	2: PIC_PROLOGUE; jmp PIC_PLT(HIDENAME(cerror)); \
-			ENTRY(__CONCAT(__sys_,x));			\
+#define	PSEUDO(x)	ENTRY(__CONCAT(__sys_,x));			\
 			.weak CNAME(__CONCAT(_,x));			\
 			.set CNAME(__CONCAT(_,x)),CNAME(__CONCAT(__sys_,x)); \
-			mov __CONCAT($SYS_,x),%eax; KERNCALL; jb 2b; ret; \
+			mov __CONCAT($SYS_,x),%eax; KERNCALL;		\
+ 			jb HIDENAME(cerror); ret; \
 			END(__CONCAT(__sys_,x))
 
 /* gas messes up offset -- although we don't currently need it, do for BCS */
Index: lib/libc/i386/gen/rfork_thread.S
===================================================================
--- lib/libc/i386/gen/rfork_thread.S	(revision 239195)
+++ lib/libc/i386/gen/rfork_thread.S	(working copy)
@@ -113,8 +113,7 @@
 	popl	%esi
 	movl	%ebp, %esp
 	popl	%ebp
-	PIC_PROLOGUE
-	jmp	PIC_PLT(HIDENAME(cerror))
+	jmp	HIDENAME(cerror)
 END(rfork_thread)
 
 	.section .note.GNU-stack,"",%progbits
Index: lib/libc/i386/sys/brk.S
===================================================================
--- lib/libc/i386/sys/brk.S	(revision 239195)
+++ lib/libc/i386/sys/brk.S	(working copy)
@@ -58,14 +58,11 @@
 ok:
 	mov	$SYS_break,%eax
 	KERNCALL
-	jb	err
+	jb	HIDENAME(cerror)
 	movl	4(%esp),%eax
 	movl	%eax,(%edx)
 	movl	$0,%eax
 	ret
-err:
-	PIC_PROLOGUE
-	jmp	PIC_PLT(HIDENAME(cerror))
 
 #else
 
@@ -77,13 +74,11 @@
 ok:
 	mov	$SYS_break,%eax
 	KERNCALL
-	jb	err
+	jb	HIDENAME(cerror)
 	movl	4(%esp),%eax
 	movl	%eax,HIDENAME(curbrk)
 	movl	$0,%eax
 	ret
-err:
-	jmp	HIDENAME(cerror)
 #endif
 END(brk)
 
Index: lib/libc/i386/sys/getcontext.S
===================================================================
--- lib/libc/i386/sys/getcontext.S	(revision 239195)
+++ lib/libc/i386/sys/getcontext.S	(working copy)
@@ -42,12 +42,9 @@
 	movl	(%esp),%ecx	/* save getcontext return address */
 	mov	$SYS_getcontext,%eax
 	KERNCALL
-	jb	1f
+	jb	HIDENAME(cerror)
 	addl	$4,%esp		/* remove stale (setcontext) return address */
 	jmp	*%ecx		/* restore return address */
-1:
-	PIC_PROLOGUE
-	jmp	PIC_PLT(HIDENAME(cerror))
 END(__sys_getcontext)
 
 	.section .note.GNU-stack,"",%progbits
Index: lib/libc/i386/sys/cerror.S
===================================================================
--- lib/libc/i386/sys/cerror.S	(revision 239195)
+++ lib/libc/i386/sys/cerror.S	(working copy)
@@ -48,13 +48,14 @@
 	.globl	CNAME(__error)
 	.type	CNAME(__error), at function
 HIDENAME(cerror):
+#ifdef PIC
+	PIC_PROLOGUE
 	pushl	%eax
-#ifdef PIC
-	/* The caller must execute the PIC prologue before jumping to cerror. */
 	call	PIC_PLT(CNAME(__error))
 	popl	%ecx
 	PIC_EPILOGUE
 #else
+	pushl	%eax
 	call	CNAME(__error)
 	popl	%ecx
 #endif
Index: lib/libc/i386/sys/sbrk.S
===================================================================
--- lib/libc/i386/sys/sbrk.S	(revision 239195)
+++ lib/libc/i386/sys/sbrk.S	(working copy)
@@ -59,7 +59,7 @@
 	addl	%eax,4(%esp)
 	mov	$SYS_break,%eax
 	KERNCALL
-	jb	err
+	jb	HIDENAME(cerror)
 	PIC_PROLOGUE
 	movl	PIC_GOT(HIDENAME(curbrk)),%edx
 	movl	(%edx),%eax
@@ -67,9 +67,6 @@
 	PIC_EPILOGUE
 back:
 	ret
-err:
-	PIC_PROLOGUE
-	jmp	PIC_PLT(HIDENAME(cerror))
 
 #else /* !PIC */
 
@@ -80,13 +77,11 @@
 	addl	%eax,4(%esp)
 	mov	$SYS_break,%eax
 	KERNCALL
-	jb	err
+	jb	HIDENAME(cerror)
 	movl	HIDENAME(curbrk),%eax
 	addl	%ecx,HIDENAME(curbrk)
 back:
 	ret
-err:
-	jmp	HIDENAME(cerror)
 #endif /* PIC */
 END(sbrk)
 
Index: lib/libc/i386/sys/Ovfork.S
===================================================================
--- lib/libc/i386/sys/Ovfork.S	(revision 239195)
+++ lib/libc/i386/sys/Ovfork.S	(working copy)
@@ -50,8 +50,7 @@
 	jmp	*%ecx
 1:
 	pushl	%ecx
-	PIC_PROLOGUE
-	jmp     PIC_PLT(HIDENAME(cerror))
+	jmp     HIDENAME(cerror)
 END(__sys_vfork)
 
 	.section .note.GNU-stack,"",%progbits
Index: lib/libc/i386/sys/ptrace.S
===================================================================
--- lib/libc/i386/sys/ptrace.S	(revision 239195)
+++ lib/libc/i386/sys/ptrace.S	(working copy)
@@ -50,11 +50,8 @@
 #endif
 	mov	$SYS_ptrace,%eax
 	KERNCALL
-	jb	err
+	jb	HIDENAME(cerror)
 	ret
-err:
-	PIC_PROLOGUE
-	jmp	PIC_PLT(HIDENAME(cerror))
 END(ptrace)
 
 	.section .note.GNU-stack,"",%progbits
Index: lib/libc/i386/sys/exect.S
===================================================================
--- lib/libc/i386/sys/exect.S	(revision 239195)
+++ lib/libc/i386/sys/exect.S	(working copy)
@@ -47,8 +47,7 @@
 	pushl	%edx
 	popf
 	KERNCALL
-	PIC_PROLOGUE
-	jmp	PIC_PLT(HIDENAME(cerror))	/* exect(file, argv, env); */
+	jmp	HIDENAME(cerror)	/* exect(file, argv, env); */
 END(exect)
 
 	.section .note.GNU-stack,"",%progbits
Index: lib/libc/i386/sys/syscall.S
===================================================================
--- lib/libc/i386/sys/syscall.S	(revision 239195)
+++ lib/libc/i386/sys/syscall.S	(working copy)
@@ -45,11 +45,8 @@
 	KERNCALL
 	push	%ecx	/* need to push a word to keep stack frame intact
 			   upon return; the word must be the return address. */
-	jb	1f
+	jb	HIDENAME(cerror)
 	ret
-1:
-	PIC_PROLOGUE
-	jmp	PIC_PLT(HIDENAME(cerror))
 END(syscall)
 
 	.section .note.GNU-stack,"",%progbits
-- 
Jilles Tjoelker


More information about the freebsd-hackers mailing list