From 7b0c1fbccb4ef1ae2ed356292cc8762360532b7f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 8 Dec 2013 19:46:30 -0800 Subject: [PATCH 1/1] altoslib: Add symbols to .ihx files Create a new 0xfe record type to hold the symbols, and append them after the EOF record so that other tools might continue to work. Signed-off-by: Keith Packard --- altoslib/AltosHexfile.java | 90 +++++++++++++++++++++++++++++++++----- altoslib/AltosHexsym.java | 30 +++++++++++++ altoslib/Makefile.am | 2 + 3 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 altoslib/AltosHexsym.java diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java index 90352927..02b08326 100644 --- a/altoslib/AltosHexfile.java +++ b/altoslib/AltosHexfile.java @@ -116,7 +116,7 @@ class HexRecord implements Comparable { return String.format("%04x: %02x (%d)", address, type, data.length); } - public HexRecord(HexFileInputStream input) throws IOException { + public HexRecord(HexFileInputStream input) throws IOException, EOFException { read_state state = read_state.marker; int nhexbytes = 0; int hex = 0; @@ -125,14 +125,16 @@ class HexRecord implements Comparable { while (state != read_state.done) { int c = input.read(); - if (c < 0 && state != read_state.white) + if (c < 0 && state != read_state.white && state != read_state.marker) throw new IOException(String.format("%d: Unexpected EOF", input.line)); if (c == ' ') continue; switch (state) { case marker: + if (c == EOF || c == -1) + throw new EOFException(); if (c != ':') - throw new IOException("Missing ':'"); + throw new IOException(String.format ("Missing ':' (got %x)", c)); state = read_state.length; nhexbytes = 2; hex = 0; @@ -208,25 +210,82 @@ class HexRecord implements Comparable { } public class AltosHexfile { - public int address; - public byte[] data; + public int address; + public byte[] data; + LinkedList symlist = new LinkedList(); public byte get_byte(int a) { return data[a - address]; } + /* CC1111-based products have the romconfig stuff located + * at a fixed address; when the file we load has no symbols, + * assume it is one of those and set the symbols appropriately + */ + final static int ao_romconfig_version_addr = 0xa0; + final static int ao_romconfig_check_addr = 0xa2; + final static int ao_serial_number_addr = 0xa4; + final static int ao_radio_cal_addr = 0xa6; + final static int ao_usb_descriptors_addr = 0xaa; + + static AltosHexsym[] cc_symbols = { + new AltosHexsym("ao_romconfig_version", ao_romconfig_version_addr), + new AltosHexsym("ao_romconfig_check", ao_romconfig_check_addr), + new AltosHexsym("ao_serial_number", ao_serial_number_addr), + new AltosHexsym("ao_radio_cal", ao_radio_cal_addr), + new AltosHexsym("ao_usb_descriptors", ao_usb_descriptors_addr) + }; + + private void add_cc_symbols() { + for (int i = 0; i < cc_symbols.length; i++) + symlist.add(cc_symbols[i]); + } + + public void add_symbol(AltosHexsym symbol) { + symlist.add(symbol); + } + + /* Take symbols from another hexfile and duplicate them here */ + public void add_symbols(AltosHexfile other) { + for (AltosHexsym symbol : other.symlist) + symlist.add(symbol); + } + + public AltosHexsym lookup_symbol(String name) { + if (symlist.isEmpty()) + add_cc_symbols(); + + for (AltosHexsym symbol : symlist) + if (name.equals(symbol.name)) + return symbol; + return null; + } + + private String make_string(byte[] data, int start, int length) { + String s = ""; + for (int i = 0; i < length; i++) + s += (char) data[start + i]; + return s; + } + + public AltosHexfile(byte[] bytes, int offset) { + data = bytes; + address = offset; + } + public AltosHexfile(FileInputStream file) throws IOException { HexFileInputStream input = new HexFileInputStream(file); LinkedList record_list = new LinkedList(); boolean done = false; while (!done) { - HexRecord record = new HexRecord(input); + try { + HexRecord record = new HexRecord(input); - if (record.type == HexRecord.EOF) - done = true; - else record_list.add(record); + } catch (EOFException eof) { + done = true; + } } long extended_addr = 0; @@ -234,9 +293,10 @@ public class AltosHexfile { long bound = 0; boolean set = false; for (HexRecord record : record_list) { + long addr; switch (record.type) { case 0: - long addr = extended_addr + record.address; + addr = extended_addr + record.address; long r_bound = addr + record.data.length; if (!set || addr < base) base = addr; @@ -256,6 +316,14 @@ public class AltosHexfile { throw new IOException("invalid extended segment address record"); extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16; break; + case 0xfe: + String name = make_string(record.data, 0, record.data.length); + addr = extended_addr + record.address; + if (name.startsWith("ao_romconfig")) + System.out.printf ("%08x: %s\n", addr, name); + AltosHexsym s = new AltosHexsym(name, addr); + symlist.add(s); + break; default: throw new IOException ("invalid hex record type"); } @@ -292,6 +360,8 @@ public class AltosHexfile { throw new IOException("invalid extended segment address record"); extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16; break; + case 0xfe: + break; default: throw new IOException ("invalid hex record type"); } diff --git a/altoslib/AltosHexsym.java b/altoslib/AltosHexsym.java new file mode 100644 index 00000000..810a4803 --- /dev/null +++ b/altoslib/AltosHexsym.java @@ -0,0 +1,30 @@ +/* + * 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. + */ + +package org.altusmetrum.altoslib_2; + +public class AltosHexsym { + String name; + long address; + + final static long invalid_addr = 0xffffffff; + + public AltosHexsym(String name, long address) { + this.name = name; + this.address = address; + } +} \ No newline at end of file diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 6d3f3fc4..b95bd071 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -55,6 +55,7 @@ altoslib_JAVA = \ AltosGPSSat.java \ AltosGreatCircle.java \ AltosHexfile.java \ + AltosHexsym.java \ AltosIdle.java \ AltosIdleFetch.java \ AltosIdleMonitor.java \ @@ -68,6 +69,7 @@ altoslib_JAVA = \ AltosMag.java \ AltosMma655x.java \ AltosMs5607.java \ + AltosNoSymbol.java \ AltosParse.java \ AltosPreferences.java \ AltosPreferencesBackend.java \ -- 2.30.2