aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-02-07 01:05:54 -0500
committerRiku Voipio <riku.voipio@nokia.com>2011-02-09 10:33:54 +0200
commitc3109ba1b109f84929abbfe0462d910d5aa8617c (patch)
tree4db0c8aca79cdc61feac4d4953644f216fdfce0c
parent82a39595f7c70aecfb4649ae5a125147b62131f8 (diff)
linux-user/FLAT: allow targets to override FLAT processing
This brings flatload.c more in line with the current Linux FLAT loader which allows targets to handle various FLAT aspects in their own way. For the common behavior, the new functions get stubbed out. Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Riku Voipio <riku.voipio@nokia.com>
-rw-r--r--Makefile.target2
-rw-r--r--linux-user/flatload.c27
-rw-r--r--linux-user/target_flat.h10
3 files changed, 22 insertions, 17 deletions
diff --git a/Makefile.target b/Makefile.target
index b0ba95f76e..48e6c00a5d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -107,7 +107,7 @@ ifdef CONFIG_LINUX_USER
$(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR))
-QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)
+QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \
elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
qemu-malloc.o $(oslib-obj-y)
diff --git a/linux-user/flatload.c b/linux-user/flatload.c
index d8b4476325..cd7af7cdff 100644
--- a/linux-user/flatload.c
+++ b/linux-user/flatload.c
@@ -41,6 +41,8 @@
#include "qemu.h"
#include "flat.h"
+#define ntohl(x) be32_to_cpu(x)
+#include <target_flat.h>
//#define DEBUG
@@ -50,14 +52,6 @@
#define DBG_FLT(...)
#endif
-#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
-#define flat_old_ram_flag(flag) (flag)
-#ifdef TARGET_WORDS_BIGENDIAN
-#define flat_get_relocate_addr(relval) (relval)
-#else
-#define flat_get_relocate_addr(relval) bswap32(relval)
-#endif
-
#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
@@ -78,8 +72,6 @@ static int load_flat_shared_library(int id, struct lib_info *p);
struct linux_binprm;
-#define ntohl(x) be32_to_cpu(x)
-
/****************************************************************************/
/*
* create_flat_tables() parses the env- and arg-strings in new user
@@ -625,6 +617,7 @@ static int load_flat_file(struct linux_binprm * bprm,
* __start to address 4 so that is okay).
*/
if (rev > OLD_FLAT_VERSION) {
+ abi_ulong persistent = 0;
for (i = 0; i < relocs; i++) {
abi_ulong addr, relval;
@@ -633,6 +626,9 @@ static int load_flat_file(struct linux_binprm * bprm,
relocated first). */
if (get_user_ual(relval, reloc + i * sizeof(abi_ulong)))
return -EFAULT;
+ relval = ntohl(relval);
+ if (flat_set_persistent(relval, &persistent))
+ continue;
addr = flat_get_relocate_addr(relval);
rp = calc_reloc(addr, libinfo, id, 1);
if (rp == RELOC_FAILED)
@@ -641,22 +637,20 @@ static int load_flat_file(struct linux_binprm * bprm,
/* Get the pointer's value. */
if (get_user_ual(addr, rp))
return -EFAULT;
+ addr = flat_get_addr_from_rp(rp, relval, flags, &persistent);
if (addr != 0) {
/*
* Do the relocation. PIC relocs in the data section are
* already in target order
*/
-
-#ifndef TARGET_WORDS_BIGENDIAN
if ((flags & FLAT_FLAG_GOTPIC) == 0)
- addr = bswap32(addr);
-#endif
+ addr = ntohl(addr);
addr = calc_reloc(addr, libinfo, id, 0);
if (addr == RELOC_FAILED)
return -ENOEXEC;
/* Write back the relocated pointer. */
- if (put_user_ual(addr, rp))
+ if (flat_put_addr_at_rp(rp, addr, relval))
return -EFAULT;
}
}
@@ -782,7 +776,8 @@ int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
stack_len *= sizeof(abi_ulong);
if ((sp + stack_len) & 15)
sp -= 16 - ((sp + stack_len) & 15);
- sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p, 1);
+ sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p,
+ flat_argvp_envp_on_stack());
/* Fake some return addresses to ensure the call chain will
* initialise library in order for us. We are required to call
diff --git a/linux-user/target_flat.h b/linux-user/target_flat.h
new file mode 100644
index 0000000000..0ba6bdd12e
--- /dev/null
+++ b/linux-user/target_flat.h
@@ -0,0 +1,10 @@
+/* If your arch needs to do custom stuff, create your own target_flat.h
+ * header file in linux-user/<your arch>/
+ */
+#define flat_argvp_envp_on_stack() 1
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+#define flat_old_ram_flag(flag) (flag)
+#define flat_get_relocate_addr(relval) (relval)
+#define flat_get_addr_from_rp(rp, relval, flags, persistent) (rp)
+#define flat_set_persistent(relval, persistent) (*persistent)
+#define flat_put_addr_at_rp(rp, addr, relval) put_user_ual(addr, rp)