blob: 6d1674049769d2abfff7883cbefb729d97b13eeb [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#include "elf.h"
Mach *mach;
extern Mach mach386;
extern Mach machpower;
static Mach *machs[] =
{
&mach386,
&machpower,
};
Mach*
machbyname(char *name)
{
int i;
for(i=0; i<nelem(machs); i++)
if(strcmp(machs[i]->name, name) == 0){
mach = machs[i];
return machs[i];
}
werrstr("machine '%s' not found", name);
return nil;
}
static struct
{
ulong magic;
int (*fn)(int, Fhdr*);
} cracktab[] = {
0x7F454C46, crackelf,
0xFEEDFACE, crackmacho,
};
Fhdr*
crackhdr(char *name, int mode)
{
uchar buf[4];
ulong magic;
int i, fd;
Fhdr *hdr;
if((fd = open(name, mode)) < 0)
return nil;
if(seek(fd, 0, 0) < 0 || readn(fd, buf, 4) != 4){
close(fd);
return nil;
}
hdr = mallocz(sizeof(Fhdr), 1);
if(hdr == nil){
close(fd);
return nil;
}
hdr->filename = strdup(name);
magic = beload4(buf);
werrstr("magic doesn't match");
for(i=0; i<nelem(cracktab); i++)
if(cracktab[i].magic == magic && seek(fd, 0, 0) == 0 && cracktab[i].fn(fd, hdr) >= 0){
_addhdr(hdr);
return hdr;
}
werrstr("unknown file type: %r");
free(hdr);
close(fd);
return nil;
}
void
uncrackhdr(Fhdr *hdr)
{
int i;
symclose(hdr);
if(hdr->elf)
elfclose(hdr->elf);
if(hdr->fd >= 0)
close(hdr->fd);
free(hdr->cmdline);
free(hdr->prog);
for(i=0; i<hdr->nthread; i++)
free(hdr->thread[i].ureg);
free(hdr->thread);
free(hdr);
}
int
mapfile(Fhdr *fp, u64int base, Map *map, Regs **regs)
{
if(fp == nil){
werrstr("no file");
return -1;
}
if(map == nil){
werrstr("no map");
return -1;
}
if(fp->map == 0){
werrstr("cannot load map for this file type");
return -1;
}
if(regs)
*regs = nil;
return fp->map(fp, base, map, regs);
}
void
unmapfile(Fhdr *fp, Map *map)
{
int i;
if(map == nil || fp == nil)
return;
for(i=0; i<map->nseg; i++){
while(i<map->nseg && map->seg[i].fd == fp->fd){
map->nseg--;
memmove(&map->seg[i], &map->seg[i+1],
(map->nseg-i)*sizeof(map->seg[0]));
}
}
}
Regs*
coreregs(Fhdr *fp, uint id)
{
UregRegs *r;
int i;
for(i=0; i<fp->nthread; i++){
if(fp->thread[i].id == id){
if((r = mallocz(sizeof *r, 1)) == nil)
return nil;
r->r.rw = _uregrw;
r->ureg = fp->thread[i].ureg;
return &r->r;
}
}
werrstr("thread not found");
return nil;
}