Change compiler setting to make default visibility of the symbols for

rtld on x86 to be hidden.  This is a micro-optimization, which allows
intrinsic references inside rtld to be handled without indirection
through PLT.  The visibility of rtld symbols for other objects in the
symbol namespace is controlled by a version script.

Reviewed by:	kan, jilles
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
This commit is contained in:
kib 2015-03-29 18:53:21 +00:00
parent 951b0c97e4
commit 563a44c171
12 changed files with 43 additions and 16 deletions

View File

@ -42,6 +42,9 @@ CFLAGS+= -fPIC
CFLAGS+= -fpic
.endif
CFLAGS+= -DPIC $(DEBUG)
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
CFLAGS+= -fvisibility=hidden
.endif
LDFLAGS+= -shared -Wl,-Bsymbolic
LIBADD= c_pic

View File

@ -47,6 +47,7 @@
#include "debug.h"
#include "rtld.h"
#include "rtld_tls.h"
/*
* Process the special R_X86_64_COPY relocations in the main program. These

View File

@ -74,7 +74,7 @@ typedef struct {
unsigned long ti_offset;
} tls_index;
extern void *__tls_get_addr(tls_index *ti);
void *__tls_get_addr(tls_index *ti) __exported;
#define RTLD_DEFAULT_STACK_PF_EXEC PF_X
#define RTLD_DEFAULT_STACK_EXEC PROT_EXEC

View File

@ -36,7 +36,7 @@
movq %rsp,%rsi # save address of exit proc
movq %rsp,%rdx # construct address of obj_main
addq $8,%rdx
call _rtld@PLT # Call rtld(sp); returns entry point
call _rtld # Call rtld(sp); returns entry point
popq %rsi # Get exit procedure address
movq %r12,%rdi # *ap
/*
@ -118,7 +118,7 @@ _rtld_bind_start:
leaq (%rsi,%rsi,2),%rsi # multiply by 3
leaq (,%rsi,8),%rsi # now 8, for 24 (sizeof Elf_Rela)
call _rtld_bind@PLT # Transfer control to the binder
call _rtld_bind # Transfer control to the binder
/* Now %rax contains the entry point of the function being called. */
movq %rax,0x60(%rsp) # Store target over reloff argument

View File

@ -48,6 +48,7 @@
#include "debug.h"
#include "rtld.h"
#include "rtld_tls.h"
/*
* Process the special R_386_COPY relocations in the main program. These

View File

@ -74,8 +74,8 @@ typedef struct {
unsigned long ti_offset;
} tls_index;
extern void *___tls_get_addr(tls_index *ti) __attribute__((__regparm__(1)));
extern void *__tls_get_addr(tls_index *ti);
void *___tls_get_addr(tls_index *ti) __attribute__((__regparm__(1))) __exported;
void *__tls_get_addr(tls_index *ti) __exported;
#define RTLD_DEFAULT_STACK_PF_EXEC PF_X
#define RTLD_DEFAULT_STACK_EXEC PROT_EXEC

View File

@ -42,7 +42,7 @@
pushl %ecx # Pass address of obj_main
pushl %ebx # Pass address of exit proc
pushl %eax # Pass initial stack pointer to rtld
call _rtld@PLT # Call rtld(sp); returns entry point
call _rtld # Call rtld(sp); returns entry point
addl $16,%esp # Remove arguments from stack
popl %edx # Get exit procedure address
movl %esi,%esp # Ignore obj_main
@ -78,7 +78,7 @@ _rtld_bind_start:
pushl 20(%esp) # Copy reloff argument
pushl 20(%esp) # Copy obj argument
call _rtld_bind@PLT # Transfer control to the binder
call _rtld_bind # Transfer control to the binder
/* Now %eax contains the entry point of the function being called. */
addl $8,%esp # Discard binder arguments

View File

