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>
This commit is contained in:
Mike Frysinger 2011-02-07 01:05:54 -05:00 committed by Riku Voipio
parent 82a39595f7
commit c3109ba1b1
3 changed files with 22 additions and 17 deletions

View File

@ -107,7 +107,7 @@ ifdef CONFIG_LINUX_USER
$(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)) $(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 \ 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 \ elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
qemu-malloc.o $(oslib-obj-y) qemu-malloc.o $(oslib-obj-y)

View File

@ -41,6 +41,8 @@
#include "qemu.h" #include "qemu.h"
#include "flat.h" #include "flat.h"
#define ntohl(x) be32_to_cpu(x)
#include <target_flat.h>
//#define DEBUG //#define DEBUG
@ -50,14 +52,6 @@
#define DBG_FLT(...) #define DBG_FLT(...)
#endif #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 RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ #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; struct linux_binprm;
#define ntohl(x) be32_to_cpu(x)
/****************************************************************************/ /****************************************************************************/
/* /*
* create_flat_tables() parses the env- and arg-strings in new user * 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). * __start to address 4 so that is okay).
*/ */
if (rev > OLD_FLAT_VERSION) { if (rev > OLD_FLAT_VERSION) {
abi_ulong persistent = 0;
for (i = 0; i < relocs; i++) { for (i = 0; i < relocs; i++) {
abi_ulong addr, relval; abi_ulong addr, relval;
@ -633,6 +626,9 @@ static int load_flat_file(struct linux_binprm * bprm,
relocated first). */ relocated first). */
if (get_user_ual(relval, reloc + i * sizeof(abi_ulong))) if (get_user_ual(relval, reloc + i * sizeof(abi_ulong)))
return -EFAULT; return -EFAULT;
relval = ntohl(relval);
if (flat_set_persistent(relval, &persistent))
continue;
addr = flat_get_relocate_addr(relval); addr = flat_get_relocate_addr(relval);
rp = calc_reloc(addr, libinfo, id, 1); rp = calc_reloc(addr, libinfo, id, 1);
if (rp == RELOC_FAILED) if (rp == RELOC_FAILED)
@ -641,22 +637,20 @@ static int load_flat_file(struct linux_binprm * bprm,
/* Get the pointer's value. */ /* Get the pointer's value. */
if (get_user_ual(addr, rp)) if (get_user_ual(addr, rp))
return -EFAULT; return -EFAULT;
addr = flat_get_addr_from_rp(rp, relval, flags, &persistent);
if (addr != 0) { if (addr != 0) {
/* /*
* Do the relocation. PIC relocs in the data section are * Do the relocation. PIC relocs in the data section are
* already in target order * already in target order
*/ */
#ifndef TARGET_WORDS_BIGENDIAN
if ((flags & FLAT_FLAG_GOTPIC) == 0) if ((flags & FLAT_FLAG_GOTPIC) == 0)
addr = bswap32(addr); addr = ntohl(addr);
#endif
addr = calc_reloc(addr, libinfo, id, 0); addr = calc_reloc(addr, libinfo, id, 0);
if (addr == RELOC_FAILED) if (addr == RELOC_FAILED)
return -ENOEXEC; return -ENOEXEC;
/* Write back the relocated pointer. */ /* Write back the relocated pointer. */
if (put_user_ual(addr, rp)) if (flat_put_addr_at_rp(rp, addr, relval))
return -EFAULT; return -EFAULT;
} }
} }
@ -782,7 +776,8 @@ int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
stack_len *= sizeof(abi_ulong); stack_len *= sizeof(abi_ulong);
if ((sp + stack_len) & 15) if ((sp + stack_len) & 15)
sp -= 16 - ((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 /* Fake some return addresses to ensure the call chain will
* initialise library in order for us. We are required to call * initialise library in order for us. We are required to call

10
linux-user/target_flat.h Normal file
View File

@ -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)