target-arm queue:
* raspi: add model of cprman clock manager * sbsa-ref: add an SBSA generic watchdog device * arm/trace: Fix hex printing * raspi: Add models of Pi 3 model A+, Pi Zero and Pi A+ * hw/arm/smmuv3: Set the restoration priority of the vSMMUv3 explicitly * Nuvoton NPCM7xx: Add USB, RNG, GPIO and watchdog support * hw/arm: fix min_cpus for xlnx-versal-virt platform * hw/arm/highbank: Silence warnings about missing fallthrough statements * linux-user: Support Aarch64 BTI * Armv7M systick: fix corner case bugs by rewriting to use ptimer -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAl+YBA4ZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3rWRD/9hqjzL4d7xKcFQdQdRXsxv 7zX82arHdxg9pNvusie/tuhX0PLswQ8TPEHEBVQvngxF7y/HqLBFuZAQvFf4ou6R 9+myTXE2RuWHOYKlrr/M6p4csABXNMm7PiA3VMeKcTEh4DoamLyBz6j1X4obPiA+ tLaRw4azzYAZnHoCaF6BX+4uf4bQZoqAtAS4IodJAAbDXJStl0VUFoS34MPhgW6/ dwGF8DbQJVYRqa7xEXck4Yx7dkx13I66+iYUf9kCyoCkdyz1sIq58fbKhXQP4lqN I3e5XGBVJfeku7w/TGOpsw8OCyTng0z636iglfLVOrsj5N03fT8j72ehY7jJsN9f CgHvQ1JAX1DvA/v23oxs3WccwAOfJJsOERtf9QxyMbTR1czCeIY1LYMnkOFtyL87 6IQpwM0WF1z4lja0dmrvhKJWjqn+kVI2cDtxrprsulCHi+pcIdJMq8vJDfxjpqqe SnDXVSAn8KjBrClaJRqHfbi+5ggsTwsLpBtEToQ4AOR342XVRfEY8IfTLb1D2+6q z99BFiyJtZ6iiJq5jgGMhppN6tEuHFK7Vr6IwhGDgFTchWb6by+K3i8/VzrbWVk9 O+KEeO92dg6jVd+6FyXOPnJ3DcUXEp6EVUVrKBBUC+LTU8Lf1MCgeprjSi87UHIX xQg635uOQU3gxkqxCaE0XA== =OFlu -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20201027-1' into staging target-arm queue: * raspi: add model of cprman clock manager * sbsa-ref: add an SBSA generic watchdog device * arm/trace: Fix hex printing * raspi: Add models of Pi 3 model A+, Pi Zero and Pi A+ * hw/arm/smmuv3: Set the restoration priority of the vSMMUv3 explicitly * Nuvoton NPCM7xx: Add USB, RNG, GPIO and watchdog support * hw/arm: fix min_cpus for xlnx-versal-virt platform * hw/arm/highbank: Silence warnings about missing fallthrough statements * linux-user: Support Aarch64 BTI * Armv7M systick: fix corner case bugs by rewriting to use ptimer # gpg: Signature made Tue 27 Oct 2020 11:27:10 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20201027-1: (48 commits) hw/timer/armv7m_systick: Rewrite to use ptimers hw/core/ptimer: Support ptimer being disabled by timer callback hw/arm/sbsa-ref: add SBSA watchdog device hw/watchdog: Implement SBSA watchdog device hw/arm/bcm2835_peripherals: connect the UART clock hw/char/pl011: add a clock input hw/misc/bcm2835_cprman: add sane reset values to the registers hw/misc/bcm2835_cprman: add the DSI0HSCK multiplexer hw/misc/bcm2835_cprman: implement clock mux behaviour hw/misc/bcm2835_cprman: add a clock mux skeleton implementation hw/misc/bcm2835_cprman: implement PLL channels behaviour hw/misc/bcm2835_cprman: add a PLL channel skeleton implementation hw/misc/bcm2835_cprman: implement PLLs behaviour hw/misc/bcm2835_cprman: add a PLL skeleton implementation hw/arm/raspi: add a skeleton implementation of the CPRMAN hw/arm/raspi: fix CPRMAN base address hw/core/clock: trace clock values in Hz instead of ns hw/core/clock: provide the VMSTATE_ARRAY_CLOCK macro arm/trace: Fix hex printing hw/arm/raspi: Add the Raspberry Pi 3 model A+ ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
802427bcda
64 changed files with 5461 additions and 279 deletions
|
|
@ -506,10 +506,16 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
|
|||
+ offsetof(struct target_rt_frame_record, tramp);
|
||||
}
|
||||
env->xregs[0] = usig;
|
||||
env->xregs[31] = frame_addr;
|
||||
env->xregs[29] = frame_addr + fr_ofs;
|
||||
env->pc = ka->_sa_handler;
|
||||
env->xregs[30] = return_addr;
|
||||
env->xregs[31] = frame_addr;
|
||||
env->pc = ka->_sa_handler;
|
||||
|
||||
/* Invoke the signal handler as if by indirect call. */
|
||||
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
|
||||
env->btype = 2;
|
||||
}
|
||||
|
||||
if (info) {
|
||||
tswap_siginfo(&frame->info, info);
|
||||
env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "qemu/guest-random.h"
|
||||
#include "qemu/units.h"
|
||||
#include "qemu/selfmap.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
#ifdef _ARCH_PPC64
|
||||
#undef ARCH_DLINFO
|
||||
|
|
@ -1521,6 +1522,39 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
|
|||
|
||||
#include "elf.h"
|
||||
|
||||
/* We must delay the following stanzas until after "elf.h". */
|
||||
#if defined(TARGET_AARCH64)
|
||||
|
||||
static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
|
||||
const uint32_t *data,
|
||||
struct image_info *info,
|
||||
Error **errp)
|
||||
{
|
||||
if (pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
|
||||
if (pr_datasz != sizeof(uint32_t)) {
|
||||
error_setg(errp, "Ill-formed GNU_PROPERTY_AARCH64_FEATURE_1_AND");
|
||||
return false;
|
||||
}
|
||||
/* We will extract GNU_PROPERTY_AARCH64_FEATURE_1_BTI later. */
|
||||
info->note_flags = *data;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#define ARCH_USE_GNU_PROPERTY 1
|
||||
|
||||
#else
|
||||
|
||||
static bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
|
||||
const uint32_t *data,
|
||||
struct image_info *info,
|
||||
Error **errp)
|
||||
{
|
||||
g_assert_not_reached();
|
||||
}
|
||||
#define ARCH_USE_GNU_PROPERTY 0
|
||||
|
||||
#endif
|
||||
|
||||
struct exec
|
||||
{
|
||||
unsigned int a_info; /* Use macros N_MAGIC, etc for access */
|
||||
|
|
@ -2372,6 +2406,150 @@ void probe_guest_base(const char *image_name, abi_ulong guest_loaddr,
|
|||
"@ 0x%" PRIx64 "\n", (uint64_t)guest_base);
|
||||
}
|
||||
|
||||
enum {
|
||||
/* The string "GNU\0" as a magic number. */
|
||||
GNU0_MAGIC = const_le32('G' | 'N' << 8 | 'U' << 16),
|
||||
NOTE_DATA_SZ = 1 * KiB,
|
||||
NOTE_NAME_SZ = 4,
|
||||
ELF_GNU_PROPERTY_ALIGN = ELF_CLASS == ELFCLASS32 ? 4 : 8,
|
||||
};
|
||||
|
||||
/*
|
||||
* Process a single gnu_property entry.
|
||||
* Return false for error.
|
||||
*/
|
||||
static bool parse_elf_property(const uint32_t *data, int *off, int datasz,
|
||||
struct image_info *info, bool have_prev_type,
|
||||
uint32_t *prev_type, Error **errp)
|
||||
{
|
||||
uint32_t pr_type, pr_datasz, step;
|
||||
|
||||
if (*off > datasz || !QEMU_IS_ALIGNED(*off, ELF_GNU_PROPERTY_ALIGN)) {
|
||||
goto error_data;
|
||||
}
|
||||
datasz -= *off;
|
||||
data += *off / sizeof(uint32_t);
|
||||
|
||||
if (datasz < 2 * sizeof(uint32_t)) {
|
||||
goto error_data;
|
||||
}
|
||||
pr_type = data[0];
|
||||
pr_datasz = data[1];
|
||||
data += 2;
|
||||
datasz -= 2 * sizeof(uint32_t);
|
||||
step = ROUND_UP(pr_datasz, ELF_GNU_PROPERTY_ALIGN);
|
||||
if (step > datasz) {
|
||||
goto error_data;
|
||||
}
|
||||
|
||||
/* Properties are supposed to be unique and sorted on pr_type. */
|
||||
if (have_prev_type && pr_type <= *prev_type) {
|
||||
if (pr_type == *prev_type) {
|
||||
error_setg(errp, "Duplicate property in PT_GNU_PROPERTY");
|
||||
} else {
|
||||
error_setg(errp, "Unsorted property in PT_GNU_PROPERTY");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*prev_type = pr_type;
|
||||
|
||||
if (!arch_parse_elf_property(pr_type, pr_datasz, data, info, errp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*off += 2 * sizeof(uint32_t) + step;
|
||||
return true;
|
||||
|
||||
error_data:
|
||||
error_setg(errp, "Ill-formed property in PT_GNU_PROPERTY");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Process NT_GNU_PROPERTY_TYPE_0. */
|
||||
static bool parse_elf_properties(int image_fd,
|
||||
struct image_info *info,
|
||||
const struct elf_phdr *phdr,
|
||||
char bprm_buf[BPRM_BUF_SIZE],
|
||||
Error **errp)
|
||||
{
|
||||
union {
|
||||
struct elf_note nhdr;
|
||||
uint32_t data[NOTE_DATA_SZ / sizeof(uint32_t)];
|
||||
} note;
|
||||
|
||||
int n, off, datasz;
|
||||
bool have_prev_type;
|
||||
uint32_t prev_type;
|
||||
|
||||
/* Unless the arch requires properties, ignore them. */
|
||||
if (!ARCH_USE_GNU_PROPERTY) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If the properties are crazy large, that's too bad. */
|
||||
n = phdr->p_filesz;
|
||||
if (n > sizeof(note)) {
|
||||
error_setg(errp, "PT_GNU_PROPERTY too large");
|
||||
return false;
|
||||
}
|
||||
if (n < sizeof(note.nhdr)) {
|
||||
error_setg(errp, "PT_GNU_PROPERTY too small");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (phdr->p_offset + n <= BPRM_BUF_SIZE) {
|
||||
memcpy(¬e, bprm_buf + phdr->p_offset, n);
|
||||
} else {
|
||||
ssize_t len = pread(image_fd, ¬e, n, phdr->p_offset);
|
||||
if (len != n) {
|
||||
error_setg_errno(errp, errno, "Error reading file header");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The contents of a valid PT_GNU_PROPERTY is a sequence
|
||||
* of uint32_t -- swap them all now.
|
||||
*/
|
||||
#ifdef BSWAP_NEEDED
|
||||
for (int i = 0; i < n / 4; i++) {
|
||||
bswap32s(note.data + i);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note that nhdr is 3 words, and that the "name" described by namesz
|
||||
* immediately follows nhdr and is thus at the 4th word. Further, all
|
||||
* of the inputs to the kernel's round_up are multiples of 4.
|
||||
*/
|
||||
if (note.nhdr.n_type != NT_GNU_PROPERTY_TYPE_0 ||
|
||||
note.nhdr.n_namesz != NOTE_NAME_SZ ||
|
||||
note.data[3] != GNU0_MAGIC) {
|
||||
error_setg(errp, "Invalid note in PT_GNU_PROPERTY");
|
||||
return false;
|
||||
}
|
||||
off = sizeof(note.nhdr) + NOTE_NAME_SZ;
|
||||
|
||||
datasz = note.nhdr.n_descsz + off;
|
||||
if (datasz > n) {
|
||||
error_setg(errp, "Invalid note size in PT_GNU_PROPERTY");
|
||||
return false;
|
||||
}
|
||||
|
||||
have_prev_type = false;
|
||||
prev_type = 0;
|
||||
while (1) {
|
||||
if (off == datasz) {
|
||||
return true; /* end, exit ok */
|
||||
}
|
||||
if (!parse_elf_property(note.data, &off, datasz, info,
|
||||
have_prev_type, &prev_type, errp)) {
|
||||
return false;
|
||||
}
|
||||
have_prev_type = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load an ELF image into the address space.
|
||||
|
||||
IMAGE_NAME is the filename of the image, to use in error messages.
|
||||
|
|
@ -2391,16 +2569,17 @@ static void load_elf_image(const char *image_name, int image_fd,
|
|||
struct elfhdr *ehdr = (struct elfhdr *)bprm_buf;
|
||||
struct elf_phdr *phdr;
|
||||
abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
|
||||
int i, retval;
|
||||
const char *errmsg;
|
||||
int i, retval, prot_exec;
|
||||
Error *err = NULL;
|
||||
|
||||
/* First of all, some simple consistency checks */
|
||||
errmsg = "Invalid ELF image for this architecture";
|
||||
if (!elf_check_ident(ehdr)) {
|
||||
error_setg(&err, "Invalid ELF image for this architecture");
|
||||
goto exit_errmsg;
|
||||
}
|
||||
bswap_ehdr(ehdr);
|
||||
if (!elf_check_ehdr(ehdr)) {
|
||||
error_setg(&err, "Invalid ELF image for this architecture");
|
||||
goto exit_errmsg;
|
||||
}
|
||||
|
||||
|
|
@ -2421,22 +2600,54 @@ static void load_elf_image(const char *image_name, int image_fd,
|
|||
|
||||
mmap_lock();
|
||||
|
||||
/* Find the maximum size of the image and allocate an appropriate
|
||||
amount of memory to handle that. */
|
||||
/*
|
||||
* Find the maximum size of the image and allocate an appropriate
|
||||
* amount of memory to handle that. Locate the interpreter, if any.
|
||||
*/
|
||||
loaddr = -1, hiaddr = 0;
|
||||
info->alignment = 0;
|
||||
for (i = 0; i < ehdr->e_phnum; ++i) {
|
||||
if (phdr[i].p_type == PT_LOAD) {
|
||||
abi_ulong a = phdr[i].p_vaddr - phdr[i].p_offset;
|
||||
struct elf_phdr *eppnt = phdr + i;
|
||||
if (eppnt->p_type == PT_LOAD) {
|
||||
abi_ulong a = eppnt->p_vaddr - eppnt->p_offset;
|
||||
if (a < loaddr) {
|
||||
loaddr = a;
|
||||
}
|
||||
a = phdr[i].p_vaddr + phdr[i].p_memsz;
|
||||
a = eppnt->p_vaddr + eppnt->p_memsz;
|
||||
if (a > hiaddr) {
|
||||
hiaddr = a;
|
||||
}
|
||||
++info->nsegs;
|
||||
info->alignment |= phdr[i].p_align;
|
||||
info->alignment |= eppnt->p_align;
|
||||
} else if (eppnt->p_type == PT_INTERP && pinterp_name) {
|
||||
g_autofree char *interp_name = NULL;
|
||||
|
||||
if (*pinterp_name) {
|
||||
error_setg(&err, "Multiple PT_INTERP entries");
|
||||
goto exit_errmsg;
|
||||
}
|
||||
|
||||
interp_name = g_malloc(eppnt->p_filesz);
|
||||
|
||||
if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
|
||||
memcpy(interp_name, bprm_buf + eppnt->p_offset,
|
||||
eppnt->p_filesz);
|
||||
} else {
|
||||
retval = pread(image_fd, interp_name, eppnt->p_filesz,
|
||||
eppnt->p_offset);
|
||||
if (retval != eppnt->p_filesz) {
|
||||
goto exit_read;
|
||||
}
|
||||
}
|
||||
if (interp_name[eppnt->p_filesz - 1] != 0) {
|
||||
error_setg(&err, "Invalid PT_INTERP entry");
|
||||
goto exit_errmsg;
|
||||
}
|
||||
*pinterp_name = g_steal_pointer(&interp_name);
|
||||
} else if (eppnt->p_type == PT_GNU_PROPERTY) {
|
||||
if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) {
|
||||
goto exit_errmsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2490,7 +2701,7 @@ static void load_elf_image(const char *image_name, int image_fd,
|
|||
(ehdr->e_type == ET_EXEC ? MAP_FIXED : 0),
|
||||
-1, 0);
|
||||
if (load_addr == -1) {
|
||||
goto exit_perror;
|
||||
goto exit_mmap;
|
||||
}
|
||||
load_bias = load_addr - loaddr;
|
||||
|
||||
|
|
@ -2525,15 +2736,41 @@ static void load_elf_image(const char *image_name, int image_fd,
|
|||
info->brk = 0;
|
||||
info->elf_flags = ehdr->e_flags;
|
||||
|
||||
prot_exec = PROT_EXEC;
|
||||
#ifdef TARGET_AARCH64
|
||||
/*
|
||||
* If the BTI feature is present, this indicates that the executable
|
||||
* pages of the startup binary should be mapped with PROT_BTI, so that
|
||||
* branch targets are enforced.
|
||||
*
|
||||
* The startup binary is either the interpreter or the static executable.
|
||||
* The interpreter is responsible for all pages of a dynamic executable.
|
||||
*
|
||||
* Elf notes are backward compatible to older cpus.
|
||||
* Do not enable BTI unless it is supported.
|
||||
*/
|
||||
if ((info->note_flags & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
|
||||
&& (pinterp_name == NULL || *pinterp_name == 0)
|
||||
&& cpu_isar_feature(aa64_bti, ARM_CPU(thread_cpu))) {
|
||||
prot_exec |= TARGET_PROT_BTI;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||
struct elf_phdr *eppnt = phdr + i;
|
||||
if (eppnt->p_type == PT_LOAD) {
|
||||
abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em, vaddr_len;
|
||||
int elf_prot = 0;
|
||||
|
||||
if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
|
||||
if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
|
||||
if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
|
||||
if (eppnt->p_flags & PF_R) {
|
||||
elf_prot |= PROT_READ;
|
||||
}
|
||||
if (eppnt->p_flags & PF_W) {
|
||||
elf_prot |= PROT_WRITE;
|
||||
}
|
||||
if (eppnt->p_flags & PF_X) {
|
||||
elf_prot |= prot_exec;
|
||||
}
|
||||
|
||||
vaddr = load_bias + eppnt->p_vaddr;
|
||||
vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr);
|
||||
|
|
@ -2551,7 +2788,7 @@ static void load_elf_image(const char *image_name, int image_fd,
|
|||
image_fd, eppnt->p_offset - vaddr_po);
|
||||
|
||||
if (error == -1) {
|
||||
goto exit_perror;
|
||||
goto exit_mmap;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2583,38 +2820,11 @@ static void load_elf_image(const char *image_name, int image_fd,
|
|||
if (vaddr_em > info->brk) {
|
||||
info->brk = vaddr_em;
|
||||
}
|
||||
} else if (eppnt->p_type == PT_INTERP && pinterp_name) {
|
||||
char *interp_name;
|
||||
|
||||
if (*pinterp_name) {
|
||||
errmsg = "Multiple PT_INTERP entries";
|
||||
goto exit_errmsg;
|
||||
}
|
||||
interp_name = malloc(eppnt->p_filesz);
|
||||
if (!interp_name) {
|
||||
goto exit_perror;
|
||||
}
|
||||
|
||||
if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
|
||||
memcpy(interp_name, bprm_buf + eppnt->p_offset,
|
||||
eppnt->p_filesz);
|
||||
} else {
|
||||
retval = pread(image_fd, interp_name, eppnt->p_filesz,
|
||||
eppnt->p_offset);
|
||||
if (retval != eppnt->p_filesz) {
|
||||
goto exit_perror;
|
||||
}
|
||||
}
|
||||
if (interp_name[eppnt->p_filesz - 1] != 0) {
|
||||
errmsg = "Invalid PT_INTERP entry";
|
||||
goto exit_errmsg;
|
||||
}
|
||||
*pinterp_name = interp_name;
|
||||
#ifdef TARGET_MIPS
|
||||
} else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
|
||||
Mips_elf_abiflags_v0 abiflags;
|
||||
if (eppnt->p_filesz < sizeof(Mips_elf_abiflags_v0)) {
|
||||
errmsg = "Invalid PT_MIPS_ABIFLAGS entry";
|
||||
error_setg(&err, "Invalid PT_MIPS_ABIFLAGS entry");
|
||||
goto exit_errmsg;
|
||||
}
|
||||
if (eppnt->p_offset + eppnt->p_filesz <= BPRM_BUF_SIZE) {
|
||||
|
|
@ -2624,7 +2834,7 @@ static void load_elf_image(const char *image_name, int image_fd,
|
|||
retval = pread(image_fd, &abiflags, sizeof(Mips_elf_abiflags_v0),
|
||||
eppnt->p_offset);
|
||||
if (retval != sizeof(Mips_elf_abiflags_v0)) {
|
||||
goto exit_perror;
|
||||
goto exit_read;
|
||||
}
|
||||
}
|
||||
bswap_mips_abiflags(&abiflags);
|
||||
|
|
@ -2649,13 +2859,16 @@ static void load_elf_image(const char *image_name, int image_fd,
|
|||
|
||||
exit_read:
|
||||
if (retval >= 0) {
|
||||
errmsg = "Incomplete read of file header";
|
||||
goto exit_errmsg;
|
||||
error_setg(&err, "Incomplete read of file header");
|
||||
} else {
|
||||
error_setg_errno(&err, errno, "Error reading file header");
|
||||
}
|
||||
exit_perror:
|
||||
errmsg = strerror(errno);
|
||||
goto exit_errmsg;
|
||||
exit_mmap:
|
||||
error_setg_errno(&err, errno, "Error mapping file");
|
||||
goto exit_errmsg;
|
||||
exit_errmsg:
|
||||
fprintf(stderr, "%s: %s\n", image_name, errmsg);
|
||||
error_reportf_err(err, "%s: ", image_name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
|
@ -2663,26 +2876,27 @@ static void load_elf_interp(const char *filename, struct image_info *info,
|
|||
char bprm_buf[BPRM_BUF_SIZE])
|
||||
{
|
||||
int fd, retval;
|
||||
Error *err = NULL;
|
||||
|
||||
fd = open(path(filename), O_RDONLY);
|
||||
if (fd < 0) {
|
||||
goto exit_perror;
|
||||
error_setg_file_open(&err, errno, filename);
|
||||
error_report_err(err);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
retval = read(fd, bprm_buf, BPRM_BUF_SIZE);
|
||||
if (retval < 0) {
|
||||
goto exit_perror;
|
||||
error_setg_errno(&err, errno, "Error reading file header");
|
||||
error_reportf_err(err, "%s: ", filename);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (retval < BPRM_BUF_SIZE) {
|
||||
memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval);
|
||||
}
|
||||
|
||||
load_elf_image(filename, fd, info, NULL, bprm_buf);
|
||||
return;
|
||||
|
||||
exit_perror:
|
||||
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static int symfind(const void *s0, const void *s1)
|
||||
|
|
@ -2961,7 +3175,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
|
|||
if (elf_interpreter) {
|
||||
info->load_bias = interp_info.load_bias;
|
||||
info->entry = interp_info.entry;
|
||||
free(elf_interpreter);
|
||||
g_free(elf_interpreter);
|
||||
}
|
||||
|
||||
#ifdef USE_ELF_CORE_DUMP
|
||||
|
|
|
|||
|
|
@ -83,6 +83,22 @@ static int validate_prot_to_pageflags(int *host_prot, int prot)
|
|||
*host_prot = (prot & (PROT_READ | PROT_WRITE))
|
||||
| (prot & PROT_EXEC ? PROT_READ : 0);
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
/*
|
||||
* The PROT_BTI bit is only accepted if the cpu supports the feature.
|
||||
* Since this is the unusual case, don't bother checking unless
|
||||
* the bit has been requested. If set and valid, record the bit
|
||||
* within QEMU's page_flags.
|
||||
*/
|
||||
if (prot & TARGET_PROT_BTI) {
|
||||
ARMCPU *cpu = ARM_CPU(thread_cpu);
|
||||
if (cpu_isar_feature(aa64_bti, cpu)) {
|
||||
valid |= TARGET_PROT_BTI;
|
||||
page_flags |= PAGE_BTI;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return prot & ~valid ? 0 : page_flags;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,10 @@ struct image_info {
|
|||
abi_ulong interpreter_loadmap_addr;
|
||||
abi_ulong interpreter_pt_dynamic_addr;
|
||||
struct image_info *other_info;
|
||||
|
||||
/* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */
|
||||
uint32_t note_flags;
|
||||
|
||||
#ifdef TARGET_MIPS
|
||||
int fp_abi;
|
||||
int interp_fp_abi;
|
||||
|
|
|
|||
|
|
@ -1277,6 +1277,10 @@ struct target_winsize {
|
|||
#define TARGET_PROT_SEM 0x08
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_AARCH64
|
||||
#define TARGET_PROT_BTI 0x10
|
||||
#endif
|
||||
|
||||
/* Common */
|
||||
#define TARGET_MAP_SHARED 0x01 /* Share changes */
|
||||
#define TARGET_MAP_PRIVATE 0x02 /* Changes are private */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue