]> Joshua Wise's Git repositories - netwatch.git/blob - elfload/loader.c
Move the Multiboot code around to have more sane filenames.
[netwatch.git] / elfload / loader.c
1 #include <string.h>
2 #include <stdio.h>
3 #include "../include/elf.h"
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <signal.h>
8 #include <fcntl.h>
9 #include <ctype.h>
10 #include <termios.h>
11 #include <sys/types.h>
12 #include <sys/mman.h>
13 #include <sys/stat.h>
14
15 #define FATAL do { fprintf(stderr, "Error at %s:%d (%d) [%s]\n", \
16   __FILE__, __LINE__, errno, strerror(errno)); exit(1); } while(0)
17
18 #define MAP_SIZE 131072
19 #define MAP_MASK (4096 - 1)
20
21 char * snarf_file(char * fname) {
22
23         int fd = open(fname, O_RDONLY);
24         if (fd < 0) FATAL;
25
26         struct stat st;
27         if (fstat(fd, &st) < 0) FATAL;
28
29         char * buf = malloc(st.st_size);
30         if (!buf) FATAL;
31         if (read(fd, buf, st.st_size) != st.st_size) FATAL;
32
33         printf("Loaded %d bytes.\n", st.st_size);
34         return buf;
35 }
36
37 void dump_to_ram (void * src, int target, int size) {
38
39         printf("Copying %d bytes to 0x%08x...\n", size, target);
40
41         int fd = open("/dev/mem", O_RDWR | O_SYNC);
42         if (fd < 0) FATAL;
43
44         void * map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE,
45                                MAP_SHARED, fd, target & ~MAP_MASK);
46
47         if (map_base == (void *) -1) FATAL;
48
49         void * virt_addr = map_base + (target & MAP_MASK);
50         memcpy(virt_addr, src, size);
51
52 }
53
54 static const unsigned char elf_ident[4] = { 0x7F, 'E', 'L', 'F' }; 
55
56 int load_elf (char * buf) {
57
58         Elf32_Ehdr * elf_hdr = (Elf32_Ehdr *) buf;
59         Elf32_Shdr * elf_sec_hdrs = (Elf32_Shdr *) (buf + elf_hdr->e_shoff);
60
61         if (memcmp(elf_hdr->e_ident, elf_ident, sizeof(elf_ident))) FATAL;
62         if (elf_hdr->e_type != ET_EXEC) FATAL;
63         if (elf_hdr->e_machine != EM_386) FATAL;
64         if (elf_hdr->e_version != EV_CURRENT) FATAL;
65
66         char * string_table = buf + elf_sec_hdrs[elf_hdr->e_shstrndx].sh_offset;
67
68         int i;
69         for (i = 0; i < elf_hdr->e_shnum; i++) {
70                 if (elf_sec_hdrs[i].sh_name == SHN_UNDEF) {
71                         continue;
72                 }
73
74                 char * section_name = string_table + elf_sec_hdrs[i].sh_name;
75
76                 if ((elf_sec_hdrs[i].sh_type != SHT_PROGBITS) || !(elf_sec_hdrs[i].sh_flags & SHF_ALLOC)) {
77                         printf("Skipping %s...\n", section_name);
78                         continue;
79                 }
80
81                 printf("Loading %s...\n", section_name);
82
83                 dump_to_ram(buf + elf_sec_hdrs[i].sh_offset,
84                             elf_sec_hdrs[i].sh_addr,
85                             elf_sec_hdrs[i].sh_size);
86         }
87
88         return 0;
89 }
90
91 int main(int argc, char **argv) {
92         if (argc != 2) {
93                 printf("Usage: %s elffile\n", argv[0]);
94                 return 1;
95         }
96
97         printf("Loading file...\n");
98
99         char * buf = snarf_file(argv[1]);
100         load_elf(buf);
101
102         return 0;
103 }
104
This page took 0.028883 seconds and 4 git commands to generate.