Skip to content

Commit

Permalink
bsd-user: Remove all non-x86 code from elfload.c
Browse files Browse the repository at this point in the history
bsd-user only builds x86 at the moment. Remove all non x86 code from
elfload.c. We'll move the x86 code to {i386,x86_64}/target_arch_elf.h
and bring it that support code from the forked bsd-user when the time
comes.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
bsdimp committed Sep 7, 2021
1 parent a899878 commit dd869a9
Showing 1 changed file with 2 additions and 345 deletions.
347 changes: 2 additions & 345 deletions bsd-user/elfload.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,6 @@
#include "disas/disas.h"
#include "qemu/path.h"

#ifdef _ARCH_PPC64
#undef ARCH_DLINFO
#undef ELF_PLATFORM
#undef ELF_HWCAP
#undef ELF_CLASS
#undef ELF_DATA
#undef ELF_ARCH
#endif

/* from personality.h */

/*
Expand Down Expand Up @@ -144,7 +135,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
}
}

#else
#else /* !TARGET_X86_64 */

#define ELF_START_MMAP 0x80000000

Expand Down Expand Up @@ -174,343 +165,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
A value of 0 tells we have no such handler. */
regs->edx = 0;
}
#endif

#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096

#endif

#ifdef TARGET_ARM

#define ELF_START_MMAP 0x80000000

#define elf_check_arch(x) ((x) == EM_ARM)

#define ELF_CLASS ELFCLASS32
#ifdef TARGET_WORDS_BIGENDIAN
#define ELF_DATA ELFDATA2MSB
#else
#define ELF_DATA ELFDATA2LSB
#endif
#define ELF_ARCH EM_ARM

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));
regs->ARM_cpsr = 0x10;
if (infop->entry & 1)
regs->ARM_cpsr |= CPSR_T;
regs->ARM_pc = infop->entry & 0xfffffffe;
regs->ARM_sp = infop->start_stack;
/* FIXME - what to for failure of get_user()? */
get_user_ual(regs->ARM_r2, stack + 8); /* envp */
get_user_ual(regs->ARM_r1, stack + 4); /* envp */
/* XXX: it seems that r0 is zeroed after ! */
regs->ARM_r0 = 0;
/* For uClinux PIC binaries. */
/* XXX: Linux does this only on ARM with no MMU (do we care ?) */
regs->ARM_r10 = infop->start_data;
}

#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096

enum
{
ARM_HWCAP_ARM_SWP = 1 << 0,
ARM_HWCAP_ARM_HALF = 1 << 1,
ARM_HWCAP_ARM_THUMB = 1 << 2,
ARM_HWCAP_ARM_26BIT = 1 << 3,
ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
ARM_HWCAP_ARM_FPA = 1 << 5,
ARM_HWCAP_ARM_VFP = 1 << 6,
ARM_HWCAP_ARM_EDSP = 1 << 7,
};

#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \
| ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \
| ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)

#endif

#ifdef TARGET_SPARC
#ifdef TARGET_SPARC64

#define ELF_START_MMAP 0x80000000

#ifndef TARGET_ABI32
#define elf_check_arch(x) ((x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS)
#else
#define elf_check_arch(x) ((x) == EM_SPARC32PLUS || (x) == EM_SPARC)
#endif

#define ELF_CLASS ELFCLASS64
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_SPARCV9

#define STACK_BIAS 2047

static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
#ifndef TARGET_ABI32
regs->tstate = 0;
#endif
regs->pc = infop->entry;
regs->npc = regs->pc + 4;
regs->y = 0;
#ifdef TARGET_ABI32
regs->u_regs[14] = infop->start_stack - 16 * 4;
#else
if (personality(infop->personality) == PER_LINUX32)
regs->u_regs[14] = infop->start_stack - 16 * 4;
else {
regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
if (bsd_type == target_freebsd) {
regs->u_regs[8] = infop->start_stack;
regs->u_regs[11] = infop->start_stack;
}
}
#endif
}

#else
#define ELF_START_MMAP 0x80000000

#define elf_check_arch(x) ((x) == EM_SPARC)

#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_SPARC

static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
regs->psr = 0;
regs->pc = infop->entry;
regs->npc = regs->pc + 4;
regs->y = 0;
regs->u_regs[14] = infop->start_stack - 16 * 4;
}

#endif
#endif

#ifdef TARGET_PPC

#define ELF_START_MMAP 0x80000000

#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)

#define elf_check_arch(x) ((x) == EM_PPC64)

#define ELF_CLASS ELFCLASS64

#else

#define elf_check_arch(x) ((x) == EM_PPC)

