aboutsummaryrefslogtreecommitdiff
path: root/linux-user/elfload.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user/elfload.c')
-rw-r--r--linux-user/elfload.c84
1 files changed, 49 insertions, 35 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 99811af..82ebf6a 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -12,6 +12,7 @@
#include "exec/page-protection.h"
#include "exec/mmap-lock.h"
#include "exec/translation-block.h"
+#include "exec/tswap.h"
#include "user/guest-base.h"
#include "user-internals.h"
#include "signal-common.h"
@@ -2122,9 +2123,12 @@ static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
memcpy(to, from, n);
}
-#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
static void bswap_ehdr(struct elfhdr *ehdr)
{
+ if (!target_needs_bswap()) {
+ return;
+ }
+
bswap16s(&ehdr->e_type); /* Object file type */
bswap16s(&ehdr->e_machine); /* Architecture */
bswap32s(&ehdr->e_version); /* Object file version */
@@ -2142,8 +2146,11 @@ static void bswap_ehdr(struct elfhdr *ehdr)
static void bswap_phdr(struct elf_phdr *phdr, int phnum)
{
- int i;
- for (i = 0; i < phnum; ++i, ++phdr) {
+ if (!target_needs_bswap()) {
+ return;
+ }
+
+ for (int i = 0; i < phnum; ++i, ++phdr) {
bswap32s(&phdr->p_type); /* Segment type */
bswap32s(&phdr->p_flags); /* Segment flags */
bswaptls(&phdr->p_offset); /* Segment file offset */
@@ -2157,8 +2164,11 @@ static void bswap_phdr(struct elf_phdr *phdr, int phnum)
static void bswap_shdr(struct elf_shdr *shdr, int shnum)
{
- int i;
- for (i = 0; i < shnum; ++i, ++shdr) {
+ if (!target_needs_bswap()) {
+ return;
+ }
+
+ for (int i = 0; i < shnum; ++i, ++shdr) {
bswap32s(&shdr->sh_name);
bswap32s(&shdr->sh_type);
bswaptls(&shdr->sh_flags);
@@ -2174,6 +2184,10 @@ static void bswap_shdr(struct elf_shdr *shdr, int shnum)
static void bswap_sym(struct elf_sym *sym)
{
+ if (!target_needs_bswap()) {
+ return;
+ }
+
bswap32s(&sym->st_name);
bswaptls(&sym->st_value);
bswaptls(&sym->st_size);
@@ -2183,6 +2197,10 @@ static void bswap_sym(struct elf_sym *sym)
#ifdef TARGET_MIPS
static void bswap_mips_abiflags(Mips_elf_abiflags_v0 *abiflags)
{
+ if (!target_needs_bswap()) {
+ return;
+ }
+
bswap16s(&abiflags->version);
bswap32s(&abiflags->ases);
bswap32s(&abiflags->isa_ext);
@@ -2190,15 +2208,6 @@ static void bswap_mips_abiflags(Mips_elf_abiflags_v0 *abiflags)
bswap32s(&abiflags->flags2);
}
#endif
-#else
-static inline void bswap_ehdr(struct elfhdr *ehdr) { }
-static inline void bswap_phdr(struct elf_phdr *phdr, int phnum) { }
-static inline void bswap_shdr(struct elf_shdr *shdr, int shnum) { }
-static inline void bswap_sym(struct elf_sym *sym) { }
-#ifdef TARGET_MIPS
-static inline void bswap_mips_abiflags(Mips_elf_abiflags_v0 *abiflags) { }
-#endif
-#endif
#ifdef USE_ELF_CORE_DUMP
static int elf_core_dump(int, const CPUArchState *);
@@ -3144,11 +3153,11 @@ static bool parse_elf_properties(const ImageSource *src,
* The contents of a valid PT_GNU_PROPERTY is a sequence of uint32_t.
* Swap most of them now, beyond the header and namesz.
*/
-#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
- for (int i = 4; i < n / 4; i++) {
- bswap32s(note.data + i);
+ if (target_needs_bswap()) {
+ for (int i = 4; i < n / 4; i++) {
+ bswap32s(note.data + i);
+ }
}
-#endif
/*
* Note that nhdr is 3 words, and that the "name" described by namesz
@@ -4000,9 +4009,12 @@ struct target_elf_prpsinfo {
char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
};
-#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
static void bswap_prstatus(struct target_elf_prstatus *prstatus)
{
+ if (!target_needs_bswap()) {
+ return;
+ }
+
prstatus->pr_info.si_signo = tswap32(prstatus->pr_info.si_signo);
prstatus->pr_info.si_code = tswap32(prstatus->pr_info.si_code);
prstatus->pr_info.si_errno = tswap32(prstatus->pr_info.si_errno);
@@ -4020,6 +4032,10 @@ static void bswap_prstatus(struct target_elf_prstatus *prstatus)
static void bswap_psinfo(struct target_elf_prpsinfo *psinfo)
{
+ if (!target_needs_bswap()) {
+ return;
+ }
+
psinfo->pr_flag = tswapal(psinfo->pr_flag);
psinfo->pr_uid = tswap16(psinfo->pr_uid);
psinfo->pr_gid = tswap16(psinfo->pr_gid);
@@ -4031,21 +4047,19 @@ static void bswap_psinfo(struct target_elf_prpsinfo *psinfo)
static void bswap_note(struct elf_note *en)
{
+ if (!target_needs_bswap()) {
+ return;
+ }
+
bswap32s(&en->n_namesz);
bswap32s(&en->n_descsz);
bswap32s(&en->n_type);
}
-#else
-static inline void bswap_prstatus(struct target_elf_prstatus *p) { }
-static inline void bswap_psinfo(struct target_elf_prpsinfo *p) {}
-static inline void bswap_note(struct elf_note *en) { }
-#endif /* HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN */
/*
* Calculate file (dump) size of given memory region.
*/
-static size_t vma_dump_size(target_ulong start, target_ulong end,
- unsigned long flags)
+static size_t vma_dump_size(vaddr start, vaddr end, int flags)
{
/* The area must be readable. */
if (!(flags & PAGE_READ)) {
@@ -4238,14 +4252,14 @@ static int dump_write(int fd, const void *ptr, size_t size)
return (0);
}
-static int wmr_page_unprotect_regions(void *opaque, target_ulong start,
- target_ulong end, unsigned long flags)
+static int wmr_page_unprotect_regions(void *opaque, vaddr start,
+ vaddr end, int flags)
{
if ((flags & (PAGE_WRITE | PAGE_WRITE_ORG)) == PAGE_WRITE_ORG) {
size_t step = MAX(TARGET_PAGE_SIZE, qemu_real_host_page_size());
while (1) {
- page_unprotect(start, 0);
+ page_unprotect(NULL, start, 0);
if (end - start <= step) {
break;
}
@@ -4260,8 +4274,8 @@ typedef struct {
size_t size;
} CountAndSizeRegions;
-static int wmr_count_and_size_regions(void *opaque, target_ulong start,
- target_ulong end, unsigned long flags)
+static int wmr_count_and_size_regions(void *opaque, vaddr start,
+ vaddr end, int flags)
{
CountAndSizeRegions *css = opaque;
@@ -4275,8 +4289,8 @@ typedef struct {
off_t offset;
} FillRegionPhdr;
-static int wmr_fill_region_phdr(void *opaque, target_ulong start,
- target_ulong end, unsigned long flags)
+static int wmr_fill_region_phdr(void *opaque, vaddr start,
+ vaddr end, int flags)
{
FillRegionPhdr *d = opaque;
struct elf_phdr *phdr = d->phdr;
@@ -4298,8 +4312,8 @@ static int wmr_fill_region_phdr(void *opaque, target_ulong start,
return 0;
}
-static int wmr_write_region(void *opaque, target_ulong start,
- target_ulong end, unsigned long flags)
+static int wmr_write_region(void *opaque, vaddr start,
+ vaddr end, int flags)
{
int fd = *(int *)opaque;
size_t size = vma_dump_size(start, end, flags);