Unified binfile interface.

This commit is contained in:
Daniel Beer 2010-05-15 15:13:58 +12:00
parent fab96c725d
commit d9e42457f5
11 changed files with 237 additions and 45 deletions

View File

@ -43,7 +43,7 @@ install: mspdebug mspdebug.man
mspdebug: main.o fet.o rf2500.o dis.o uif.o ihex.o elf32.o stab.o util.o \ mspdebug: main.o fet.o rf2500.o dis.o uif.o ihex.o elf32.o stab.o util.o \
bsl.o sim.o symmap.o gdb.o btree.o device.o rtools.o sym.o devcmd.o \ bsl.o sim.o symmap.o gdb.o btree.o device.o rtools.o sym.o devcmd.o \
cproc.o vector.o cproc_util.o expr.o fet_error.o cproc.o vector.o cproc_util.o expr.o fet_error.o binfile.o
$(CC) $(LDFLAGS) -o $@ $^ -lusb $(READLINE_LIBS) $(CC) $(LDFLAGS) -o $@ $^ -lusb $(READLINE_LIBS)
.c.o: .c.o:

108
binfile.c Normal file
View File

@ -0,0 +1,108 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009, 2010 Daniel Beer
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "util.h"
#include "binfile.h"
#include "ihex.h"
#include "elf32.h"
#include "symmap.h"
struct file_format {
int (*check)(FILE *in);
int (*extract)(FILE *in, binfile_imgcb_t cb, void *user_data);
int (*syms)(FILE *in, stab_t stab);
};
static const struct file_format formats[] = {
{
.check = elf32_check,
.extract = elf32_extract,
.syms = elf32_syms
},
{
.check = ihex_check,
.extract = ihex_extract
},
{
.check = symmap_check,
.syms = symmap_syms
}
};
static const struct file_format *identify(FILE *in)
{
int i;
for (i = 0; i < ARRAY_LEN(formats); i++) {
const struct file_format *f = &formats[i];
if (f->check(in) > 0)
return f;
}
return NULL;
}
int binfile_info(FILE *in)
{
const struct file_format *fmt = identify(in);
int flags = 0;
if (fmt) {
if (fmt->extract)
flags |= BINFILE_HAS_TEXT;
if (fmt->syms)
flags |= BINFILE_HAS_SYMS;
}
return flags;
}
int binfile_extract(FILE *in, binfile_imgcb_t cb, void *user_data)
{
const struct file_format *fmt = identify(in);
if (!fmt) {
fprintf(stderr, "binfile: unknown file format\n");
return -1;
}
if (!fmt->extract) {
fprintf(stderr, "binfile: this format contains no code\n");
return -1;
}
return fmt->extract(in, cb, user_data);
}
int binfile_syms(FILE *in, stab_t stab)
{
const struct file_format *fmt = identify(in);
if (!fmt) {
fprintf(stderr, "binfile: unknown file format\n");
return -1;
}
if (!fmt->syms) {
fprintf(stderr, "binfile: this format contains no symbols\n");
return -1;
}
return fmt->syms(in, stab);
}

View File

@ -21,24 +21,32 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include "stab.h" #include "stab.h"
/* Callback for binary image data */ /* Callback for binary image data */
typedef int (*imgfunc_t)(void *user_data, typedef int (*binfile_imgcb_t)(void *user_data,
uint16_t addr, const uint8_t *data, int len); uint16_t addr, const uint8_t *data, int len);
/* Intel HEX file support */ #define BINFILE_HAS_SYMS 0x01
int ihex_check(FILE *in); #define BINFILE_HAS_TEXT 0x02
int ihex_extract(FILE *in, imgfunc_t cb, void *user_data);
/* ELF32 file support */ /* Examine the given file and figure out what it contains. If the file
int elf32_check(FILE *in); * type is unknown, 0 is returned. If an IO error occurs, -1 is
int elf32_extract(FILE *in, imgfunc_t cb, void *user_data); * returned. Otherwise, the return value is a positive integer
int elf32_syms(FILE *in, stab_t stab); * bitmask.
*/
int binfile_info(FILE *in);
/* *.map file support */ /* If possible, extract the text from this file, feeding it in chunks
int symmap_check(FILE *in); * of an indeterminate size to the callback given.
int symmap_syms(FILE *in, stab_t stab); *
* Returns 0 if successful, -1 if an error occurs.
*/
int binfile_extract(FILE *in, binfile_imgcb_t cb, void *user_data);
/* Attempt to load symbols from the file and store them in the given
* symbol table. Returns 0 on success or -1 if an error occurs.
*/
int binfile_syms(FILE *in, stab_t stab);
#endif #endif

View File