#define ELF_CLASS ELFCLASS32

#endif

#ifdef TARGET_WORDS_BIGENDIAN
#define ELF_DATA ELFDATA2MSB
#else
#define ELF_DATA ELFDATA2LSB
#endif
#define ELF_ARCH EM_PPC

/*
* We need to put in some extra aux table entries to tell glibc what
* the cache block size is, so it can use the dcbz instruction safely.
*/
#define AT_DCACHEBSIZE 19
#define AT_ICACHEBSIZE 20
#define AT_UCACHEBSIZE 21
/* A special ignored type value for PPC, for glibc compatibility. */
#define AT_IGNOREPPC 22
/*
* The requirements here are:
* - keep the final alignment of sp (sp & 0xf)
* - make sure the 32-bit value at the first 16 byte aligned position of
* AUXV is greater than 16 for glibc compatibility.
* AT_IGNOREPPC is used for that.
* - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
* even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
*/
#define DLINFO_ARCH_ITEMS 5
#define ARCH_DLINFO \
do { \
NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20); \
NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20); \
NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \
/* \
* Now handle glibc compatibility. \
*/ \
NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
} while (0)

static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
{
abi_ulong pos = infop->start_stack;
abi_ulong tmp;
#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
abi_ulong entry, toc;
#endif

_regs->gpr[1] = infop->start_stack;
#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
get_user_u64(entry, infop->entry);
entry += infop->load_addr;
get_user_u64(toc, infop->entry + 8);
toc += infop->load_addr;
_regs->gpr[2] = toc;
infop->entry = entry;
#endif
_regs->nip = infop->entry;
/* Note that isn't exactly what regular kernel does
* but this is what the ABI wants and is needed to allow
* execution of PPC BSD programs.
*/
/* FIXME - what to for failure of get_user()? */
get_user_ual(_regs->gpr[3], pos);
pos += sizeof(abi_ulong);
_regs->gpr[4] = pos;
for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong)) {
get_user_ual(tmp, pos);
}
_regs->gpr[5] = pos;
}
#endif /* !TARGET_X86_64 */

#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096

#endif

#ifdef TARGET_MIPS

#define ELF_START_MMAP 0x80000000

#define elf_check_arch(x) ((x) == EM_MIPS)

#ifdef TARGET_MIPS64
#define ELF_CLASS ELFCLASS64
#else
#define ELF_CLASS ELFCLASS32
#endif
#ifdef TARGET_WORDS_BIGENDIAN
#define ELF_DATA ELFDATA2MSB
#else
#define ELF_DATA ELFDATA2LSB
#endif
#define ELF_ARCH EM_MIPS

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;
}

#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096

#endif /* TARGET_MIPS */

#ifdef TARGET_SH4

#define ELF_START_MMAP 0x80000000

#define elf_check_arch(x) ((x) == EM_SH)

#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_SH

static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
/* Check other registers XXXXX */
regs->pc = infop->entry;
regs->regs[15] = infop->start_stack;
}

#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096

#endif

#ifdef TARGET_CRIS

#define ELF_START_MMAP 0x80000000

#define elf_check_arch(x) ((x) == EM_CRIS)

#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_CRIS

static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
regs->erp = infop->entry;
}

#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 8192

#endif

#ifdef TARGET_M68K

#define ELF_START_MMAP 0x80000000

#define elf_check_arch(x) ((x) == EM_68K)

#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_68K

/* ??? 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)
{
regs->usp = infop->start_stack;
regs->sr = 0;
regs->pc = infop->entry;
}

#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 8192

#endif

#ifdef TARGET_ALPHA

#define ELF_START_MMAP (0x30000000000ULL)

#define elf_check_arch(x) ((x) == ELF_ARCH)

#define ELF_CLASS ELFCLASS64
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_ALPHA

static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
regs->pc = infop->entry;
regs->ps = 8;
regs->usp = infop->start_stack;
regs->unique = infop->start_data; /* ? */
printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n",
regs->unique, infop->start_data);
}

#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 8192

#endif /* TARGET_ALPHA */

#ifndef ELF_PLATFORM
#define ELF_PLATFORM (NULL)
#endif
Expand Down Expand Up @@ -1119,10 +780,6 @@ static void load_symbols(struct elfhdr *hdr, int fd)
}
continue;
}
#if defined(TARGET_ARM) || defined(TARGET_MIPS)
/* The bottom address bit marks a Thumb or MIPS16 symbol. */
syms[i].st_value &= ~(target_ulong)1;
#endif
i++;
}

Expand Down

0 comments on commit dd869a9

Please sign in to comment.