mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-05 21:00:05 +00:00
Mon Jun 10 06:14:03 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* sysdeps/mach/hurd/dl-sysdep.c (__open): Define this instead of open. (__close, __mmap): Likewise define with __ names now. Mon Jun 10 05:13:18 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * elf/dl-support.c: New file. * elf/Makefile (CFLAGS-dl-support.c): New variable. (routines, elide-routines.so): Add dl-support. * elf/dl-minimal.c (_dl_pagesize): Remove common defn. * elf/dl-load.c (_dl_pagesize): Define it here. (_dl_map_object_from_fd): Initialize it if zero. * elf/link.h (_dl_pagesize): Remove const. Sun Jun 9 04:04:26 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * elf/Makefile (routines): Add dl-symbol. * elf/dl-lookup.c (_dl_symbol_value): Moved to ... * elf/dl-symbol.c: New file. * elf/elf.h (Elf32_Xword, Elf32_Sxword): New types. (Elf32_Section, Elf64_Section): New types, 16 bits. (Elf32_Sym, Elf64_Sym): Use it. * elf/dl-deps.c (_dl_open): Moved to ... * elf/dl-open.c: New file. * Makefile (routines): Add dl-open. * elf/Makefile (dl-routines): New variable. (routines): Add $(dl-routines). (elide-routines.so): New variable, set to $(dl-routines). (libdl-inhibit-o): Variable removed; build all flavors of -ldl. (rtld-routines): All but rtld, dl-sysdep, and dl-minimal moved to $(dl-routines). * elf/dl-lookup.c (_dl_lookup_symbol): Remove magic symbol grokage. * elf/dladdr.c: Use ELFW(ST_BIND) in place of ELF32_ST_BIND. * elf/dl-load.c (open_path): Use __ names for open and close. Avoid using strdup. (_dl_map_object): Likewise. (_dl_map_object_from_fd): Use __ names for mmap, munmap, and mprotect. * elf/dl-minimal.c (malloc): Likewise. * elf/dl-reloc.c (_dl_relocate_object): Likewise. * elf/dl-minimal.c (_dl_pagesize): New variable. (malloc): Use that instead of a static variable. * elf/dl-reloc.c (_dl_relocate_object): Use _dl_pagesize instead of calling getpagesize. * elf/dl-load.c (_dl_map_object_from_fd): Likewise. * elf/link.h: Declare _dl_pagesize. * elf/rtld.c (dl_r_debug): Renamed to _dl_r_debug. * elf/link.h (struct link_map): Use Half for l_phnum instead of Word. * elf/rtld.c (dl_main): Use Half for phdr count arg. (_dl_sysdep_start): Update prototype of DL_MAIN function ptr arg. * elf/dl-load.c (_dl_map_object_from_fd): Use explicit Elf32_Word to extract 4-byte magic number, not ElfW(Word). Match EI_CLASS against native wordsize, either 32 or 64. * elf/elf.h (Elf64_Byte, Elf64_Section): Typedefs removed. In C a char is always a byte, no need for a typedef. Section indices are 16-bit quantities in elf64, which already have a typedef Elf64_Half. Remove partial -lelf implementation. There is now a separately-distributed `libelf' package that implements it. * elf/dl-lookup.c: Don't #include <libelf.h> any more. (_dl_elf_hash): New function, moved from libelf.h:elf_hash. (_dl_lookup_symbol): Use it instead of elf_hash. * elf/libelf.h: File removed. * elf/elf_hash.c: File removed. * elf/Makefile (headers): Remove libelf.h. (extra-libs): Remove libelf. (libelf-routines): Variable removed. * elf/Makefile (libdl.so): Remove commands from this target. The implicit rule commands are correct, this explicit rule just serves to add some dependencies. * elf/dl-lookup.c (_dl_lookup_symbol): Use ELFW(ST_TYPE) in place of ELF32_ST_TYPE. Likewise ST_BIND. * elf/do-rel.h (elf_dynamic_do_rel): Likewise R_SYM. * elf/link.h (ElfW): New macro for wordsize-independent ElfXX_* type naming. (ELFW): New macro, likewise for ELFXX_* macro naming. (_ElfW, _ElfW_1): New macros, subroutines of ElfW and ELF. Sat Jun 8 20:52:38 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> * elf/link.h, elf/do-rel.h, elf/dynamic-link.h, elf/dl-deps.c, elf/dl-init.c, elf/dl-load.c, elf/dl-lookup.c, elf/dl-reloc.c, elf/dl-runtime.c, elf/dladdr.c, elf/dlclose.c, elf/dlsym.c, elf/linux-compat.c, elf/rtld.c: Change all uses of `Elf32_XXX' to `ElfW(XXX)' for wordsize-independence. Sat Jun 8 20:50:42 1996 Richard Henderson <rth@tamu.edu> * elf/elf.h: Move Elf64_* types in parity with Elf32 counterparts. (Elf64_auxv_t): New type. (EM_ALPHA, R_ALPHA_*): New macros for elf64-alpha format.
This commit is contained in:
parent
564210fe2f
commit
266180eb98
108
ChangeLog
108
ChangeLog
@ -1,3 +1,111 @@
|
||||
Mon Jun 10 06:14:03 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* sysdeps/mach/hurd/dl-sysdep.c (__open): Define this instead of open.
|
||||
(__close, __mmap): Likewise define with __ names now.
|
||||
|
||||
Mon Jun 10 05:13:18 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/dl-support.c: New file.
|
||||
* elf/Makefile (CFLAGS-dl-support.c): New variable.
|
||||
(routines, elide-routines.so): Add dl-support.
|
||||
|
||||
* elf/dl-minimal.c (_dl_pagesize): Remove common defn.
|
||||
* elf/dl-load.c (_dl_pagesize): Define it here.
|
||||
(_dl_map_object_from_fd): Initialize it if zero.
|
||||
* elf/link.h (_dl_pagesize): Remove const.
|
||||
|
||||
Sun Jun 9 04:04:26 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/Makefile (routines): Add dl-symbol.
|
||||
* elf/dl-lookup.c (_dl_symbol_value): Moved to ...
|
||||
* elf/dl-symbol.c: New file.
|
||||
|
||||
* elf/elf.h (Elf32_Xword, Elf32_Sxword): New types.
|
||||
(Elf32_Section, Elf64_Section): New types, 16 bits.
|
||||
(Elf32_Sym, Elf64_Sym): Use it.
|
||||
|
||||
* elf/dl-deps.c (_dl_open): Moved to ...
|
||||
* elf/dl-open.c: New file.
|
||||
* Makefile (routines): Add dl-open.
|
||||
|
||||
* elf/Makefile (dl-routines): New variable.
|
||||
(routines): Add $(dl-routines).
|
||||
(elide-routines.so): New variable, set to $(dl-routines).
|
||||
(libdl-inhibit-o): Variable removed; build all flavors of -ldl.
|
||||
(rtld-routines): All but rtld, dl-sysdep, and dl-minimal moved to
|
||||
$(dl-routines).
|
||||
|
||||
* elf/dl-lookup.c (_dl_lookup_symbol): Remove magic symbol grokage.
|
||||
|
||||
* elf/dladdr.c: Use ELFW(ST_BIND) in place of ELF32_ST_BIND.
|
||||
|
||||
* elf/dl-load.c (open_path): Use __ names for open and close. Avoid
|
||||
using strdup.
|
||||
(_dl_map_object): Likewise.
|
||||
(_dl_map_object_from_fd): Use __ names for mmap, munmap, and mprotect.
|
||||
* elf/dl-minimal.c (malloc): Likewise.
|
||||
* elf/dl-reloc.c (_dl_relocate_object): Likewise.
|
||||
|
||||
* elf/dl-minimal.c (_dl_pagesize): New variable.
|
||||
(malloc): Use that instead of a static variable.
|
||||
* elf/dl-reloc.c (_dl_relocate_object): Use _dl_pagesize instead of
|
||||
calling getpagesize.
|
||||
* elf/dl-load.c (_dl_map_object_from_fd): Likewise.
|
||||
* elf/link.h: Declare _dl_pagesize.
|
||||
|
||||
* elf/rtld.c (dl_r_debug): Renamed to _dl_r_debug.
|
||||
|
||||
* elf/link.h (struct link_map): Use Half for l_phnum instead of Word.
|
||||
* elf/rtld.c (dl_main): Use Half for phdr count arg.
|
||||
(_dl_sysdep_start): Update prototype of DL_MAIN function ptr arg.
|
||||
|
||||
* elf/dl-load.c (_dl_map_object_from_fd): Use explicit Elf32_Word to
|
||||
extract 4-byte magic number, not ElfW(Word). Match EI_CLASS against
|
||||
native wordsize, either 32 or 64.
|
||||
|
||||
* elf/elf.h (Elf64_Byte, Elf64_Section): Typedefs removed. In C a
|
||||
char is always a byte, no need for a typedef. Section indices are
|
||||
16-bit quantities in elf64, which already have a typedef Elf64_Half.
|
||||
|
||||
Remove partial -lelf implementation. There is now a
|
||||
separately-distributed `libelf' package that implements it.
|
||||
* elf/dl-lookup.c: Don't #include <libelf.h> any more.
|
||||
(_dl_elf_hash): New function, moved from
|
||||
libelf.h:elf_hash.
|
||||
(_dl_lookup_symbol): Use it instead of elf_hash.
|
||||
* elf/libelf.h: File removed.
|
||||
* elf/elf_hash.c: File removed.
|
||||
* elf/Makefile (headers): Remove libelf.h.
|
||||
(extra-libs): Remove libelf.
|
||||
(libelf-routines): Variable removed.
|
||||
|
||||
* elf/Makefile (libdl.so): Remove commands from this target. The
|
||||
implicit rule commands are correct, this explicit rule just serves to
|
||||
add some dependencies.
|
||||
|
||||
* elf/dl-lookup.c (_dl_lookup_symbol): Use ELFW(ST_TYPE) in place of
|
||||
ELF32_ST_TYPE. Likewise ST_BIND.
|
||||
* elf/do-rel.h (elf_dynamic_do_rel): Likewise R_SYM.
|
||||
|
||||
* elf/link.h (ElfW): New macro for wordsize-independent ElfXX_* type
|
||||
naming.
|
||||
(ELFW): New macro, likewise for ELFXX_* macro naming.
|
||||
(_ElfW, _ElfW_1): New macros, subroutines of ElfW and ELF.
|
||||
|
||||
Sat Jun 8 20:52:38 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/link.h, elf/do-rel.h, elf/dynamic-link.h, elf/dl-deps.c,
|
||||
elf/dl-init.c, elf/dl-load.c, elf/dl-lookup.c, elf/dl-reloc.c,
|
||||
elf/dl-runtime.c, elf/dladdr.c, elf/dlclose.c, elf/dlsym.c,
|
||||
elf/linux-compat.c, elf/rtld.c: Change all uses of `Elf32_XXX' to
|
||||
`ElfW(XXX)' for wordsize-independence.
|
||||
|
||||
Sat Jun 8 20:50:42 1996 Richard Henderson <rth@tamu.edu>
|
||||
|
||||
* elf/elf.h: Move Elf64_* types in parity with Elf32 counterparts.
|
||||
(Elf64_auxv_t): New type.
|
||||
(EM_ALPHA, R_ALPHA_*): New macros for elf64-alpha format.
|
||||
|
||||
Mon Jun 10 02:22:24 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* sysdeps/unix/sysv/linux/configure.in: New file, start with configure.
|
||||
|
34
elf/Makefile
34
elf/Makefile
@ -20,19 +20,26 @@
|
||||
|
||||
subdir := elf
|
||||
|
||||
headers := elf.h libelf.h link.h dlfcn.h
|
||||
routines := init-first
|
||||
headers = elf.h link.h dlfcn.h
|
||||
routines = init-first $(dl-routines) dl-open dl-symbol dl-support
|
||||
|
||||
extra-libs = libelf libdl
|
||||
libelf-routines := elf_hash
|
||||
libdl-routines := dlopen dlclose dlsym dlerror dladdr
|
||||
libdl-inhibit-o = $(filter-out .so,$(object-suffixes)) # Build only shared.
|
||||
# The core dynamic linking functions are in libc for the static and
|
||||
# profiled libraries.
|
||||
dl-routines = $(addprefix dl-,load lookup object reloc deps \
|
||||
runtime error init fini)
|
||||
# But they are absent from the shared libc, because that code is in ld.so.
|
||||
elide-routines.so = $(dl-routines) dl-support
|
||||
|
||||
rtld-routines := rtld $(addprefix dl-,minimal load lookup object reloc \
|
||||
deps runtime sysdep error init fini)
|
||||
# ld.so uses those routines, plus some special stuff for being the program
|
||||
# interpreter and operating independent of libc.
|
||||
rtld-routines := rtld $(dl-routines) dl-sysdep dl-minimal
|
||||
distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
|
||||
soinit.c sofini.c ldd.sh.in linux-compat.c
|
||||
|
||||
extra-libs = libdl
|
||||
libdl-routines := dlopen dlclose dlsym dlerror dladdr
|
||||
|
||||
|
||||
all: # Make this the default target; it will be defined in Rules.
|
||||
|
||||
include ../Makeconfig
|
||||
@ -43,7 +50,7 @@ generated = librtld.so dl-allobjs.so
|
||||
install-others = $(slibdir)/$(rtld-installed-name)
|
||||
install-bin = ldd
|
||||
|
||||
# Make sure these things is built in the `make lib' pass so it can be used
|
||||
# Make sure these things are built in the `make lib' pass so they can be used
|
||||
# to run programs during the `make others' pass.
|
||||
lib-noranlib: $(objpfx)ld.so $(addprefix $(objpfx),$(extra-objs))
|
||||
|
||||
@ -81,16 +88,17 @@ $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
|
||||
-Wl,-rpath=$(default-rpath) $^
|
||||
endef
|
||||
|
||||
# The dl code in the static libc needs a default library path.
|
||||
CFLAGS-dl-support.c = -D'DEFAULT_RPATH="$(default-rpath)"'
|
||||
|
||||
# The Linux-compatible dynamic linker shared object is just the same
|
||||
# with one object file of compatibility initialization code added.
|
||||
$(objpfx)ld-linux.so.1: $(objpfx)linux-compat.so
|
||||
|
||||
|
||||
# Specify the dependencies of libdl.so; its commands come from the generic
|
||||
# rule to build a shared library.
|
||||
$(objpfx)libdl.so: $(objpfx)libdl_pic.a $(common-objpfx)libc.so $(objpfx)ld.so
|
||||
$(patsubst %/,cd %;,$(objpfx)) \
|
||||
$(LINK.o) -shared -o $(@:$(objpfx)%=%) \
|
||||
$(LDFLAGS.so) $(LDFLAGS-dl.so) \
|
||||
-Wl,--whole-archive $(^:$(objpfx)%=%) $(no-whole-archive)
|
||||
|
||||
$(slibdir)/$(rtld-installed-name): $(objpfx)ld.so; $(do-install-program)
|
||||
$(slibdir)/ld-linux.so.1: $(objpfx)ld-linux.so.1; $(do-install-program)
|
||||
|
@ -56,7 +56,7 @@ _dl_map_object_deps (struct link_map *map)
|
||||
{
|
||||
const char *strtab
|
||||
= ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
const Elf32_Dyn *d;
|
||||
const ElfW(Dyn) *d;
|
||||
for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
|
||||
if (d->d_tag == DT_NEEDED)
|
||||
{
|
||||
@ -97,28 +97,3 @@ _dl_map_object_deps (struct link_map *map)
|
||||
scanp->map->l_reserved = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct link_map *
|
||||
_dl_open (struct link_map *parent, const char *file, int mode)
|
||||
{
|
||||
struct link_map *new, *l;
|
||||
Elf32_Addr init;
|
||||
|
||||
/* Load the named object. */
|
||||
new = _dl_map_object (parent, file);
|
||||
|
||||
/* Load that object's dependencies. */
|
||||
_dl_map_object_deps (new);
|
||||
|
||||
/* Relocate the objects loaded. */
|
||||
for (l = new; l; l = l->l_next)
|
||||
if (! l->l_relocated)
|
||||
_dl_relocate_object (l, (mode & RTLD_BINDING_MASK) == RTLD_LAZY);
|
||||
|
||||
/* Run the initializer functions of new objects. */
|
||||
while (init = _dl_init_next (new))
|
||||
(*(void (*) (void)) init) ();
|
||||
|
||||
return new;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ Cambridge, MA 02139, USA. */
|
||||
/* Run initializers for MAP and its dependencies, in inverse dependency
|
||||
order (that is, leaf nodes first). */
|
||||
|
||||
Elf32_Addr
|
||||
ElfW(Addr)
|
||||
_dl_init_next (struct link_map *map)
|
||||
{
|
||||
unsigned int i;
|
||||
|
133
elf/dl-load.c
133
elf/dl-load.c
@ -60,6 +60,7 @@ Cambridge, MA 02139, USA. */
|
||||
#define STRING(x) #x
|
||||
|
||||
int _dl_zerofd = -1;
|
||||
size_t _dl_pagesize;
|
||||
|
||||
|
||||
/* Try to open NAME in one of the directories in DIRPATH.
|
||||
@ -82,31 +83,48 @@ open_path (const char *name, size_t namelen,
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = alloca (strlen (dirpath) + 1 + namelen);
|
||||
buf = __alloca (strlen (dirpath) + 1 + namelen);
|
||||
do
|
||||
{
|
||||
size_t buflen;
|
||||
|
||||
dirpath = p;
|
||||
p = strpbrk (dirpath, ":;");
|
||||
if (p == NULL)
|
||||
p = strchr (dirpath, '\0');
|
||||
|
||||
if (p == dirpath)
|
||||
/* Two adjacent colons, or a colon at the beginning or the end of
|
||||
the path means to search the current directory. */
|
||||
(void) memcpy (buf, name, namelen);
|
||||
{
|
||||
/* Two adjacent colons, or a colon at the beginning or the end of
|
||||
the path means to search the current directory. */
|
||||
(void) memcpy (buf, name, namelen);
|
||||
buflen = namelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Construct the pathname to try. */
|
||||
(void) memcpy (buf, dirpath, p - dirpath);
|
||||
buf[p - dirpath] = '/';
|
||||
(void) memcpy (&buf[(p - dirpath) + 1], name, namelen);
|
||||
buflen = p - dirpath + 1 + namelen;
|
||||
}
|
||||
|
||||
fd = open (buf, O_RDONLY);
|
||||
fd = __open (buf, O_RDONLY);
|
||||
if (fd != -1)
|
||||
{
|
||||
*realname = strdup (buf);
|
||||
return fd;
|
||||
*realname = malloc (buflen);
|
||||
if (*realname)
|
||||
{
|
||||
memcpy (*realname, buf, buflen);
|
||||
return fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No memory for the name, we certainly won't be able
|
||||
to load and link it. */
|
||||
__close (fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (errno != ENOENT && errno != EACCES)
|
||||
/* The file exists and is readable, but something went wrong. */
|
||||
@ -117,7 +135,6 @@ open_path (const char *name, size_t namelen,
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Map in the shared object file NAME. */
|
||||
|
||||
struct link_map *
|
||||
@ -163,9 +180,19 @@ _dl_map_object (struct link_map *loader, const char *name)
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = open (name, O_RDONLY);
|
||||
fd = __open (name, O_RDONLY);
|
||||
if (fd != -1)
|
||||
realname = strdup (name);
|
||||
{
|
||||
size_t len = strlen (name) + 1;
|
||||
realname = malloc (len);
|
||||
if (realname)
|
||||
memcpy (realname, name, len);
|
||||
else
|
||||
{
|
||||
__close (fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd == -1)
|
||||
@ -182,25 +209,24 @@ struct link_map *
|
||||
_dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
{
|
||||
struct link_map *l = NULL;
|
||||
const size_t pagesize = getpagesize ();
|
||||
void *file_mapping = NULL;
|
||||
size_t mapping_size = 0;
|
||||
|
||||
#define LOSE(s) lose (0, (s))
|
||||
void lose (int code, const char *msg)
|
||||
{
|
||||
(void) close (fd);
|
||||
(void) __close (fd);
|
||||
if (file_mapping)
|
||||
munmap (file_mapping, mapping_size);
|
||||
__munmap (file_mapping, mapping_size);
|
||||
_dl_signal_error (code, l ? l->l_name : name, msg);
|
||||
}
|
||||
|
||||
inline caddr_t map_segment (Elf32_Addr mapstart, size_t len,
|
||||
inline caddr_t map_segment (ElfW(Addr) mapstart, size_t len,
|
||||
int prot, int fixed, off_t offset)
|
||||
{
|
||||
caddr_t mapat = mmap ((caddr_t) mapstart, len, prot,
|
||||
fixed|MAP_COPY|MAP_FILE,
|
||||
fd, offset);
|
||||
caddr_t mapat = __mmap ((caddr_t) mapstart, len, prot,
|
||||
fixed|MAP_COPY|MAP_FILE,
|
||||
fd, offset);
|
||||
if (mapat == (caddr_t) -1)
|
||||
lose (errno, "failed to map segment from shared object");
|
||||
return mapat;
|
||||
@ -213,11 +239,11 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
{
|
||||
void *result;
|
||||
if (file_mapping)
|
||||
munmap (file_mapping, mapping_size);
|
||||
mapping_size = (location + size + 1 + pagesize - 1);
|
||||
mapping_size &= ~(pagesize - 1);
|
||||
result = mmap (file_mapping, mapping_size, PROT_READ,
|
||||
MAP_COPY|MAP_FILE, fd, 0);
|
||||
__munmap (file_mapping, mapping_size);
|
||||
mapping_size = (location + size + 1 + _dl_pagesize - 1);
|
||||
mapping_size &= ~(_dl_pagesize - 1);
|
||||
result = __mmap (file_mapping, mapping_size, PROT_READ,
|
||||
MAP_COPY|MAP_FILE, fd, 0);
|
||||
if (result == (void *) -1)
|
||||
lose (errno, "cannot map file data");
|
||||
file_mapping = result;
|
||||
@ -225,9 +251,9 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
return file_mapping + location;
|
||||
}
|
||||
|
||||
const Elf32_Ehdr *header;
|
||||
const Elf32_Phdr *phdr;
|
||||
const Elf32_Phdr *ph;
|
||||
const ElfW(Ehdr) *header;
|
||||
const ElfW(Phdr) *phdr;
|
||||
const ElfW(Phdr) *ph;
|
||||
int type;
|
||||
|
||||
/* Look again to see if the real name matched another already loaded. */
|
||||
@ -236,12 +262,15 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
{
|
||||
/* The object is already loaded.
|
||||
Just bump its reference count and return it. */
|
||||
close (fd);
|
||||
__close (fd);
|
||||
free (realname);
|
||||
++l->l_opencount;
|
||||
return l;
|
||||
}
|
||||
|
||||
if (_dl_pagesize == 0)
|
||||
_dl_pagesize = __getpagesize ();
|
||||
|
||||
/* Map in the first page to read the header. */
|
||||
header = map (0, sizeof *header);
|
||||
|
||||
@ -260,8 +289,10 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
#endif
|
||||
)
|
||||
LOSE ("invalid ELF header");
|
||||
if (header->e_ident[EI_CLASS] != ELFCLASS32)
|
||||
LOSE ("ELF file class not 32-bit");
|
||||
#define ELF32_CLASS ELFCLASS32
|
||||
#define ELF64_CLASS ELFCLASS64
|
||||
if (header->e_ident[EI_CLASS] != ELFW(CLASS))
|
||||
LOSE ("ELF file class not " STRING(__ELF_WORDSIZE) "-bit");
|
||||
if (header->e_ident[EI_DATA] != byteorder)
|
||||
LOSE ("ELF file data encoding not " byteorder_name);
|
||||
if (header->e_ident[EI_VERSION] != EV_CURRENT)
|
||||
@ -270,7 +301,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
LOSE ("ELF file version not " STRING(EV_CURRENT));
|
||||
if (! elf_machine_matches_host (header->e_machine))
|
||||
LOSE ("ELF file machine architecture not " ELF_MACHINE_NAME);
|
||||
if (header->e_phentsize != sizeof (Elf32_Phdr))
|
||||
if (header->e_phentsize != sizeof (ElfW(Phdr)))
|
||||
LOSE ("ELF file's phentsize not the expected size");
|
||||
|
||||
/* Enter the new object in the list of loaded objects. */
|
||||
@ -289,13 +320,13 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
l->l_entry = header->e_entry;
|
||||
type = header->e_type;
|
||||
l->l_phnum = header->e_phnum;
|
||||
phdr = map (header->e_phoff, l->l_phnum * sizeof (Elf32_Phdr));
|
||||
phdr = map (header->e_phoff, l->l_phnum * sizeof (ElfW(Phdr)));
|
||||
|
||||
{
|
||||
/* Scan the program header table, collecting its load commands. */
|
||||
struct loadcmd
|
||||
{
|
||||
Elf32_Addr mapstart, mapend, dataend, allocend;
|
||||
ElfW(Addr) mapstart, mapend, dataend, allocend;
|
||||
off_t mapoff;
|
||||
int prot;
|
||||
} loadcmds[l->l_phnum], *c;
|
||||
@ -320,15 +351,15 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
case PT_LOAD:
|
||||
/* A load command tells us to map in part of the file.
|
||||
We record the load commands and process them all later. */
|
||||
if (ph->p_align % pagesize != 0)
|
||||
if (ph->p_align % _dl_pagesize != 0)
|
||||
LOSE ("ELF load command alignment not page-aligned");
|
||||
if ((ph->p_vaddr - ph->p_offset) % ph->p_align)
|
||||
LOSE ("ELF load command address/offset not properly aligned");
|
||||
{
|
||||
struct loadcmd *c = &loadcmds[nloadcmds++];
|
||||
c->mapstart = ph->p_vaddr & ~(ph->p_align - 1);
|
||||
c->mapend = ((ph->p_vaddr + ph->p_filesz + pagesize - 1)
|
||||
& ~(pagesize - 1));
|
||||
c->mapend = ((ph->p_vaddr + ph->p_filesz + _dl_pagesize - 1)
|
||||
& ~(_dl_pagesize - 1));
|
||||
c->dataend = ph->p_vaddr + ph->p_filesz;
|
||||
c->allocend = ph->p_vaddr + ph->p_memsz;
|
||||
c->mapoff = ph->p_offset & ~(ph->p_align - 1);
|
||||
@ -344,7 +375,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
}
|
||||
|
||||
/* We are done reading the file's headers now. Unmap them. */
|
||||
munmap (file_mapping, mapping_size);
|
||||
__munmap (file_mapping, mapping_size);
|
||||
|
||||
/* Now process the load commands and map segments into memory. */
|
||||
c = loadcmds;
|
||||
@ -362,16 +393,16 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
mapat = map_segment (c->mapstart,
|
||||
loadcmds[nloadcmds - 1].allocend - c->mapstart,
|
||||
c->prot, 0, c->mapoff);
|
||||
l->l_addr = (Elf32_Addr) mapat - c->mapstart;
|
||||
l->l_addr = (ElfW(Addr)) mapat - c->mapstart;
|
||||
|
||||
/* Change protection on the excess portion to disallow all access;
|
||||
the portions we do not remap later will be inaccessible as if
|
||||
unallocated. Then jump into the normal segment-mapping loop to
|
||||
handle the portion of the segment past the end of the file
|
||||
mapping. */
|
||||
mprotect (mapat + c->mapend,
|
||||
loadcmds[nloadcmds - 1].allocend - c->mapend,
|
||||
0);
|
||||
__mprotect (mapat + c->mapend,
|
||||
loadcmds[nloadcmds - 1].allocend - c->mapend,
|
||||
0);
|
||||
goto postmap;
|
||||
}
|
||||
|
||||
@ -387,11 +418,11 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
{
|
||||
/* Extra zero pages should appear at the end of this segment,
|
||||
after the data mapped from the file. */
|
||||
Elf32_Addr zero, zeroend, zeropage;
|
||||
ElfW(Addr) zero, zeroend, zeropage;
|
||||
|
||||
zero = l->l_addr + c->dataend;
|
||||
zeroend = l->l_addr + c->allocend;
|
||||
zeropage = (zero + pagesize - 1) & ~(pagesize - 1);
|
||||
zeropage = (zero + _dl_pagesize - 1) & ~(_dl_pagesize - 1);
|
||||
|
||||
if (zeroend < zeropage)
|
||||
/* All the extra data is in the last page of the segment.
|
||||
@ -404,23 +435,23 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
if ((c->prot & PROT_WRITE) == 0)
|
||||
{
|
||||
/* Dag nab it. */
|
||||
if (mprotect ((caddr_t) (zero & ~(pagesize - 1)),
|
||||
pagesize, c->prot|PROT_WRITE) < 0)
|
||||
if (__mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)),
|
||||
_dl_pagesize, c->prot|PROT_WRITE) < 0)
|
||||
lose (errno, "cannot change memory protections");
|
||||
}
|
||||
memset ((void *) zero, 0, zeropage - zero);
|
||||
if ((c->prot & PROT_WRITE) == 0)
|
||||
mprotect ((caddr_t) (zero & ~(pagesize - 1)),
|
||||
pagesize, c->prot);
|
||||
__mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)),
|
||||
_dl_pagesize, c->prot);
|
||||
}
|
||||
|
||||
if (zeroend > zeropage)
|
||||
{
|
||||
/* Map the remaining zero pages in from the zero fill FD. */
|
||||
caddr_t mapat;
|
||||
mapat = mmap ((caddr_t) zeropage, zeroend - zeropage, c->prot,
|
||||
MAP_ANON|MAP_PRIVATE|MAP_FIXED,
|
||||
_dl_zerofd, 0);
|
||||
mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage,
|
||||
c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED,
|
||||
_dl_zerofd, 0);
|
||||
if (mapat == (caddr_t) -1)
|
||||
lose (errno, "cannot map zero-fill pages");
|
||||
}
|
||||
@ -441,11 +472,11 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
|
||||
LOSE ("object file has no dynamic section");
|
||||
}
|
||||
else
|
||||
(Elf32_Addr) l->l_ld += l->l_addr;
|
||||
(ElfW(Addr)) l->l_ld += l->l_addr;
|
||||
|
||||
if (l->l_phdr == 0)
|
||||
l->l_phdr = (void *) ((const Elf32_Ehdr *) l->l_addr)->e_phoff;
|
||||
(Elf32_Addr) l->l_phdr += l->l_addr;
|
||||
l->l_phdr = (void *) ((const ElfW(Ehdr) *) l->l_addr)->e_phoff;
|
||||
(ElfW(Addr)) l->l_phdr += l->l_addr;
|
||||
|
||||
elf_get_dynamic_info (l->l_ld, l->l_info);
|
||||
if (l->l_info[DT_HASH])
|
||||
|
103
elf/dl-lookup.c
103
elf/dl-lookup.c
@ -18,27 +18,48 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <libelf.h>
|
||||
#include <link.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
/* This is the hashing function specified by the ELF ABI. */
|
||||
static inline unsigned
|
||||
_dl_elf_hash (const char *name)
|
||||
{
|
||||
unsigned long int hash = 0;
|
||||
while (*name != '\0')
|
||||
{
|
||||
unsigned long int hi;
|
||||
hash = (hash << 4) + *name++;
|
||||
hi = hash & 0xf0000000;
|
||||
if (hi != 0)
|
||||
{
|
||||
hash ^= hi >> 24;
|
||||
/* The ELF ABI says `hash &= ~hi', but this is equivalent
|
||||
in this case and on some machines one insn instead of two. */
|
||||
hash ^= hi;
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* Search loaded objects' symbol tables for a definition of the symbol
|
||||
UNDEF_NAME. The chosen value can't be RELOC_ADDR. If NOPLT is nonzero,
|
||||
then a PLT entry cannot satisfy the reference; some different binding
|
||||
must be found. */
|
||||
|
||||
Elf32_Addr
|
||||
_dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
ElfW(Addr)
|
||||
_dl_lookup_symbol (const char *undef_name, const ElfW(Sym) **ref,
|
||||
struct link_map *symbol_scope[2],
|
||||
const char *reference_name,
|
||||
Elf32_Addr reloc_addr,
|
||||
ElfW(Addr) reloc_addr,
|
||||
int noplt)
|
||||
{
|
||||
unsigned long int hash = elf_hash (undef_name);
|
||||
const unsigned long int hash = _dl_elf_hash (undef_name);
|
||||
struct
|
||||
{
|
||||
Elf32_Addr a;
|
||||
const Elf32_Sym *s;
|
||||
ElfW(Addr) a;
|
||||
const ElfW(Sym) *s;
|
||||
} weak_value = { 0, NULL };
|
||||
size_t i;
|
||||
struct link_map **scope, *map;
|
||||
@ -48,9 +69,9 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
if (*scope)
|
||||
for (i = 0; i < (*scope)->l_nsearchlist; ++i)
|
||||
{
|
||||
const Elf32_Sym *symtab;
|
||||
const ElfW(Sym) *symtab;
|
||||
const char *strtab;
|
||||
Elf32_Word symidx;
|
||||
ElfW(Word) symidx;
|
||||
|
||||
map = (*scope)->l_searchlist[i];
|
||||
|
||||
@ -63,7 +84,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
symidx != STN_UNDEF;
|
||||
symidx = map->l_chain[symidx])
|
||||
{
|
||||
const Elf32_Sym *sym = &symtab[symidx];
|
||||
const ElfW(Sym) *sym = &symtab[symidx];
|
||||
|
||||
if (sym->st_value == 0 || /* No value. */
|
||||
/* Cannot resolve to the location being filled in. */
|
||||
@ -71,7 +92,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
(noplt && sym->st_shndx == SHN_UNDEF)) /* Reject PLT. */
|
||||
continue;
|
||||
|
||||
switch (ELF32_ST_TYPE (sym->st_info))
|
||||
switch (ELFW(ST_TYPE) (sym->st_info))
|
||||
{
|
||||
case STT_NOTYPE:
|
||||
case STT_FUNC:
|
||||
@ -86,7 +107,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
/* Not the symbol we are looking for. */
|
||||
continue;
|
||||
|
||||
switch (ELF32_ST_BIND (sym->st_info))
|
||||
switch (ELFW(ST_BIND) (sym->st_info))
|
||||
{
|
||||
case STB_GLOBAL:
|
||||
/* Global definition. Just what we need. */
|
||||
@ -108,41 +129,15 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
}
|
||||
}
|
||||
|
||||
if (weak_value.s == NULL && ELF32_ST_BIND ((*ref)->st_info) != STB_WEAK)
|
||||
if (weak_value.s == NULL && ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK)
|
||||
{
|
||||
/* The symbol was not defined by any object in scope. To allow
|
||||
access to dynamic linker functionality without using -ldl and
|
||||
thereby brining the dynamic linker's symbols into scope, we
|
||||
recognize a few magical symbol names and resolve them to the
|
||||
addresses of functions inside the dynamic linker. */
|
||||
|
||||
struct magic
|
||||
{
|
||||
unsigned long int hash;
|
||||
const char *name;
|
||||
Elf32_Addr value;
|
||||
};
|
||||
static struct magic magic[] =
|
||||
{
|
||||
{ 0xd6a2a5e, "_GNU_libc_dl_open", (Elf32_Addr) &_dl_open },
|
||||
/* { 0x69ef845, "_GNU_libc_dl_close", (Elf32_Addr) &_dl_close },*/
|
||||
{ 0xae4d63c, "_GNU_libc_dl_symbol", (Elf32_Addr) &_dl_symbol_value },
|
||||
{ 0, NULL, 0 }
|
||||
};
|
||||
struct magic *m;
|
||||
|
||||
for (m = magic; m->hash; ++m)
|
||||
if (hash == m->hash && !strcmp (undef_name, m->name))
|
||||
return m->value;
|
||||
|
||||
{
|
||||
const char msg[] = "undefined symbol: ";
|
||||
char buf[sizeof msg + strlen (undef_name)];
|
||||
memcpy (buf, msg, sizeof msg - 1);
|
||||
memcpy (&buf[sizeof msg - 1], undef_name,
|
||||
sizeof buf - sizeof msg + 1);
|
||||
_dl_signal_error (0, reference_name, buf);
|
||||
}
|
||||
/* We could find no value for a strong reference. */
|
||||
const char msg[] = "undefined symbol: ";
|
||||
char buf[sizeof msg + strlen (undef_name)];
|
||||
memcpy (buf, msg, sizeof msg - 1);
|
||||
memcpy (&buf[sizeof msg - 1], undef_name,
|
||||
sizeof buf - sizeof msg + 1);
|
||||
_dl_signal_error (0, reference_name, buf);
|
||||
}
|
||||
|
||||
*ref = weak_value.s;
|
||||
@ -155,23 +150,11 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
void
|
||||
_dl_setup_hash (struct link_map *map)
|
||||
{
|
||||
Elf32_Word *hash = (void *) map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr;
|
||||
Elf32_Word nchain;
|
||||
ElfW(Word) *hash = (void *) map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr;
|
||||
ElfW(Word) nchain;
|
||||
map->l_nbuckets = *hash++;
|
||||
nchain = *hash++;
|
||||
map->l_buckets = hash;
|
||||
hash += map->l_nbuckets;
|
||||
map->l_chain = hash;
|
||||
}
|
||||
|
||||
/* Look up symbol NAME in MAP's scope and return its run-time address. */
|
||||
|
||||
Elf32_Addr
|
||||
_dl_symbol_value (struct link_map *map, const char *name)
|
||||
{
|
||||
Elf32_Addr loadbase;
|
||||
const Elf32_Sym *ref = NULL;
|
||||
struct link_map *scope[2] = { map, NULL };
|
||||
loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0, 0);
|
||||
return loadbase + ref->st_value;
|
||||
}
|
||||
|
@ -34,10 +34,9 @@ void *
|
||||
malloc (size_t n)
|
||||
{
|
||||
extern int _dl_zerofd;
|
||||
static size_t pagesize;
|
||||
|
||||
if (pagesize == 0)
|
||||
pagesize = __getpagesize ();
|
||||
if (_dl_pagesize == 0)
|
||||
_dl_pagesize = __getpagesize ();
|
||||
|
||||
if (_dl_zerofd == -1)
|
||||
_dl_zerofd = _dl_sysdep_open_zero_fill ();
|
||||
@ -47,8 +46,8 @@ malloc (size_t n)
|
||||
/* Consume any unused space in the last page of our data segment. */
|
||||
extern int _end;
|
||||
alloc_ptr = &_end;
|
||||
alloc_end = (void *) 0 + (((alloc_ptr - (void *) 0) + pagesize - 1)
|
||||
& ~(pagesize - 1));
|
||||
alloc_end = (void *) 0 + (((alloc_ptr - (void *) 0) + _dl_pagesize - 1)
|
||||
& ~(_dl_pagesize - 1));
|
||||
}
|
||||
|
||||
/* Make sure the allocation pointer is ideally aligned. */
|
||||
@ -59,13 +58,13 @@ malloc (size_t n)
|
||||
{
|
||||
/* Insufficient space left; allocate another page. */
|
||||
caddr_t page;
|
||||
assert (n <= pagesize);
|
||||
page = mmap (0, pagesize, PROT_READ|PROT_WRITE,
|
||||
MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0);
|
||||
assert (n <= _dl_pagesize);
|
||||
page = __mmap (0, _dl_pagesize, PROT_READ|PROT_WRITE,
|
||||
MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0);
|
||||
assert (page != (caddr_t) -1);
|
||||
if (page != alloc_end)
|
||||
alloc_ptr = page;
|
||||
alloc_end = page + pagesize;
|
||||
alloc_end = page + _dl_pagesize;
|
||||
}
|
||||
|
||||
alloc_last_block = (void *) alloc_ptr;
|
||||
|
45
elf/dl-open.c
Normal file
45
elf/dl-open.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* Load a shared object at runtime, relocate it, and run its initializer.
|
||||
Copyright (C) 1996 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
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <link.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
struct link_map *
|
||||
_dl_open (struct link_map *parent, const char *file, int mode)
|
||||
{
|
||||
struct link_map *new, *l;
|
||||
ElfW(Addr) init;
|
||||
|
||||
/* Load the named object. */
|
||||
new = _dl_map_object (parent, file);
|
||||
|
||||
/* Load that object's dependencies. */
|
||||
_dl_map_object_deps (new);
|
||||
|
||||
/* Relocate the objects loaded. */
|
||||
for (l = new; l; l = l->l_next)
|
||||
if (! l->l_relocated)
|
||||
_dl_relocate_object (l, (mode & RTLD_BINDING_MASK) == RTLD_LAZY);
|
||||
|
||||
/* Run the initializer functions of new objects. */
|
||||
while (init = _dl_init_next (new))
|
||||
(*(void (*) (void)) init) ();
|
||||
|
||||
return new;
|
||||
}
|
@ -28,8 +28,6 @@ Cambridge, MA 02139, USA. */
|
||||
void
|
||||
_dl_relocate_object (struct link_map *l, int lazy)
|
||||
{
|
||||
const size_t pagesize = getpagesize ();
|
||||
|
||||
if (l->l_relocated)
|
||||
return;
|
||||
|
||||
@ -37,17 +35,17 @@ _dl_relocate_object (struct link_map *l, int lazy)
|
||||
{
|
||||
/* Bletch. We must make read-only segments writable
|
||||
long enough to relocate them. */
|
||||
const Elf32_Phdr *ph;
|
||||
const ElfW(Phdr) *ph;
|
||||
for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
|
||||
if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
|
||||
{
|
||||
caddr_t mapstart = ((caddr_t) l->l_addr +
|
||||
(ph->p_vaddr & ~(pagesize - 1)));
|
||||
(ph->p_vaddr & ~(_dl_pagesize - 1)));
|
||||
caddr_t mapend = ((caddr_t) l->l_addr +
|
||||
((ph->p_vaddr + ph->p_memsz + pagesize - 1)
|
||||
& ~(pagesize - 1)));
|
||||
if (mprotect (mapstart, mapend - mapstart,
|
||||
PROT_READ|PROT_WRITE) < 0)
|
||||
((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1)
|
||||
& ~(_dl_pagesize - 1)));
|
||||
if (__mprotect (mapstart, mapend - mapstart,
|
||||
PROT_READ|PROT_WRITE) < 0)
|
||||
_dl_signal_error (errno, l->l_name,
|
||||
"cannot make segment writable for relocation");
|
||||
}
|
||||
@ -59,8 +57,8 @@ _dl_relocate_object (struct link_map *l, int lazy)
|
||||
const char *strtab
|
||||
= ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
|
||||
Elf32_Addr resolve (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr, int noplt)
|
||||
ElfW(Addr) resolve (const ElfW(Sym) **ref,
|
||||
ElfW(Addr) reloc_addr, int noplt)
|
||||
{
|
||||
return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope,
|
||||
l->l_name, reloc_addr, noplt);
|
||||
@ -97,21 +95,21 @@ _dl_relocate_object (struct link_map *l, int lazy)
|
||||
if (l->l_info[DT_TEXTREL])
|
||||
{
|
||||
/* Undo the protection change we made before relocating. */
|
||||
const Elf32_Phdr *ph;
|
||||
const ElfW(Phdr) *ph;
|
||||
for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
|
||||
if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
|
||||
{
|
||||
caddr_t mapstart = ((caddr_t) l->l_addr +
|
||||
(ph->p_vaddr & ~(pagesize - 1)));
|
||||
(ph->p_vaddr & ~(_dl_pagesize - 1)));
|
||||
caddr_t mapend = ((caddr_t) l->l_addr +
|
||||
((ph->p_vaddr + ph->p_memsz + pagesize - 1)
|
||||
& ~(pagesize - 1)));
|
||||
((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1)
|
||||
& ~(_dl_pagesize - 1)));
|
||||
int prot = 0;
|
||||
if (ph->p_flags & PF_R)
|
||||
prot |= PROT_READ;
|
||||
if (ph->p_flags & PF_X)
|
||||
prot |= PROT_EXEC;
|
||||
if (mprotect (mapstart, mapend - mapstart, prot) < 0)
|
||||
if (__mprotect (mapstart, mapend - mapstart, prot) < 0)
|
||||
_dl_signal_error (errno, l->l_name,
|
||||
"can't restore segment prot after reloc");
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ Cambridge, MA 02139, USA. */
|
||||
#define elf_machine_rel 1
|
||||
#define elf_machine_rela 2
|
||||
#if elf_machine_relplt == elf_machine_rel
|
||||
#define PLTREL Elf32_Rel
|
||||
#define PLTREL ElfW(Rel)
|
||||
#elif elf_machine_relplt == elf_machine_rela
|
||||
#define PLTREL Elf32_Rela
|
||||
#define PLTREL ElfW(Rela)
|
||||
#else
|
||||
#error "dl-machine.h bug: elf_machine_relplt not rel or rela"
|
||||
#endif
|
||||
@ -37,11 +37,11 @@ Cambridge, MA 02139, USA. */
|
||||
in the trampoline code will be a local PC-relative call. Tell the
|
||||
compiler not to worry that the function appears not to be called. */
|
||||
|
||||
static Elf32_Addr fixup (
|
||||
static ElfW(Addr) fixup (
|
||||
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
|
||||
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
|
||||
#endif
|
||||
struct link_map *l, Elf32_Word reloc_offset)
|
||||
struct link_map *l, ElfW(Word) reloc_offset)
|
||||
__attribute__ ((unused));
|
||||
|
||||
/* This function is called through a special trampoline from the PLT the
|
||||
@ -51,15 +51,15 @@ static Elf32_Addr fixup (
|
||||
to that address. Future calls will bounce directly from the PLT to the
|
||||
function. */
|
||||
|
||||
static Elf32_Addr
|
||||
static ElfW(Addr)
|
||||
fixup (
|
||||
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
|
||||
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
|
||||
#endif
|
||||
struct link_map *l, Elf32_Word reloc_offset)
|
||||
struct link_map *l, ElfW(Word) reloc_offset)
|
||||
{
|
||||
const Elf32_Sym *const symtab
|
||||
= (const Elf32_Sym *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
const ElfW(Sym) *const symtab
|
||||
= (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
const char *strtab =
|
||||
(const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
|
||||
@ -67,8 +67,8 @@ fixup (
|
||||
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
|
||||
reloc_offset);
|
||||
|
||||
Elf32_Addr resolve (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr, int noplt)
|
||||
ElfW(Addr) resolve (const ElfW(Sym) **ref,
|
||||
ElfW(Addr) reloc_addr, int noplt)
|
||||
{
|
||||
struct link_map *scope[2] = { _dl_loaded, NULL };
|
||||
return _dl_lookup_symbol (strtab + (*ref)->st_name, ref,
|
||||
@ -76,9 +76,9 @@ fixup (
|
||||
}
|
||||
|
||||
/* Perform the specified relocation. */
|
||||
elf_machine_relplt (l, reloc, &symtab[ELF32_R_SYM (reloc->r_info)], resolve);
|
||||
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)], resolve);
|
||||
|
||||
return *(Elf32_Addr *) (l->l_addr + reloc->r_offset);
|
||||
return *(ElfW(Addr) *) (l->l_addr + reloc->r_offset);
|
||||
}
|
||||
|
||||
|
||||
|
51
elf/dl-support.c
Normal file
51
elf/dl-support.c
Normal file
@ -0,0 +1,51 @@
|
||||
/* Support for dynamic linking code in static libc.
|
||||
Copyright (C) 1996 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
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* This file defines some things that for the dynamic linker are defined in
|
||||
rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */
|
||||
|
||||
int _dl_secure; /* Always honor LD_LIBRARY_PATH. */
|
||||
|
||||
extern char *__progname;
|
||||
char **_dl_argv = &__progname; /* This is checked for some error messages. */
|
||||
|
||||
/* This defines the default search path for libraries.
|
||||
For the dynamic linker it is set by -rpath when linking. */
|
||||
const char *_dl_rpath = DEFAULT_RPATH;
|
||||
|
||||
/* This is the only dl-sysdep.c function that is actually needed at run-time
|
||||
by _dl_map_object. */
|
||||
|
||||
int
|
||||
_dl_sysdep_open_zero_fill (void)
|
||||
{
|
||||
return __open ("/dev/zero", O_RDONLY);
|
||||
}
|
||||
|
||||
/* This should never be called. */
|
||||
void
|
||||
_dl_sysdep_fatal (void)
|
||||
{
|
||||
assert (! "_dl_sysdep_fatal called");
|
||||
}
|
||||
|
33
elf/dl-symbol.c
Normal file
33
elf/dl-symbol.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* Look up a symbol's run-time value in the scope of a loaded object.
|
||||
Copyright (C) 1995, 1996 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
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <link.h>
|
||||
|
||||
/* Look up symbol NAME in MAP's scope and return its run-time address. */
|
||||
|
||||
ElfW(Addr)
|
||||
_dl_symbol_value (struct link_map *map, const char *name)
|
||||
{
|
||||
ElfW(Addr) loadbase;
|
||||
const ElfW(Sym) *ref = NULL;
|
||||
struct link_map *scope[2] = { map, NULL };
|
||||
loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0, 0);
|
||||
return loadbase + ref->st_value;
|
||||
}
|
@ -25,9 +25,9 @@ Cambridge, MA 02139, USA. */
|
||||
int
|
||||
dladdr (void *address, Dl_info *info)
|
||||
{
|
||||
const Elf32_Addr addr = (Elf32_Addr) address;
|
||||
const ElfW(Addr) addr = (ElfW(Addr)) address;
|
||||
struct link_map *l, *match;
|
||||
const Elf32_Sym *symtab, *matchsym;
|
||||
const ElfW(Sym) *symtab, *matchsym;
|
||||
const char *strtab;
|
||||
|
||||
/* Find the highest-addressed object that ADDRESS is not below. */
|
||||
@ -64,8 +64,8 @@ dladdr (void *address, Dl_info *info)
|
||||
for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
|
||||
if (addr >= match->l_addr + symtab->st_value && !matchsym ||
|
||||
matchsym->st_value < symtab->st_value &&
|
||||
ELF32_ST_BIND (symtab->st_info) == STB_GLOBAL ||
|
||||
ELF32_ST_BIND (symtab->st_info) == STB_WEAK)
|
||||
ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL ||
|
||||
ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
|
||||
matchsym = symtab;
|
||||
|
||||
if (matchsym)
|
||||
|
@ -65,7 +65,7 @@ dlclose (void *handle)
|
||||
{
|
||||
/* That was the last reference, and this was a dlopen-loaded
|
||||
object. We can unmap it. */
|
||||
const Elf32_Phdr *ph;
|
||||
const ElfW(Phdr) *ph;
|
||||
|
||||
if (map->l_info[DT_FINI])
|
||||
/* Call its termination function. */
|
||||
@ -76,8 +76,8 @@ dlclose (void *handle)
|
||||
for (ph = map->l_phdr; ph < &map->l_phdr[map->l_phnum]; ++ph)
|
||||
if (ph->p_type == PT_LOAD)
|
||||
{
|
||||
Elf32_Addr mapstart = ph->p_vaddr & ~(ph->p_align - 1);
|
||||
Elf32_Addr mapend = ((ph->p_vaddr + ph->p_memsz
|
||||
ElfW(Addr) mapstart = ph->p_vaddr & ~(ph->p_align - 1);
|
||||
ElfW(Addr) mapend = ((ph->p_vaddr + ph->p_memsz
|
||||
+ ph->p_align - 1)
|
||||
& ~(ph->p_align - 1));
|
||||
munmap ((caddr_t) mapstart, mapend - mapstart);
|
||||
|
@ -27,8 +27,8 @@ void *
|
||||
dlsym (void *handle, const char *name)
|
||||
{
|
||||
struct link_map *map = handle;
|
||||
Elf32_Addr loadbase;
|
||||
const Elf32_Sym *ref = NULL;
|
||||
ElfW(Addr) loadbase;
|
||||
const ElfW(Sym) *ref = NULL;
|
||||
void doit (void)
|
||||
{
|
||||
struct link_map *scope[2] = { map, NULL };
|
||||
|
24
elf/do-rel.h
24
elf/do-rel.h
@ -21,9 +21,9 @@ Cambridge, MA 02139, USA. */
|
||||
`elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */
|
||||
|
||||
#ifdef DO_RELA
|
||||
#define elf_dynamic_do_rel elf_dynamic_do_rela
|
||||
#define Elf32_Rel Elf32_Rela
|
||||
#define elf_machine_rel elf_machine_rela
|
||||
#define elf_dynamic_do_rel elf_dynamic_do_rela
|
||||
#define Rel Rela
|
||||
#define elf_machine_rel elf_machine_rela
|
||||
#endif
|
||||
|
||||
|
||||
@ -37,15 +37,15 @@ Cambridge, MA 02139, USA. */
|
||||
static inline void
|
||||
elf_dynamic_do_rel (struct link_map *map,
|
||||
int reltag, int sztag,
|
||||
Elf32_Addr (*resolve) (const Elf32_Sym **symbol,
|
||||
Elf32_Addr reloc_addr, int noplt),
|
||||
ElfW(Addr) (*resolve) (const ElfW(Sym) **symbol,
|
||||
ElfW(Addr) reloc_addr, int noplt),
|
||||
int lazy)
|
||||
{
|
||||
const Elf32_Sym *const symtab
|
||||
= (const Elf32_Sym *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
const Elf32_Rel *r
|
||||
= (const Elf32_Rel *) (map->l_addr + map->l_info[reltag]->d_un.d_ptr);
|
||||
const Elf32_Rel *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r];
|
||||
const ElfW(Sym) *const symtab
|
||||
= (const ElfW(Sym) *) (map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
const ElfW(Rel) *r
|
||||
= (const ElfW(Rel) *) (map->l_addr + map->l_info[reltag]->d_un.d_ptr);
|
||||
const ElfW(Rel) *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r];
|
||||
|
||||
if (lazy)
|
||||
/* Doing lazy PLT relocations; they need very little info. */
|
||||
@ -53,9 +53,9 @@ elf_dynamic_do_rel (struct link_map *map,
|
||||
elf_machine_lazy_rel (map, r);
|
||||
else
|
||||
for (; r < end; ++r)
|
||||
elf_machine_rel (map, r, &symtab[ELF32_R_SYM (r->r_info)], resolve);
|
||||
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], resolve);
|
||||
}
|
||||
|
||||
#undef elf_dynamic_do_rel
|
||||
#undef Elf32_Rel
|
||||
#undef Rel
|
||||
#undef elf_machine_rel
|
||||
|
@ -25,7 +25,7 @@ Cambridge, MA 02139, USA. */
|
||||
/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
|
||||
|
||||
static inline void
|
||||
elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM + DT_PROCNUM])
|
||||
elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Dyn) *info[DT_NUM + DT_PROCNUM])
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -48,9 +48,9 @@ elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM + DT_PROCNUM])
|
||||
}
|
||||
|
||||
if (info[DT_RELA])
|
||||
assert (info[DT_RELAENT]->d_un.d_val == sizeof (Elf32_Rela));
|
||||
assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
|
||||
if (info[DT_REL])
|
||||
assert (info[DT_RELENT]->d_un.d_val == sizeof (Elf32_Rel));
|
||||
assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
|
||||
if (info[DT_PLTREL])
|
||||
assert (info[DT_PLTREL]->d_un.d_val == DT_REL ||
|
||||
info[DT_PLTREL]->d_un.d_val == DT_RELA);
|
||||
|
244
elf/elf.h
244
elf/elf.h
@ -23,16 +23,37 @@ Cambridge, MA 02139, USA. */
|
||||
#define _ELF_H 1
|
||||
|
||||
|
||||
/* Standard ELF types.
|
||||
/* Standard ELF types. Using __attribute__ mode ensures that GCC
|
||||
will choose the right number of bits for these types. */
|
||||
|
||||
Using __attribute__ mode ensures that gcc will choose the right for
|
||||
these types. */
|
||||
|
||||
typedef unsigned int Elf32_Addr __attribute__ ((mode (SI)));
|
||||
/* Type for a 16-bit quantity. */
|
||||
typedef unsigned int Elf32_Half __attribute__ ((mode (HI)));
|
||||
typedef unsigned int Elf32_Off __attribute__ ((mode (SI)));
|
||||
typedef int Elf32_Sword __attribute__ ((mode (SI)));
|
||||
typedef unsigned int Elf64_Half __attribute__ ((mode (HI)));
|
||||
|
||||
/* Types for signed and unsigned 32-bit quantities. */
|
||||
typedef unsigned int Elf32_Word __attribute__ ((mode (SI)));
|
||||
typedef int Elf32_Sword __attribute__ ((mode (SI)));
|
||||
typedef unsigned int Elf64_Word __attribute__ ((mode (SI)));
|
||||
typedef int Elf64_Sword __attribute__ ((mode (SI)));
|
||||
|
||||
/* Types for signed and unsigned 64-bit quantities. */
|
||||
typedef unsigned int Elf32_Xword __attribute__ ((mode (DI)));
|
||||
typedef int Elf32_Sxword __attribute__ ((mode (DI)));
|
||||
typedef unsigned int Elf64_Xword __attribute__ ((mode (DI)));
|
||||
typedef int Elf64_Sxword __attribute__ ((mode (DI)));
|
||||
|
||||
/* Type of addresses. */
|
||||
typedef unsigned int Elf32_Addr __attribute__ ((mode (SI)));
|
||||
typedef unsigned int Elf64_Addr __attribute__ ((mode (DI)));
|
||||
|
||||
/* Type of file offsets. */
|
||||
typedef unsigned int Elf32_Off __attribute__ ((mode (SI)));
|
||||
typedef unsigned int Elf64_Off __attribute__ ((mode (DI)));
|
||||
|
||||
/* Type for section indices, which are 16-bit quantities. */
|
||||
typedef unsigned int Elf32_Section __attribute__ ((mode (HI)));
|
||||
typedef unsigned int Elf64_Section __attribute__ ((mode (HI)));
|
||||
|
||||
|
||||
/* The ELF file header. This appears at the start of every ELF file. */
|
||||
|
||||
@ -56,6 +77,24 @@ typedef struct
|
||||
Elf32_Half e_shstrndx; /* Section header string table index */
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
|
||||
Elf64_Half e_type; /* Object file type */
|
||||
Elf64_Half e_machine; /* Architecture */
|
||||
Elf64_Word e_version; /* Object file version */
|
||||
Elf64_Addr e_entry; /* Entry point virtual address */
|
||||
Elf64_Off e_phoff; /* Program header table file offset */
|
||||
Elf64_Off e_shoff; /* Section header table file offset */
|
||||
Elf64_Word e_flags; /* Processor-specific flags */
|
||||
Elf64_Half e_ehsize; /* ELF header size in bytes */
|
||||
Elf64_Half e_phentsize; /* Program header table entry size */
|
||||
Elf64_Half e_phnum; /* Program header table entry count */
|
||||
Elf64_Half e_shentsize; /* Section header table entry size */
|
||||
Elf64_Half e_shnum; /* Section header table entry count */
|
||||
Elf64_Half e_shstrndx; /* Section header string table index */
|
||||
} Elf64_Ehdr;
|
||||
|
||||
/* Fields in the e_ident array. The EI_* macros are indices into the
|
||||
array. The macros under each EI_* macro are the values the byte
|
||||
may have. */
|
||||
@ -125,6 +164,8 @@ typedef struct
|
||||
pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
|
||||
chances of collision with official or non-GNU unofficial values. */
|
||||
|
||||
#define EM_ALPHA 0x9026
|
||||
|
||||
/* Legal values for e_version (version). */
|
||||
|
||||
#define EV_NONE 0 /* Invalid ELF version */
|
||||
@ -146,6 +187,20 @@ typedef struct
|
||||
Elf32_Word sh_entsize; /* Entry size if section holds table */
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word sh_name; /* Section name (string tbl index) */
|
||||
Elf64_Word sh_type; /* Section type */
|
||||
Elf64_Xword sh_flags; /* Section flags */
|
||||
Elf64_Addr sh_addr; /* Section virtual addr at execution */
|
||||
Elf64_Off sh_offset; /* Section file offset */
|
||||
Elf64_Xword sh_size; /* Section size in bytes */
|
||||
Elf64_Word sh_link; /* Link to another section */
|
||||
Elf64_Word sh_info; /* Additional section information */
|
||||
Elf64_Xword sh_addralign; /* Section alignment */
|
||||
Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||
} Elf64_Shdr;
|
||||
|
||||
/* Special section indices. */
|
||||
|
||||
#define SHN_UNDEF 0 /* Undefined section */
|
||||
@ -192,9 +247,19 @@ typedef struct
|
||||
Elf32_Word st_size; /* Symbol size */
|
||||
unsigned char st_info; /* Symbol type and binding */
|
||||
unsigned char st_other; /* No defined meaning, 0 */
|
||||
Elf32_Half st_shndx; /* Section index */
|
||||
Elf32_Section st_shndx; /* Section index */
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word st_name; /* Symbol name (string tbl index) */
|
||||
unsigned char st_info; /* Symbol type and binding */
|
||||
unsigned char st_other; /* No defined meaning, 0 */
|
||||
Elf64_Section st_shndx; /* Section index */
|
||||
Elf64_Addr st_value; /* Symbol value */
|
||||
Elf64_Xword st_size; /* Symbol size */
|
||||
} Elf64_Sym;
|
||||
|
||||
/* Special section index. */
|
||||
|
||||
#define SHN_UNDEF 0 /* No section, undefined symbol. */
|
||||
@ -205,6 +270,11 @@ typedef struct
|
||||
#define ELF32_ST_TYPE(val) ((val) & 0xf)
|
||||
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
|
||||
|
||||
/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */
|
||||
#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
|
||||
#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
|
||||
#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type))
|
||||
|
||||
/* Legal values for ST_BIND subfield of st_info (symbol binding). */
|
||||
|
||||
#define STB_LOCAL 0 /* Local symbol */
|
||||
@ -241,6 +311,17 @@ typedef struct
|
||||
Elf32_Word r_info; /* Relocation type and symbol index */
|
||||
} Elf32_Rel;
|
||||
|
||||
/* I have seen two different definitions of the Elf64_Rel and
|
||||
Elf64_Rela structures, so we'll leave them out until Novell (or
|
||||
whoever) gets their act together. */
|
||||
/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr r_offset; /* Address */
|
||||
Elf64_Xword r_info; /* Relocation type and symbol index */
|
||||
} Elf64_Rel;
|
||||
|
||||
/* Relocation table entry with addend (in section of type SHT_RELA). */
|
||||
|
||||
typedef struct
|
||||
@ -250,6 +331,13 @@ typedef struct
|
||||
Elf32_Sword r_addend; /* Addend */
|
||||
} Elf32_Rela;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr r_offset; /* Address */
|
||||
Elf64_Xword r_info; /* Relocation type and symbol index */
|
||||
Elf64_Sxword r_addend; /* Addend */
|
||||
} Elf64_Rela;
|
||||
|
||||
/* How to extract and insert information held in the r_info field. */
|
||||
|
||||
#define ELF32_R_SYM(val) ((val) >> 8)
|
||||
@ -262,7 +350,8 @@ typedef struct
|
||||
|
||||
/* Program segment header. */
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word p_type; /* Segment type */
|
||||
Elf32_Off p_offset; /* Segment file offset */
|
||||
Elf32_Addr p_vaddr; /* Segment virtual address */
|
||||
@ -273,6 +362,18 @@ typedef struct {
|
||||
Elf32_Word p_align; /* Segment alignment */
|
||||
} Elf32_Phdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word p_type; /* Segment type */
|
||||
Elf64_Word p_flags; /* Segment flags */
|
||||
Elf64_Off p_offset; /* Segment file offset */
|
||||
Elf64_Addr p_vaddr; /* Segment virtual address */
|
||||
Elf64_Addr p_paddr; /* Segment physical address */
|
||||
Elf64_Xword p_filesz; /* Segment size in file */
|
||||
Elf64_Xword p_memsz; /* Segment size in memory */
|
||||
Elf64_Xword p_align; /* Segment alignment */
|
||||
} Elf64_Phdr;
|
||||
|
||||
/* Legal values for p_type (segment type). */
|
||||
|
||||
#define PT_NULL 0 /* Program header table entry unused */
|
||||
@ -316,6 +417,16 @@ typedef struct
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Sxword d_tag; /* Dynamic entry type */
|
||||
union
|
||||
{
|
||||
Elf64_Xword d_val; /* Integer value */
|
||||
Elf64_Addr d_ptr; /* Address value */
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
/* Legal values for d_tag (dynamic entry type). */
|
||||
|
||||
#define DT_NULL 0 /* Marks end of dynamic section */
|
||||
@ -347,76 +458,6 @@ typedef struct
|
||||
#define DT_HIPROC 0x7fffffff /* End of processor-specific */
|
||||
#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */
|
||||
|
||||
/* Standard 64 bit ELF types. */
|
||||
|
||||
typedef unsigned int Elf64_Addr __attribute__ ((mode (DI)));
|
||||
typedef unsigned int Elf64_Half __attribute__ ((mode (HI)));
|
||||
typedef unsigned int Elf64_Off __attribute__ ((mode (DI)));
|
||||
typedef int Elf64_Sword __attribute__ ((mode (SI)));
|
||||
typedef int Elf64_Sxword __attribute__ ((mode (DI)));
|
||||
typedef unsigned int Elf64_Word __attribute__ ((mode (SI)));
|
||||
typedef unsigned int Elf64_Xword __attribute__ ((mode (DI)));
|
||||
typedef unsigned int Elf64_Byte __attribute__ ((mode (QI)));
|
||||
typedef unsigned int Elf64_Section __attribute__ ((mode (HI)));
|
||||
|
||||
/* 64 bit ELF file header. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
|
||||
Elf64_Half e_type; /* Object file type */
|
||||
Elf64_Half e_machine; /* Architecture */
|
||||
Elf64_Word e_version; /* Object file version */
|
||||
Elf64_Addr e_entry; /* Entry point virtual address */
|
||||
Elf64_Off e_phoff; /* Program header table file offset */
|
||||
Elf64_Off e_shoff; /* Section header table file offset */
|
||||
Elf64_Word e_flags; /* Processor-specific flags */
|
||||
Elf64_Half e_ehsize; /* ELF header size in bytes */
|
||||
Elf64_Half e_phentsize; /* Program header table entry size */
|
||||
Elf64_Half e_phnum; /* Program header table entry count */
|
||||
Elf64_Half e_shentsize; /* Section header table entry size */
|
||||
Elf64_Half e_shnum; /* Section header table entry count */
|
||||
Elf64_Half e_shstrndx; /* Section header string table index */
|
||||
} Elf64_Ehdr;
|
||||
|
||||
/* 64 bit section header. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word sh_name; /* Section name (string tbl index) */
|
||||
Elf64_Word sh_type; /* Section type */
|
||||
Elf64_Xword sh_flags; /* Section flags */
|
||||
Elf64_Addr sh_addr; /* Section virtual addr at execution */
|
||||
Elf64_Off sh_offset; /* Section file offset */
|
||||
Elf64_Xword sh_size; /* Section size in bytes */
|
||||
Elf64_Word sh_link; /* Link to another section */
|
||||
Elf64_Word sh_info; /* Additional section information */
|
||||
Elf64_Xword sh_addralign; /* Section alignment */
|
||||
Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||
} Elf64_Shdr;
|
||||
|
||||
/* 64 bit symbol table entry. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word st_name; /* Symbol name (string tbl index) */
|
||||
Elf64_Byte st_info; /* Symbol type and binding */
|
||||
Elf64_Byte st_other; /* No defined meaning, 0 */
|
||||
Elf64_Section st_shndx; /* Section index */
|
||||
Elf64_Addr st_value; /* Symbol value */
|
||||
Elf64_Xword st_size; /* Symbol size */
|
||||
} Elf64_Sym;
|
||||
|
||||
/* The 64 bit st_info field is the same as the 32 bit one. */
|
||||
|
||||
#define ELF64_ST_BIND(val) (((unsigned char) (val)) >> 4)
|
||||
#define ELF64_ST_TYPE(val) ((val) & 0xf)
|
||||
#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
|
||||
|
||||
/* I have seen two different definitions of the Elf64_Rel and
|
||||
Elf64_Rela structures, so we'll leave them out until Novell (or
|
||||
whoever) gets their act together. */
|
||||
|
||||
/* Auxiliary vector. */
|
||||
|
||||
/* This vector is normally only used by the program interpreter. The
|
||||
@ -437,6 +478,17 @@ typedef struct
|
||||
} a_un;
|
||||
} Elf32_auxv_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long int a_type; /* Entry type */
|
||||
union
|
||||
{
|
||||
long int a_val; /* Integer value */
|
||||
void *a_ptr; /* Pointer value */
|
||||
void (*a_fcn) (void); /* Function pointer value */
|
||||
} a_un;
|
||||
} Elf64_auxv_t;
|
||||
|
||||
/* Legal values for a_type (entry type). */
|
||||
|
||||
#define AT_NULL 0 /* End of vector */
|
||||
@ -684,4 +736,38 @@ typedef Elf32_Addr Elf32_Conflict;
|
||||
#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
|
||||
|
||||
|
||||
/* Alpha specific declarations. */
|
||||
|
||||
/* Alpha relocs. */
|
||||
|
||||
#define R_ALPHA_NONE 0 /* No reloc */
|
||||
#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
|
||||
#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
|
||||
#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
|
||||
#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
|
||||
#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
|
||||
#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
|
||||
#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
|
||||
#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
|
||||
#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
|
||||
#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
|
||||
#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
|
||||
#define R_ALPHA_OP_PUSH 12 /* OP stack push */
|
||||
#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */
|
||||
#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */
|
||||
#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */
|
||||
#define R_ALPHA_GPVALUE 16
|
||||
#define R_ALPHA_GPRELHIGH 17
|
||||
#define R_ALPHA_GPRELLOW 18
|
||||
#define R_ALPHA_IMMED_GP_16 19
|
||||
#define R_ALPHA_IMMED_GP_HI32 20
|
||||
#define R_ALPHA_IMMED_SCN_HI32 21
|
||||
#define R_ALPHA_IMMED_BR_HI32 22
|
||||
#define R_ALPHA_IMMED_LO32 23
|
||||
#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
|
||||
#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
|
||||
#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
|
||||
#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
|
||||
|
||||
|
||||
#endif /* elf.h */
|
||||
|
@ -1,4 +0,0 @@
|
||||
/* Define the global function for the inline `elf_hash' in libelf.h. */
|
||||
|
||||
#define _EXTERN_INLINE /* Define the function globally. */
|
||||
#include "libelf.h"
|
283
elf/libelf.h
283
elf/libelf.h
@ -1,283 +0,0 @@
|
||||
/* Interface for manipulating ELF object files; functions found in -lelf.
|
||||
Copyright (C) 1995 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
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _LIBELF_H
|
||||
#define _LIBELF_H 1
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <elf.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Commands to operate on an Elf descriptor.
|
||||
The meanings are slightly different for the different functions. */
|
||||
typedef enum
|
||||
{
|
||||
ELF_C_NULL = 0,
|
||||
ELF_C_READ, /* Read from the file. */
|
||||
ELF_C_WRITE, /* Write the file, ignoring old contents. */
|
||||
ELF_C_CLR, /* Clear specified flag bits. */
|
||||
ELF_C_SET, /* Set specified flag bits. */
|
||||
ELF_C_FDDONE, /* Close the fd; no further io will happen. */
|
||||
ELF_C_FDREAD, /* Read the whole file, then close it. */
|
||||
ELF_C_RDWR, /* Read from and modify the file. */
|
||||
ELF_C_NUM /* Number of valid command values. */
|
||||
} Elf_Cmd;
|
||||
|
||||
|
||||
/* Flag bits for `elf_flag*'. */
|
||||
#define ELF_F_DIRTY 0x1 /* Object is */
|
||||
#define ELF_F_LAYOUT 0x4
|
||||
|
||||
|
||||
/* File types. */
|
||||
typedef enum
|
||||
{
|
||||
ELF_K_NONE = 0,
|
||||
ELF_K_AR,
|
||||
ELF_K_COFF, /* The GNU -lelf does not support COFF. */
|
||||
ELF_K_ELF,
|
||||
ELF_K_NUM /* Number of valid file kinds. */
|
||||
} Elf_Kind;
|
||||
|
||||
|
||||
/* Translation types. */
|
||||
typedef enum
|
||||
{
|
||||
ELF_T_BYTE = 0,
|
||||
ELF_T_ADDR,
|
||||
ELF_T_DYN,
|
||||
ELF_T_EHDR,
|
||||
ELF_T_HALF,
|
||||
ELF_T_OFF,
|
||||
ELF_T_PHDR,
|
||||
ELF_T_RELA,
|
||||
ELF_T_REL,
|
||||
ELF_T_SHDR,
|
||||
ELF_T_SWORD,
|
||||
ELF_T_SYM,
|
||||
ELF_T_WORD,
|
||||
ELF_T_NUM
|
||||
} Elf_Type;
|
||||
|
||||
|
||||
/* These types are opaque to user code; only pointers to them are used. */
|
||||
typedef struct Elf Elf;
|
||||
typedef struct Elf_Scn Elf_Scn;
|
||||
|
||||
|
||||
/* Archive member header. */
|
||||
typedef struct
|
||||
{
|
||||
char *ar_name;
|
||||
time_t ar_date;
|
||||
uid_t ar_uid;
|
||||
gid_t ar_gid;
|
||||
mode_t ar_mode;
|
||||
off_t ar_size;
|
||||
char *ar_rawname;
|
||||
} Elf_Arhdr;
|
||||
|
||||
/* Archive symbol table. */
|
||||
typedef struct
|
||||
{
|
||||
char *as_name;
|
||||
size_t as_off;
|
||||
unsigned long int as_hash;
|
||||
} Elf_Arsym;
|
||||
|
||||
|
||||
/* Data descriptor. */
|
||||
typedef struct
|
||||
{
|
||||
void *d_buf;
|
||||
Elf_Type d_type;
|
||||
size_t d_size;
|
||||
off_t d_off; /* Offset into section. */
|
||||
size_t d_align; /* Alignment in section. */
|
||||
unsigned int d_version; /* ELF version. */
|
||||
} Elf_Data;
|
||||
|
||||
|
||||
|
||||
/* Open an Elf descriptor on file descriptor FD.
|
||||
REF is the Elf descriptor for the containing archive (to open a member);
|
||||
or the descriptor previously returned for FD (to add a user reference);
|
||||
or NULL. */
|
||||
extern Elf *elf_begin __P ((int __fd, Elf_Cmd __cmd, Elf *__ref));
|
||||
|
||||
/* Finish using ELF (remove a user reference); if this is the last user
|
||||
reference, its data will be freed. */
|
||||
extern int elf_end __P ((Elf *__elf));
|
||||
|
||||
/* Control the library's access to the file descriptor for ELF.
|
||||
CMD is either ELF_C_FDDONE or ELF_C_FDREAD. */
|
||||
extern int elf_cntl __P ((Elf *__elf, Elf_Cmd __cmd));
|
||||
|
||||
|
||||
/* Return a string describing an ELF error number. */
|
||||
extern __const char *elf_errmsg __P ((int __errno));
|
||||
|
||||
/* Return the ELF error number for the last failed operation. */
|
||||
extern int elf_errno __P ((void));
|
||||
|
||||
/* Set the byte value used to fill sections for alignment. */
|
||||
extern void elf_fill __P ((int __fillchar));
|
||||
|
||||
/* The following functions `elf_flag*' all operate the same way:
|
||||
CMD is either ELF_C_SET or ELF_C_CLR; FLAGS are `ELF_F_*' above,
|
||||
which are set or cleared for the object the call relates to. */
|
||||
|
||||
/* Modify flags affecting the file as a whole (?). */
|
||||
extern unsigned int elf_flagelf __P ((Elf *__elf, Elf_Cmd __cmd,
|
||||
unsigned int __flags));
|
||||
/* Modify flags affecting DATA. */
|
||||
extern unsigned int elf_flagdata __P ((Elf_Data *__data, Elf_Cmd __cmd,
|
||||
unsigned int __flags));
|
||||
/* Modify flags affecting the ELF header. */
|
||||
extern unsigned int elf_flagehdr __P ((Elf *__elf, Elf_Cmd __cmd,
|
||||
unsigned int __flags));
|
||||
/* Modify flags affecting the ELF program header. */
|
||||
extern unsigned int elf_flagphdr __P ((Elf *__elf, Elf_Cmd __cmd,
|
||||
unsigned int __flags));
|
||||
/* Modify flags affecting the given section's data. */
|
||||
extern unsigned int elf_flagscn __P ((Elf_Scn *__scn, Elf_Cmd __cmd,
|
||||
unsigned int __flags));
|
||||
/* Modify flags affecting the given section's header. */
|
||||
extern unsigned int elf_flagshdr __P ((Elf_Scn *__scn, Elf_Cmd __cmd,
|
||||
unsigned int __flags));
|
||||
|
||||
|
||||
extern size_t elf32_fsize __P ((Elf_Type __type, size_t __count,
|
||||
unsigned int __ver));
|
||||
|
||||
/* Return the archive header for ELF, which must describe an archive. */
|
||||
extern Elf_Arhdr *elf_getarhdr __P ((Elf *__elf));
|
||||
|
||||
/* Return the archive symbol table for ELF, and store
|
||||
in *NELTSP the number of elements in the table. */
|
||||
extern Elf_Arsym *elf_getarsym __P ((Elf *__elf, size_t *__neltsp));
|
||||
|
||||
/* Return the file offset for the beginning of ELF.
|
||||
If ELF describes an archive member, this points to the member header. */
|
||||
extern off_t elf_getbase __P ((Elf *__elf));
|
||||
|
||||
/* Extract the data from a section. */
|
||||
extern Elf_Data *elf_getdata __P ((Elf_Scn *__scn, Elf_Data *__data));
|
||||
|
||||
/* Extract the ELF header from the file. */
|
||||
extern Elf32_Ehdr *elf32_getehdr __P ((Elf *__elf));
|
||||
|
||||
/* Extract the initial ELF identification bytes from the file.
|
||||
If PTR is nonnull, the number of identification bytes is stored there. */
|
||||
extern char *elf_getident __P((Elf *__elf, size_t *__ptr));
|
||||
|
||||
/* Extract the ELF program header from the file. */
|
||||
extern Elf32_Phdr *elf32_getphdr __P ((Elf *__elf));
|
||||
|
||||
/* Extract the indicated section from the file. */
|
||||
extern Elf_Scn *elf_getscn __P ((Elf *__elf, size_t __index));
|
||||
|
||||
/* Extract the section header from the section. */
|
||||
extern Elf32_Shdr *elf32_getshdr __P ((Elf_Scn *__scn));
|
||||
|
||||
/* Return the index of the section following SCN. */
|
||||
extern size_t elf_ndxscn __P ((Elf_Scn *__scn));
|
||||
|
||||
|
||||
/* Standard ELF symbol name hash function. */
|
||||
extern unsigned long int elf_hash __P ((__const char *__name));
|
||||
|
||||
#if defined (__OPTIMIZE__) || defined (_EXTERN_INLINE)
|
||||
#ifndef _EXTERN_INLINE
|
||||
#define _EXTERN_INLINE extern __inline
|
||||
#endif
|
||||
_EXTERN_INLINE unsigned long int
|
||||
elf_hash (__const char *__name)
|
||||
{
|
||||
/* This is the hashing function specified by the ELF ABI. */
|
||||
unsigned long int __hash = 0;
|
||||
while (*__name != '\0')
|
||||
{
|
||||
unsigned long int __hi;
|
||||
__hash = (__hash << 4) + *__name++;
|
||||
__hi = __hash & 0xf0000000;
|
||||
if (__hi != 0)
|
||||
{
|
||||
__hash ^= __hi >> 24;
|
||||
/* The ELF ABI says `hash &= ~hi', but this is equivalent
|
||||
in this case and on some machines one insn instead of two. */
|
||||
__hash ^= __hi;
|
||||
}
|
||||
}
|
||||
return __hash;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return the kind of file ELF describes. */
|
||||
extern Elf_Kind elf_kind __P ((Elf *__elf));
|
||||
|
||||
extern Elf_Data *elf_newdata __P ((Elf_Scn *__scn));
|
||||
|
||||
/* Create the ELF header for ELF. */
|
||||
extern Elf32_Ehdr *elf32_newehdr __P ((Elf *__elf));
|
||||
|
||||
/* Create the program header for ELF, with COUNT segments. */
|
||||
extern Elf32_Phdr *elf32_newphdr __P ((Elf *__elf, size_t __count));
|
||||
|
||||
/* Create a new section in ELF. */
|
||||
extern Elf_Scn *elf_newscn __P ((Elf *__elf));
|
||||
|
||||
/* Return the section following SCN. */
|
||||
extern Elf_Scn *elf_nextscn __P ((Elf *__elf, Elf_Scn *__scn));
|
||||
|
||||
/* Set up ELF to read the next archive member. */
|
||||
extern Elf_Cmd elf_next __P ((Elf *__elf));
|
||||
|
||||
/* Set up ELF (which must describe an archive) to read the
|
||||
archive member that starts at file position OFFSET. */
|
||||
extern size_t elf_rand __P ((Elf *__elf, size_t __offset));
|
||||
|
||||
extern Elf_Data *elf_rawdata __P ((Elf_Scn *__scn, Elf_Data *__data));
|
||||
|
||||
/* Read the entire file into memory; store its size in *PTR. */
|
||||
extern char *elf_rawfile __P ((Elf *__elf, size_t *__ptr));
|
||||
|
||||
/* Return a pointer to the string at OFFSET bytes into the string table.
|
||||
SECTION is the index of the SHT_STRTAB section in ELF. */
|
||||
extern char *elf_strptr __P ((Elf *__elf, size_t __section, size_t __offset));
|
||||
|
||||
/* If CMD is ELF_C_NULL, update ELF's data structures based on any
|
||||
user modifications, and set the ELF_F_DIRTY flag if anything changed.
|
||||
If CMD is ELF_C_WRITE, do that and then write the changes to the file. */
|
||||
extern off_t elf_update __P ((Elf *__elf, Elf_Cmd __cmd));
|
||||
|
||||
/* Handle ELF version VER. Return the old version handled,
|
||||
or EV_NONE if VER is unrecognized. */
|
||||
extern unsigned int elf_version __P ((unsigned int __ver));
|
||||
|
||||
extern Elf_Data *elf32_xlatetof __P ((Elf_Data *__dst, const Elf_Data *__src,
|
||||
unsigned int __encode));
|
||||
extern Elf_Data *elf32_xlatetom __P ((Elf_Data *__dst, const Elf_Data *__src,
|
||||
unsigned int __encode));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _LIBELF_H */
|
47
elf/link.h
47
elf/link.h
@ -20,8 +20,20 @@ Cambridge, MA 02139, USA. */
|
||||
#ifndef _LINK_H
|
||||
#define _LINK_H 1
|
||||
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
#define __ELF_WORDSIZE 32 /* XXX */
|
||||
|
||||
/* We use this macro to refer to ELF types independent of the native wordsize.
|
||||
`ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */
|
||||
#define ElfW(type) _ElfW (Elf, __ELF_WORDSIZE, type)
|
||||
#define ELFW(type) _ElfW (ELF, __ELF_WORDSIZE, type)
|
||||
#define _ElfW(e,w,t) _ElfW_1 (e, w, _##t)
|
||||
#define _ElfW_1(e,w,t) e##w##t
|
||||
|
||||
|
||||
/* Rendezvous structure used by the run-time dynamic linker to communicate
|
||||
details of shared object loading to the debugger. If the executable's
|
||||
@ -39,7 +51,7 @@ struct r_debug
|
||||
library or unmap it, and again when the mapping change is complete.
|
||||
The debugger can set a breakpoint at this address if it wants to
|
||||
notice shared object mapping changes. */
|
||||
Elf32_Addr r_brk;
|
||||
ElfW(Addr) r_brk;
|
||||
enum
|
||||
{
|
||||
/* This state value describes the mapping change taking place when
|
||||
@ -49,7 +61,7 @@ struct r_debug
|
||||
RT_DELETE, /* Beginning to remove an object mapping. */
|
||||
} r_state;
|
||||
|
||||
Elf32_Addr r_ldbase; /* Base address the linker is loaded at. */
|
||||
ElfW(Addr) r_ldbase; /* Base address the linker is loaded at. */
|
||||
};
|
||||
|
||||
/* This symbol refers to the "dynamic structure" in the `.dynamic' section
|
||||
@ -59,7 +71,7 @@ struct r_debug
|
||||
if (dyn->d_tag == DT_DEBUG) r_debug = (struct r_debug) dyn->d_un.d_ptr;
|
||||
*/
|
||||
|
||||
extern Elf32_Dyn _DYNAMIC[];
|
||||
extern ElfW(Dyn) _DYNAMIC[];
|
||||
|
||||
|
||||
/* Structure describing a loaded shared object. The `l_next' and `l_prev'
|
||||
@ -73,9 +85,9 @@ struct link_map
|
||||
/* These first few members are part of the protocol with the debugger.
|
||||
This is the same format used in SVR4. */
|
||||
|
||||
Elf32_Addr l_addr; /* Base address shared object is loaded at. */
|
||||
ElfW(Addr) l_addr; /* Base address shared object is loaded at. */
|
||||
char *l_name; /* Absolute file name object was found in. */
|
||||
Elf32_Dyn *l_ld; /* Dynamic section of the shared object. */
|
||||
ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */
|
||||
struct link_map *l_next, *l_prev; /* Chain of loaded objects. */
|
||||
|
||||
/* All following members are internal to the dynamic linker.
|
||||
@ -85,10 +97,10 @@ struct link_map
|
||||
/* Indexed pointers to dynamic section.
|
||||
[0,DT_NUM) are indexed by the processor-independent tags.
|
||||
[DT_NUM,DT_NUM+DT_PROCNUM] are indexed by the tag minus DT_LOPROC. */
|
||||
Elf32_Dyn *l_info[DT_NUM + DT_PROCNUM];
|
||||
const Elf32_Phdr *l_phdr; /* Pointer to program header table in core. */
|
||||
Elf32_Word l_phnum; /* Number of program header entries. */
|
||||
Elf32_Addr l_entry; /* Entry point location. */
|
||||
ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM];
|
||||
const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */
|
||||
ElfW(Addr) l_entry; /* Entry point location. */
|
||||
ElfW(Half) l_phnum; /* Number of program header entries. */
|
||||
|
||||
/* Array of DT_NEEDED dependencies and their dependencies, in
|
||||
dependency order for symbol lookup. This is null before the
|
||||
@ -97,8 +109,8 @@ struct link_map
|
||||
unsigned int l_nsearchlist;
|
||||
|
||||
/* Symbol hash table. */
|
||||
Elf32_Word l_nbuckets;
|
||||
const Elf32_Word *l_buckets, *l_chain;
|
||||
ElfW(Word) l_nbuckets;
|
||||
const ElfW(Word) *l_buckets, *l_chain;
|
||||
|
||||
unsigned int l_opencount; /* Reference count for dlopen/dlclose. */
|
||||
enum /* Where this object came from. */
|
||||
@ -123,6 +135,9 @@ struct link_map
|
||||
user interface to run-time dynamic linking. */
|
||||
|
||||
|
||||
/* Cached value of `getpagesize ()'. */
|
||||
extern size_t _dl_pagesize;
|
||||
|
||||
/* File descriptor referring to the zero-fill device. */
|
||||
extern int _dl_zerofd;
|
||||
|
||||
@ -209,15 +224,15 @@ extern struct link_map *_dl_open (struct link_map *loader,
|
||||
being fixed up and the chosen symbol cannot be one with this value. If
|
||||
NOPLT is nonzero, then the reference must not be resolved to a PLT
|
||||
entry. */
|
||||
extern Elf32_Addr _dl_lookup_symbol (const char *undef,
|
||||
const Elf32_Sym **sym,
|
||||
extern ElfW(Addr) _dl_lookup_symbol (const char *undef,
|
||||
const ElfW(Sym) **sym,
|
||||
struct link_map *symbol_scope[2],
|
||||
const char *reference_name,
|
||||
Elf32_Addr reloc_addr,
|
||||
ElfW(Addr) reloc_addr,
|
||||
int noplt);
|
||||
|
||||
/* Look up symbol NAME in MAP's scope and return its run-time address. */
|
||||
extern Elf32_Addr _dl_symbol_value (struct link_map *map, const char *name);
|
||||
extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name);
|
||||
|
||||
|
||||
/* Structure describing the dynamic linker itself. */
|
||||
@ -242,7 +257,7 @@ extern void _dl_relocate_object (struct link_map *map, int lazy);
|
||||
its dependencies that has not yet been run. When there are no more
|
||||
initializers to be run, this returns zero. The functions are returned
|
||||
in the order they should be called. */
|
||||
extern Elf32_Addr _dl_init_next (struct link_map *map);
|
||||
extern ElfW(Addr) _dl_init_next (struct link_map *map);
|
||||
|
||||
/* Call the finalizer functions of all shared objects whose
|
||||
initializer functions have completed. */
|
||||
|
@ -32,9 +32,9 @@ Cambridge, MA 02139, USA. */
|
||||
void
|
||||
_init (void)
|
||||
{
|
||||
const Elf32_Sym *ref = NULL;
|
||||
const ElfW(Sym) *ref = NULL;
|
||||
struct link_map *scope[2] = { _dl_loaded, NULL };
|
||||
Elf32_Addr loadbase = _dl_lookup_symbol ("atexit", &ref, scope,
|
||||
ElfW(Addr) loadbase = _dl_lookup_symbol ("atexit", &ref, scope,
|
||||
"<ld-linux.so.1 initialization>",
|
||||
0, 1);
|
||||
(*(__typeof (atexit) *) (loadbase + ref->st_value)) (&_dl_fini);
|
||||
|
42
elf/rtld.c
42
elf/rtld.c
@ -35,10 +35,10 @@ RTLD_START
|
||||
After this, file access calls and getenv must work. This is responsible
|
||||
for setting _dl_secure if we need to be secure (e.g. setuid),
|
||||
and for setting _dl_argc and _dl_argv, and then calling _dl_main. */
|
||||
extern Elf32_Addr _dl_sysdep_start (void **start_argptr,
|
||||
void (*dl_main) (const Elf32_Phdr *phdr,
|
||||
Elf32_Word phent,
|
||||
Elf32_Addr *user_entry));
|
||||
extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
|
||||
void (*dl_main) (const ElfW(Phdr) *phdr,
|
||||
ElfW(Half) phent,
|
||||
ElfW(Addr) *user_entry));
|
||||
extern void _dl_sysdep_start_cleanup (void);
|
||||
|
||||
int _dl_secure;
|
||||
@ -46,15 +46,15 @@ int _dl_argc;
|
||||
char **_dl_argv;
|
||||
const char *_dl_rpath;
|
||||
|
||||
struct r_debug dl_r_debug;
|
||||
struct r_debug _dl_r_debug;
|
||||
|
||||
static void dl_main (const Elf32_Phdr *phdr,
|
||||
Elf32_Word phent,
|
||||
Elf32_Addr *user_entry);
|
||||
static void dl_main (const ElfW(Phdr) *phdr,
|
||||
ElfW(Half) phent,
|
||||
ElfW(Addr) *user_entry);
|
||||
|
||||
struct link_map _dl_rtld_map;
|
||||
|
||||
Elf32_Addr
|
||||
ElfW(Addr)
|
||||
_dl_start (void *arg)
|
||||
{
|
||||
struct link_map bootstrap_map;
|
||||
@ -120,17 +120,17 @@ void _start (void);
|
||||
unsigned int _dl_skip_args; /* Nonzero if we were run directly. */
|
||||
|
||||
static void
|
||||
dl_main (const Elf32_Phdr *phdr,
|
||||
Elf32_Word phent,
|
||||
Elf32_Addr *user_entry)
|
||||
dl_main (const ElfW(Phdr) *phdr,
|
||||
ElfW(Half) phent,
|
||||
ElfW(Addr) *user_entry)
|
||||
{
|
||||
const Elf32_Phdr *ph;
|
||||
const ElfW(Phdr) *ph;
|
||||
struct link_map *l;
|
||||
const char *interpreter_name;
|
||||
int lazy;
|
||||
int list_only = 0;
|
||||
|
||||
if (*user_entry == (Elf32_Addr) &_start)
|
||||
if (*user_entry == (ElfW(Addr)) &_start)
|
||||
{
|
||||
/* Ho ho. We are not the program interpreter! We are the program
|
||||
itself! This means someone ran ld.so as a command. Well, that
|
||||
@ -240,7 +240,7 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
/* There is a DT_DEBUG entry in the dynamic section. Fill it in
|
||||
with the run-time address of the r_debug structure, which we
|
||||
will set up later to communicate with the debugger. */
|
||||
l->l_info[DT_DEBUG]->d_un.d_ptr = (Elf32_Addr) &dl_r_debug;
|
||||
l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) &_dl_r_debug;
|
||||
|
||||
/* Put the link_map for ourselves on the chain so it can be found by
|
||||
name. */
|
||||
@ -292,9 +292,9 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
|
||||
for (i = 1; i < _dl_argc; ++i)
|
||||
{
|
||||
const Elf32_Sym *ref = NULL;
|
||||
const ElfW(Sym) *ref = NULL;
|
||||
struct link_map *scope[2] ={ _dl_loaded, NULL };
|
||||
Elf32_Addr loadbase
|
||||
ElfW(Addr) loadbase
|
||||
= _dl_lookup_symbol (_dl_argv[i], &ref, scope, "argument", 0, 0);
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
@ -345,10 +345,10 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
_dl_relocate_object (&_dl_rtld_map, lazy);
|
||||
|
||||
/* Tell the debugger where to find the map of loaded objects. */
|
||||
dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
|
||||
dl_r_debug.r_ldbase = _dl_rtld_map.l_addr; /* Record our load address. */
|
||||
dl_r_debug.r_map = _dl_loaded;
|
||||
dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state;
|
||||
_dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
|
||||
_dl_r_debug.r_ldbase = _dl_rtld_map.l_addr; /* Record our load address. */
|
||||
_dl_r_debug.r_map = _dl_loaded;
|
||||
_dl_r_debug.r_brk = (ElfW(Addr)) &_dl_r_debug_state;
|
||||
|
||||
if (_dl_rtld_map.l_info[DT_INIT])
|
||||
{
|
||||
|
@ -270,7 +270,7 @@ _dl_sysdep_message (const char *msg, ...)
|
||||
it will get the user's definition (i.e. usually libc's). */
|
||||
|
||||
int
|
||||
open (const char *file_name, int mode, ...)
|
||||
__open (const char *file_name, int mode, ...)
|
||||
{
|
||||
enum retry_type doretry;
|
||||
char retryname[1024]; /* XXX string_t LOSES! */
|
||||
@ -495,7 +495,7 @@ open (const char *file_name, int mode, ...)
|
||||
}
|
||||
|
||||
int
|
||||
close (int fd)
|
||||
__close (int fd)
|
||||
{
|
||||
if (fd != (int) MACH_PORT_NULL)
|
||||
__mach_port_deallocate (__mach_task_self (), (mach_port_t) fd);
|
||||
@ -503,7 +503,7 @@ close (int fd)
|
||||
}
|
||||
|
||||
caddr_t
|
||||
mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
|
||||
__mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
|
||||
{
|
||||
error_t err;
|
||||
vm_prot_t vmprot;
|
||||
@ -554,9 +554,9 @@ _exit (int status)
|
||||
}
|
||||
|
||||
weak_symbol (_exit)
|
||||
weak_symbol (open)
|
||||
weak_symbol (close)
|
||||
weak_symbol (mmap)
|
||||
weak_symbol (__open)
|
||||
weak_symbol (__close)
|
||||
weak_symbol (__mmap)
|
||||
|
||||
|
||||
/* This function is called by interruptible RPC stubs. For initial
|
||||
|
Loading…
Reference in New Issue
Block a user