Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu
Pull m68nommu updates from Greg Ungerer: "A series of cleanups for the FLAT format binary loader, binfmt_flat, from Christoph. The end goal is to support no-MMU on RISC-V, and the last patch enables that" * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu: riscv: add binfmt_flat support binfmt_flat: don't offset the data start binfmt_flat: move the MAX_SHARED_LIBS definition to binfmt_flat.c binfmt_flat: remove the persistent argument from flat_get_addr_from_rp binfmt_flat: provide an asm-generic/flat.h binfmt_flat: make support for old format binaries optional binfmt_flat: add a ARCH_HAS_BINFMT_FLAT option binfmt_flat: add endianess annotations binfmt_flat: use fixed size type for the on-disk format binfmt_flat: consolidate two version of flat_v2_reloc_t binfmt_flat: remove the unused OLD_FLAT_FLAG_RAM definition binfmt_flat: remove the uapi <linux/flat.h> header binfmt_flat: replace flat_argvp_envp_on_stack with a Kconfig variable binfmt_flat: remove flat_old_ram_flag binfmt_flat: provide a default version of flat_get_relocate_addr binfmt_flat: remove flat_set_persistent binfmt_flat: remove flat_reloc_valid
This commit is contained in:
commit
398364a35d
|
@ -4,6 +4,7 @@ config ARM
|
|||
default y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_CLOCKSOURCE_DATA
|
||||
select ARCH_HAS_BINFMT_FLAT
|
||||
select ARCH_HAS_DEBUG_VIRTUAL if MMU
|
||||
select ARCH_HAS_DEVMEM_IS_ALLOWED
|
||||
select ARCH_HAS_ELF_RANDOMIZE
|
||||
|
@ -30,6 +31,7 @@ config ARM
|
|||
select ARCH_USE_BUILTIN_BSWAP
|
||||
select ARCH_USE_CMPXCHG_LOCKREF
|
||||
select ARCH_WANT_IPC_PARSE_VERSION
|
||||
select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
|
||||
select BUILDTIME_EXTABLE_SORT if MMU
|
||||
select CLONE_BACKWARDS
|
||||
select CPU_PM if SUSPEND || CPU_IDLE
|
||||
|
|
|
@ -5,6 +5,7 @@ generic-y += early_ioremap.h
|
|||
generic-y += emergency-restart.h
|
||||
generic-y += exec.h
|
||||
generic-y += extable.h
|
||||
generic-y += flat.h
|
||||
generic-y += irq_regs.h
|
||||
generic-y += kdebug.h
|
||||
generic-y += local.h
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
config C6X
|
||||
def_bool y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_HAS_BINFMT_FLAT
|
||||
select ARCH_HAS_SYNC_DMA_FOR_CPU
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
|
||||
select CLKDEV_LOOKUP
|
||||
|
|
|
@ -4,11 +4,8 @@
|
|||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#define flat_argvp_envp_on_stack() 0
|
||||
#define flat_old_ram_flag(flags) (flags)
|
||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||
u32 *addr, u32 *persistent)
|
||||
u32 *addr)
|
||||
{
|
||||
*addr = get_unaligned((__force u32 *)rp);
|
||||
return 0;
|
||||
|
@ -18,7 +15,5 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
|
|||
put_unaligned(addr, (__force u32 *)rp);
|
||||
return 0;
|
||||
}
|
||||
#define flat_get_relocate_addr(rel) (rel)
|
||||
#define flat_set_persistent(relval, p) 0
|
||||
|
||||
#endif /* __ASM_C6X_FLAT_H */
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
config H8300
|
||||
def_bool y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_HAS_BINFMT_FLAT
|
||||
select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
|
||||
select BINFMT_FLAT_OLD_ALWAYS_RAM
|
||||
select GENERIC_ATOMIC64
|
||||
select HAVE_UID16
|
||||
select VIRT_TO_BUS
|
||||
|
|
|
@ -8,11 +8,6 @@
|
|||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#define flat_argvp_envp_on_stack() 1
|
||||
#define flat_old_ram_flag(flags) 1
|
||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||
#define flat_set_persistent(relval, p) 0
|
||||
|
||||
/*
|
||||
* on the H8 a couple of the relocations have an instruction in the
|
||||
* top byte. As there can only be 24bits of address space, we just
|
||||
|
@ -22,7 +17,7 @@
|
|||
|
||||
#define flat_get_relocate_addr(rel) (rel & ~0x00000001)
|
||||
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||
u32 *addr, u32 *persistent)
|
||||
u32 *addr)
|
||||
{
|
||||
u32 val = get_unaligned((__force u32 *)rp);
|
||||
if (!(flags & FLAT_FLAG_GOTPIC))
|
||||
|
|
|
@ -3,12 +3,14 @@ config M68K
|
|||
bool
|
||||
default y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_HAS_BINFMT_FLAT
|
||||
select ARCH_HAS_DMA_MMAP_PGPROT if MMU && !COLDFIRE
|
||||
select ARCH_HAS_DMA_PREP_COHERENT
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
|
||||
select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
|
||||
select ARCH_NO_COHERENT_DMA_MMAP if !MMU
|
||||
select ARCH_NO_PREEMPT if !COLDFIRE
|
||||
select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
|
||||
select DMA_DIRECT_REMAP if HAS_DMA && MMU && !COLDFIRE
|
||||
select HAVE_IDE
|
||||
select HAVE_AOUT if MMU
|
||||
|
|
|
@ -6,35 +6,7 @@
|
|||
#ifndef __M68KNOMMU_FLAT_H__
|
||||
#define __M68KNOMMU_FLAT_H__
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define flat_argvp_envp_on_stack() 1
|
||||
#define flat_old_ram_flag(flags) (flags)
|
||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||
u32 *addr, u32 *persistent)
|
||||
{
|
||||
#ifdef CONFIG_CPU_HAS_NO_UNALIGNED
|
||||
return copy_from_user(addr, rp, 4) ? -EFAULT : 0;
|
||||
#else
|
||||
return get_user(*addr, rp);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
|
||||
{
|
||||
#ifdef CONFIG_CPU_HAS_NO_UNALIGNED
|
||||
return copy_to_user(rp, &addr, 4) ? -EFAULT : 0;
|
||||
#else
|
||||
return put_user(addr, rp);
|
||||
#endif
|
||||
}
|
||||
#define flat_get_relocate_addr(rel) (rel)
|
||||
|
||||
static inline int flat_set_persistent(u32 relval, u32 *persistent)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#include <asm-generic/flat.h>
|
||||
|
||||
#define FLAT_PLAT_INIT(regs) \
|
||||
do { \
|
||||
|
|
|
@ -3,6 +3,7 @@ config MICROBLAZE
|
|||
def_bool y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_NO_SWAP
|
||||
select ARCH_HAS_BINFMT_FLAT if !MMU
|
||||
select ARCH_HAS_DMA_COHERENT_TO_PFN if MMU
|
||||
select ARCH_HAS_GCOV_PROFILE_ALL
|
||||
select ARCH_HAS_SYNC_DMA_FOR_CPU
|
||||
|
|
|
@ -13,11 +13,6 @@
|
|||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#define flat_argvp_envp_on_stack() 0
|
||||
#define flat_old_ram_flag(flags) (flags)
|
||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||
#define flat_set_persistent(relval, p) 0
|
||||
|
||||
/*
|
||||
* Microblaze works a little differently from other arches, because
|
||||
* of the MICROBLAZE_64 reloc type. Here, a 32 bit address is split
|
||||
|
@ -33,7 +28,7 @@
|
|||
*/
|
||||
|
||||
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||
u32 *addr, u32 *persistent)
|
||||
u32 *addr)
|
||||
{
|
||||
u32 *p = (__force u32 *)rp;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ config RISCV
|
|||
select OF
|
||||
select OF_EARLY_FLATTREE
|
||||
select OF_IRQ
|
||||
select ARCH_HAS_BINFMT_FLAT
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
select CLONE_BACKWARDS
|
||||
select COMMON_CLK
|
||||
|
|
|
@ -5,6 +5,7 @@ generic-y += compat.h
|
|||
generic-y += device.h
|
||||
generic-y += div64.h
|
||||
generic-y += extable.h
|
||||
generic-y += flat.h
|
||||
generic-y += dma.h
|
||||
generic-y += dma-contiguous.h
|
||||
generic-y += dma-mapping.h
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
config SUPERH
|
||||
def_bool y
|
||||
select ARCH_HAS_BINFMT_FLAT if !MMU
|
||||
select ARCH_HAS_PTE_SPECIAL
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select ARCH_MIGHT_HAVE_PC_PARPORT
|
||||
|
|
|
@ -11,11 +11,8 @@
|
|||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#define flat_argvp_envp_on_stack() 0
|
||||
#define flat_old_ram_flag(flags) (flags)
|
||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||
u32 *addr, u32 *persistent)
|
||||
u32 *addr)
|
||||
{
|
||||
*addr = get_unaligned((__force u32 *)rp);
|
||||
return 0;
|
||||
|
@ -25,8 +22,6 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
|
|||
put_unaligned(addr, (__force u32 *)rp);
|
||||
return 0;
|
||||
}
|
||||
#define flat_get_relocate_addr(rel) (rel)
|
||||
#define flat_set_persistent(relval, p) ({ (void)p; 0; })
|
||||
|
||||
#define FLAT_PLAT_INIT(_r) \
|
||||
do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
config XTENSA
|
||||
def_bool y
|
||||
select ARCH_32BIT_OFF_T
|
||||
select ARCH_HAS_BINFMT_FLAT if !MMU
|
||||
select ARCH_HAS_SYNC_DMA_FOR_CPU
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
|
||||
select ARCH_NO_COHERENT_DMA_MMAP if !MMU
|
||||
|
|
|
@ -4,11 +4,8 @@
|
|||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#define flat_argvp_envp_on_stack() 0
|
||||
#define flat_old_ram_flag(flags) (flags)
|
||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||
u32 *addr, u32 *persistent)
|
||||
u32 *addr)
|
||||
{
|
||||
*addr = get_unaligned((__force u32 *)rp);
|
||||
return 0;
|
||||
|
@ -18,7 +15,5 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
|
|||
put_unaligned(addr, (__force u32 *)rp);
|
||||
return 0;
|
||||
}
|
||||
#define flat_get_relocate_addr(rel) (rel)
|
||||
#define flat_set_persistent(relval, p) 0
|
||||
|
||||
#endif /* __ASM_XTENSA_FLAT_H */
|
||||
|
|
|
@ -91,12 +91,28 @@ config BINFMT_SCRIPT
|
|||
|
||||
Most systems will not boot if you say M or N here. If unsure, say Y.
|
||||
|
||||
config ARCH_HAS_BINFMT_FLAT
|
||||
bool
|
||||
|
||||
config BINFMT_FLAT
|
||||
bool "Kernel support for flat binaries"
|
||||
depends on !MMU || ARM || M68K
|
||||
depends on ARCH_HAS_BINFMT_FLAT
|
||||
help
|
||||
Support uClinux FLAT format binaries.
|
||||
|
||||
config BINFMT_FLAT_ARGVP_ENVP_ON_STACK
|
||||
bool
|
||||
|
||||
config BINFMT_FLAT_OLD_ALWAYS_RAM
|
||||
bool
|
||||
|
||||
config BINFMT_FLAT_OLD
|
||||
bool "Enable support for very old legacy flat binaries"
|
||||
depends on BINFMT_FLAT
|
||||
help
|
||||
Support decade old uClinux FLAT format binaries. Unless you know
|
||||
you have some of those say N here.
|
||||
|
||||
config BINFMT_ZFLAT
|
||||
bool "Enable ZFLAT support"
|
||||
depends on BINFMT_FLAT
|
||||
|
|
|
@ -42,6 +42,11 @@
|
|||
#include <asm/unaligned.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/flat.h>
|
||||
|
||||
#ifndef flat_get_relocate_addr
|
||||
#define flat_get_relocate_addr(rel) (rel)
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
@ -63,6 +68,12 @@
|
|||
#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
|
||||
#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
|
||||
|
||||
#ifdef CONFIG_BINFMT_SHARED_FLAT
|
||||
#define MAX_SHARED_LIBS (4)
|
||||
#else
|
||||
#define MAX_SHARED_LIBS (1)
|
||||
#endif
|
||||
|
||||
struct lib_info {
|
||||
struct {
|
||||
unsigned long start_code; /* Start of text segment */
|
||||
|
@ -120,14 +131,15 @@ static int create_flat_tables(struct linux_binprm *bprm, unsigned long arg_start
|
|||
|
||||
sp -= bprm->envc + 1;
|
||||
sp -= bprm->argc + 1;
|
||||
sp -= flat_argvp_envp_on_stack() ? 2 : 0;
|
||||
if (IS_ENABLED(CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK))
|
||||
sp -= 2; /* argvp + envp */
|
||||
sp -= 1; /* &argc */
|
||||
|
||||
current->mm->start_stack = (unsigned long)sp & -FLAT_STACK_ALIGN;
|
||||
sp = (unsigned long __user *)current->mm->start_stack;
|
||||
|
||||
__put_user(bprm->argc, sp++);
|
||||
if (flat_argvp_envp_on_stack()) {
|
||||
if (IS_ENABLED(CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK)) {
|
||||
unsigned long argv, envp;
|
||||
argv = (unsigned long)(sp + 2);
|
||||
envp = (unsigned long)(sp + 2 + bprm->argc + 1);
|
||||
|
@ -345,7 +357,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp)
|
|||
start_code = p->lib_list[id].start_code;
|
||||
text_len = p->lib_list[id].text_len;
|
||||
|
||||
if (!flat_reloc_valid(r, start_brk - start_data + text_len)) {
|
||||
if (r > start_brk - start_data + text_len) {
|
||||
pr_err("reloc outside program 0x%lx (0 - 0x%lx/0x%lx)",
|
||||
r, start_brk-start_data+text_len, text_len);
|
||||
goto failed;
|
||||
|
@ -368,6 +380,7 @@ failed:
|
|||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BINFMT_FLAT_OLD
|
||||
static void old_reloc(unsigned long rl)
|
||||
{
|
||||
static const char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" };
|
||||
|
@ -405,6 +418,7 @@ static void old_reloc(unsigned long rl)
|
|||
|
||||
pr_debug("Relocation became %lx\n", val);
|
||||
}
|
||||
#endif /* CONFIG_BINFMT_FLAT_OLD */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
@ -415,7 +429,8 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
unsigned long textpos, datapos, realdatastart;
|
||||
u32 text_len, data_len, bss_len, stack_len, full_data, flags;
|
||||
unsigned long len, memp, memp_size, extra, rlim;
|
||||
u32 __user *reloc, *rp;
|
||||
__be32 __user *reloc;
|
||||
u32 __user *rp;
|
||||
struct inode *inode;
|
||||
int i, rev, relocs;
|
||||
loff_t fpos;
|
||||
|
@ -454,6 +469,7 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
if (flags & FLAT_FLAG_KTRACE)
|
||||
pr_info("Loading file: %s\n", bprm->filename);
|
||||
|
||||
#ifdef CONFIG_BINFMT_FLAT_OLD
|
||||
if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) {
|
||||
pr_err("bad flat file version 0x%x (supported 0x%lx and 0x%lx)\n",
|
||||
rev, FLAT_VERSION, OLD_FLAT_VERSION);
|
||||
|
@ -469,6 +485,23 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* fix up the flags for the older format, there were all kinds
|
||||
* of endian hacks, this only works for the simple cases
|
||||
*/
|
||||
if (rev == OLD_FLAT_VERSION &&
|
||||
(flags || IS_ENABLED(CONFIG_BINFMT_FLAT_OLD_ALWAYS_RAM)))
|
||||
flags = FLAT_FLAG_RAM;
|
||||
|
||||
#else /* CONFIG_BINFMT_FLAT_OLD */
|
||||
if (rev != FLAT_VERSION) {
|
||||
pr_err("bad flat file version 0x%x (supported 0x%lx)\n",
|
||||
rev, FLAT_VERSION);
|
||||
ret = -ENOEXEC;
|
||||
goto err;
|
||||
}
|
||||
#endif /* !CONFIG_BINFMT_FLAT_OLD */
|
||||
|
||||
/*
|
||||
* Make sure the header params are sane.
|
||||
* 28 bits (256 MB) is way more than reasonable in this case.
|
||||
|
@ -480,13 +513,6 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* fix up the flags for the older format, there were all kinds
|
||||
* of endian hacks, this only works for the simple cases
|
||||
*/
|
||||
if (rev == OLD_FLAT_VERSION && flat_old_ram_flag(flags))
|
||||
flags = FLAT_FLAG_RAM;
|
||||
|
||||
#ifndef CONFIG_BINFMT_ZFLAT
|
||||
if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {
|
||||
pr_err("Support for ZFLAT executables is not enabled.\n");
|
||||
|
@ -547,7 +573,7 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
goto err;
|
||||
}
|
||||
|
||||
len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
|
||||
len = data_len + extra;
|
||||
len = PAGE_ALIGN(len);
|
||||
realdatastart = vm_mmap(NULL, 0, len,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
|
||||
|
@ -561,9 +587,7 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
vm_munmap(textpos, text_len);
|
||||
goto err;
|
||||
}
|
||||
datapos = ALIGN(realdatastart +
|
||||
MAX_SHARED_LIBS * sizeof(unsigned long),
|
||||
FLAT_DATA_ALIGN);
|
||||
datapos = ALIGN(realdatastart, FLAT_DATA_ALIGN);
|
||||
|
||||
pr_debug("Allocated data+bss+stack (%u bytes): %lx\n",
|
||||
data_len + bss_len + stack_len, datapos);
|
||||
|
@ -587,13 +611,13 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
goto err;
|
||||
}
|
||||
|
||||
reloc = (u32 __user *)
|
||||
reloc = (__be32 __user *)
|
||||
(datapos + (ntohl(hdr->reloc_start) - text_len));
|
||||
memp = realdatastart;
|
||||
memp_size = len;
|
||||
} else {
|
||||
|
||||
len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(u32);
|
||||
len = text_len + data_len + extra;
|
||||
len = PAGE_ALIGN(len);
|
||||
textpos = vm_mmap(NULL, 0, len,
|
||||
PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
|
||||
|
@ -608,11 +632,9 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
}
|
||||
|
||||
realdatastart = textpos + ntohl(hdr->data_start);
|
||||
datapos = ALIGN(realdatastart +
|
||||
MAX_SHARED_LIBS * sizeof(u32),
|
||||
FLAT_DATA_ALIGN);
|
||||
datapos = ALIGN(realdatastart, FLAT_DATA_ALIGN);
|
||||
|
||||
reloc = (u32 __user *)
|
||||
reloc = (__be32 __user *)
|
||||
(datapos + (ntohl(hdr->reloc_start) - text_len));
|
||||
memp = textpos;
|
||||
memp_size = len;
|
||||
|
@ -627,8 +649,9 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
(text_len + full_data
|
||||
- sizeof(struct flat_hdr)),
|
||||
0);
|
||||
memmove((void *) datapos, (void *) realdatastart,
|
||||
full_data);
|
||||
if (datapos != realdatastart)
|
||||
memmove((void *)datapos, (void *)realdatastart,
|
||||
full_data);
|
||||
#else
|
||||
/*
|
||||
* This is used on MMU systems mainly for testing.
|
||||
|
@ -684,8 +707,7 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
if (IS_ERR_VALUE(result)) {
|
||||
ret = result;
|
||||
pr_err("Unable to read code+data+bss, errno %d\n", ret);
|
||||
vm_munmap(textpos, text_len + data_len + extra +
|
||||
MAX_SHARED_LIBS * sizeof(u32));
|
||||
vm_munmap(textpos, text_len + data_len + extra);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -775,20 +797,18 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
* __start to address 4 so that is okay).
|
||||
*/
|
||||
if (rev > OLD_FLAT_VERSION) {
|
||||
u32 __maybe_unused persistent = 0;
|
||||
for (i = 0; i < relocs; i++) {
|
||||
u32 addr, relval;
|
||||
__be32 tmp;
|
||||
|
||||
/*
|
||||
* Get the address of the pointer to be
|
||||
* relocated (of course, the address has to be
|
||||
* relocated first).
|
||||
*/
|
||||
if (get_user(relval, reloc + i))
|
||||
if (get_user(tmp, reloc + i))
|
||||
return -EFAULT;
|
||||
relval = ntohl(relval);
|
||||
if (flat_set_persistent(relval, &persistent))
|
||||
continue;
|
||||
relval = ntohl(tmp);
|
||||
addr = flat_get_relocate_addr(relval);
|
||||
rp = (u32 __user *)calc_reloc(addr, libinfo, id, 1);
|
||||
if (rp == (u32 __user *)RELOC_FAILED) {
|
||||
|
@ -797,8 +817,7 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
}
|
||||
|
||||
/* Get the pointer's value. */
|
||||
ret = flat_get_addr_from_rp(rp, relval, flags,
|
||||
&addr, &persistent);
|
||||
ret = flat_get_addr_from_rp(rp, relval, flags, &addr);
|
||||
if (unlikely(ret))
|
||||
goto err;
|
||||
|
||||
|
@ -807,8 +826,13 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
* Do the relocation. PIC relocs in the data section are
|
||||
* already in target order
|
||||
*/
|
||||
if ((flags & FLAT_FLAG_GOTPIC) == 0)
|
||||
addr = ntohl(addr);
|
||||
if ((flags & FLAT_FLAG_GOTPIC) == 0) {
|
||||
/*
|
||||
* Meh, the same value can have a different
|
||||
* byte order based on a flag..
|
||||
*/
|
||||
addr = ntohl((__force __be32)addr);
|
||||
}
|
||||
addr = calc_reloc(addr, libinfo, id, 0);
|
||||
if (addr == RELOC_FAILED) {
|
||||
ret = -ENOEXEC;
|
||||
|
@ -821,14 +845,15 @@ static int load_flat_file(struct linux_binprm *bprm,
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_BINFMT_FLAT_OLD
|
||||
} else {
|
||||
for (i = 0; i < relocs; i++) {
|
||||
u32 relval;
|
||||
__be32 relval;
|
||||
if (get_user(relval, reloc + i))
|
||||
return -EFAULT;
|
||||
relval = ntohl(relval);
|
||||
old_reloc(relval);
|
||||
old_reloc(ntohl(relval));
|
||||
}
|
||||
#endif /* CONFIG_BINFMT_FLAT_OLD */
|
||||
}
|
||||
|
||||
flush_icache_range(start_code, end_code);
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* arch/arm/include/asm/flat.h -- uClinux flat-format executables
|
||||
*/
|
||||
|
||||
#ifndef __ARM_FLAT_H__
|
||||
#define __ARM_FLAT_H__
|
||||
#ifndef _ASM_GENERIC_FLAT_H
|
||||
#define _ASM_GENERIC_FLAT_H
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define flat_argvp_envp_on_stack() 1
|
||||
#define flat_old_ram_flag(flags) (flags)
|
||||
#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
|
||||
|
||||
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
|
||||
u32 *addr, u32 *persistent)
|
||||
u32 *addr)
|
||||
{
|
||||
#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
return copy_from_user(addr, rp, 4) ? -EFAULT : 0;
|
||||
|
@ -31,7 +23,4 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
|
|||
#endif
|
||||
}
|
||||
|
||||
#define flat_get_relocate_addr(rel) (rel)
|
||||
#define flat_set_persistent(relval, p) 0
|
||||
|
||||
#endif /* __ARM_FLAT_H__ */
|
||||
#endif /* _ASM_GENERIC_FLAT_H */
|
|
@ -10,8 +10,41 @@
|
|||
#ifndef _LINUX_FLAT_H
|
||||
#define _LINUX_FLAT_H
|
||||
|
||||
#include <uapi/linux/flat.h>
|
||||
#include <asm/flat.h>
|
||||
#define FLAT_VERSION 0x00000004L
|
||||
|
||||
/*
|
||||
* To make everything easier to port and manage cross platform
|
||||
* development, all fields are in network byte order.
|
||||
*/
|
||||
|
||||
struct flat_hdr {
|
||||
char magic[4];
|
||||
__be32 rev; /* version (as above) */
|
||||
__be32 entry; /* Offset of first executable instruction
|
||||
with text segment from beginning of file */
|
||||
__be32 data_start; /* Offset of data segment from beginning of
|
||||
file */
|
||||
__be32 data_end; /* Offset of end of data segment from beginning
|
||||
of file */
|
||||
__be32 bss_end; /* Offset of end of bss segment from beginning
|
||||
of file */
|
||||
|
||||
/* (It is assumed that data_end through bss_end forms the bss segment.) */
|
||||
|
||||
__be32 stack_size; /* Size of stack, in bytes */
|
||||
__be32 reloc_start; /* Offset of relocation records from beginning of
|
||||
file */
|
||||
__be32 reloc_count; /* Number of relocation records */
|
||||
__be32 flags;
|
||||
__be32 build_date; /* When the program/library was built */
|
||||
__u32 filler[5]; /* Reservered, set to zero */
|
||||
};
|
||||
|
||||
#define FLAT_FLAG_RAM 0x0001 /* load program entirely into RAM */
|
||||
#define FLAT_FLAG_GOTPIC 0x0002 /* program is PIC with GOT */
|
||||
#define FLAT_FLAG_GZIP 0x0004 /* all but the header is compressed */
|
||||
#define FLAT_FLAG_GZDATA 0x0008 /* only data/relocs are compressed (for XIP) */
|
||||
#define FLAT_FLAG_KTRACE 0x0010 /* output useful kernel trace for debugging */
|
||||
|
||||
/*
|
||||
* While it would be nice to keep this header clean, users of older
|
||||
|
@ -22,28 +55,21 @@
|
|||
* with the format above, except to fix bugs with old format support.
|
||||
*/
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#define OLD_FLAT_VERSION 0x00000002L
|
||||
#define OLD_FLAT_RELOC_TYPE_TEXT 0
|
||||
#define OLD_FLAT_RELOC_TYPE_DATA 1
|
||||
#define OLD_FLAT_RELOC_TYPE_BSS 2
|
||||
|
||||
typedef union {
|
||||
unsigned long value;
|
||||
u32 value;
|
||||
struct {
|
||||
# if defined(mc68000) && !defined(CONFIG_COLDFIRE)
|
||||
signed long offset : 30;
|
||||
unsigned long type : 2;
|
||||
# define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD) || \
|
||||
(defined(mc68000) && !defined(CONFIG_COLDFIRE))
|
||||
s32 offset : 30;
|
||||
u32 type : 2;
|
||||
# elif defined(__BIG_ENDIAN_BITFIELD)
|
||||
unsigned long type : 2;
|
||||
signed long offset : 30;
|
||||
# define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
|
||||
# elif defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
signed long offset : 30;
|
||||
unsigned long type : 2;
|
||||
# define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
|
||||
u32 type : 2;
|
||||
s32 offset : 30;
|
||||
# else
|
||||
# error "Unknown bitfield order for flat files."
|
||||
# endif
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (C) 2002-2003 David McCullough <davidm@snapgear.com>
|
||||
* Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
|
||||
* The Silver Hammer Group, Ltd.
|
||||
*
|
||||
* This file provides the definitions and structures needed to
|
||||
* support uClinux flat-format executables.
|
||||
*/
|
||||
|
||||
#ifndef _UAPI_LINUX_FLAT_H
|
||||
#define _UAPI_LINUX_FLAT_H
|
||||
|
||||
|
||||
#define FLAT_VERSION 0x00000004L
|
||||
|
||||
#ifdef CONFIG_BINFMT_SHARED_FLAT
|
||||
#define MAX_SHARED_LIBS (4)
|
||||
#else
|
||||
#define MAX_SHARED_LIBS (1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* To make everything easier to port and manage cross platform
|
||||
* development, all fields are in network byte order.
|
||||
*/
|
||||
|
||||
struct flat_hdr {
|
||||
char magic[4];
|
||||
unsigned long rev; /* version (as above) */
|
||||
unsigned long entry; /* Offset of first executable instruction
|
||||
with text segment from beginning of file */
|
||||
unsigned long data_start; /* Offset of data segment from beginning of
|
||||
file */
|
||||
unsigned long data_end; /* Offset of end of data segment
|
||||
from beginning of file */
|
||||
unsigned long bss_end; /* Offset of end of bss segment from beginning
|
||||
of file */
|
||||
|
||||
/* (It is assumed that data_end through bss_end forms the bss segment.) */
|
||||
|
||||
unsigned long stack_size; /* Size of stack, in bytes */
|
||||
unsigned long reloc_start; /* Offset of relocation records from
|
||||
beginning of file */
|
||||
unsigned long reloc_count; /* Number of relocation records */
|
||||
unsigned long flags;
|
||||
unsigned long build_date; /* When the program/library was built */
|
||||
unsigned long filler[5]; /* Reservered, set to zero */
|
||||
};
|
||||
|
||||
#define FLAT_FLAG_RAM 0x0001 /* load program entirely into RAM */
|
||||
#define FLAT_FLAG_GOTPIC 0x0002 /* program is PIC with GOT */
|
||||
#define FLAT_FLAG_GZIP 0x0004 /* all but the header is compressed */
|
||||
#define FLAT_FLAG_GZDATA 0x0008 /* only data/relocs are compressed (for XIP) */
|
||||
#define FLAT_FLAG_KTRACE 0x0010 /* output useful kernel trace for debugging */
|
||||
|
||||
|
||||
|
||||
#endif /* _UAPI_LINUX_FLAT_H */
|
Loading…
Reference in New Issue