Subject: lib/13435: libsa loadfile() loads binary or kernel at wrong address
To: None <gnats-bugs@gnats.netbsd.org>
From: None <nigel@ind.tansu.com.au>
List: netbsd-bugs
Date: 07/11/2001 04:35:05
>Number:         13435
>Category:       lib
>Synopsis:       libsa loadfile() loads binary or kernel at wrong address
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jul 11 04:33:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Nigel Pearson
>Release:        None
>Organization:
Telstra NW-D
>Environment:
Not applicable
>Description:
	Revision 1.10 of loadfile.c, compiled into Mac68k Booter program.
When loading a standard mac68k kernel with a non-zero entry point
(e.g. a_entry = 0x2e00), the kernel image is being loaded offset by
the entry. (i.e. 0x0 thru 0x2e00 is unused, entry point is now 0x5c00).


	Am correcting problem by applying this hack in loadfile():

i = hdr.aout.a_entry;hdr.aout.a_entry = 0;

rval = aout_exec(fd, &hdr.aout, marks, flags);

marks[MARK_ENTRY] += i;
>How-To-Repeat:
Can probably e-mail you a test program if unable to reproduce.
>Fix:
	Discussion: aout_exec(), for some reason I cannot fathom, sets minp
and maxp to ALIGNENTRY(entry). This means that header or text section
will _always_ be loaded at marks[MARK_START] + entry. Look at the code:

aout_exec(fd, x, marks, flags)...
	u_long entry = x->a_entry;...
	paddr_t offset = marks[MARK_START];...
	minp = maxp = ALIGNENTRY(entry);
...
	if (flags & LOAD_TEXT) {		PROGRESS(("%ld", x->a_text));		if (READ(fd, maxp, x->a_text - sub) != x->a_text - sub) {
...



	Suspect we should do :

% diff -u loadfile.c loadfile-hack.c  
--- loadfile.c  Mon Jul  9 12:18:19 2001
+++ loadfile-hack.c     Wed Jul 11 21:34:57 2001
@@ -446,9 +446,8 @@
        u_long *marks;
        int flags;
 {
-       u_long entry = x->a_entry;
        paddr_t aoutp = 0;
-       paddr_t minp, maxp;
+       paddr_t minp, maxp = 0;
        int cc;
        paddr_t offset = marks[MARK_START];
        u_long magic = N_GETMAGIC(*x);
@@ -460,8 +459,6 @@
        else
                sub = sizeof(*x);
 
-       minp = maxp = ALIGNENTRY(entry);
-
        if (lseek(fd, sizeof(*x), SEEK_SET) == -1)  {
                WARN(("lseek text"));
                return 1;
@@ -618,7 +615,7 @@
        }
 
        marks[MARK_START] = LOADADDR(minp);
-       marks[MARK_ENTRY] = LOADADDR(entry);
+       marks[MARK_ENTRY] = LOADADDR(x->a_entry);
        marks[MARK_NSYM] = x->a_syms;
        marks[MARK_SYM] = LOADADDR(aoutp);
        marks[MARK_END] = LOADADDR(maxp);
%
>Release-Note:
>Audit-Trail:
>Unformatted: