summaryrefslogtreecommitdiff
path: root/exec/exec.c
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2013-08-15 18:41:54 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2013-08-29 00:09:48 +0200
commit1fed12bc2963e5d4f9b29faa35d5c1f515ca6bf9 (patch)
tree270641380d609165e02d97a60f09ecdca58a87f4 /exec/exec.c
parent48da1229d36a9ca6c044e34bbdde77067d8036a1 (diff)
exec: remove the BFD code
This commit removes the parts of the exec server that were once using the Binary File Descriptor library. As I understand it, the BFD code stopped working because it uses stdio streams and the glue code for that has never been ported to libio. The code has been #ifdefed out ever since. It may or may not work in its current state, so it is removed. If someone is interested, it can always be recovered from the version control system. * exec/exec.c: Remove all BFD related code. * exec/priv.h: Likewise. * TODO: Remove the corresponding item.
Diffstat (limited to 'exec/exec.c')
-rw-r--r--exec/exec.c567
1 files changed, 55 insertions, 512 deletions
diff --git a/exec/exec.c b/exec/exec.c
index 3971478b..f139792b 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -7,10 +7,6 @@
#ifdef GZIP
Can gunzip executables into core on the fly.
#endif
- #ifdef BFD
- Can exec any executable format the BFD library understands
- to be for this flavor of machine.
- #endif
#ifdef BZIP2
Can bunzip2 executables into core on the fly.
#endif
@@ -50,26 +46,7 @@ size_t std_nports, std_nints;
pthread_rwlock_t std_lock = PTHREAD_RWLOCK_INITIALIZER;
-#ifdef BFD
-/* Return a Hurd error code corresponding to the most recent BFD error. */
-static error_t
-b2he (error_t deflt)
-{
- switch (bfd_get_error ())
- {
- case bfd_error_system_call:
- return errno;
-
- case bfd_error_no_memory:
- return ENOMEM;
-
- default:
- return deflt;
- }
-}
-#else
#define b2he() a2he (errno)
-#endif
#ifdef GZIP
static void check_gzip (struct execdata *);
@@ -79,41 +56,6 @@ static void check_gzip (struct execdata *);
static void check_bzip2 (struct execdata *);
#endif
-#ifdef BFD
-
-/* Check a section, updating the `locations' vector [BFD]. */
-static void
-check_section (bfd *bfd, asection *sec, void *userdata)
-{
- struct execdata *u = userdata;
- static const union
- {
- char string[8];
- unsigned int quadword __attribute__ ((mode (DI)));
- } interp = { string: ".interp" };
-
- if (u->error)
- return;
-
- /* Fast strcmp for this 8-byte constant string. */
- if (*(const __typeof (interp.quadword) *) sec->name == interp.quadword)
- u->interp.section = sec;
-
- if (!(sec->flags & (SEC_ALLOC|SEC_LOAD)) ||
- (sec->flags & SEC_NEVER_LOAD))
- /* Nothing to do for this section. */
- return;
-
- if (sec->flags & SEC_LOAD)
- {
- u->info.bfd_locations[sec->index] = sec->filepos;
- if ((off_t) sec->filepos < 0 || (off_t) sec->filepos > u->file_size)
- u->error = ENOEXEC;
- }
-}
-#endif
-
-
/* Zero the specified region but don't crash the server if it faults. */
#include <hurd/sigpreempt.h>
@@ -135,69 +77,45 @@ load_section (void *section, struct execdata *u)
vm_prot_t vm_prot;
int anywhere;
vm_address_t mask = 0;
-#ifdef BFD
- asection *const sec = section;
-#endif
const ElfW(Phdr) *const ph = section;
if (u->error)
return;
-#ifdef BFD
- if (u->bfd && sec->flags & SEC_NEVER_LOAD)
- /* Nothing to do for this section. */
- return;
-#endif
-
vm_prot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
-#ifdef BFD
- if (u->bfd)
- {
- addr = (vm_address_t) sec->vma;
- filepos = u->info.bfd_locations[sec->index];
- memsz = sec->_raw_size;
- filesz = (sec->flags & SEC_LOAD) ? memsz : 0;
- if (sec->flags & (SEC_READONLY|SEC_ROM))
- vm_prot &= ~VM_PROT_WRITE;
- anywhere = 0;
- }
+ addr = ph->p_vaddr & ~(ph->p_align - 1);
+ memsz = ph->p_vaddr + ph->p_memsz - addr;
+ filepos = ph->p_offset & ~(ph->p_align - 1);
+ filesz = ph->p_offset + ph->p_filesz - filepos;
+ if ((ph->p_flags & PF_R) == 0)
+ vm_prot &= ~VM_PROT_READ;
+ if ((ph->p_flags & PF_W) == 0)
+ vm_prot &= ~VM_PROT_WRITE;
+ if ((ph->p_flags & PF_X) == 0)
+ vm_prot &= ~VM_PROT_EXECUTE;
+ anywhere = u->info.elf.anywhere;
+ if (! anywhere)
+ addr += u->info.elf.loadbase;
else
-#endif
- {
- addr = ph->p_vaddr & ~(ph->p_align - 1);
- memsz = ph->p_vaddr + ph->p_memsz - addr;
- filepos = ph->p_offset & ~(ph->p_align - 1);
- filesz = ph->p_offset + ph->p_filesz - filepos;
- if ((ph->p_flags & PF_R) == 0)
- vm_prot &= ~VM_PROT_READ;
- if ((ph->p_flags & PF_W) == 0)
- vm_prot &= ~VM_PROT_WRITE;
- if ((ph->p_flags & PF_X) == 0)
- vm_prot &= ~VM_PROT_EXECUTE;
- anywhere = u->info.elf.anywhere;
- if (! anywhere)
- addr += u->info.elf.loadbase;
- else
#if 0
- switch (elf_machine)
- {
- case EM_386:
- case EM_486:
- /* On the i386, programs normally load at 0x08000000, and
- expect their data segment to be able to grow dynamically
- upward from its start near that address. We need to make
- sure that the dynamic linker is not mapped in a conflicting
- address. */
- /* mask = 0xf8000000UL; */ /* XXX */
- break;
- default:
- break;
- }
+ switch (elf_machine)
+ {
+ case EM_386:
+ case EM_486:
+ /* On the i386, programs normally load at 0x08000000, and
+ expect their data segment to be able to grow dynamically
+ upward from its start near that address. We need to make
+ sure that the dynamic linker is not mapped in a conflicting
+ address. */
+ /* mask = 0xf8000000UL; */ /* XXX */
+ break;
+ default:
+ break;
+ }
#endif
- if (anywhere && addr < vm_page_size)
- addr = vm_page_size;
- }
+ if (anywhere && addr < vm_page_size)
+ addr = vm_page_size;
if (memsz == 0)
/* This section is empty; ignore it. */
@@ -502,16 +420,6 @@ map (struct execdata *e, off_t posn, size_t len)
return map_buffer (e) + offset;
}
-
-/* Initialize E's stdio stream. */
-static void prepare_stream (struct execdata *e);
-
-/* Point the stream at the buffer of file data in E->file_data. */
-static void prepare_in_memory (struct execdata *e);
-
-
-#ifndef EXECDATA_STREAM
-
/* We don't have a stdio stream, but we have a mapping window
we need to initialize. */
static void
@@ -521,199 +429,7 @@ prepare_stream (struct execdata *e)
e->map_vsize = e->map_fsize = 0;
e->map_filepos = 0;
}
-
-static void prepare_in_memory (struct execdata *e)
-{
- prepare_stream(e);
-}
-
-#else
-
-#ifdef _STDIO_USES_IOSTREAM
-
-# error implement me for libio!
-
-#else /* old GNU stdio */
-
-#if 0
-void *
-map (struct execdata *e, off_t posn, size_t len)
-{
- FILE *f = &e->stream;
- const size_t size = e->file_size;
- size_t offset;
-
- if ((f->__offset & ~(f->__bufsize - 1)) == (posn & ~(f->__bufsize - 1)) &&
- f->__buffer + (posn + len - f->__offset) < f->__get_limit)
- /* The current mapping window covers it. */
- offset = posn & (f->__bufsize - 1);
- else if (e->file_data != NULL)
- {
- /* The current "mapping window" is in fact the whole file contents.
- So if it's not in there, it's not in there. */
- f->__eof = 1;
- return NULL;
- }
- else if (e->filemap == MACH_PORT_NULL)
- {
- /* No mapping for the file. Read the data by RPC. */
- char *buffer = f->__buffer;
- mach_msg_type_number_t nread = f->__bufsize;
- /* Read as much as we can get into the buffer right now. */
- e->error = io_read (e->file, &buffer, &nread, posn, round_page (len));
- if (e->error)
- {
- errno = e->error;
- f->__error = 1;
- return NULL;
- }
- if (buffer != f->__buffer)
- {
- /* The data was returned out of line. Discard the old buffer. */
- if (f->__bufsize != 0)
- munmap (f->__buffer, f->__bufsize);
- f->__buffer = buffer;
- f->__bufsize = round_page (nread);
- }
-
- f->__offset = posn;
- f->__get_limit = f->__buffer + nread;
- offset = 0;
- }
- else
- {
- /* Deallocate the old mapping area. */
- if (f->__buffer != NULL)
- munmap (f->__buffer, f->__bufsize);
- f->__buffer = NULL;
-
- /* Make sure our mapping is page-aligned in the file. */
- offset = posn & (vm_page_size - 1);
- f->__offset = trunc_page (posn);
- f->__bufsize = round_page (posn + len) - f->__offset;
-
- /* Map the data from the file. */
- if (vm_map (mach_task_self (),
- (vm_address_t *) &f->__buffer, f->__bufsize, 0, 1,
- e->filemap, f->__offset, 1, VM_PROT_READ, VM_PROT_READ,
- VM_INHERIT_NONE))
- {
- errno = e->error = EIO;
- f->__error = 1;
- return NULL;
- }
-
- if (e->cntl)
- e->cntl->accessed = 1;
-
- if (f->__offset + f->__bufsize > size)
- f->__get_limit = f->__buffer + (size - f->__offset);
- else
- f->__get_limit = f->__buffer + f->__bufsize;
- }
-
- f->__target = f->__offset;
- f->__bufp = f->__buffer + offset;
-
- if (f->__bufp + len > f->__get_limit)
- {
- f->__eof = 1;
- return NULL;
- }
-
- return f->__bufp;
-}
-#endif
-
-/* stdio input-room function.
- XXX/fault in the stdio case (or libio replacement), i.e. for bfd
- (if ever revived), need to check all the mapping fault issues */
-static int
-input_room (FILE *f)
-{
- struct execdata *e = f->__cookie;
- char *p = map (e, f->__target, 1);
- if (p == NULL)
- {
- (e->error ? f->__error : f->__eof) = 1;
- return EOF;
- }
-
- f->__target = f->__offset;
- f->__bufp = p;
-
- return (unsigned char) *f->__bufp++;
-}
-
-static int
-close_exec_stream (void *cookie)
-{
- struct execdata *e = cookie;
-
- if (e->stream.__buffer != NULL)
- munmap (e->stream.__buffer, e->stream.__bufsize);
-
- return 0;
-}
-
-/* stdio seek function. */
-static int
-fake_seek (void *cookie, fpos_t *pos, int whence)
-{
- struct execdata *e = cookie;
-
- /* Set __target to match the specifed seek location */
- switch (whence)
- {
- case SEEK_END:
- e->stream.__target = e->file_size + *pos;
- break;
-
- case SEEK_CUR:
- e->stream.__target += *pos;
- break;
-
- case SEEK_SET:
- e->stream.__target = *pos;
- break;
- }
- *pos = e->stream.__target;
- return 0;
-}
-
-/* Initialize E's stdio stream. */
-static void
-prepare_stream (struct execdata *e)
-{
- memset (&e->stream, 0, sizeof (e->stream));
- e->stream.__magic = _IOMAGIC;
- e->stream.__mode.__read = 1;
- e->stream.__userbuf = 1;
- e->stream.__room_funcs.__input = input_room;
- e->stream.__io_funcs.seek = fake_seek;
- e->stream.__io_funcs.close = close_exec_stream;
- e->stream.__cookie = e;
- e->stream.__seen = 1;
-}
-
-/* Point the stream at the buffer of file data. */
-static void
-prepare_in_memory (struct execdata *e)
-{
- memset (&e->stream, 0, sizeof (e->stream));
- e->stream.__magic = _IOMAGIC;
- e->stream.__mode.__read = 1;
- e->stream.__buffer = e->file_data;
- e->stream.__bufsize = e->file_size;
- e->stream.__get_limit = e->stream.__buffer + e->stream.__bufsize;
- e->stream.__bufp = e->stream.__buffer;
- e->stream.__seen = 1;
-}
-#endif
-
-#endif
-
/* Prepare to check and load FILE. */
static void
prepare (file_t file, struct execdata *e)
@@ -722,9 +438,6 @@ prepare (file_t file, struct execdata *e)
e->file = file;
-#ifdef BFD
- e->bfd = NULL;
-#endif
e->file_data = NULL;
e->cntl = NULL;
e->filemap = MACH_PORT_NULL;
@@ -801,42 +514,6 @@ prepare (file_t file, struct execdata *e)
}
}
-/* Check the magic number, etc. of the file.
- On successful return, the caller must allocate the
- E->locations vector, and map check_section over the BFD. */
-
-#ifdef BFD
-static void
-check_bfd (struct execdata *e)
-{
- bfd_set_error (bfd_error_no_error);
-
- e->bfd = bfd_openstreamr (NULL, NULL, &e->stream);
- if (e->bfd == NULL)
- {
- e->error = b2he (ENOEXEC);
- return;
- }
-
- if (!bfd_check_format (e->bfd, bfd_object))
- {
- e->error = b2he (ENOEXEC);
- return;
- }
- else if (/* !(e->bfd->flags & EXEC_P) || XXX */
- (host_bfd.arch_info->compatible = e->bfd->arch_info->compatible,
- bfd_arch_get_compatible (&host_bfd, e->bfd)) != host_bfd.arch_info)
- {
- /* This file is of a recognized binary file format, but it is not
- executable on this machine. */
- e->error = b2he (ENOEXEC);
- return;
- }
-
- e->entry = e->bfd->start_address;
-}
-#endif
-
#include <endian.h>
#if BYTE_ORDER == BIG_ENDIAN
#define host_ELFDATA ELFDATA2MSB
@@ -955,13 +632,6 @@ static void
check (struct execdata *e)
{
check_elf (e); /* XXX/fault */
-#ifdef BFD
- if (e->error == ENOEXEC)
- {
- e->error = 0;
- check_bfd (e);
- }
-#endif
}
@@ -1004,18 +674,7 @@ void
finish (struct execdata *e, int dealloc_file)
{
finish_mapping (e);
-#ifdef BFD
- if (e->bfd != NULL)
- {
- bfd_close (e->bfd);
- e->bfd = NULL;
- }
- else
-#endif
{
-#ifdef EXECDATA_STREAM
- fclose (&e->stream);
-#else
if (e->file_data != NULL) {
free (e->file_data);
e->file_data = NULL;
@@ -1023,7 +682,6 @@ finish (struct execdata *e, int dealloc_file)
munmap (map_buffer (e), map_vsize (e));
map_buffer (e) = NULL;
}
-#endif
}
if (dealloc_file && e->file != MACH_PORT_NULL)
{
@@ -1041,81 +699,18 @@ load (task_t usertask, struct execdata *e)
if (! e->error)
{
-#ifdef BFD
- if (e->bfd)
- {
- void load_bfd_section (bfd *bfd, asection *sec, void *userdata)
- {
- load_section (sec, userdata);
- }
- bfd_map_over_sections (e->bfd, &load_bfd_section, e);
- }
- else
-#endif
- {
- ElfW(Word) i;
- for (i = 0; i < e->info.elf.phnum; ++i)
- if (e->info.elf.phdr[i].p_type == PT_LOAD)
- load_section (&e->info.elf.phdr[i], e);
-
- /* The entry point address is relative to wherever we loaded the
- program text. */
- e->entry += e->info.elf.loadbase;
- }
+ ElfW(Word) i;
+ for (i = 0; i < e->info.elf.phnum; ++i)
+ if (e->info.elf.phdr[i].p_type == PT_LOAD)
+ load_section (&e->info.elf.phdr[i], e);
+
+ /* The entry point address is relative to wherever we loaded the
+ program text. */
+ e->entry += e->info.elf.loadbase;
}
/* Release the conch for the file. */
finish_mapping (e);
-
- if (! e->error)
- {
- /* Do post-loading processing on the task. */
-
-#ifdef BFD
- if (e->bfd)
- {
- /* Do post-loading processing for a section. This consists of
- peeking the pages of non-demand-paged executables. */
-
- void postload_section (bfd *bfd, asection *sec, void *userdata)
- {
- struct execdata *u = userdata;
- vm_address_t addr = 0;
- vm_size_t secsize = 0;
-
- addr = (vm_address_t) sec->vma;
- secsize = sec->_raw_size;
-
- if ((sec->flags & SEC_LOAD) && !(bfd->flags & D_PAGED))
- {
- /* Pre-load the section by peeking every mapped page. */
- vm_address_t myaddr, a;
- vm_size_t mysize;
- myaddr = 0;
-
- /* We have already mapped the file into the task in
- load_section. Now read from the task's memory into our
- own address space so we can peek each page and cause it to
- be paged in. */
- u->error = vm_read (u->task, trunc_page (addr),
- round_page (secsize), &myaddr, &mysize);
- if (u->error)
- return;
-
- /* Peek at the first word of each page. */
- for (a = ((myaddr + mysize) & ~(vm_page_size - 1));
- a >= myaddr; a -= vm_page_size)
- /* Force it to be paged in. */
- (void) *(volatile int *) a;
-
- munmap ((caddr_t) myaddr, mysize);
- }
- }
-
- bfd_map_over_sections (e->bfd, postload_section, e);
- }
-#endif
- }
}
#ifdef GZIP
@@ -1466,20 +1061,9 @@ do_exec (file_t file,
/* The file is not a valid executable. */
goto out;
-#ifdef BFD
- if (e.bfd)
- {
- e.info.bfd_locations = alloca (e.bfd->section_count *
- sizeof (vm_offset_t));
- bfd_map_over_sections (e.bfd, check_section, &e);
- }
- else
-#endif
- {
- const ElfW(Phdr) *phdr = e.info.elf.phdr;
- e.info.elf.phdr = alloca (e.info.elf.phnum * sizeof (ElfW(Phdr)));
- check_elf_phdr (&e, phdr);
- }
+ const ElfW(Phdr) *phdr = e.info.elf.phdr;
+ e.info.elf.phdr = alloca (e.info.elf.phnum * sizeof (ElfW(Phdr)));
+ check_elf_phdr (&e, phdr);
if (oldtask == MACH_PORT_NULL)
flags |= EXEC_NEWTASK;
@@ -1685,33 +1269,11 @@ do_exec (file_t file,
along with this executable. Find the name of the file and open
it. */
-#ifdef BFD
- char namebuf[e.bfd ? e.interp.section->_raw_size : 0];
-#endif
- char *name;
-
-#ifdef BFD
- if (e.bfd)
- {
- if (! bfd_get_section_contents (e.bfd, e.interp.section,
- namebuf, 0,
- e.interp.section->_raw_size))
- {
- e.error = b2he (errno);
- name = NULL;
- }
- else
- name = namebuf;
- }
- else
-#endif
- {
- name = map (&e, (e.interp.phdr->p_offset
- & ~(e.interp.phdr->p_align - 1)),
- e.interp.phdr->p_filesz);
- if (! name && ! e.error)
- e.error = ENOEXEC;
- }
+ char *name = map (&e, (e.interp.phdr->p_offset
+ & ~(e.interp.phdr->p_align - 1)),
+ e.interp.phdr->p_filesz);
+ if (! name && ! e.error)
+ e.error = ENOEXEC;
if (! name)
e.interp.section = NULL;
@@ -1749,21 +1311,10 @@ do_exec (file_t file,
prepare_and_check (interp.file, &interp);
if (! interp.error)
{
-#ifdef BFD
- if (interp.bfd)
- {
- interp.info.bfd_locations = alloca (interp.bfd->section_count *
- sizeof (vm_offset_t));
- bfd_map_over_sections (interp.bfd, check_section, &e);
- }
- else
-#endif
- {
- const ElfW(Phdr) *phdr = interp.info.elf.phdr;
- interp.info.elf.phdr = alloca (interp.info.elf.phnum *
- sizeof (ElfW(Phdr)));
- check_elf_phdr (&interp, phdr);
- }
+ const ElfW(Phdr) *phdr = interp.info.elf.phdr;
+ interp.info.elf.phdr = alloca (interp.info.elf.phnum *
+ sizeof (ElfW(Phdr)));
+ check_elf_phdr (&interp, phdr);
}
e.error = interp.error;
}
@@ -1842,10 +1393,7 @@ do_exec (file_t file,
the image so that a load-anywhere image gets the adjusted addresses. */
if (e.info.elf.phdr_addr != 0)
{
-#ifdef BFD
- if (!e.bfd)
-#endif
- e.info.elf.phdr_addr += e.info.elf.loadbase;
+ e.info.elf.phdr_addr += e.info.elf.loadbase;
boot->phdr_addr = e.info.elf.phdr_addr;
boot->phdr_size = e.info.elf.phnum * sizeof (ElfW(Phdr));
}
@@ -1864,17 +1412,12 @@ do_exec (file_t file,
&boot->stack_base, &boot->stack_size);
if (e.error)
goto out;
-#ifdef BFD
- if (!e.bfd)
-#endif
- {
- /* It would probably be better to change mach_setup_thread so
- it does a vm_map with the right permissions to start with. */
- if (!e.info.elf.execstack)
- e.error = vm_protect (newtask, boot->stack_base, boot->stack_size,
- 0, VM_PROT_READ | VM_PROT_WRITE);
- }
+ /* It would probably be better to change mach_setup_thread so
+ it does a vm_map with the right permissions to start with. */
+ if (!e.info.elf.execstack)
+ e.error = vm_protect (newtask, boot->stack_base, boot->stack_size,
+ 0, VM_PROT_READ | VM_PROT_WRITE);
if (oldtask != newtask && oldtask != MACH_PORT_NULL)
{