summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/errno.h4
-rw-r--r--ldso/include/dl-hash.h1
-rw-r--r--ldso/include/dl-syscall.h4
-rw-r--r--ldso/ldso/dl-elf.c133
-rw-r--r--ldso/ldso/dl-hash.c15
-rw-r--r--libc/sysdeps/linux/common/bits/types.h33
6 files changed, 56 insertions, 134 deletions
diff --git a/include/errno.h b/include/errno.h
index 390e51521..203a62e3e 100644
--- a/include/errno.h
+++ b/include/errno.h
@@ -43,8 +43,10 @@ __BEGIN_DECLS
variable. This redeclaration using the macro still works, but it
will be a function declaration without a prototype and may trigger
a -Wstrict-prototypes warning. */
-#ifndef errno
+#ifndef __ASSEMBLER__
+# ifndef errno
extern int errno;
+# endif
#endif
#if 0 /*def __USE_GNU uClibc note: not supported */
diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h
index 37e420c14..185cdc799 100644
--- a/ldso/include/dl-hash.h
+++ b/ldso/include/dl-hash.h
@@ -89,7 +89,6 @@ extern struct dyn_elf * _dl_symbol_tables;
extern struct elf_resolve * _dl_loaded_modules;
extern struct dyn_elf * _dl_handles;
-extern struct elf_resolve * _dl_check_hashed_files(const char * libname);
extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname,
char * loadaddr, unsigned long * dynamic_info,
unsigned long dynamic_addr, unsigned long dynamic_size);
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 3f20229cd..d4348afc0 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -12,7 +12,6 @@
#include <bits/kernel_stat.h>
#include <bits/kernel_types.h>
-
/* _dl_open() parameters */
#define O_RDONLY 0x0000
#define O_WRONLY 01
@@ -82,6 +81,9 @@ static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, le
#define __NR__dl_stat __NR_stat
static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
+#define __NR__dl_fstat __NR_fstat
+static inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf);
+
#define __NR__dl_munmap __NR_munmap
static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 14a10bc1f..28b3094d1 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -180,71 +180,6 @@ search_for_named_library(const char *name, int secure, const char *path_list,
return NULL;
}
-/* Check if the named library is already loaded... */
-struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname,
- int trace_loaded_objects)
-{
- const char *pnt, *pnt1;
- struct elf_resolve *tpnt1;
- const char *libname, *libname2;
- static const char libc[] = "libc.so.";
- static const char aborted_wrong_lib[] = "%s: aborted attempt to load %s!\n";
-
- pnt = libname = full_libname;
-
- _dl_if_debug_dprint("Checking if '%s' is already loaded\n", full_libname);
- /* quick hack to ensure mylibname buffer doesn't overflow. don't
- allow full_libname or any directory to be longer than 1024. */
- if (_dl_strlen(full_libname) > 1024)
- return NULL;
-
- /* Skip over any initial initial './' and '/' stuff to
- * get the short form libname with no path garbage */
- pnt1 = _dl_strrchr(pnt, '/');
- if (pnt1) {
- libname = pnt1 + 1;
- }
-
- /* Make sure they are not trying to load the wrong C library!
- * This sometimes happens esp with shared libraries when the
- * library path is somehow wrong! */
-#define isdigit(c) (c >= '0' && c <= '9')
- if ((_dl_strncmp(libname, libc, 8) == 0) && _dl_strlen(libname) >=8 &&
- isdigit(libname[8]))
- {
- /* Abort attempts to load glibc, libc5, etc */
- if ( libname[8]!='0') {
- if (!trace_loaded_objects) {
- _dl_dprintf(2, aborted_wrong_lib, libname, _dl_progname);
- _dl_exit(1);
- }
- return NULL;
- }
- }
-
- /* Critical step! Weed out duplicates early to avoid
- * function aliasing, which wastes memory, and causes
- * really bad things to happen with weaks and globals. */
- for (tpnt1 = _dl_loaded_modules; tpnt1; tpnt1 = tpnt1->next) {
-
- /* Skip over any initial initial './' and '/' stuff to
- * get the short form libname with no path garbage */
- libname2 = tpnt1->libname;
- pnt1 = _dl_strrchr(libname2, '/');
- if (pnt1) {
- libname2 = pnt1 + 1;
- }
-
- if (_dl_strcmp(libname2, libname) == 0) {
- /* Well, that was certainly easy */
- return tpnt1;
- }
- }
-
- return NULL;
-}
-
-
/* Used to return error codes back to dlopen et. al. */
unsigned long _dl_error_number;
unsigned long _dl_internal_error_number;
@@ -271,14 +206,6 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
libname = pnt + 1;
}
- /* Critical step! Weed out duplicates early to avoid
- * function aliasing, which wastes memory, and causes
- * really bad things to happen with weaks and globals. */
- if ((tpnt1=_dl_check_if_named_library_is_loaded(libname, trace_loaded_objects))!=NULL) {
- tpnt1->usage_count++;
- return tpnt1;
- }
-
_dl_if_debug_dprint("\tfind library='%s'; searching\n", libname);
/* If the filename has any '/', try it straight and leave it at that.
For IBCS2 compatibility under linux, we substitute the string
@@ -290,7 +217,6 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
if (tpnt1) {
return tpnt1;
}
- //goto goof;
}
/*
@@ -411,48 +337,37 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
int i, flags, piclib, infile;
ElfW(Addr) relro_addr = 0;
size_t relro_size = 0;
-
- /* If this file is already loaded, skip this step */
- tpnt = _dl_check_hashed_files(libname);
- if (tpnt) {
- if (*rpnt) {
- (*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
- _dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf));
- (*rpnt)->next->prev = (*rpnt);
- *rpnt = (*rpnt)->next;
- (*rpnt)->dyn = tpnt;
- tpnt->symbol_scope = _dl_symbol_tables;
- }
- tpnt->usage_count++;
- tpnt->libtype = elf_lib;
- _dl_if_debug_dprint("file='%s'; already loaded\n", libname);
- return tpnt;
- }
-
- /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
- we don't load the library if it isn't setuid. */
-
- if (secure) {
- struct stat st;
-
- if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
- return NULL;
- }
+ struct stat st;
libaddr = 0;
infile = _dl_open(libname, O_RDONLY, 0);
if (infile < 0) {
-#if 0
- /*
- * NO! When we open shared libraries we may search several paths.
- * it is inappropriate to generate an error here.
- */
- _dl_dprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
-#endif
_dl_internal_error_number = LD_ERROR_NOFILE;
return NULL;
}
+ if (_dl_fstat(infile, &st) < 0) {
+ _dl_internal_error_number = LD_ERROR_NOFILE;
+ _dl_close(infile);
+ return NULL;
+ }
+ /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
+ we don't load the library if it isn't setuid. */
+ if (secure)
+ if (!(st.st_mode & S_ISUID)) {
+ _dl_close(infile);
+ return NULL;
+ }
+
+ /* Check if file is already loaded */
+ for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+ if(tpnt->st_dev == st.st_dev && tpnt->st_ino == st.st_ino) {
+ /* Already loaded */
+ tpnt->usage_count++;
+ _dl_close(infile);
+ return tpnt;
+ }
+ }
header = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (_dl_mmap_check_error(header)) {
@@ -665,6 +580,8 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
dynamic_addr, 0);
tpnt->relro_addr = relro_addr;
tpnt->relro_size = relro_size;
+ tpnt->st_dev = st.st_dev;
+ tpnt->st_ino = st.st_ino;
tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
tpnt->n_phent = epnt->e_phnum;
diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c
index 188b2917a..2247207a6 100644
--- a/ldso/ldso/dl-hash.c
+++ b/ldso/ldso/dl-hash.c
@@ -77,21 +77,6 @@ static inline Elf_Symndx _dl_elf_hash(const char *name)
return hash;
}
-/* Check to see if a library has already been added to the hash chain. */
-struct elf_resolve *_dl_check_hashed_files(const char *libname)
-{
- struct elf_resolve *tpnt;
- int len = _dl_strlen(libname);
-
- for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
- if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&
- (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))
- return tpnt;
- }
-
- return NULL;
-}
-
/*
* We call this function when we have just read an ELF library or executable.
* We add the relevant info to the symbol chain, so that we can resolve all
diff --git a/libc/sysdeps/linux/common/bits/types.h b/libc/sysdeps/linux/common/bits/types.h
index 07b8ff1a7..aebd8b8c5 100644
--- a/libc/sysdeps/linux/common/bits/types.h
+++ b/libc/sysdeps/linux/common/bits/types.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,92,1994-1999,2000,2001 Free Software Foundation, Inc.
+/* bits/types.h -- definitions of __*_t types underlying *_t types.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -24,6 +25,7 @@
#define _BITS_TYPES_H 1
#include <features.h>
+#include <bits/wordsize.h>
#define __need_size_t
#include <stddef.h>
@@ -31,10 +33,14 @@
/* Convenience types. */
typedef unsigned char __u_char;
-typedef unsigned short __u_short;
+typedef unsigned short int __u_short;
typedef unsigned int __u_int;
-typedef unsigned long __u_long;
-#ifdef __GNUC__
+typedef unsigned long int __u_long;
+
+#if __WORDSIZE == 64
+typedef long int __quad_t;
+typedef unsigned long int __u_quad_t;
+#elif defined(__GNUC__)
__extension__ typedef unsigned long long int __u_quad_t;
__extension__ typedef long long int __quad_t;
#else
@@ -53,12 +59,23 @@ typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;
-#ifdef __GNUC__
+#if __WORDSIZE == 64
+typedef signed long int __int64_t;
+typedef unsigned long int __uint64_t;
+#elif defined(__GNUC__)
__extension__ typedef signed long long int __int64_t;
__extension__ typedef unsigned long long int __uint64_t;
#endif
typedef __quad_t *__qaddr_t;
+#if __WORDSIZE == 32
+# define __SWORD_TYPE int
+#elif __WORDSIZE == 64
+# define __SWORD_TYPE long int
+#else
+# error
+#endif
+
typedef __u_quad_t __dev_t; /* Type of device numbers. */
typedef __u_int __uid_t; /* Type of user identifications. */
typedef __u_int __gid_t; /* Type of group identifications. */
@@ -68,7 +85,7 @@ typedef __u_int __nlink_t; /* Type of file link counts. */
typedef long int __off_t; /* Type of file sizes and offsets. */
typedef __quad_t __loff_t; /* Type of file sizes and offsets. */
typedef int __pid_t; /* Type of process identifications. */
-typedef int __ssize_t; /* Type of a byte count, or error. */
+typedef __SWORD_TYPE __ssize_t; /* Type of a byte count, or error. */
typedef __u_long __rlim_t; /* Type of resource counts. */
typedef __u_quad_t __rlim64_t; /* Type of resource counts (LFS). */
typedef __u_int __id_t; /* General type for ID. */
@@ -85,14 +102,14 @@ typedef long int __time_t;
typedef unsigned int __useconds_t;
typedef long int __suseconds_t;
typedef long int __swblk_t; /* Type of a swap block maybe? */
-
+
typedef long int __clock_t;
/* Clock ID used in clock and timer functions. */
typedef int __clockid_t;
/* Timer ID returned by `timer_create'. */
-typedef int __timer_t;
+typedef void *__timer_t;
/* Number of descriptors that can fit in an `fd_set'. */