@ -163,8 +163,8 @@ static uint32_t gnu_hash(const char *);
static bool matched_symbol(SymLook *, const Obj_Entry *, Sym_Match_Result *,
const unsigned long);
void r_debug_state(struct r_debug *, struct link_map *) __noinline;
void _r_debug_postinit(struct link_map *) __noinline;
void r_debug_state(struct r_debug *, struct link_map *) __noinline __exported;
void _r_debug_postinit(struct link_map *) __noinline __exported;
int __sys_openat(int, const char *, int, ...);
@ -172,7 +172,7 @@ int __sys_openat(int, const char *, int, ...);
* Data declarations.
*/
static char *error_message; /* Message for dlerror(), or NULL */
struct r_debug r_debug; /* for GDB; */
struct r_debug r_debug __exported; /* for GDB; */
static bool libmap_disable; /* Disable libmap */
static bool ld_loadfltr; /* Immediate filters processing */
static char *libmap_override; /* Maps to use in addition to libmap.conf */
@ -212,6 +212,23 @@ extern Elf_Dyn _DYNAMIC;
#define RTLD_IS_DYNAMIC() (&_DYNAMIC != NULL)
#endif
int dlclose(void *) __exported;
char *dlerror(void) __exported;
void *dlopen(const char *, int) __exported;
void *fdlopen(int, int) __exported;
void *dlsym(void *, const char *) __exported;
dlfunc_t dlfunc(void *, const char *) __exported;
void *dlvsym(void *, const char *, const char *) __exported;
int dladdr(const void *, Dl_info *) __exported;
void dllockinit(void *, void *(*)(void *), void (*)(void *), void (*)(void *),
void (*)(void *), void (*)(void *), void (*)(void *)) __exported;
int dlinfo(void *, int , void *) __exported;
int dl_iterate_phdr(__dl_iterate_hdr_callback, void *) __exported;
int _rtld_addr_phdr(const void *, struct dl_phdr_info *) __exported;
int _rtld_get_stack_prot(void) __exported;
int _rtld_is_dlopened(void *) __exported;
void _rtld_error(const char *, ...) __exported;
int npagesizes, osreldate;
size_t *pagesizes;

View File

@ -353,7 +353,7 @@ typedef struct Struct_SymLook {
struct Struct_RtldLockState *lockstate;
} SymLook;
void _rtld_error(const char *, ...) __printflike(1, 2);
void _rtld_error(const char *, ...) __printflike(1, 2) __exported;
const char *rtld_strerror(int);
Obj_Entry *map_object(int, const char *, const struct stat *);
void *xcalloc(size_t, size_t);

View File

@ -51,6 +51,10 @@
#include "rtld.h"
#include "rtld_machdep.h"
void _rtld_thread_init(struct RtldLockInfo *) __exported;
void _rtld_atfork_pre(int *) __exported;
void _rtld_atfork_post(int *) __exported;
#define WAFLAG 0x1 /* A writer holds the lock */
#define RC_INCR 0x2 /* Adjusts count of readers desiring lock */

View File

@ -44,9 +44,9 @@ struct RtldLockInfo
void (*at_fork)(void);
};
extern void _rtld_thread_init(struct RtldLockInfo *);
extern void _rtld_atfork_pre(int *);
extern void _rtld_atfork_post(int *);
extern void _rtld_thread_init(struct RtldLockInfo *) __exported;
extern void _rtld_atfork_pre(int *) __exported;
extern void _rtld_atfork_post(int *) __exported;
#ifdef IN_RTLD

View File

@ -57,13 +57,14 @@
* The value returned from this function is suitable for installing
* directly into the thread pointer register.
*/
extern void *_rtld_allocate_tls(void* oldtls, size_t tcbsize, size_t tcbalign);
void *_rtld_allocate_tls(void* oldtls, size_t tcbsize, size_t tcbalign)
__exported;
/*
* Free a TLS block allocated using _rtld_allocate_tls(). The tcbsize
* and tcbalign parameters must be the same as those used to allocate
* the block.
*/
extern void _rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign);
void _rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign) __exported;
#endif