This commit is contained in:
cinap_lenrek 2021-05-29 14:20:04 +02:00
commit a624902621
4 changed files with 91 additions and 60 deletions

View file

@ -25,7 +25,7 @@ typedef struct Exec {
long pcsz; /* size of pc/line number table */ long pcsz; /* size of pc/line number table */
} Exec; } Exec;
#define HDR_MAGIC 0x00008000 #define HDR_MAGIC 0x00008000 /* header expansion */
#define _MAGIC(f, b) ((f)|((((4*(b))+0)*(b))+7)) #define _MAGIC(f, b) ((f)|((((4*(b))+0)*(b))+7))
#define A_MAGIC _MAGIC(0, 8) /* 68020 */ #define A_MAGIC _MAGIC(0, 8) /* 68020 */
@ -62,7 +62,18 @@ The text segment consists of the header and the first
bytes of the binary file. bytes of the binary file.
The The
.B entry .B entry
field gives the virtual address of the entry point of the program. field gives the virtual address of the entry point of the program
unless
.B HDR_MAGIC
flag is present in the
.B magic
field.
In that case, the header is expanded
by 8 bytes containing the 64-bit virtual address of the
program entry point and the 32-bit
.B entry
field is reserved for physical kernel entry point.
.PP
The data segment starts at the first page-rounded virtual address The data segment starts at the first page-rounded virtual address
after the text segment. after the text segment.
It consists of the next It consists of the next

View file

@ -10,6 +10,8 @@ Block* allocb(int);
int anyhigher(void); int anyhigher(void);
int anyready(void); int anyready(void);
Image* attachimage(int, Chan*, uintptr, ulong); Image* attachimage(int, Chan*, uintptr, ulong);
ulong beswal(ulong);
uvlong beswav(uvlong);
int blocklen(Block*); int blocklen(Block*);
void bootlinks(void); void bootlinks(void);
void cachedel(Image*, uintptr); void cachedel(Image*, uintptr);

View file

