aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/imgact_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/imgact_elf.c')
-rw-r--r--sys/kern/imgact_elf.c35
1 files changed, 14 insertions, 21 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index fa6ddaf286e0..236894f4b2de 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -75,11 +75,6 @@ __FBSDID("$FreeBSD$");
#include <machine/elf.h>
#include <machine/md_var.h>
-#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
-#include <machine/fpu.h>
-#include <compat/ia32/ia32_reg.h>
-#endif
-
#define OLD_EI_BRAND 8
static int __elfN(check_header)(const Elf_Ehdr *hdr);
@@ -837,13 +832,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
phdr[i].p_vaddr + et_dyn_addr - seg_addr);
/*
- * Is this .text or .data? We can't use
- * VM_PROT_WRITE or VM_PROT_EXEC, it breaks the
- * alpha terribly and possibly does other bad
- * things so we stick to the old way of figuring
- * it out: If the segment contains the program
- * entry point, it's a text segment, otherwise it
- * is a data segment.
+ * Make the largest executable segment the official
+ * text segment and all others data.
*
* Note that obreak() assumes that data_addr +
* data_size == end of data load area, and the ELF
@@ -851,12 +841,10 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
* address. If multiple data segments exist, the
* last one will be used.
*/
- if (hdr->e_entry >= phdr[i].p_vaddr &&
- hdr->e_entry < (phdr[i].p_vaddr +
- phdr[i].p_memsz)) {
+
+ if (phdr[i].p_flags & PF_X && text_size < seg_size) {
text_size = seg_size;
text_addr = seg_addr;
- entry = (u_long)hdr->e_entry + et_dyn_addr;
} else {
data_size = seg_size;
data_addr = seg_addr;
@@ -876,6 +864,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
data_size = text_size;
}
+ entry = (u_long)hdr->e_entry + et_dyn_addr;
+
/*
* Check limits. It should be safe to check the
* limits after loading the segments since we do
@@ -953,6 +943,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
imgp->auxargs = elf_auxargs;
imgp->interpreted = 0;
+ imgp->reloc_base = addr;
imgp->proc->p_osrel = osrel;
return (error);
@@ -1136,11 +1127,11 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
#ifdef COMPRESS_USER_CORES
done:
-#endif
if (core_buf)
free(core_buf, M_TEMP);
if (gzfile)
gzclose(gzfile);
+#endif
free(hdr, M_TEMP);
@@ -1303,7 +1294,9 @@ __elfN(corehdr)(td, vp, cred, numsegs, hdr, hdrsize, gzfile)
}
}
-#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
+#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
+#include <compat/freebsd32/freebsd32.h>
+
typedef struct prstatus32 elf_prstatus_t;
typedef struct prpsinfo32 elf_prpsinfo_t;
typedef struct fpreg32 elf_prfpregset_t;
@@ -1387,7 +1380,7 @@ __elfN(puthdr)(struct thread *td, void *dst, size_t *off, int numsegs)
status->pr_osreldate = osreldate;
status->pr_cursig = p->p_sig;
status->pr_pid = thr->td_tid;
-#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
+#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
fill_regs32(thr, &status->pr_reg);
fill_fpregs32(thr, fpregset);
#else
@@ -1439,8 +1432,8 @@ __elfN(puthdr)(struct thread *td, void *dst, size_t *off, int numsegs)
ehdr->e_ident[EI_ABIVERSION] = 0;
ehdr->e_ident[EI_PAD] = 0;
ehdr->e_type = ET_CORE;
-#if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32
- ehdr->e_machine = EM_386;
+#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
+ ehdr->e_machine = ELF_ARCH32;
#else
ehdr->e_machine = ELF_ARCH;
#endif