From patchwork Mon Jun 24 02:03:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stacey Son X-Patchwork-Id: 253940 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 2C0CD2C007E for ; Tue, 25 Jun 2013 03:53:11 +1000 (EST) Received: from localhost ([::1]:59919 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ur9xV-0001Er-Sr for incoming@patchwork.ozlabs.org; Mon, 24 Jun 2013 12:49:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42062) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ur9wR-0000gb-8k for qemu-devel@nongnu.org; Mon, 24 Jun 2013 12:49:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ur9wD-0005vB-1t for qemu-devel@nongnu.org; Mon, 24 Jun 2013 12:48:35 -0400 Received: from cdptpa-omtalb.mail.rr.com ([75.180.132.120]:47264) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ur9wC-0005tz-Sg for qemu-devel@nongnu.org; Mon, 24 Jun 2013 12:48:20 -0400 X-Authority-Analysis: v=2.0 cv=Ev5QXFgA c=1 sm=0 a=Oa4axR4OH/tQIi4PbzyetA==:17 a=BzKiyTcfMA4A:10 a=_0lAotXF3rcA:10 a=dBRESv0yCI8A:10 a=6I5d2MoRAAAA:8 a=KGjhK52YXX0A:10 a=YdbTuIGobqcA:10 a=_HciwOp7iBmPUs-rKLoA:9 a=SV7veod9ZcQA:10 a=EGfMd9ZCUOF1opRs:21 a=AABmnpmAbVt0U6ML:21 a=Oa4axR4OH/tQIi4PbzyetA==:117 X-Cloudmark-Score: 0 X-Authenticated-User: X-Originating-IP: 76.187.137.252 Received: from [76.187.137.252] ([76.187.137.252:52972] helo=salmon.son.org) by cdptpa-oedge01.mail.rr.com (envelope-from ) (ecelerity 2.2.3.46 r()) with ESMTP id 42/AA-06197-25878C15; Mon, 24 Jun 2013 16:48:18 +0000 Received: from son.org (localhost [127.0.0.1]) by salmon.son.org (8.14.7/8.14.7) with ESMTP id r5O249FS042003; Sun, 23 Jun 2013 21:04:09 -0500 (CDT) (envelope-from sson@son.org) Received: (from sson@localhost) by son.org (8.14.7/8.14.7/Submit) id r5O248K7042002; Sun, 23 Jun 2013 21:04:08 -0500 (CDT) (envelope-from sson) From: Stacey Son To: qemu-devel@nongnu.org Date: Sun, 23 Jun 2013 21:03:38 -0500 Message-Id: <1372039435-41921-7-git-send-email-sson@FreeBSD.org> X-Mailer: git-send-email 1.7.8 In-Reply-To: <1372039435-41921-1-git-send-email-sson@FreeBSD.org> References: <1372039435-41921-1-git-send-email-sson@FreeBSD.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 75.180.132.120 Cc: Stacey Son Subject: [Qemu-devel] [PATCH 06/23] bsd-user: fix thread initialization and ELF addresses for mips/mips64 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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; ie_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; iend_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; }