@ -6,16 +6,6 @@
#include "../port/error.h" #include "../port/error.h"
#include "a.out.h" #include "a.out.h"
static ulong
l2be(long l)
{
uchar *cp;
cp = (uchar*)&l;
return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3];
}
static void static void
readn(Chan *c, void *vp, long n) readn(Chan *c, void *vp, long n)
{ {
@ -35,8 +25,11 @@ readn(Chan *c, void *vp, long n)
void void
rebootcmd(int argc, char *argv[]) rebootcmd(int argc, char *argv[])
{ {
struct {
Exec;
uvlong hdr[1];
} ehdr;
Chan *c; Chan *c;
Exec exec;
ulong magic, text, rtext, entry, data, size, align; ulong magic, text, rtext, entry, data, size, align;
uchar *p; uchar *p;
@ -49,11 +42,11 @@ rebootcmd(int argc, char *argv[])
nexterror(); nexterror();
} }
readn(c, &exec, sizeof(Exec)); readn(c, &ehdr, sizeof(Exec));
magic = l2be(exec.magic); magic = beswal(ehdr.magic);
entry = l2be(exec.entry); entry = beswal(ehdr.entry);
text = l2be(exec.text); text = beswal(ehdr.text);
data = l2be(exec.data); data = beswal(ehdr.data);
if(!(magic == AOUT_MAGIC)){ if(!(magic == AOUT_MAGIC)){
switch(magic){ switch(magic){
@ -66,7 +59,7 @@ rebootcmd(int argc, char *argv[])
} }
} }
if(magic & HDR_MAGIC) if(magic & HDR_MAGIC)
readn(c, &exec, 8); readn(c, ehdr.hdr, sizeof(ehdr.hdr));
switch(magic){ switch(magic){
case R_MAGIC: case R_MAGIC:

View file

@ -234,6 +234,8 @@ shargs(char *s, int n, char **ap)
{ {
int i; int i;
if(n <= 2 || s[0] != '#' || s[1] != '!')
return -1;
s += 2; s += 2;
n -= 2; /* skip #! */ n -= 2; /* skip #! */
for(i=0;; i++){ for(i=0;; i++){
@ -261,27 +263,42 @@ shargs(char *s, int n, char **ap)
return i; return i;
} }
static ulong ulong
l2be(long l) beswal(ulong l)
{ {
uchar *cp; uchar *p;
cp = (uchar*)&l; p = (uchar*)&l;
return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3]; return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
uvlong
beswav(uvlong v)
{
uchar *p;
p = (uchar*)&v;
return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40)
| ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24)
| ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8)
| (uvlong)p[7];
} }
uintptr uintptr
sysexec(va_list list) sysexec(va_list list)
{ {
Exec exec; struct {
char line[sizeof(Exec)]; Exec;
uvlong hdr[1];
} ehdr;
char line[sizeof(ehdr)];
char *progarg[sizeof(line)/2+1]; char *progarg[sizeof(line)/2+1];
volatile char *args, *elem, *file0; volatile char *args, *elem, *file0;
char **argv, **argp, **argp0; char **argv, **argp, **argp0;
char *a, *e, *charp, *file; char *a, *e, *charp, *file;
int i, n, indir; int i, n, indir;
ulong magic, ssize, nargs, nbytes; ulong magic, ssize, nargs, nbytes;
uintptr t, d, b, entry, bssend, text, data, bss, tstk, align; uintptr t, d, b, entry, text, data, bss, bssend, tstk, align;
Segment *s, *ts; Segment *s, *ts;
Image *img; Image *img;
Tos *tos; Tos *tos;
@ -311,7 +328,7 @@ sysexec(va_list list)
} }
nexterror(); nexterror();
} }
align = BY2PG; align = BY2PG-1;
indir = 0; indir = 0;
file = file0; file = file0;
for(;;){ for(;;){
@ -323,39 +340,47 @@ sysexec(va_list list)
if(!indir) if(!indir)
kstrdup(&elem, up->genbuf); kstrdup(&elem, up->genbuf);
n = devtab[tc->type]->read(tc, &exec, sizeof(Exec), 0); n = devtab[tc->type]->read(tc, &ehdr, sizeof(ehdr), 0);
if(n <= 2) if(n >= sizeof(Exec)) {
error(Ebadexec); magic = beswal(ehdr.magic);
magic = l2be(exec.magic); if(magic == AOUT_MAGIC) {
if(n == sizeof(Exec) && (magic == AOUT_MAGIC)){ if(magic & HDR_MAGIC) {
entry = l2be(exec.entry); if(n < sizeof(ehdr))
text = l2be(exec.text); error(Ebadexec);
if(magic & HDR_MAGIC) entry = beswav(ehdr.hdr[0]);
text += 8; text = UTZERO+sizeof(ehdr);
switch(magic){ } else {
case S_MAGIC: /* 2MB segment alignment for amd64 */ entry = beswal(ehdr.entry);
align = 0x200000; text = UTZERO+sizeof(Exec);
break; }
case V_MAGIC: /* 16K segment alignment for mips */ if(entry < text)
align = 0x4000; error(Ebadexec);
break; text += beswal(ehdr.text);
case R_MAGIC: /* 64K segment alignment for arm64 */ if(text <= entry || text >= (USTKTOP-USTKSIZE))
align = 0x10000; error(Ebadexec);
break;
switch(magic){
case S_MAGIC: /* 2MB segment alignment for amd64 */
align = 0x1fffff;
break;
case V_MAGIC: /* 16K segment alignment for mips */
align = 0x3fff;
break;
case R_MAGIC: /* 64K segment alignment for arm64 */
align = 0xffff;
break;
}
break; /* for binary */
} }
if(text >= (USTKTOP-USTKSIZE)-(UTZERO+sizeof(Exec))
|| entry < UTZERO+sizeof(Exec)
|| entry >= UTZERO+sizeof(Exec)+text)
error(Ebadexec);
break; /* for binary */
} }
if(indir++)
error(Ebadexec);
/* /*
* Process #! /bin/sh args ... * Process #! /bin/sh args ...
*/ */
memmove(line, &exec, n); memmove(line, &ehdr, n);
if(line[0]!='#' || line[1]!='!' || indir++)
error(Ebadexec);
n = shargs(line, n, progarg); n = shargs(line, n, progarg);
if(n < 1) if(n < 1)
error(Ebadexec); error(Ebadexec);
@ -371,10 +396,10 @@ sysexec(va_list list)
cclose(tc); cclose(tc);
} }
data = l2be(exec.data); t = (text+align) & ~align;
bss = l2be(exec.bss); text -= UTZERO;
align--; data = beswal(ehdr.data);
t = (UTZERO+sizeof(Exec)+text+align) & ~align; bss = beswal(ehdr.bss);
align = BY2PG-1; align = BY2PG-1;
d = (t + data + align) & ~align; d = (t + data + align) & ~align;
bssend = t + data + bss; bssend = t + data + bss;
@ -518,7 +543,7 @@ sysexec(va_list list)
up->seg[TSEG] = ts; up->seg[TSEG] = ts;
ts->flushme = 1; ts->flushme = 1;
ts->fstart = 0; ts->fstart = 0;
ts->flen = sizeof(Exec)+text; ts->flen = text;
unlock(img); unlock(img);
/* Data. Shared. */ /* Data. Shared. */