-/*
- * Look through the Elf file for the AltOS symbols
- * that can be adjusted before the image is written
- * to the device
- */
-static int
-find_symbols (Elf *e)
-{
- Elf_Scn *scn;
- Elf_Data *symbol_data = NULL;
- GElf_Shdr shdr;
- GElf_Sym sym;
- int i, symbol_count, s;
- int required = 0;
- char *symbol_name;
-
- /*
- * Find the symbols
- */
-
- scn = NULL;
- while ((scn = elf_nextscn(e, scn)) != NULL) {
- if (gelf_getshdr(scn, &shdr) != &shdr)
- return 0;
-
- if (shdr.sh_type == SHT_SYMTAB) {
- symbol_data = elf_getdata(scn, NULL);
- symbol_count = shdr.sh_size / shdr.sh_entsize;
- break;
- }
- }
-
- if (!symbol_data)
- return 0;
-
- for (i = 0; i < symbol_count; i++) {
- gelf_getsym(symbol_data, i, &sym);
-
- symbol_name = elf_strptr(e, shdr.sh_link, sym.st_name);
-
- for (s = 0; s < NUM_SYMBOLS; s++)
- if (!strcmp (ao_symbols[s].name, symbol_name)) {
- int t;
- ao_symbols[s].addr = sym.st_value;
- if (ao_symbols[s].required)
- ++required;
- }
- }
-
- return required >= NUM_REQUIRED_SYMBOLS;
-}
-
-struct load {
- uint32_t addr;
- uint32_t len;
- uint8_t buf[0];
-};
-
-struct load *
-new_load (uint32_t addr, uint32_t len)
-{
- struct load *new = calloc (1, sizeof (struct load) + len);
- if (!new)
- abort();
-
- new->addr = addr;
- new->len = len;
- return new;
-}
-
-void
-load_paste(struct load *into, struct load *from)
-{
- if (from->addr < into->addr || into->addr + into->len < from->addr + from->len)
- abort();
-
- memcpy(into->buf + from->addr - into->addr, from->buf, from->len);
-}
-
-/*
- * Make a new load structure large enough to hold the old one and
- * the new data
- */
-struct load *
-expand_load(struct load *from, uint32_t addr, uint32_t len)
-{
- struct load *new;
-
- if (from) {
- uint32_t from_last = from->addr + from->len;
- uint32_t last = addr + len;
-
- if (addr > from->addr)
- addr = from->addr;
- if (last < from_last)
- last = from_last;
-
- len = last - addr;
-
- if (addr == from->addr && len == from->len)
- return from;
- }
- new = new_load(addr, len);
- if (from) {
- load_paste(new, from);
- free (from);
- }
- return new;
-}
-
-/*
- * Create a new load structure with data from the existing one
- * and the new data
- */
-struct load *
-load_write(struct load *from, uint32_t addr, uint32_t len, void *data)
-{
- struct load *new;
-
- new = expand_load(from, addr, len);
- memcpy(new->buf + addr - new->addr, data, len);
- return new;
-}
-
-/*
- * Construct a large in-memory block for all
- * of the loaded sections of the program
- */
-static struct load *
-get_load(Elf *e)
-{
- Elf_Scn *scn;
- size_t shstrndx;
- GElf_Shdr shdr;
- Elf_Data *data;
- uint8_t *buf;
- char *got_name;
- size_t nphdr;
- int p;
- GElf_Phdr phdr;
- struct load *load = NULL;
-
- if (elf_getshdrstrndx(e, &shstrndx) < 0)
- return 0;
-
- if (elf_getphdrnum(e, &nphdr) < 0)
- return 0;
-
- /*
- * As far as I can tell, all of the phdr sections should
- * be flashed to memory
- */
- for (p = 0; p < nphdr; p++) {
-
- /* Find this phdr */
- gelf_getphdr(e, p, &phdr);
-
- /* Get the associated file section */
- scn = gelf_offscn(e, phdr.p_offset);
-
- if (gelf_getshdr(scn, &shdr) != &shdr)
- abort();
-
- data = elf_getdata(scn, NULL);
-
- /* Write the section data into the memory block */
- load = load_write(load, phdr.p_paddr, phdr.p_filesz, data->d_buf);
- }
- return load;
-}