@ -533,7 +533,6 @@ static int cmd_prog(cproc_t cp, char **arg)
device_t dev = cproc_device(cp); device_t dev = cproc_device(cp);
stab_t stab = cproc_stab(cp); stab_t stab = cproc_stab(cp);
FILE *in; FILE *in;
int result = 0;
struct prog_data prog; struct prog_data prog;
if (cproc_prompt_abort(cp, CPROC_MODIFY_SYMS)) if (cproc_prompt_abort(cp, CPROC_MODIFY_SYMS))
@ -552,14 +551,14 @@ static int cmd_prog(cproc_t cp, char **arg)
prog_init(&prog, dev); prog_init(&prog, dev);
if (elf32_check(in)) { if (binfile_extract(in, prog_feed, &prog) < 0) {
result = elf32_extract(in, prog_feed, &prog); fclose(in);
return -1;
}
if (binfile_info(in) & BINFILE_HAS_SYMS) {
stab_clear(stab); stab_clear(stab);
elf32_syms(in, stab); binfile_syms(in, stab);
} else if (ihex_check(in)) {
result = ihex_extract(in, prog_feed, &prog);
} else {
fprintf(stderr, "prog: %s: unknown file type\n", *arg);
} }
fclose(in); fclose(in);
@ -573,7 +572,7 @@ static int cmd_prog(cproc_t cp, char **arg)
} }
cproc_unmodify(cp, CPROC_MODIFY_SYMS); cproc_unmodify(cp, CPROC_MODIFY_SYMS);
return result; return 0;
} }
static const struct cproc_command commands[] = { static const struct cproc_command commands[] = {

View File

@ -24,7 +24,7 @@
#else #else
#include <elf.h> #include <elf.h>
#endif #endif
#include "binfile.h" #include "elf32.h"
#ifndef EM_MSP430 #ifndef EM_MSP430
#define EM_MSP430 0x69 #define EM_MSP430 0x69
@ -136,7 +136,7 @@ static uint32_t file_to_phys(struct elf32_info *info, uint32_t v)
} }
static int feed_section(struct elf32_info *info, static int feed_section(struct elf32_info *info,
FILE *in, int offset, int size, imgfunc_t cb, FILE *in, int offset, int size, binfile_imgcb_t cb,
void *user_data) void *user_data)
{ {
uint8_t buf[1024]; uint8_t buf[1024];
@ -186,7 +186,7 @@ static int read_all(struct elf32_info *info, FILE *in)
return 0; return 0;
} }
int elf32_extract(FILE *in, imgfunc_t cb, void *user_data) int elf32_extract(FILE *in, binfile_imgcb_t cb, void *user_data)
{ {
struct elf32_info info; struct elf32_info info;
int i; int i;

28
elf32.h Normal file
View File

@ -0,0 +1,28 @@
/* MSPDebug - debugging tool for the eZ430
* Copyright (C) 2009, 2010 Daniel Beer
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ELF32_H_
#define ELF32_H_
#include "binfile.h"
int elf32_check(FILE *in);
int elf32_extract(FILE *in, binfile_imgcb_t cb, void *user_data);
int elf32_syms(FILE *in, stab_t stab);
#endif

6
ihex.c
View File

@ -19,7 +19,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "binfile.h" #include "ihex.h"
int ihex_check(FILE *in) int ihex_check(FILE *in)
{ {
@ -27,7 +27,7 @@ int ihex_check(FILE *in)
return fgetc(in) == ':'; return fgetc(in) == ':';
} }
static int feed_line(FILE *in, uint8_t *data, int nbytes, imgfunc_t cb, static int feed_line(FILE *in, uint8_t *data, int nbytes, binfile_imgcb_t cb,
void *user_data) void *user_data)
{ {
uint8_t cksum = 0; uint8_t cksum = 0;
@ -52,7 +52,7 @@ static int feed_line(FILE *in, uint8_t *data, int nbytes, imgfunc_t cb,
data + 4, nbytes - 5); data + 4, nbytes - 5);
} }
int ihex_extract(FILE *in, imgfunc_t cb, void *user_data) int ihex_extract(FILE *in, binfile_imgcb_t cb, void *user_data)
{ {
char buf[128]; char buf[128];
int lno = 0; int lno = 0;

27
ihex.h Normal file
View File

@ -0,0 +1,27 @@
/* MSPDebug - debugging tool for the eZ430
* Copyright (C) 2009, 2010 Daniel Beer
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef IHEX_H_
#define IHEX_H_
#include "binfile.h"
int ihex_check(FILE *in);
int ihex_extract(FILE *in, binfile_imgcb_t cb, void *user_data);
#endif

25
sym.c
View File

@ -57,7 +57,6 @@ static int cmd_sym_load_add(cproc_t cp, int clear, char **arg)
{ {
stab_t stab = cproc_stab(cp); stab_t stab = cproc_stab(cp);
FILE *in; FILE *in;
int result = 0;
if (clear && cproc_prompt_abort(cp, CPROC_MODIFY_SYMS)) if (clear && cproc_prompt_abort(cp, CPROC_MODIFY_SYMS))
return 0; return 0;
@ -68,24 +67,20 @@ static int cmd_sym_load_add(cproc_t cp, int clear, char **arg)
return -1; return -1;
} }
if (clear) if (clear) {
stab_clear(stab); stab_clear(stab);
cproc_unmodify(cp, CPROC_MODIFY_SYMS);
} else {
cproc_modify(cp, CPROC_MODIFY_SYMS);
}
if (elf32_check(in)) if (binfile_syms(in, stab) < 0) {
result = elf32_syms(in, stab); fclose(in);
else if (symmap_check(in)) return -1;
result = symmap_syms(in, stab); }
else
fprintf(stderr, "sym: %s: unknown file type\n", *arg);
fclose(in); fclose(in);
return 0;
if (clear)
cproc_unmodify(cp, CPROC_MODIFY_SYMS);
else
cproc_modify(cp, CPROC_MODIFY_SYMS);
return result;
} }
static int savemap_cb(void *user_data, const char *name, uint16_t value) static int savemap_cb(void *user_data, const char *name, uint16_t value)

View File

@ -19,7 +19,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "binfile.h" #include "symmap.h"
int symmap_check(FILE *in) int symmap_check(FILE *in)
{ {

27
symmap.h Normal file
View File

@ -0,0 +1,27 @@
/* MSPDebug - debugging tool for the eZ430
* Copyright (C) 2009, 2010 Daniel Beer
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef SYMMAP_H_
#define SYMMAP_H_
#include "binfile.h"
int symmap_check(FILE *in);
int symmap_syms(FILE *in, stab_t stab);
#endif