[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 06/23] bsd-user: fix thread initialization and ELF a
From: |
Stacey Son |
Subject: |
[Qemu-devel] [PATCH 06/23] bsd-user: fix thread initialization and ELF addresses for mips/mips64 |
Date: |
Sun, 23 Jun 2013 21:03:38 -0500 |
Initialize all the registers correctly for mips/mips64 in init_thread(), use
the correct ELF_START_MMAP for mips64, use the correct run-time linker, and
clean up the code by eliminating some #if's. Also, fix all the checkpatch.pl
warnings and errors.
Signed-off-by: Stacey Son <address@hidden>
---
bsd-user/elfload.c | 185 +++++++++++++++++++++++++++++-----------------------
1 files changed, 103 insertions(+), 82 deletions(-)
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 0f6c3db..8c8ed6a 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -45,10 +45,11 @@
* These occupy the top three bytes.
*/
enum {
- ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA
space */
- FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs
point to descriptors
- * (signal handling)
- */
+ ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA
+ space */
+ FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs
+ point to descriptors
+ (signal handling) */
MMAP_PAGE_ZERO = 0x0100000,
ADDR_COMPAT_LAYOUT = 0x0200000,
READ_IMPLIES_EXEC = 0x0400000,
@@ -163,7 +164,8 @@ static inline void init_thread(struct target_pt_regs *regs,
struct image_info *i
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_386
-static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
{
regs->esp = infop->start_stack;
regs->eip = infop->entry;
@@ -198,7 +200,8 @@ static inline void init_thread(struct target_pt_regs *regs,
struct image_info *i
#endif
#define ELF_ARCH EM_ARM
-static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
{
abi_long stack = infop->start_stack;
memset(regs, 0, sizeof(*regs));
@@ -255,7 +258,8 @@ enum
#define STACK_BIAS 2047
-static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
{
#ifndef TARGET_ABI32
regs->tstate = 0;
@@ -287,7 +291,8 @@ static inline void init_thread(struct target_pt_regs *regs,
struct image_info *i
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_SPARC
-static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
{
regs->psr = 0;
regs->pc = infop->entry;
@@ -355,7 +360,8 @@ do {
\
NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
} while (0)
-static inline void init_thread(struct target_pt_regs *_regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *_regs,
+ struct image_info *infop)
{
abi_ulong pos = infop->start_stack;
abi_ulong tmp;
@@ -391,13 +397,13 @@ static inline void init_thread(struct target_pt_regs
*_regs, struct image_info *
#ifdef TARGET_MIPS
-#define ELF_START_MMAP 0x80000000
-
#define elf_check_arch(x) ( (x) == EM_MIPS )
#ifdef TARGET_MIPS64
+#define ELF_START_MMAP 0x2aaaaab000ULL
#define ELF_CLASS ELFCLASS64
#else
+#define ELF_START_MMAP 0x80000000
#define ELF_CLASS ELFCLASS32
#endif
#ifdef TARGET_WORDS_BIGENDIAN
@@ -407,11 +413,14 @@ static inline void init_thread(struct target_pt_regs
*_regs, struct image_info *
#endif
#define ELF_ARCH EM_MIPS
-static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
{
regs->cp0_status = 2 << CP0St_KSU;
- regs->cp0_epc = infop->entry;
- regs->regs[29] = infop->start_stack;
+ regs->regs[25] = regs->cp0_epc = infop->entry & ~3; /* t9/pc = entry */
+ regs->regs[4] = regs->regs[29] = infop->start_stack; /* a0/sp = stack */
+ regs->regs[5] = regs->regs[6] = 0; /* a1/a2 = 0 */
+ regs->regs[7] = TARGET_PS_STRINGS; /* a3 = ps_strings */
}
#define USE_ELF_CORE_DUMP
@@ -429,7 +438,8 @@ static inline void init_thread(struct target_pt_regs *regs,
struct image_info *i
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_SH
-static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
{
/* Check other registers XXXXX */
regs->pc = infop->entry;
@@ -451,7 +461,8 @@ static inline void init_thread(struct target_pt_regs *regs,
struct image_info *i
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_CRIS
-static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
{
regs->erp = infop->entry;
}
@@ -474,7 +485,8 @@ static inline void init_thread(struct target_pt_regs *regs,
struct image_info *i
/* ??? Does this need to do anything?
#define ELF_PLAT_INIT(_r) */
-static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
{
regs->usp = infop->start_stack;
regs->sr = 0;
@@ -496,7 +508,8 @@ static inline void init_thread(struct target_pt_regs *regs,
struct image_info *i
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_ALPHA
-static inline void init_thread(struct target_pt_regs *regs, struct image_info
*infop)
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
{
regs->pc = infop->entry;
regs->ps = 8;
@@ -555,7 +568,8 @@ struct exec
/* Necessary parameters */
#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
-#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned
long)(TARGET_ELF_EXEC_PAGESIZE-1))
+#define TARGET_ELF_PAGESTART(_v) ((_v) & \
+ ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
#define INTERPRETER_NONE 0
@@ -574,7 +588,7 @@ static int load_aout_interp(void * exptr, int interp_fd);
#ifdef BSWAP_NEEDED
static void bswap_ehdr(struct elfhdr *ehdr)
{
- bswap16s(&ehdr->e_type); /* Object file type */
+ bswap16s(&ehdr->e_type); /* Object file type */
bswap16s(&ehdr->e_machine); /* Architecture */
bswap32s(&ehdr->e_version); /* Object file version */
bswaptls(&ehdr->e_entry); /* Entry point virtual address */
@@ -582,37 +596,45 @@ static void bswap_ehdr(struct elfhdr *ehdr)
bswaptls(&ehdr->e_shoff); /* Section header table file offset */
bswap32s(&ehdr->e_flags); /* Processor-specific flags */
bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
- bswap16s(&ehdr->e_phentsize); /* Program header table entry
size */
+ bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
bswap16s(&ehdr->e_phnum); /* Program header table entry count */
- bswap16s(&ehdr->e_shentsize); /* Section header table entry
size */
+ bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
bswap16s(&ehdr->e_shnum); /* Section header table entry count */
- bswap16s(&ehdr->e_shstrndx); /* Section header string table
index */
+ bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
}
-static void bswap_phdr(struct elf_phdr *phdr)
+static void bswap_phdr(struct elf_phdr *phdr, int phnum)
{
- bswap32s(&phdr->p_type); /* Segment type */
- bswaptls(&phdr->p_offset); /* Segment file offset */
- bswaptls(&phdr->p_vaddr); /* Segment virtual address */
- bswaptls(&phdr->p_paddr); /* Segment physical address */
- bswaptls(&phdr->p_filesz); /* Segment size in file */
- bswaptls(&phdr->p_memsz); /* Segment size in memory */
- bswap32s(&phdr->p_flags); /* Segment flags */
- bswaptls(&phdr->p_align); /* Segment alignment */
+ int i;
+
+ for (i = 0; i < phnum; i++, phdr++) {
+ bswap32s(&phdr->p_type); /* Segment type */
+ bswaptls(&phdr->p_offset); /* Segment file offset */
+ bswaptls(&phdr->p_vaddr); /* Segment virtual address */
+ bswaptls(&phdr->p_paddr); /* Segment physical address */
+ bswaptls(&phdr->p_filesz); /* Segment size in file */
+ bswaptls(&phdr->p_memsz); /* Segment size in memory */
+ bswap32s(&phdr->p_flags); /* Segment flags */
+ bswaptls(&phdr->p_align); /* Segment alignment */
+ }
}
-static void bswap_shdr(struct elf_shdr *shdr)
+static void bswap_shdr(struct elf_shdr *shdr, int shnum)
{
- bswap32s(&shdr->sh_name);
- bswap32s(&shdr->sh_type);
- bswaptls(&shdr->sh_flags);
- bswaptls(&shdr->sh_addr);
- bswaptls(&shdr->sh_offset);
- bswaptls(&shdr->sh_size);
- bswap32s(&shdr->sh_link);
- bswap32s(&shdr->sh_info);
- bswaptls(&shdr->sh_addralign);
- bswaptls(&shdr->sh_entsize);
+ int i;
+
+ for (i = 0; i < shnum; i++, shdr++) {
+ bswap32s(&shdr->sh_name);
+ bswap32s(&shdr->sh_type);
+ bswaptls(&shdr->sh_flags);
+ bswaptls(&shdr->sh_addr);
+ bswaptls(&shdr->sh_offset);
+ bswaptls(&shdr->sh_size);
+ bswap32s(&shdr->sh_link);
+ bswap32s(&shdr->sh_info);
+ bswaptls(&shdr->sh_addralign);
+ bswaptls(&shdr->sh_entsize);
+ }
}
static void bswap_sym(struct elf_sym *sym)
@@ -622,7 +644,15 @@ static void bswap_sym(struct elf_sym *sym)
bswaptls(&sym->st_size);
bswap16s(&sym->st_shndx);
}
-#endif
+
+#else /* ! BSWAP_NEEDED */
+
+static void bswap_ehdr(struct elfhdr *ehdr) { }
+static void bswap_phdr(struct elf_phdr *phdr, int phnum) { }
+static void bswap_shdr(struct elf_shdr *shdr, int shnum) { }
+static void bswap_sym(struct elf_sym *sym) { }
+
+#endif /* ! BSWAP_NEEDED */
/*
* 'copy_elf_strings()' copies argument/envelope strings from user
@@ -868,9 +898,7 @@ static abi_ulong load_elf_interp(struct elfhdr *
interp_elf_ex,
last_bss = 0;
error = 0;
-#ifdef BSWAP_NEEDED
bswap_ehdr(interp_elf_ex);
-#endif
/* First of all, some simple consistency checks */
if ((interp_elf_ex->e_type != ET_EXEC &&
interp_elf_ex->e_type != ET_DYN) ||
@@ -911,12 +939,7 @@ static abi_ulong load_elf_interp(struct elfhdr *
interp_elf_ex,
free (elf_phdata);
return retval;
}
-#ifdef BSWAP_NEEDED
- eppnt = elf_phdata;
- for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
- bswap_phdr(eppnt);
- }
-#endif
+ bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);
if (interp_elf_ex->e_type == ET_DYN) {
/* in order to avoid hardcoding the interpreter load
@@ -1065,9 +1088,7 @@ static void load_symbols(struct elfhdr *hdr, int fd)
for (i = 0; i < hdr->e_shnum; i++) {
if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
return;
-#ifdef BSWAP_NEEDED
- bswap_shdr(&sechdr);
-#endif
+ bswap_shdr(&sechdr, 1);
if (sechdr.sh_type == SHT_SYMTAB) {
symtab = sechdr;
lseek(fd, hdr->e_shoff
@@ -1075,9 +1096,7 @@ static void load_symbols(struct elfhdr *hdr, int fd)
if (read(fd, &strtab, sizeof(strtab))
!= sizeof(strtab))
return;
-#ifdef BSWAP_NEEDED
- bswap_shdr(&strtab);
-#endif
+ bswap_shdr(&strtab, 1);
goto found;
}
}
@@ -1110,9 +1129,7 @@ static void load_symbols(struct elfhdr *hdr, int fd)
i = 0;
while (i < nsyms) {
-#ifdef BSWAP_NEEDED
bswap_sym(syms + i);
-#endif
// Throw away entries which we do not need.
if (syms[i].st_shndx == SHN_UNDEF ||
syms[i].st_shndx >= SHN_LORESERVE ||
@@ -1194,9 +1211,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct
target_pt_regs *regs,
load_addr = 0;
load_bias = 0;
elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
-#ifdef BSWAP_NEEDED
bswap_ehdr(&elf_ex);
-#endif
/* First of all, some simple consistency checks */
if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
@@ -1204,12 +1219,14 @@ int load_elf_binary(struct bsd_binprm *bprm, struct
target_pt_regs *regs,
return -ENOEXEC;
}
+#ifndef __FreeBSD__
bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
if (!bprm->p) {
retval = -E2BIG;
}
+#endif /* ! __FreeBSD__ */
/* Now read in all of the header information */
elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
@@ -1230,12 +1247,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct
target_pt_regs *regs,
return -errno;
}
-#ifdef BSWAP_NEEDED
- elf_ppnt = elf_phdata;
- for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
- bswap_phdr(elf_ppnt);
- }
-#endif
+ bswap_phdr(elf_phdata, elf_ex.e_phnum);
elf_ppnt = elf_phdata;
elf_bss = 0;
@@ -1288,9 +1300,9 @@ int load_elf_binary(struct bsd_binprm *bprm, struct
target_pt_regs *regs,
/* JRP - Need to add X86 lib dir stuff here... */
- if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
- strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) {
- ibcs2_interpreter = 1;
+ if (strcmp(elf_interpreter, "/usr/lib/libc.so.1") == 0 ||
+ strcmp(elf_interpreter, "/usr/lib/ld-elf.so.1") == 0) {
+ ibcs2_interpreter = 1;
}
#if 0
@@ -1437,7 +1449,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct
target_pt_regs *regs,
} else if (elf_ex.e_type == ET_DYN) {
/* Try and get dynamic programs out of the way of the default mmap
base, as well as whatever program they might try to exec. This
- is because the brk will follow the loader, and is not movable.
*/
+ is because the brk will follow the loader, and is not movable.
*/
/* NOTE: for qemu, we do a big mmap to get enough space
without hardcoding any address */
error = target_mmap(0, ET_DYN_MAP_SIZE,
@@ -1550,19 +1562,22 @@ int load_elf_binary(struct bsd_binprm *bprm, struct
target_pt_regs *regs,
info->end_data = end_data;
info->start_stack = bprm->p;
- /* Calling set_brk effectively mmaps the pages that we need for the bss
and break
- sections */
+ /*
+ * Calling set_brk effectively mmaps the pages that we need for the bss
+ * and break sections.
+ */
set_brk(elf_bss, elf_brk);
padzero(elf_bss, elf_brk);
#if 0
- printf("(start_brk) %x\n" , info->start_brk);
- printf("(end_code) %x\n" , info->end_code);
- printf("(start_code) %x\n" , info->start_code);
- printf("(end_data) %x\n" , info->end_data);
- printf("(start_stack) %x\n" , info->start_stack);
- printf("(brk) %x\n" , info->brk);
+ printf("(start_brk) 0x" TARGET_FMT_lx "\n" , info->start_brk);
+ printf("(end_code) 0x" TARGET_FMT_lx "\n" , info->end_code);
+ printf("(start_code) 0x" TARGET_FMT_lx "\n" , info->start_code);
+ printf("(start_data) 0x" TARGET_FMT_lx "\n" , info->start_data);
+ printf("(end_data) 0x" TARGET_FMT_lx "\n" , info->end_data);
+ printf("(start_stack) 0x" TARGET_FMT_lx "\n" , info->start_stack);
+ printf("(brk) 0x" TARGET_FMT_lx "\n" , info->brk);
#endif
if ( info->personality == PER_SVR4 )
@@ -1571,12 +1586,18 @@ int load_elf_binary(struct bsd_binprm *bprm, struct
target_pt_regs *regs,
and some applications "depend" upon this behavior.
Since we do not have the power to recompile these, we
emulate the SVr4 behavior. Sigh. */
- mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ |
PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE, -1, 0);
+ mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ |
+ PROT_EXEC, MAP_FIXED | MAP_PRIVATE, -1, 0);
}
info->entry = elf_entry;
+#ifdef USE_ELF_CORE_DUMP
+ /* not yet */
+ /* bprm->core_dump = &elf_core_dump; */
+ bprm->core_dump = NULL;
+#endif
+
return 0;
}
--
1.7.8
- [Qemu-devel] [PATCH 00/23] bsd-user: FreeBSD support for mips/mips64 and arm, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 07/23] bsd-user: find target executable in path when absolute path not given, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 05/23] bsd-user: add bsd_binprm to TaskState for core dumping emulation, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 06/23] bsd-user: fix thread initialization and ELF addresses for mips/mips64,
Stacey Son <=
- [Qemu-devel] [PATCH 13/23] bsd-user: add shims for signal related system calls, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 08/23] bsd-user: initialize stack with signal trampolin code and canary, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 02/23] bsd-user: add initial support for mips/mips64, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 01/23] bsd-user: initial code clean up, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 11/23] bsd-user: add shims for file related system calls, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 10/23] bsd-user: add shims for memory management related syscalls, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 09/23] bsd-user: refresh FreeBSD's system call numbers, Stacey Son, 2013/06/24