Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-5]: src/sys/compat/ibcs2 Support loading of COFF NMAGIC files w...
details: https://anonhg.NetBSD.org/src/rev/86b2233fef27
branches: netbsd-1-5
changeset: 488230:86b2233fef27
user: matt <matt%NetBSD.org@localhost>
date: Thu Jun 22 16:37:09 2000 +0000
description:
Support loading of COFF NMAGIC files whose sections don't fall on a page
boundary.
diffstat:
sys/compat/ibcs2/ibcs2_exec.c | 111 +++++++++++++++++++++++++++++++++++------
1 files changed, 95 insertions(+), 16 deletions(-)
diffs (144 lines):
diff -r fba65b511804 -r 86b2233fef27 sys/compat/ibcs2/ibcs2_exec.c
--- a/sys/compat/ibcs2/ibcs2_exec.c Thu Jun 22 16:35:53 2000 +0000
+++ b/sys/compat/ibcs2/ibcs2_exec.c Thu Jun 22 16:37:09 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ibcs2_exec.c,v 1.28 2000/06/16 01:56:36 matt Exp $ */
+/* $NetBSD: ibcs2_exec.c,v 1.28.2.1 2000/06/22 16:37:09 matt Exp $ */
/*
* Copyright (c) 1994, 1995, 1998 Scott Bartram
@@ -374,11 +374,13 @@
VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
/* set up command for bss segment */
- if (ap->a_bsize > 0)
+ if (ap->a_bsize > 0) {
NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize,
COFF_SEGMENT_ALIGN(fp, ap, ap->a_dstart + ap->a_dsize),
NULLVP, 0,
VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+ epp->ep_dsize += ap->a_bsize;
+ }
return exec_ibcs2_coff_setup_stack(p, epp);
}
@@ -395,28 +397,105 @@
struct coff_filehdr *fp;
struct coff_aouthdr *ap;
{
+ u_long tsize, tend, toverlap, doverlap;
+
epp->ep_taddr = COFF_SEGMENT_ALIGN(fp, ap, ap->a_tstart);
epp->ep_tsize = ap->a_tsize;
- epp->ep_daddr = COFF_ROUND(ap->a_dstart, COFF_LDPGSZ);
+ epp->ep_daddr = ap->a_dstart;
epp->ep_dsize = ap->a_dsize;
epp->ep_entry = ap->a_entry;
- /* set up command for text segment */
- NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_tsize,
- epp->ep_taddr, epp->ep_vp, COFF_TXTOFF(fp, ap),
- VM_PROT_READ|VM_PROT_EXECUTE);
+ /* Do the text and data pages overlap?
+ */
+ tend = epp->ep_taddr + epp->ep_tsize - 1;
+ if (trunc_page(tend) == trunc_page(epp->ep_daddr)) {
+ /* If the first page of text is the first page of data,
+ * then we consider it all data.
+ */
+ if (trunc_page(epp->ep_taddr) == trunc_page(epp->ep_daddr)) {
+ tsize = 0;
+ } else {
+ tsize = trunc_page(tend) - epp->ep_taddr;
+ }
+
+ /* If the text and data file and VA offsets are the
+ * same, simply bring the data segment to start on
+ * the start of the page.
+ */
+ if (epp->ep_daddr - epp->ep_taddr ==
+ COFF_DATOFF(fp, ap) - COFF_TXTOFF(fp, ap)) {
+ u_long diff = epp->ep_daddr - trunc_page(epp->ep_daddr);
+ epp->ep_daddr -= diff;
+ epp->ep_dsize += diff;
+ epp->ep_tsize = tsize;
+ toverlap = 0;
+ doverlap = 0;
+ } else {
+ /* otherwise copy the individual pieces */
+ toverlap = epp->ep_tsize - tsize;
+ doverlap = round_page(epp->ep_daddr) - epp->ep_daddr;
+ if (doverlap > epp->ep_dsize)
+ doverlap = epp->ep_dsize;
+ }
+ } else {
+ tsize = epp->ep_tsize;
+ toverlap = 0;
+ doverlap = 0;
+ }
- /* set up command for data segment */
- NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_dsize,
- epp->ep_daddr, epp->ep_vp, COFF_DATOFF(fp, ap),
- VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+ DPRINTF(("nmagic_vmcmds:"));
+ if (tsize > 0) {
+ /* set up command for text segment */
+ NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, tsize,
+ epp->ep_taddr, epp->ep_vp, COFF_TXTOFF(fp, ap),
+ VM_PROT_READ|VM_PROT_EXECUTE);
+ DPRINTF((" map_readvn(%#lx/%#lx@%#x)",
+ epp->ep_taddr, tsize, COFF_TXTOFF(fp, ap)));
+ }
+ if (toverlap > 0) {
+ NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, toverlap,
+ epp->ep_taddr + tsize, epp->ep_vp,
+ COFF_TXTOFF(fp, ap) + tsize,
+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+ DPRINTF((" map_readvn(%#lx/%#lx@%#lx)",
+ epp->ep_taddr + tsize, toverlap,
+ COFF_TXTOFF(fp, ap) + tsize));
+ NEW_VMCMD(&epp->ep_vmcmds, vmcmd_readvn, doverlap,
+ epp->ep_daddr, epp->ep_vp,
+ COFF_DATOFF(fp, ap),
+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+ DPRINTF((" readvn(%#lx/%#lx@%#lx)", epp->ep_daddr, doverlap,
+ COFF_DATOFF(fp, ap)));
+ }
+
+ if (epp->ep_dsize > doverlap) {
+ /* set up command for data segment */
+ NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
+ epp->ep_dsize - doverlap, epp->ep_daddr + doverlap,
+ epp->ep_vp, COFF_DATOFF(fp, ap) + doverlap,
+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+ DPRINTF((" map_readvn(%#lx/%#lx@%#lx)",
+ epp->ep_daddr + doverlap, epp->ep_dsize - doverlap,
+ COFF_DATOFF(fp, ap) + doverlap));
+ }
+
+ /* Handle page remainders for pagedvn.
+ */
/* set up command for bss segment */
- if (ap->a_bsize > 0)
- NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ap->a_bsize,
- COFF_SEGMENT_ALIGN(fp, ap, ap->a_dstart + ap->a_dsize),
- NULLVP, 0,
- VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+ if (ap->a_bsize > 0) {
+ u_long dend = round_page(epp->ep_daddr + epp->ep_dsize);
+ u_long dspace = dend - (epp->ep_daddr + epp->ep_dsize);
+ if (ap->a_bsize > dspace) {
+ NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero,
+ ap->a_bsize - dspace, dend, NULLVP, 0,
+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+ DPRINTF((" map_zero(%#lx/%#lx)",
+ dend, ap->a_bsize - dspace));
+ }
+ epp->ep_dsize += ap->a_bsize;
+ }
+ DPRINTF(("\n"));
return exec_ibcs2_coff_setup_stack(p, epp);
}
Home |
Main Index |
Thread Index |
Old Index