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 */
} Exec;
#define HDR_MAGIC 0x00008000
#define HDR_MAGIC 0x00008000 /* header expansion */
#define _MAGIC(f, b) ((f)|((((4*(b))+0)*(b))+7))
#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.
The
.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
after the text segment.
It consists of the next

View file

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

View file

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

View file

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