Subject: ICBS/ICBS2
To: None <current-users@sun-lamp.cs.berkeley.edu>
From: Christos Zoulas <christos@deshaw.com>
List: current-users
Date: 05/17/1994 19:10:31
This little program will run an elf/svr4 statically linked binary
of "hello world"; I am currently working on the system call remapping...
I put this hack quickly together, just to make sure it would work...
christos
/*
* Parse an Elf binary, load it into memory and execute it.
*/
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
typedef unsigned long Elf32_Addr;
typedef unsigned long Elf32_Off;
typedef long Elf32_Sword;
typedef long Elf32_Word;
typedef unsigned short Elf32_Half;
#define ELF_IDSIZE 16
enum Elf32_e_type {
Elf32_et_none = 0,
Elf32_et_rel,
Elf32_et_exec,
Elf32_et_dyn,
Elf32_et_core,
Elf32_et_num
};
enum Elf32_e_machine {
Elf32_em_none = 0,
Elf32_em_m32,
Elf32_em_sparc,
Elf32_em_386,
Elf32_em_86k,
Elf32_em_88k,
Elf32_em_486,
Elf32_em_860,
Elf32_em_num
};
typedef struct {
unsigned char e_ident[ELF_IDSIZE]; /* Id bytes */
Elf32_Half e_type; /* file type */
Elf32_Half e_machine; /* machine type */
Elf32_Word e_version; /* version number */
Elf32_Addr e_entry; /* entry point */
Elf32_Off e_phoff; /* Program hdr offset */
Elf32_Off e_shoff; /* Section hdr offset */
Elf32_Word e_flags; /* Processor flags */
Elf32_Half e_ehsize; /* sizeof ehdr */
Elf32_Half e_phentsize; /* Program header entry size */
Elf32_Half e_phnum; /* Number of program headers */
Elf32_Half e_shentsize; /* Section header entry size */
Elf32_Half e_shnum; /* Number of section headers */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
enum Elf32_p_pf {
Elf32_pf_r = 4,
Elf32_pf_w = 2,
Elf32_pf_x = 1
};
typedef struct {
Elf32_Word p_type; /* entry type */
Elf32_Off p_offset; /* offset */
Elf32_Addr p_vaddr; /* virtual address */
Elf32_Addr p_paddr; /* physical address */
Elf32_Word p_filesz; /* file size */
Elf32_Word p_memsz; /* memory size */
Elf32_Word p_flags; /* flags */
Elf32_Word p_align; /* memory & file alignment */
} Elf32_Phdr;
#define Elf32_e_ident "\177ELF"
#define Elf32_e_siz (sizeof(Elf32_e_ident) - 1)
void
print_Ehdr(e)
Elf32_Ehdr *e;
{
printf("e_ident %s\n", e->e_ident);
printf("e_type %d\n", e->e_type);
printf("e_machine %d\n", e->e_machine);
printf("e_version %ld\n", e->e_version);
printf("e_entry %lx\n", e->e_entry);
printf("e_phoff %lx\n", e->e_phoff);
printf("e_shoff %lx\n", e->e_shoff);
printf("e_flags %lx\n", e->e_flags);
printf("e_ehsize %d\n", e->e_ehsize);
printf("e_phentsize %d\n", e->e_phentsize);
printf("e_phnum %d\n", e->e_phnum);
printf("e_shentsize %d\n", e->e_shentsize);
printf("e_shnum %d\n", e->e_shnum);
printf("e_shstrndx %d\n", e->e_shstrndx);
}
void
print_Phdr(p)
Elf32_Phdr *p;
{
printf("p_type %ld\n", p->p_type);
printf("p_offset %lx\n", p->p_offset);
printf("p_vaddr %lx\n", p->p_vaddr);
printf("p_paddr %lx\n", p->p_paddr);
printf("p_filesz %ld\n", p->p_filesz);
printf("p_memsz %ld\n", p->p_memsz);
printf("p_flags %lx\n", p->p_flags);
printf("p_align %ld\n", p->p_align);
}
void
load_psection(fd, p)
int fd;
Elf32_Phdr *p;
{
#define AL(a,b) ((a) & ~((b) - 1))
unsigned long vaddr = AL(p->p_vaddr, p->p_align);
unsigned long offset = p->p_offset - (p->p_vaddr - vaddr);
int prot = 0;
caddr_t m;
#ifdef DEBUG
printf("vaddr = %x p_vaddr %x\n", vaddr, p->p_vaddr);
printf("offset = %x p_offset %x\n", offset, p->p_offset);
#endif
prot |= (p->p_flags & Elf32_pf_r) ? PROT_READ : 0;
prot |= (p->p_flags & Elf32_pf_w) ? PROT_WRITE : 0;
prot |= (p->p_flags & Elf32_pf_x) ? PROT_EXEC : 0;
m = mmap((caddr_t) vaddr, p->p_memsz, prot, MAP_FIXED, fd, offset);
if (m == (caddr_t) -1)
perror("mmap");
#ifdef DEBUG
else
printf("Mapped at %lx prot=%x\n", m, prot);
#endif
}
int
main(argc, argv)
int argc;
char **argv;
{
Elf32_Ehdr e;
Elf32_Phdr p;
int i;
int fd;
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
if (read(fd, &e, sizeof(e)) != sizeof(e)) {
perror("read");
return 1;
}
#ifdef DEBUG
print_Ehdr(&e);
#endif
if (memcmp(e.e_ident, Elf32_e_ident, Elf32_e_siz) != 0) {
fprintf(stderr, "Not an elf file\n");
return 1;
}
if (e.e_type != Elf32_et_exec) {
fprintf(stderr, "Not an elf executable\n");
return 1;
}
if (e.e_machine != Elf32_em_386 && e.e_machine != Elf32_em_486) {
fprintf(stderr, "Not an elf/386 or 486 executable\n");
return 1;
}
if (lseek(fd, e.e_phoff, L_SET) == (off_t) -1) {
perror("lseek");
return 1;
}
for (i = 0; i < e.e_phnum; i++) {
if (read(fd, &p, sizeof(p)) != sizeof(p)) {
perror("read");
return 1;
}
#ifdef DEBUG
print_Phdr(&p);
#endif
load_psection(fd, &p);
}
return ((int (*)()) e.e_entry)();
}
------------------------------------------------------------------------------