40 #include "loader/symtab.h"
49 #define PRINTF(...) printf(__VA_ARGS__)
51 #define PRINTF(...) do {} while (0)
58 unsigned char e_ident[EI_NIDENT];
67 elf32_half e_phentsize;
69 elf32_half e_shentsize;
71 elf32_half e_shstrndx;
90 elf32_word sh_addralign;
91 elf32_word sh_entsize;
96 #define SHT_PROGBITS 1
101 #define SHT_DYNAMIC 6
106 #define SHT_DYNSYM 11
107 #define SHT_LOPROC 0x70000000
108 #define SHT_HIPROC 0x7fffffff
109 #define SHT_LOUSER 0x80000000
110 #define SHT_HIUSER 0xffffffff
121 unsigned char st_info;
122 unsigned char st_other;
126 #define ELF32_R_SYM(info) ((info) >> 8)
127 #define ELF32_R_TYPE(info) ((unsigned char)(info))
129 struct relevant_section {
130 unsigned char number;
139 static struct relevant_section bss, data, rodata, text;
141 static const unsigned char elf_magic_header[] =
142 {0x7f, 0x45, 0x4c, 0x46,
150 seek_read(
int fd,
unsigned int offset,
char *buf,
int len)
153 cfs_read(fd, buf, len);
157 PRINTF(
"seek_read: Read len %d from offset %d\n",
159 for(i = 0; i < len; ++i ) {
160 PRINTF(
"%02x ", buf[i]);
177 find_local_symbol(
int fd,
const char *symbol,
178 unsigned int symtab,
unsigned short symtabsize,
184 struct relevant_section *sect;
186 for(a = symtab; a < symtab + symtabsize; a +=
sizeof(s)) {
187 seek_read(fd, a, (
char *)&s,
sizeof(s));
190 seek_read(fd, strtab + s.st_name, name,
sizeof(name));
191 if(strcmp(name, symbol) == 0) {
192 if(s.st_shndx == bss.number) {
194 }
else if(s.st_shndx == data.number) {
196 }
else if(s.st_shndx == text.number) {
201 return &(sect->address[s.st_value]);
209 relocate_section(
int fd,
210 unsigned int section,
unsigned short size,
211 unsigned int sectionaddr,
215 unsigned int symtab,
unsigned short symtabsize,
216 unsigned char using_relas)
219 struct elf32_rela rela;
225 struct relevant_section *sect;
229 rel_size =
sizeof(
struct elf32_rela);
231 rel_size =
sizeof(
struct elf32_rel);
234 for(a = section; a < section + size; a += rel_size) {
235 seek_read(fd, a, (
char *)&rela, rel_size);
237 symtab +
sizeof(
struct elf32_sym) * ELF32_R_SYM(rela.r_info),
238 (
char *)&s,
sizeof(s));
240 seek_read(fd, strtab + s.st_name, name,
sizeof(name));
241 PRINTF(
"name: %s\n", name);
242 addr = (
char *)symtab_lookup(name);
245 PRINTF(
"name not found in global: %s\n", name);
246 addr = find_local_symbol(fd, name, symtab, symtabsize, strtab);
247 PRINTF(
"found address %p\n", addr);
250 if(s.st_shndx == bss.number) {
252 }
else if(s.st_shndx == data.number) {
254 }
else if(s.st_shndx == rodata.number) {
256 }
else if(s.st_shndx == text.number) {
259 PRINTF(
"elfloader unknown name: '%30s'\n", name);
264 addr = sect->address;
267 if(s.st_shndx == bss.number) {
269 }
else if(s.st_shndx == data.number) {
271 }
else if(s.st_shndx == rodata.number) {
273 }
else if(s.st_shndx == text.number) {
279 addr = sect->address;
284 seek_read(fd, sectionaddr + rela.r_offset, (
char *)&rela.r_addend, 4);
293 find_program_processes(
int fd,
294 unsigned int symtab,
unsigned short size,
301 for(a = symtab; a < symtab + size; a +=
sizeof(s)) {
302 seek_read(fd, a, (
char *)&s,
sizeof(s));
305 seek_read(fd, strtab + s.st_name, name,
sizeof(name));
306 if(strcmp(name,
"autostart_processes") == 0) {
307 return &data.address[s.st_value];
323 print_chars(
unsigned char *ptr,
int num)
326 for(i = 0; i < num; ++i) {
327 PRINTF(
"%d", ptr[i]);
340 struct elf32_ehdr ehdr;
341 struct elf32_shdr shdr;
342 struct elf32_shdr strtable;
344 unsigned int shdrptr;
345 unsigned int nameptr;
349 unsigned short shdrnum, shdrsize;
351 unsigned char using_relas = -1;
352 unsigned short textoff = 0, textsize, textrelaoff = 0, textrelasize;
353 unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize;
354 unsigned short rodataoff = 0, rodatasize, rodatarelaoff = 0, rodatarelasize;
355 unsigned short symtaboff = 0, symtabsize;
356 unsigned short strtaboff = 0, strtabsize;
357 unsigned short bsssize = 0;
359 struct process **process;
365 seek_read(fd, 0, (
char *)&ehdr,
sizeof(ehdr));
370 if(memcmp(ehdr.e_ident, elf_magic_header,
sizeof(elf_magic_header)) != 0) {
371 PRINTF(
"ELF header problems\n");
376 shdrptr = ehdr.e_shoff;
377 seek_read(fd, shdrptr, (
char *)&shdr,
sizeof(shdr));
380 shdrsize = ehdr.e_shentsize;
381 shdrnum = ehdr.e_shnum;
383 PRINTF(
"Section header: size %d num %d\n", shdrsize, shdrnum);
386 seek_read(fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx,
387 (
char *)&strtable,
sizeof(strtable));
392 strs = strtable.sh_offset;
394 PRINTF(
"Strtable offset %d\n", strs);
414 textsize = textrelasize = datasize = datarelasize =
415 rodatasize = rodatarelasize = symtabsize = strtabsize = 0;
417 bss.number = data.number = rodata.number = text.number = -1;
419 shdrptr = ehdr.e_shoff;
420 for(i = 0; i < shdrnum; ++i) {
422 seek_read(fd, shdrptr, (
char *)&shdr,
sizeof(shdr));
425 nameptr = strs + shdr.sh_name;
426 seek_read(fd, nameptr, name,
sizeof(name));
427 PRINTF(
"Section shdrptr 0x%x, %d + %d type %d\n",
436 if(shdr.sh_type == SHT_SYMTAB) {
438 symtaboff = shdr.sh_offset;
439 symtabsize = shdr.sh_size;
440 }
else if(shdr.sh_type == SHT_STRTAB) {
442 strtaboff = shdr.sh_offset;
443 strtabsize = shdr.sh_size;
444 }
else if(strncmp(name,
".text", 5) == 0) {
445 textoff = shdr.sh_offset;
446 textsize = shdr.sh_size;
448 text.offset = textoff;
449 }
else if(strncmp(name,
".rel.text", 9) == 0) {
451 textrelaoff = shdr.sh_offset;
452 textrelasize = shdr.sh_size;
453 }
else if(strncmp(name,
".rela.text", 10) == 0) {
455 textrelaoff = shdr.sh_offset;
456 textrelasize = shdr.sh_size;
457 }
else if(strncmp(name,
".data", 5) == 0) {
458 dataoff = shdr.sh_offset;
459 datasize = shdr.sh_size;
461 data.offset = dataoff;
462 }
else if(strncmp(name,
".rodata", 7) == 0) {
464 rodataoff = shdr.sh_offset;
465 rodatasize = shdr.sh_size;
467 rodata.offset = rodataoff;
468 }
else if(strncmp(name,
".rel.rodata", 11) == 0) {
471 rodatarelaoff = shdr.sh_offset;
472 rodatarelasize = shdr.sh_size;
473 }
else if(strncmp(name,
".rela.rodata", 12) == 0) {
475 rodatarelaoff = shdr.sh_offset;
476 rodatarelasize = shdr.sh_size;
477 }
else if(strncmp(name,
".rel.data", 9) == 0) {
480 datarelaoff = shdr.sh_offset;
481 datarelasize = shdr.sh_size;
482 }
else if(strncmp(name,
".rela.data", 10) == 0) {
484 datarelaoff = shdr.sh_offset;
485 datarelasize = shdr.sh_size;
486 }
else if(strncmp(name,
".bss", 4) == 0) {
487 bsssize = shdr.sh_size;
496 if(symtabsize == 0) {
499 if(strtabsize == 0) {
506 PRINTF(
"before allocate ram\n");
508 data.address = (
char *)bss.address + bsssize;
509 PRINTF(
"before allocate rom\n");
511 rodata.address = (
char *)text.address + textsize;
514 PRINTF(
"bss base address: bss.address = 0x%08x\n", bss.address);
515 PRINTF(
"data base address: data.address = 0x%08x\n", data.address);
516 PRINTF(
"text base address: text.address = 0x%08x\n", text.address);
517 PRINTF(
"rodata base address: rodata.address = 0x%08x\n", rodata.address);
521 PRINTF(
"elfloader: relocate text\n");
522 if(textrelasize > 0) {
523 ret = relocate_section(fd,
524 textrelaoff, textrelasize,
529 symtaboff, symtabsize, using_relas);
536 PRINTF(
"elfloader: relocate rodata\n");
537 if(rodatarelasize > 0) {
538 ret = relocate_section(fd,
539 rodatarelaoff, rodatarelasize,
544 symtaboff, symtabsize, using_relas);
546 PRINTF(
"elfloader: data failed\n");
552 PRINTF(
"elfloader: relocate data\n");
553 if(datarelasize > 0) {
554 ret = relocate_section(fd,
555 datarelaoff, datarelasize,
560 symtaboff, symtabsize, using_relas);
562 PRINTF(
"elfloader: data failed\n");
571 memset(bss.address, 0, bsssize);
572 seek_read(fd, dataoff, data.address, datasize);
574 PRINTF(
"elfloader: autostart search\n");
575 process = (
struct process **) find_local_symbol(fd,
"autostart_processes", symtaboff, symtabsize, strtaboff);
576 if(process !=
NULL) {
577 PRINTF(
"elfloader: autostart found\n");
581 PRINTF(
"elfloader: no autostart\n");
582 process = (
struct process **) find_program_processes(fd, symtaboff, symtabsize, strtaboff);
583 if(process !=
NULL) {
584 PRINTF(
"elfloader: FOUND PRG\n");