summaryrefslogtreecommitdiffstats
path: root/sys/kern/imgact_elf.c
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-03-25 14:21:22 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-03-25 14:21:22 +0000
commitb60f1f5349665e80134bc9f0afab88b52539ab40 (patch)
tree9f68b9edfaa4a3646a81d8bf5c749ea4ef443a9c /sys/kern/imgact_elf.c
parent2f9c438c7714403eb93207d6ff8980460a6ece72 (diff)
downloadFreeBSD-src-b60f1f5349665e80134bc9f0afab88b52539ab40.zip
FreeBSD-src-b60f1f5349665e80134bc9f0afab88b52539ab40.tar.gz
Change the way text_addr and data_addr are computed to use the
executable status of segments instead of detecting the main text segment by which segment contains the program entry point. This affects obreak() and is required for correct operation of that function on 64-bit PowerPC systems. The previous behavior was apparently required only for the Alpha, which is no longer supported. Reviewed by: jhb Tested on: amd64, sparc64, powerpc
Diffstat (limited to 'sys/kern/imgact_elf.c')
-rw-r--r--sys/kern/imgact_elf.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 0fffb9f..47e1f64 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -832,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
@@ -846,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;
@@ -871,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
OpenPOWER on IntegriCloud