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: