Commit 91808d6e authored by David Howells's avatar David Howells Committed by Linus Torvalds

[PATCH] FRV: Add FDPIC ELF binary format driver

The attached patch adds a new binary format driver that allows a special
variety of ELF to be used that permits the dynamic sections that comprise an
executable, its dynamic loader and its shared libaries and its stack and data
to be located anywhere within the address space.

This is used to provide shared libraries and shared executables (at least, as
far as the read-only dynamic sections go) on uClinux. Not only that, but the
same binaries can be run on MMU linux without a problem.

This is achieved by:

 (1) Passing loadmaps to the dynamic loader (or to a statically linked
     executable) to indicate the whereabouts of the various dynamic sections.

 (2) Using a GOT inside the program.

 (3) Passing setup_arg_pages() the stack pointer to be.

 (4) Allowing the arch greated control over how an executable is laid out in
     memory in MMU Linux.

 (5) Rewriting mm/nommu.c to support MAP_PRIVATE on files, thus allowing _mmap_
     to handle sharing of private-readonly mappings.
Signed-Off-By: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 481a21d6
......@@ -23,6 +23,19 @@ config BINFMT_ELF
ld.so (check the file <file:Documentation/Changes> for location and
latest version).
config BINFMT_ELF_FDPIC
bool "Kernel support for FDPIC ELF binaries"
default y
depends on FRV
help
ELF FDPIC binaries are based on ELF, but allow the individual load
segments of a binary to be located in memory independently of each
other. This makes this format ideal for use in environments where no
MMU is available as it still permits text segments to be shared,
even if data segments are not.
It is also possible to run FDPIC ELF binaries on MMU linux also.
config BINFMT_FLAT
tristate "Kernel support for flat binaries"
depends on !MMU || SUPERH
......
......@@ -25,6 +25,7 @@ obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o
obj-y += binfmt_script.o
obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
......
This diff is collapsed.
/* elf-fdpic.h: FDPIC ELF load map
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _LINUX_ELF_FDPIC_H
#define _LINUX_ELF_FDPIC_H
#include <linux/elf.h>
#define PT_GNU_STACK (PT_LOOS + 0x474e551)
/* segment mappings for ELF FDPIC libraries/executables/interpreters */
struct elf32_fdpic_loadseg {
Elf32_Addr addr; /* core address to which mapped */
Elf32_Addr p_vaddr; /* VMA recorded in file */
Elf32_Word p_memsz; /* allocation size recorded in file */
};
struct elf32_fdpic_loadmap {
Elf32_Half version; /* version of these structures, just in case... */
Elf32_Half nsegs; /* number of segments */
struct elf32_fdpic_loadseg segs[];
};
#define ELF32_FDPIC_LOADMAP_VERSION 0x0000
/*
* binfmt binary parameters structure
*/
struct elf_fdpic_params {
struct elfhdr hdr; /* ref copy of ELF header */
struct elf_phdr *phdrs; /* ref copy of PT_PHDR table */
struct elf32_fdpic_loadmap *loadmap; /* loadmap to be passed to userspace */
unsigned long elfhdr_addr; /* mapped ELF header user address */
unsigned long ph_addr; /* mapped PT_PHDR user address */
unsigned long map_addr; /* mapped loadmap user address */
unsigned long entry_addr; /* mapped entry user address */
unsigned long stack_size; /* stack size requested (PT_GNU_STACK) */
unsigned long dynamic_addr; /* mapped PT_DYNAMIC user address */
unsigned long load_addr; /* user address at which to map binary */
unsigned long flags;
#define ELF_FDPIC_FLAG_ARRANGEMENT 0x0000000f /* PT_LOAD arrangement flags */
#define ELF_FDPIC_FLAG_INDEPENDENT 0x00000000 /* PT_LOADs can be put anywhere */
#define ELF_FDPIC_FLAG_HONOURVADDR 0x00000001 /* PT_LOAD.vaddr must be honoured */
#define ELF_FDPIC_FLAG_CONSTDISP 0x00000002 /* PT_LOADs require constant
* displacement */
#define ELF_FDPIC_FLAG_CONTIGUOUS 0x00000003 /* PT_LOADs should be contiguous */
#define ELF_FDPIC_FLAG_EXEC_STACK 0x00000010 /* T if stack to be executable */
#define ELF_FDPIC_FLAG_NOEXEC_STACK 0x00000020 /* T if stack not to be executable */
#define ELF_FDPIC_FLAG_EXECUTABLE 0x00000040 /* T if this object is the executable */
#define ELF_FDPIC_FLAG_PRESENT 0x80000000 /* T if this object is present */
};
#ifdef CONFIG_MMU
extern void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params,
struct elf_fdpic_params *interp_params,
unsigned long *start_stack,
unsigned long *start_brk);
#endif
#endif /* _LINUX_ELF_FDPIC_H */
......@@ -18,6 +18,9 @@ extern int __set_personality(unsigned long);
* These occupy the top three bytes.
*/
enum {
FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs point to descriptors
* (signal handling)
*/
MMAP_PAGE_ZERO = 0x0100000,
ADDR_COMPAT_LAYOUT = 0x0200000,
READ_IMPLIES_EXEC = 0x0400000,
......@@ -43,6 +46,7 @@ enum {
enum {
PER_LINUX = 0x0000,
PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS,
PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment