aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/Makefile27
-rw-r--r--elf/dl-load.c12
-rw-r--r--elf/dlfcn.h11
-rw-r--r--elf/elf.h4
-rw-r--r--elf/rtld.c5
5 files changed, 46 insertions, 13 deletions
diff --git a/elf/Makefile b/elf/Makefile
index ef9207c07b..269a872969 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -20,7 +20,7 @@
subdir := elf
-headers = elf.h bits/elfclass.h link.h dlfcn.h
+headers = elf.h bits/elfclass.h bits/dlfcn.h link.h dlfcn.h
routines = $(dl-routines) dl-open dl-close dl-symbol dl-support \
dl-version enbl-secure
@@ -88,6 +88,30 @@ $(objpfx)dl-allobjs.so: $(rtld-routines:%=$(objpfx)%.so)
$(objpfx)librtld.so: $(objpfx)dl-allobjs.so $(common-objpfx)libc_pic.a
$(reloc-link) '-Wl,-(' $^ -lgcc '-Wl,-)'
+# Do we need a linker script?
+rtld-ldscript-in := $(firstword $(wildcard $(+sysdep_dirs:%=%/rtld-ldscript.in)))
+ifneq (,$(rtld-ldscript-in))
+LDFLAGS-rtld = -T $(objpfx)rtld-ldscript
+
+before-compile += $(objpfx)rtld-ldscript
+rtld-parms = $(wildcard $(+sysdep_dirs:%=%/rtld-parms))
+include $(rtld-parms)
+generated += rtld-ldscript
+$(objpfx)rtld-ldscript: $(rtld-ldscript-in) $(rtld-parms)
+ sed -e 's#@@rtld-oformat@@#$(rtld-oformat)#' \
+ -e 's#@@rtld-arch@@#$(rtld-arch)#' \
+ -e 's#@@rtld-entry@@#$(rtld-entry)#' \
+ -e 's#@@rtld-base@@#$(rtld-base)#' $< >$@
+
+$(objpfx)ld.so: $(objpfx)librtld.so $(objpfx)rtld-ldscript
+ $(rtld-link) -Wl,-soname=$(rtld-installed-name)
+
+define rtld-link
+$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
+ -Wl,-rpath=$(default-rpath) $(LDFLAGS-rtld) \
+ $(filter-out $(objpfx)rtld-ldscript,$^)
+endef
+else
$(objpfx)ld.so: $(objpfx)librtld.so
$(rtld-link) -Wl,-soname=$(rtld-installed-name)
@@ -95,6 +119,7 @@ define rtld-link
$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
-Wl,-rpath=$(default-rpath) $^
endef
+endif
# The dl code in the static libc needs a default library path.
CFLAGS-dl-support.c = -D'DEFAULT_RPATH="$(default-rpath)"'
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 10cc074a6a..87859219f1 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -44,6 +44,15 @@
#define MAP_COPY MAP_PRIVATE
#endif
+/* Some systems link their relocatable objects for another base address
+ than 0. We want to know the base address for these such that we can
+ subtract this address from the segment addresses during mapping.
+ This results in a more efficient address space usage. Defaults to
+ zero for almost all systems. */
+#ifndef MAP_BASE_ADDR
+#define MAP_BASE_ADDR(l) 0
+#endif
+
#include <endian.h>
#if BYTE_ORDER == BIG_ENDIAN
@@ -335,7 +344,8 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
caddr_t mapat;
ElfW(Addr) mappref;
size_t maplength = loadcmds[nloadcmds - 1].allocend - c->mapstart;
- mappref = ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart);
+ mappref = (ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart)
+ - MAP_BASE_ADDR (l));
mapat = map_segment (mappref, maplength, c->prot, 0, c->mapoff);
l->l_addr = (ElfW(Addr)) mapat - c->mapstart;
diff --git a/elf/dlfcn.h b/elf/dlfcn.h
index 9b06988e96..9db5fb4635 100644
--- a/elf/dlfcn.h
+++ b/elf/dlfcn.h
@@ -22,15 +22,8 @@
#include <features.h>
-/* The MODE argument to `dlopen' contains one of the following: */
-#define RTLD_LAZY 0x001 /* Lazy function call binding. */
-#define RTLD_NOW 0x002 /* Immediate function call binding. */
-#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
-
-/* If the following bit is set in the MODE argument to `dlopen',
- the symbols of the loaded object and its dependencies are made
- visible as if the object were linked directly into the program. */
-#define RTLD_GLOBAL 0x100
+/* Collect various system dependand definitions and declarations. */
+#include <bits/dlfcn.h>
/* If the first argument of `dlsym' is set to RTLD_NEXT the run-time
address of the symbol called NAME in the next shared object is
diff --git a/elf/elf.h b/elf/elf.h
index 63d36b141c..d01bc90c90 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -741,6 +741,8 @@ typedef struct
#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
+#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
+#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
/* Special section indices. */
@@ -810,6 +812,8 @@ typedef struct
/* Legal values for p_type field of Elf32_Phdr. */
#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
/* Legal values for d_tag field of Elf32_Dyn. */
diff --git a/elf/rtld.c b/elf/rtld.c
index 22c1059fd2..a025757e05 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -25,6 +25,7 @@
#include <sys/mman.h> /* Check if MAP_ANON is defined. */
#include <stdio-common/_itoa.h>
#include <assert.h>
+#include <entry.h>
#include "dynamic-link.h"
@@ -137,7 +138,7 @@ _dl_start (void *arg)
/* Now life is peachy; we can do all normal operations.
On to the real work. */
-void _start (void);
+void ENTRY_POINT (void);
/* Some helper functions. */
@@ -268,7 +269,7 @@ dl_main (const ElfW(Phdr) *phdr,
/* Set up a flag which tells we are just starting. */
_dl_starting_up = 1;
- if (*user_entry == (ElfW(Addr)) &_start)
+ if (*user_entry == (ElfW(Addr)) &ENTRY_POINT)
{
/* Ho ho. We are not the program interpreter! We are the program
itself! This means someone ran ld.so as a command. Well, that