diff options
-rw-r--r-- | include/errno.h | 4 | ||||
-rw-r--r-- | ldso/include/dl-hash.h | 1 | ||||
-rw-r--r-- | ldso/include/dl-syscall.h | 4 | ||||
-rw-r--r-- | ldso/ldso/dl-elf.c | 133 | ||||
-rw-r--r-- | ldso/ldso/dl-hash.c | 15 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/bits/types.h | 33 |
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'. */ |