From: Keith Packard Date: Wed, 27 Nov 2013 21:59:06 +0000 (-0800) Subject: ao-tools: Create general elf and hex library routines X-Git-Tag: 1.3~91 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=95a8180f3d7929dbad65c80421f99c925f245af0 ao-tools: Create general elf and hex library routines Pulls the elf stuff out of ao-stmload, change the hex stuff into ao_ routines. Signed-off-by: Keith Packard --- diff --git a/ao-tools/ao-dbg/ao-dbg-command.c b/ao-tools/ao-dbg/ao-dbg-command.c index eab7bc68..11c521e8 100644 --- a/ao-tools/ao-dbg/ao-dbg-command.c +++ b/ao-tools/ao-dbg/ao-dbg-command.c @@ -202,8 +202,8 @@ command_dump (int argc, char **argv) enum command_result command_file (int argc, char **argv) { - struct hex_file *hex; - struct hex_image *image; + struct ao_hex_file *hex; + struct ao_hex_image *image; FILE *file; if (argc != 2) @@ -211,16 +211,16 @@ command_file (int argc, char **argv) file = fopen (argv[1], "r"); if (!file) return command_error; - hex = ccdbg_hex_file_read(file, argv[1]); + hex = ao_hex_file_read(file, argv[1]); fclose(file); if (!hex) return command_error; if (hex->nrecord == 0) { - ccdbg_hex_file_free(hex); + ao_hex_file_free(hex); return command_error; } - image = ccdbg_hex_image_create(hex); - ccdbg_hex_file_free(hex); + image = ao_hex_image_create(hex); + ao_hex_file_free(hex); start_address = image->address; ccdbg_set_rom(s51_dbg, image); return command_success; @@ -495,8 +495,8 @@ command_load (int argc, char **argv) { char *filename = argv[1]; FILE *file; - struct hex_file *hex; - struct hex_image *image; + struct ao_hex_file *hex; + struct ao_hex_image *image; if (!filename) return command_error; @@ -505,13 +505,13 @@ command_load (int argc, char **argv) perror(filename); return command_error; } - hex = ccdbg_hex_file_read(file, filename); + hex = ao_hex_file_read(file, filename); fclose(file); if (!hex) { return command_error; } - image = ccdbg_hex_image_create(hex); - ccdbg_hex_file_free(hex); + image = ao_hex_image_create(hex); + ao_hex_file_free(hex); if (!image) { fprintf(stderr, "image create failed\n"); return command_error; @@ -523,7 +523,7 @@ command_load (int argc, char **argv) } else { fprintf(stderr, "Can only load to RAM\n"); } - ccdbg_hex_image_free(image); + ao_hex_image_free(image); return command_success; } diff --git a/ao-tools/ao-load/ao-load.c b/ao-tools/ao-load/ao-load.c index e3cef4a5..c1f55149 100644 --- a/ao-tools/ao-load/ao-load.c +++ b/ao-tools/ao-load/ao-load.c @@ -80,7 +80,7 @@ find_symbols(FILE *map) } static int -rewrite(struct hex_image *image, unsigned addr, char *data, int len) +rewrite(struct ao_hex_image *image, unsigned addr, char *data, int len) { int i; if (addr < image->address || image->address + image->length < addr + len) @@ -114,8 +114,8 @@ main (int argc, char **argv) struct ccdbg *dbg; uint8_t status; uint16_t pc; - struct hex_file *hex; - struct hex_image *image; + struct ao_hex_file *hex; + struct ao_hex_image *image; char *filename; FILE *file; FILE *map; @@ -182,18 +182,18 @@ main (int argc, char **argv) } fclose(map); - hex = ccdbg_hex_file_read(file, filename); + hex = ao_hex_file_read(file, filename); fclose(file); if (!hex) { perror(filename); exit (1); } - image = ccdbg_hex_image_create(hex); + image = ao_hex_image_create(hex); if (!image) { fprintf(stderr, "image create failed\n"); exit (1); } - ccdbg_hex_file_free(hex); + ao_hex_file_free(hex); serial = strtoul(serial_string, NULL, 0); if (!serial) @@ -276,7 +276,7 @@ main (int argc, char **argv) } else { printf("Cannot load code to 0x%04x\n", image->address); - ccdbg_hex_image_free(image); + ao_hex_image_free(image); ccdbg_close(dbg); exit(1); } diff --git a/ao-tools/ao-rawload/ao-rawload.c b/ao-tools/ao-rawload/ao-rawload.c index a4746b19..17ed73ca 100644 --- a/ao-tools/ao-rawload/ao-rawload.c +++ b/ao-tools/ao-rawload/ao-rawload.c @@ -40,8 +40,8 @@ main (int argc, char **argv) struct ccdbg *dbg; uint8_t status; uint16_t pc; - struct hex_file *hex; - struct hex_image *image; + struct ao_hex_file *hex; + struct ao_hex_image *image; char *filename; FILE *file; char *tty = NULL; @@ -75,17 +75,17 @@ main (int argc, char **argv) perror(filename); exit(1); } - hex = ccdbg_hex_file_read(file, filename); + hex = ao_hex_file_read(file, filename); fclose(file); if (!hex) exit (1); - image = ccdbg_hex_image_create(hex); + image = ao_hex_image_create(hex); if (!image) { fprintf(stderr, "image create failed\n"); exit (1); } - ccdbg_hex_file_free(hex); + ao_hex_file_free(hex); if (!tty) tty = cc_usbdevs_find_by_arg(device, "TIDongle"); dbg = ccdbg_open(tty); @@ -107,7 +107,7 @@ main (int argc, char **argv) } else { printf("Cannot load code to 0x%04x\n", image->address); - ccdbg_hex_image_free(image); + ao_hex_image_free(image); ccdbg_close(dbg); exit(1); } diff --git a/ao-tools/ao-stmload/Makefile.am b/ao-tools/ao-stmload/Makefile.am index 4eaf699c..68b518f1 100644 --- a/ao-tools/ao-stmload/Makefile.am +++ b/ao-tools/ao-stmload/Makefile.am @@ -11,7 +11,7 @@ ao_stmload_DEPENDENCIES = $(AO_STMLOAD_LIBS) ao_stmload_LDADD=$(AO_STMLOAD_LIBS) $(LIBSTLINK_LIBS) $(LIBUSB_LIBS) -lelf -ao_stmload_SOURCES=ao-stmload.c ao-elf.c ao-stmload.h ao-selfload.c +ao_stmload_SOURCES=ao-stmload.c ao-stmload.h ao-selfload.c man_MANS = ao-stmload.1 diff --git a/ao-tools/ao-stmload/ao-elf.c b/ao-tools/ao-stmload/ao-elf.c deleted file mode 100644 index dad8fb80..00000000 --- a/ao-tools/ao-stmload/ao-elf.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ao-elf.h" -#include -#include -#include -#include -#include -#include -#include -#include "ccdbg.h" -#include "ao-stmload.h" - -/* - * 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; - char *section_name; - size_t shstrndx; - - if (elf_getshdrstrndx(e, &shstrndx) < 0) - return 0; - - /* - * 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 < ao_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 >= ao_num_required_symbols; -} - -uint32_t round4(uint32_t a) { - return (a + 3) & ~3; -} - -struct hex_image * -new_load (uint32_t addr, uint32_t len) -{ - struct hex_image *new; - - len = round4(len); - new = calloc (1, sizeof (struct hex_image) + len); - if (!new) - abort(); - - new->address = addr; - new->length = len; - return new; -} - -void -load_paste(struct hex_image *into, struct hex_image *from) -{ - if (from->address < into->address || into->address + into->length < from->address + from->length) - abort(); - - memcpy(into->data + from->address - into->address, from->data, from->length); -} - -/* - * Make a new load structure large enough to hold the old one and - * the new data - */ -struct hex_image * -expand_load(struct hex_image *from, uint32_t address, uint32_t length) -{ - struct hex_image *new; - - if (from) { - uint32_t from_last = from->address + from->length; - uint32_t last = address + length; - - if (address > from->address) - address = from->address; - if (last < from_last) - last = from_last; - - length = last - address; - - if (address == from->address && length == from->length) - return from; - } - new = new_load(address, length); - 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 hex_image * -load_write(struct hex_image *from, uint32_t address, uint32_t length, void *data) -{ - struct hex_image *new; - - new = expand_load(from, address, length); - memcpy(new->data + address - new->address, data, length); - return new; -} - -/* - * Construct a large in-memory block for all - * of the loaded sections of the program - */ -static struct hex_image * -get_load(Elf *e) -{ - Elf_Scn *scn; - size_t shstrndx; - GElf_Shdr shdr; - Elf_Data *data; - char *got_name; - size_t nphdr; - size_t p; - GElf_Phdr phdr; - GElf_Addr p_paddr; - GElf_Off p_offset; - GElf_Addr sh_paddr; - struct hex_image *load = NULL; - char *section_name; - size_t nshdr; - size_t s; - - if (elf_getshdrstrndx(e, &shstrndx) < 0) - return 0; - - if (elf_getphdrnum(e, &nphdr) < 0) - return 0; - - if (elf_getshdrnum(e, &nshdr) < 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); - - if (phdr.p_type != PT_LOAD) - continue; - - p_offset = phdr.p_offset; - /* Get the associated file section */ - -#if 0 - printf ("offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", - (uint32_t) phdr.p_offset, - (uint32_t) phdr.p_vaddr, - (uint32_t) phdr.p_paddr, - (uint32_t) phdr.p_filesz, - (uint32_t) phdr.p_memsz); -#endif - - for (s = 0; s < nshdr; s++) { - scn = elf_getscn(e, s); - - if (!scn) { - printf ("getscn failed\n"); - abort(); - } - if (gelf_getshdr(scn, &shdr) != &shdr) { - printf ("gelf_getshdr failed\n"); - abort(); - } - - section_name = elf_strptr(e, shstrndx, shdr.sh_name); - - if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { - - if (shdr.sh_size == 0) - continue; - - sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; - - printf ("\tsize %08x rom %08x exec %08x %s\n", - (uint32_t) shdr.sh_size, - (uint32_t) sh_paddr, - (uint32_t) shdr.sh_addr, - section_name); - - data = elf_getdata(scn, NULL); - - /* Write the section data into the memory block */ - load = load_write(load, sh_paddr, shdr.sh_size, data->d_buf); - } - } - } - return load; -} - -/* - * Open the specified ELF file and - * check for the symbols we need - */ - -struct hex_image * -ao_load_elf(char *name) -{ - int fd; - Elf *e; - Elf_Scn *scn; - Elf_Data *symbol_data = NULL; - GElf_Shdr shdr; - GElf_Sym sym; - size_t n, shstrndx, sz; - int i, symbol_count, s; - int required = 0; - struct hex_image *image; - - if (elf_version(EV_CURRENT) == EV_NONE) - return NULL; - - fd = open(name, O_RDONLY, 0); - - if (fd < 0) - return NULL; - - e = elf_begin(fd, ELF_C_READ, NULL); - - if (!e) - return NULL; - - if (elf_kind(e) != ELF_K_ELF) - return NULL; - - if (elf_getshdrstrndx(e, &shstrndx) != 0) - return NULL; - - if (!find_symbols(e)) { - fprintf (stderr, "Cannot find required symbols\n"); - return NULL; - } - - image = get_load(e); - if (!image) { - fprintf (stderr, "Cannot create memory image from file\n"); - return NULL; - } - - return image; -} diff --git a/ao-tools/ao-stmload/ao-elf.h b/ao-tools/ao-stmload/ao-elf.h deleted file mode 100644 index 4303d5ca..00000000 --- a/ao-tools/ao-stmload/ao-elf.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#ifndef _AO_ELF_H_ -#define _AO_ELF_H_ - -struct hex_image * -ao_load_elf(char *name); - -#endif diff --git a/ao-tools/ao-stmload/ao-selfload.c b/ao-tools/ao-stmload/ao-selfload.c index 95667dca..dee1c3cb 100644 --- a/ao-tools/ao-stmload/ao-selfload.c +++ b/ao-tools/ao-stmload/ao-selfload.c @@ -64,16 +64,16 @@ ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]) } } -struct hex_image * +struct ao_hex_image * ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length) { - struct hex_image *image; + struct ao_hex_image *image; int pages; int page; uint32_t base = address & ~0xff; uint32_t bound = (address + length + 0xff) & ~0xff; - image = calloc(sizeof (struct hex_image) + (bound - base), 1); + image = calloc(sizeof (struct ao_hex_image) + (bound - base), 1); image->address = base; image->length = bound - base; pages = image->length / 0x100; @@ -83,7 +83,7 @@ ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length) } int -ao_self_write(struct cc_usb *cc, struct hex_image *image) +ao_self_write(struct cc_usb *cc, struct ao_hex_image *image) { uint8_t block[256]; uint8_t check[256]; diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index dd25f07f..6e3906fd 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -34,7 +34,7 @@ #define AO_USB_DESC_STRING 3 -struct sym ao_symbols[] = { +struct ao_elf_sym ao_symbols[] = { { 0, AO_BOOT_APPLICATION_BASE + 0x100, "ao_romconfig_version", 1 }, #define AO_ROMCONFIG_VERSION (ao_symbols[0].addr) @@ -62,7 +62,7 @@ int ao_num_required_symbols = NUM_REQUIRED_SYMBOLS; * Edit the to-be-written memory block */ static int -rewrite(struct hex_image *load, unsigned address, uint8_t *data, int length) +rewrite(struct ao_hex_image *load, unsigned address, uint8_t *data, int length) { int i; @@ -86,7 +86,7 @@ rewrite(struct hex_image *load, unsigned address, uint8_t *data, int length) static uint16_t get_uint16_cc(struct cc_usb *cc, uint32_t addr) { - struct hex_image *hex = ao_self_read(cc, addr, 2); + struct ao_hex_image *hex = ao_self_read(cc, addr, 2); uint16_t v; uint8_t *data; @@ -101,7 +101,7 @@ get_uint16_cc(struct cc_usb *cc, uint32_t addr) static uint32_t get_uint32_cc(struct cc_usb *cc, uint32_t addr) { - struct hex_image *hex = ao_self_read(cc, addr, 4); + struct ao_hex_image *hex = ao_self_read(cc, addr, 4); uint32_t v; uint8_t *data; @@ -281,7 +281,7 @@ main (int argc, char **argv) int c; stlink_t *sl = NULL; int was_flashed = 0; - struct hex_image *load; + struct ao_hex_image *load; int tries; struct cc_usb *cc = NULL; int use_stlink = 0; @@ -329,10 +329,10 @@ main (int argc, char **argv) usage(argv[0]); if (ends_with (filename, ".elf")) { - load = ao_load_elf(filename); + load = ao_load_elf(filename, ao_symbols, ao_num_symbols); } else if (ends_with (filename, ".ihx")) { int i; - load = ccdbg_hex_load(filename); + load = ao_hex_load(filename); for (i = 0; i < ao_num_symbols; i++) ao_symbols[i].addr = ao_symbols[i].default_addr; } else diff --git a/ao-tools/ao-stmload/ao-stmload.h b/ao-tools/ao-stmload/ao-stmload.h index 98884535..28c2dda4 100644 --- a/ao-tools/ao-stmload/ao-stmload.h +++ b/ao-tools/ao-stmload/ao-stmload.h @@ -18,16 +18,11 @@ #ifndef _AO_STMLOAD_H_ #define _AO_STMLOAD_H_ -struct sym { - unsigned addr; - unsigned default_addr; - char *name; - int required; -}; +#include "ao-elf.h" #define AO_BOOT_APPLICATION_BASE 0x08001000 -extern struct sym ao_symbols[]; +extern struct ao_elf_sym ao_symbols[]; extern int ao_num_symbols; extern int ao_num_required_symbols; @@ -38,11 +33,11 @@ ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]); void ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]); -struct hex_image * +struct ao_hex_image * ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length); int -ao_self_write(struct cc_usb *cc, struct hex_image *image); +ao_self_write(struct cc_usb *cc, struct ao_hex_image *image); extern int ao_self_verbose; diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index fd4dab25..868b64f1 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -11,7 +11,6 @@ libao_tools_a_SOURCES = \ ccdbg-debug.h \ ccdbg-flash.c \ ccdbg.h \ - ccdbg-hex.c \ ccdbg-io.c \ ccdbg-manual.c \ ccdbg-memory.c \ @@ -40,4 +39,8 @@ libao_tools_a_SOURCES = \ i0.c \ chbevl.c \ mconf.h \ - cephes.h + cephes.h \ + ao-hex.c \ + ao-hex.h \ + ao-elf.c \ + ao-elf.h diff --git a/ao-tools/lib/ao-elf.c b/ao-tools/lib/ao-elf.c new file mode 100644 index 00000000..932dc853 --- /dev/null +++ b/ao-tools/lib/ao-elf.c @@ -0,0 +1,293 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ao-elf.h" +#include "ao-hex.h" + +/* + * Look through the Elf file for symbols that can be adjusted before + * the image is written to the device + */ +static bool +find_symbols (Elf *e, struct ao_elf_sym *symbols, int num_symbols) +{ + Elf_Scn *scn; + Elf_Data *symbol_data = NULL; + GElf_Shdr shdr; + GElf_Sym sym; + int i, symbol_count, s; + char *symbol_name; + size_t shstrndx; + + if (elf_getshdrstrndx(e, &shstrndx) < 0) + return false; + + /* + * Find the symbols + */ + + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + + if (gelf_getshdr(scn, &shdr) != &shdr) + return false; + + 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 false; + + 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 (symbols[s].name, symbol_name)) { + symbols[s].addr = sym.st_value; + symbols[s].found = true; + } + } + for (s = 0; s < num_symbols; s++) + if (symbols[s].required && !symbols[s].found) + return false; + return true; +} + +static uint32_t +round4(uint32_t a) { + return (a + 3) & ~3; +} + +static struct ao_hex_image * +new_load (uint32_t addr, uint32_t len) +{ + struct ao_hex_image *new; + + len = round4(len); + new = calloc (1, sizeof (struct ao_hex_image) + len); + if (!new) + abort(); + + new->address = addr; + new->length = len; + return new; +} + +static void +load_paste(struct ao_hex_image *into, struct ao_hex_image *from) +{ + if (from->address < into->address || into->address + into->length < from->address + from->length) + abort(); + + memcpy(into->data + from->address - into->address, from->data, from->length); +} + +/* + * Make a new load structure large enough to hold the old one and + * the new data + */ +static struct ao_hex_image * +expand_load(struct ao_hex_image *from, uint32_t address, uint32_t length) +{ + struct ao_hex_image *new; + + if (from) { + uint32_t from_last = from->address + from->length; + uint32_t last = address + length; + + if (address > from->address) + address = from->address; + if (last < from_last) + last = from_last; + + length = last - address; + + if (address == from->address && length == from->length) + return from; + } + new = new_load(address, length); + 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 + */ +static struct ao_hex_image * +load_write(struct ao_hex_image *from, uint32_t address, uint32_t length, void *data) +{ + struct ao_hex_image *new; + + new = expand_load(from, address, length); + memcpy(new->data + address - new->address, data, length); + return new; +} + +/* + * Construct a large in-memory block for all + * of the loaded sections of the program + */ +static struct ao_hex_image * +get_load(Elf *e) +{ + Elf_Scn *scn; + size_t shstrndx; + GElf_Shdr shdr; + Elf_Data *data; + size_t nphdr; + size_t p; + GElf_Phdr phdr; + GElf_Addr sh_paddr; + struct ao_hex_image *load = NULL; + char *section_name; + size_t nshdr; + size_t s; + + if (elf_getshdrstrndx(e, &shstrndx) < 0) + return 0; + + if (elf_getphdrnum(e, &nphdr) < 0) + return 0; + + if (elf_getshdrnum(e, &nshdr) < 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); + + if (phdr.p_type != PT_LOAD) + continue; + + /* Get the associated file section */ + +#if 0 + printf ("offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", + (uint32_t) phdr.p_offset, + (uint32_t) phdr.p_vaddr, + (uint32_t) phdr.p_paddr, + (uint32_t) phdr.p_filesz, + (uint32_t) phdr.p_memsz); +#endif + + for (s = 0; s < nshdr; s++) { + scn = elf_getscn(e, s); + + if (!scn) { + printf ("getscn failed\n"); + abort(); + } + if (gelf_getshdr(scn, &shdr) != &shdr) { + printf ("gelf_getshdr failed\n"); + abort(); + } + + section_name = elf_strptr(e, shstrndx, shdr.sh_name); + + if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { + + if (shdr.sh_size == 0) + continue; + + sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; + + printf ("\tsize %08x rom %08x exec %08x %s\n", + (uint32_t) shdr.sh_size, + (uint32_t) sh_paddr, + (uint32_t) shdr.sh_addr, + section_name); + + data = elf_getdata(scn, NULL); + + /* Write the section data into the memory block */ + load = load_write(load, sh_paddr, shdr.sh_size, data->d_buf); + } + } + } + return load; +} + +/* + * Open the specified ELF file and + * check for the symbols we need + */ + +struct ao_hex_image * +ao_load_elf(char *name, struct ao_elf_sym *symbols, int num_symbols) +{ + int fd; + Elf *e; + size_t shstrndx; + struct ao_hex_image *image; + + if (elf_version(EV_CURRENT) == EV_NONE) + return NULL; + + fd = open(name, O_RDONLY, 0); + + if (fd < 0) + return NULL; + + e = elf_begin(fd, ELF_C_READ, NULL); + + if (!e) + return NULL; + + if (elf_kind(e) != ELF_K_ELF) + return NULL; + + if (elf_getshdrstrndx(e, &shstrndx) != 0) + return NULL; + + if (!find_symbols(e, symbols, num_symbols)) { + fprintf (stderr, "Cannot find required symbols\n"); + return NULL; + } + + image = get_load(e); + if (!image) { + fprintf (stderr, "Cannot create memory image from file\n"); + return NULL; + } + + return image; +} diff --git a/ao-tools/lib/ao-elf.h b/ao-tools/lib/ao-elf.h new file mode 100644 index 00000000..f3a2358c --- /dev/null +++ b/ao-tools/lib/ao-elf.h @@ -0,0 +1,39 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_ELF_H_ +#define _AO_ELF_H_ + +#include +#include +#include "ao-hex.h" + +struct ao_elf_sym { + unsigned addr; + unsigned default_addr; + char *name; + bool required; + bool found; +}; + +struct ao_hex_image * +ao_load_elf(char *name, struct ao_elf_sym *symbols, int num_symbols); + +int +ao_elf_find_symbols (Elf *e, struct ao_elf_sym *symbols, int num_symbols); + +#endif /* _AO_ELF_H_ */ diff --git a/ao-tools/lib/ao-hex.c b/ao-tools/lib/ao-hex.c new file mode 100644 index 00000000..85acc07f --- /dev/null +++ b/ao-tools/lib/ao-hex.c @@ -0,0 +1,384 @@ +/* + * Copyright © 2008 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include +#include +#include +#include "ao-hex.h" + +struct ao_hex_input { + FILE *file; + int line; + char *name; +}; + +enum ao_hex_read_state { + read_marker, + read_length, + read_address, + read_type, + read_data, + read_checksum, + read_newline, + read_white, + read_done, +}; + + +static void +ao_hex_error(struct ao_hex_input *input, char *format, ...) +{ + va_list ap; + + va_start(ap, format); + fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); + vfprintf(stderr, format, ap); + fprintf(stderr, "\n"); + va_end(ap); +} + +static void +ao_hex_free(struct ao_hex_record *record) +{ + if (!record) return; + free(record); +} + +static struct ao_hex_record * +ao_hex_alloc(uint8_t length) +{ + struct ao_hex_record *record; + + record = calloc(1, sizeof(struct ao_hex_record) + length); + record->length = length; + return record; +} + +static int +ishex(char c) +{ + return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); +} + +static int +fromhex(char c) +{ + if (isdigit(c)) + return c - '0'; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + abort(); + return 0; +} + +static uint8_t +ao_hex_checksum(struct ao_hex_record *record) +{ + uint8_t checksum = 0; + int i; + + checksum += record->length; + checksum += record->address >> 8; + checksum += record->address & 0xff; + checksum += record->type; + for (i = 0; i < record->length; i++) + checksum += record->data[i]; + return -checksum; +} + +static struct ao_hex_record * +ao_hex_read_record(struct ao_hex_input *input) +{ + struct ao_hex_record *record = NULL; + enum ao_hex_read_state state = read_marker; + char c; + int nhexbytes; + uint32_t hex; + uint32_t ndata; + uint8_t checksum; + + while (state != read_done) { + c = getc(input->file); + if (c == EOF && state != read_white) { + ao_hex_error(input, "Unexpected EOF"); + goto bail; + } + if (c == ' ') + continue; + if (c == '\n') + input->line++; + switch (state) { + case read_marker: + if (c != ':') { + ao_hex_error(input, "Missing ':'"); + goto bail; + } + state = read_length; + nhexbytes = 2; + hex = 0; + break; + case read_length: + case read_address: + case read_type: + case read_data: + case read_checksum: + if (!ishex(c)) { + ao_hex_error(input, "Non-hex char '%c'", + c); + goto bail; + } + hex = hex << 4 | fromhex(c); + --nhexbytes; + if (nhexbytes != 0) + break; + + switch (state) { + case read_length: + record = ao_hex_alloc(hex); + if (!record) { + ao_hex_error(input, "Out of memory"); + goto bail; + } + state = read_address; + nhexbytes = 4; + break; + case read_address: + record->address = hex; + state = read_type; + nhexbytes = 2; + break; + case read_type: + record->type = hex; + state = read_data; + nhexbytes = 2; + ndata = 0; + break; + case read_data: + record->data[ndata] = hex; + ndata++; + nhexbytes = 2; + break; + case read_checksum: + record->checksum = hex; + state = read_newline; + break; + default: + break; + } + if (state == read_data) + if (ndata == record->length) { + nhexbytes = 2; + state = read_checksum; + } + hex = 0; + break; + case read_newline: + if (c != '\n' && c != '\r') { + ao_hex_error(input, "Missing newline"); + goto bail; + } + state = read_white; + break; + case read_white: + if (!isspace(c)) { + if (c == '\n') + input->line--; + if (c != EOF) + ungetc(c, input->file); + state = read_done; + } + break; + case read_done: + break; + } + } + checksum = ao_hex_checksum(record); + if (checksum != record->checksum) { + ao_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", + record->checksum, checksum); + goto bail; + } + return record; + +bail: + ao_hex_free(record); + return NULL; +} + +void +ao_hex_file_free(struct ao_hex_file *hex) +{ + int i; + + if (!hex) + return; + for (i = 0; i < hex->nrecord; i++) + ao_hex_free(hex->records[i]); + free(hex); +} + +struct ao_hex_file * +ao_hex_file_read(FILE *file, char *name) +{ + struct ao_hex_input input; + struct ao_hex_file *hex = NULL, *newhex; + struct ao_hex_record *record; + int srecord = 1; + int done = 0; + + hex = calloc(sizeof (struct ao_hex_file) + sizeof (struct ao_hex_record *), 1); + input.name = name; + input.line = 1; + input.file = file; + while (!done) { + record = ao_hex_read_record(&input); + if (!record) + goto bail; + if (hex->nrecord == srecord) { + srecord *= 2; + newhex = realloc(hex, + sizeof (struct ao_hex_file) + + srecord * sizeof (struct ao_hex_record *)); + if (!newhex) + goto bail; + hex = newhex; + } + hex->records[hex->nrecord++] = record; + if (record->type == AO_HEX_RECORD_EOF) + done = 1; + } + return hex; + +bail: + ao_hex_file_free(hex); + return NULL; +} + +struct ao_hex_image * +ao_hex_image_create(struct ao_hex_file *hex) +{ + struct ao_hex_image *image; + struct ao_hex_record *record; + int i; + uint32_t addr; + uint32_t base, bound; + uint32_t offset; + uint32_t extended_addr; + + int length; + + base = 0xffffffff; + bound = 0x0; + extended_addr = 0; + for (i = 0; i < hex->nrecord; i++) { + uint32_t r_bound; + record = hex->records[i]; + switch (record->type) { + case 0: + addr = extended_addr + record->address; + r_bound = addr + record->length; + if (addr < base) + base = addr; + if (r_bound > bound) + bound = r_bound; + break; + case 1: + break; + case 2: + if (record->length != 2) + return NULL; + extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; + break; + case 4: + if (record->length != 2) + return NULL; + extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + break; + } + + } + length = bound - base; + image = calloc(sizeof(struct ao_hex_image) + length, 1); + if (!image) + return NULL; + image->address = base; + image->length = length; + memset(image->data, 0xff, length); + extended_addr = 0; + for (i = 0; i < hex->nrecord; i++) { + record = hex->records[i]; + switch (record->type) { + case 0: + addr = extended_addr + record->address; + offset = addr - base; + memcpy(image->data + offset, record->data, record->length); + break; + case 1: + break; + case 2: + extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; + break; + case 4: + extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + break; + } + } + return image; +} + +void +ao_hex_image_free(struct ao_hex_image *image) +{ + free(image); +} + +int +ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b) +{ + if (a->length != b->length) + return 0; + if (memcmp(a->data, b->data, a->length) != 0) + return 0; + return 1; +} + +struct ao_hex_image * +ao_hex_load(char *filename) +{ + FILE *file; + struct ao_hex_file *hex_file; + struct ao_hex_image *hex_image; + + file = fopen (filename, "r"); + if (!file) + return 0; + + hex_file = ao_hex_file_read(file, filename); + fclose(file); + if (!hex_file) + return 0; + hex_image = ao_hex_image_create(hex_file); + if (!hex_image) + return 0; + ao_hex_file_free(hex_file); + return hex_image; +} diff --git a/ao-tools/lib/ao-hex.h b/ao-tools/lib/ao-hex.h new file mode 100644 index 00000000..8528eb45 --- /dev/null +++ b/ao-tools/lib/ao-hex.h @@ -0,0 +1,68 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_HEX_H_ +#define _AO_HEX_H_ + +#include + +#define AO_HEX_RECORD_NORMAL 0x00 +#define AO_HEX_RECORD_EOF 0x01 +#define AO_HEX_RECORD_EXTENDED_ADDRESS_4 0x02 +#define AO_HEX_RECORD_EXTENDED_ADDRESS_8 0x04 +#define AO_HEX_RECORD_SYMBOL 0xfe + +/* Intel hex file format data + */ +struct ao_hex_record { + uint8_t length; + uint16_t address; + uint8_t type; + uint8_t checksum; + uint8_t data[0]; +}; + +struct ao_hex_file { + int nrecord; + struct ao_hex_record *records[0]; +}; + +struct ao_hex_image { + uint32_t address; + uint32_t length; + uint8_t data[0]; +}; + +struct ao_hex_file * +ao_hex_file_read(FILE *file, char *name); + +void +ao_hex_file_free(struct ao_hex_file *hex); + +struct ao_hex_image * +ao_hex_image_create(struct ao_hex_file *hex); + +void +ao_hex_image_free(struct ao_hex_image *image); + +struct ao_hex_image * +ao_hex_load(char *filename); + +int +ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b); + +#endif /* _AO_HEX_H_ */ diff --git a/ao-tools/lib/ccdbg-command.c b/ao-tools/lib/ccdbg-command.c index a1002879..55c912b2 100644 --- a/ao-tools/lib/ccdbg-command.c +++ b/ao-tools/lib/ccdbg-command.c @@ -157,7 +157,7 @@ ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc) } uint8_t -ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image) +ccdbg_execute_hex_image(struct ccdbg *dbg, struct ao_hex_image *image) { uint16_t pc; uint8_t status; diff --git a/ao-tools/lib/ccdbg-flash.c b/ao-tools/lib/ccdbg-flash.c index 1b46870b..44eb952b 100644 --- a/ao-tools/lib/ccdbg-flash.c +++ b/ao-tools/lib/ccdbg-flash.c @@ -238,7 +238,7 @@ ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock) #endif uint8_t -ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) +ccdbg_flash_hex_image(struct ccdbg *dbg, struct ao_hex_image *image) { uint16_t flash_prog; uint16_t flash_len; diff --git a/ao-tools/lib/ccdbg-hex.c b/ao-tools/lib/ccdbg-hex.c deleted file mode 100644 index 184b4e3b..00000000 --- a/ao-tools/lib/ccdbg-hex.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright © 2008 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" -#include -#include - -struct hex_input { - FILE *file; - int line; - char *name; -}; - -enum hex_read_state { - read_marker, - read_length, - read_address, - read_type, - read_data, - read_checksum, - read_newline, - read_white, - read_done, -}; - - -static void -ccdbg_hex_error(struct hex_input *input, char *format, ...) -{ - va_list ap; - - va_start(ap, format); - fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); - vfprintf(stderr, format, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -static void -ccdbg_hex_free(struct hex_record *record) -{ - if (!record) return; - free(record); -} - -static struct hex_record * -ccdbg_hex_alloc(uint8_t length) -{ - struct hex_record *record; - - record = calloc(1, sizeof(struct hex_record) + length); - record->length = length; - return record; -} - -static int -ishex(char c) -{ - return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); -} - -static int -fromhex(char c) -{ - if (isdigit(c)) - return c - '0'; - if ('a' <= c && c <= 'f') - return c - 'a' + 10; - if ('A' <= c && c <= 'F') - return c - 'A' + 10; - abort(); - return 0; -} - -static uint8_t -ccdbg_hex_checksum(struct hex_record *record) -{ - uint8_t checksum = 0; - int i; - - checksum += record->length; - checksum += record->address >> 8; - checksum += record->address & 0xff; - checksum += record->type; - for (i = 0; i < record->length; i++) - checksum += record->data[i]; - return -checksum; -} - -static struct hex_record * -ccdbg_hex_read_record(struct hex_input *input) -{ - struct hex_record *record = NULL; - enum hex_read_state state = read_marker; - char c; - int nhexbytes; - uint32_t hex; - uint32_t ndata; - uint8_t checksum; - - while (state != read_done) { - c = getc(input->file); - if (c == EOF && state != read_white) { - ccdbg_hex_error(input, "Unexpected EOF"); - goto bail; - } - if (c == ' ') - continue; - if (c == '\n') - input->line++; - switch (state) { - case read_marker: - if (c != ':') { - ccdbg_hex_error(input, "Missing ':'"); - goto bail; - } - state = read_length; - nhexbytes = 2; - hex = 0; - break; - case read_length: - case read_address: - case read_type: - case read_data: - case read_checksum: - if (!ishex(c)) { - ccdbg_hex_error(input, "Non-hex char '%c'", - c); - goto bail; - } - hex = hex << 4 | fromhex(c); - --nhexbytes; - if (nhexbytes != 0) - break; - - switch (state) { - case read_length: - record = ccdbg_hex_alloc(hex); - if (!record) { - ccdbg_hex_error(input, "Out of memory"); - goto bail; - } - state = read_address; - nhexbytes = 4; - break; - case read_address: - record->address = hex; - state = read_type; - nhexbytes = 2; - break; - case read_type: - record->type = hex; - state = read_data; - nhexbytes = 2; - ndata = 0; - break; - case read_data: - record->data[ndata] = hex; - ndata++; - nhexbytes = 2; - break; - case read_checksum: - record->checksum = hex; - state = read_newline; - break; - default: - break; - } - if (state == read_data) - if (ndata == record->length) { - nhexbytes = 2; - state = read_checksum; - } - hex = 0; - break; - case read_newline: - if (c != '\n' && c != '\r') { - ccdbg_hex_error(input, "Missing newline"); - goto bail; - } - state = read_white; - break; - case read_white: - if (!isspace(c)) { - if (c == '\n') - input->line--; - if (c != EOF) - ungetc(c, input->file); - state = read_done; - } - break; - case read_done: - break; - } - } - checksum = ccdbg_hex_checksum(record); - if (checksum != record->checksum) { - ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", - record->checksum, checksum); - goto bail; - } - return record; - -bail: - ccdbg_hex_free(record); - return NULL; -} - -void -ccdbg_hex_file_free(struct hex_file *hex) -{ - int i; - - if (!hex) - return; - for (i = 0; i < hex->nrecord; i++) - ccdbg_hex_free(hex->records[i]); - free(hex); -} - -struct hex_file * -ccdbg_hex_file_read(FILE *file, char *name) -{ - struct hex_input input; - struct hex_file *hex = NULL, *newhex; - struct hex_record *record; - int srecord = 1; - int done = 0; - - hex = calloc(sizeof (struct hex_file) + sizeof (struct hex_record *), 1); - input.name = name; - input.line = 1; - input.file = file; - while (!done) { - record = ccdbg_hex_read_record(&input); - if (!record) - goto bail; - if (hex->nrecord == srecord) { - srecord *= 2; - newhex = realloc(hex, - sizeof (struct hex_file) + - srecord * sizeof (struct hex_record *)); - if (!newhex) - goto bail; - hex = newhex; - } - hex->records[hex->nrecord++] = record; - if (record->type == HEX_RECORD_EOF) - done = 1; - } - return hex; - -bail: - ccdbg_hex_file_free(hex); - return NULL; -} - -struct hex_image * -ccdbg_hex_image_create(struct hex_file *hex) -{ - struct hex_image *image; - struct hex_record *record; - int i; - uint32_t addr; - uint32_t base, bound; - uint32_t offset; - uint32_t extended_addr; - - int length; - - base = 0xffffffff; - bound = 0x0; - extended_addr = 0; - for (i = 0; i < hex->nrecord; i++) { - uint32_t r_bound; - record = hex->records[i]; - switch (record->type) { - case 0: - addr = extended_addr + record->address; - r_bound = addr + record->length; - if (addr < base) - base = addr; - if (r_bound > bound) - bound = r_bound; - break; - case 1: - break; - case 2: - if (record->length != 2) - return NULL; - extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; - break; - case 4: - if (record->length != 2) - return NULL; - extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; - break; - } - - } - length = bound - base; - image = calloc(sizeof(struct hex_image) + length, 1); - if (!image) - return NULL; - image->address = base; - image->length = length; - memset(image->data, 0xff, length); - extended_addr = 0; - for (i = 0; i < hex->nrecord; i++) { - record = hex->records[i]; - switch (record->type) { - case 0: - addr = extended_addr + record->address; - offset = addr - base; - memcpy(image->data + offset, record->data, record->length); - break; - case 1: - break; - case 2: - extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; - break; - case 4: - extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; - break; - } - } - return image; -} - -void -ccdbg_hex_image_free(struct hex_image *image) -{ - free(image); -} - -int -ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b) -{ - if (a->length != b->length) - return 0; - if (memcmp(a->data, b->data, a->length) != 0) - return 0; - return 1; -} - -struct hex_image * -ccdbg_hex_load(char *filename) -{ - FILE *file; - struct hex_file *hex_file; - struct hex_image *hex_image; - - file = fopen (filename, "r"); - if (!file) - return 0; - - hex_file = ccdbg_hex_file_read(file, filename); - fclose(file); - if (!hex_file) - return 0; - hex_image = ccdbg_hex_image_create(hex_file); - if (!hex_image) - return 0; - ccdbg_hex_file_free(hex_file); - return hex_image; -} diff --git a/ao-tools/lib/ccdbg-memory.c b/ao-tools/lib/ccdbg-memory.c index 554ac637..04059e2e 100644 --- a/ao-tools/lib/ccdbg-memory.c +++ b/ao-tools/lib/ccdbg-memory.c @@ -117,18 +117,18 @@ ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte) } uint8_t -ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset) +ccdbg_write_hex_image(struct ccdbg *dbg, struct ao_hex_image *image, uint16_t offset) { ccdbg_write_memory(dbg, image->address + offset, image->data, image->length); return 0; } -struct hex_image * +struct ao_hex_image * ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length) { - struct hex_image *image; + struct ao_hex_image *image; - image = calloc(sizeof(struct hex_image) + length, 1); + image = calloc(sizeof(struct ao_hex_image) + length, 1); image->address = address; image->length = length; memset(image->data, 0xff, length); diff --git a/ao-tools/lib/ccdbg-rom.c b/ao-tools/lib/ccdbg-rom.c index 71bed220..6e8e7378 100644 --- a/ao-tools/lib/ccdbg-rom.c +++ b/ao-tools/lib/ccdbg-rom.c @@ -19,10 +19,10 @@ #include "ccdbg.h" uint8_t -ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom) +ccdbg_set_rom(struct ccdbg *dbg, struct ao_hex_image *rom) { if (dbg->rom) - ccdbg_hex_image_free(dbg->rom); + ao_hex_image_free(dbg->rom); dbg->rom = rom; return 0; } @@ -30,7 +30,7 @@ ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom) uint8_t ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes) { - struct hex_image *rom = dbg->rom; + struct ao_hex_image *rom = dbg->rom; if (!rom) return 0; if (addr < rom->address || rom->address + rom->length < addr + nbytes) @@ -42,7 +42,7 @@ uint8_t ccdbg_rom_replace_xmem(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes) { - struct hex_image *rom = dbg->rom; + struct ao_hex_image *rom = dbg->rom; if (!rom) return 0; diff --git a/ao-tools/lib/ccdbg.h b/ao-tools/lib/ccdbg.h index a27ff5d1..b17f289d 100644 --- a/ao-tools/lib/ccdbg.h +++ b/ao-tools/lib/ccdbg.h @@ -33,6 +33,7 @@ #include "ccdbg-debug.h" #include "cc-bitbang.h" #include "cc-usb.h" +#include "ao-hex.h" /* 8051 instructions */ @@ -103,29 +104,9 @@ struct ccdbg { struct cc_bitbang *bb; struct cc_usb *usb; - struct hex_image *rom; + struct ao_hex_image *rom; }; -/* Intel hex file format data - */ -struct hex_record { - uint8_t length; - uint16_t address; - uint8_t type; - uint8_t checksum; - uint8_t data[0]; -}; - -struct hex_file { - int nrecord; - struct hex_record *records[0]; -}; - -struct hex_image { - uint32_t address; - uint32_t length; - uint8_t data[0]; -}; #define CC_STATE_ACC 0x1 #define CC_STATE_PSW 0x2 @@ -139,10 +120,6 @@ struct ccstate { uint8_t sfr[CC_STATE_NSFR]; }; -#define HEX_RECORD_NORMAL 0x00 -#define HEX_RECORD_EOF 0x01 -#define HEX_RECORD_EXTENDED_ADDRESS 0x02 - /* CC1111 debug port commands */ #define CC_CHIP_ERASE 0x14 @@ -234,30 +211,11 @@ uint8_t ccdbg_set_pc(struct ccdbg *dbg, uint16_t pc); uint8_t -ccdbg_execute_hex_image(struct ccdbg *dbg, struct hex_image *image); +ccdbg_execute_hex_image(struct ccdbg *dbg, struct ao_hex_image *image); /* ccdbg-flash.c */ uint8_t -ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image); - -/* ccdbg-hex.c */ -struct hex_file * -ccdbg_hex_file_read(FILE *file, char *name); - -void -ccdbg_hex_file_free(struct hex_file *hex); - -struct hex_image * -ccdbg_hex_image_create(struct hex_file *hex); - -void -ccdbg_hex_image_free(struct hex_image *image); - -struct hex_image * -ccdbg_hex_load(char *filename); - -int -ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b); +ccdbg_flash_hex_image(struct ccdbg *dbg, struct ao_hex_image *image); /* ccdbg-io.c */ struct ccdbg * @@ -304,9 +262,9 @@ uint8_t ccdbg_write_uint8(struct ccdbg *dbg, uint16_t addr, uint8_t byte); uint8_t -ccdbg_write_hex_image(struct ccdbg *dbg, struct hex_image *image, uint16_t offset); +ccdbg_write_hex_image(struct ccdbg *dbg, struct ao_hex_image *image, uint16_t offset); -struct hex_image * +struct ao_hex_image * ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length); uint8_t @@ -317,7 +275,7 @@ ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes); /* ccdbg-rom.c */ uint8_t -ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom); +ccdbg_set_rom(struct ccdbg *dbg, struct ao_hex_image *rom); uint8_t ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes);