bug #34518: loading intel hex files > 64k using record-type 4

(Extended Linear Address Record)

Replace the change from r928 (handling of 0x8000000 offset in AVR32
files) by a completely different logic that no longer breaks hex files
for other devices starting with an offset; also apply a similar change
to S-record files, as well as when writing files.



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1017 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
joerg_wunsch 2011-10-10 13:42:08 +00:00
parent 44c650220a
commit 941b2cd4d0
3 changed files with 67 additions and 32 deletions

View File

@ -1,3 +1,14 @@
2011-10-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
bug #34518: loading intel hex files > 64k using record-type 4
(Extended Linear Address Record)
fileio.c: Replace the change from r928 (handling of 0x8000000
offset in AVR32 files) by a completely different logic that no
longer breaks hex files for other devices starting with an
offset; also apply a similar change to S-record files, as well
as when writing files.
fileio.c: (Ditto.)
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* avrftdi.c: Remove stray printf()s by fprintf(stderr)

View File

@ -52,14 +52,14 @@ static int b2ihex(unsigned char * inbuf, int bufsize,
char * outfile, FILE * outf);
static int ihex2b(char * infile, FILE * inf,
AVRMEM * mem, int bufsize);
AVRMEM * mem, int bufsize, unsigned int fileoffset);
static int b2srec(unsigned char * inbuf, int bufsize,
int recsize, int startaddr,
char * outfile, FILE * outf);
static int srec2b(char * infile, FILE * inf,
AVRMEM * mem, int bufsize);
AVRMEM * mem, int bufsize, unsigned int fileoffset);
static int ihex_readrec(struct ihexrec * ihex, char * rec);
@ -262,21 +262,20 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
*
* */
static int ihex2b(char * infile, FILE * inf,
AVRMEM * mem, int bufsize)
AVRMEM * mem, int bufsize, unsigned int fileoffset)
{
char buffer [ MAX_LINE_LEN ];
unsigned int nextaddr, baseaddr, maxaddr, offsetaddr;
unsigned int nextaddr, baseaddr, maxaddr;
int i;
int lineno;
int len;
struct ihexrec ihex;
int rc;
lineno = 0;
baseaddr = 0;
maxaddr = 0;
offsetaddr = 0;
nextaddr = 0;
lineno = 0;
baseaddr = 0;
maxaddr = 0;
nextaddr = 0;
while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
lineno++;
@ -301,23 +300,29 @@ static int ihex2b(char * infile, FILE * inf,
switch (ihex.rectyp) {
case 0: /* data record */
nextaddr = ihex.loadofs + baseaddr;
if ((nextaddr + ihex.reclen) > (bufsize+offsetaddr)) {
if (fileoffset != 0 && baseaddr < fileoffset) {
fprintf(stderr,
"%s: ERROR: address 0x%04x out of range (below fileoffset 0x%x) at line %d of %s\n",
progname, baseaddr, fileoffset, lineno, infile);
return -1;
}
nextaddr = ihex.loadofs + baseaddr - fileoffset;
if (nextaddr + ihex.reclen > bufsize) {
fprintf(stderr,
"%s: ERROR: address 0x%04x out of range at line %d of %s\n",
progname, nextaddr+ihex.reclen, lineno, infile);
return -1;
}
for (i=0; i<ihex.reclen; i++) {
mem->buf[nextaddr+i-offsetaddr] = ihex.data[i];
mem->tags[nextaddr+i-offsetaddr] = TAG_ALLOCATED;
mem->buf[nextaddr+i] = ihex.data[i];
mem->tags[nextaddr+i] = TAG_ALLOCATED;
}
if (nextaddr+ihex.reclen > maxaddr)
maxaddr = nextaddr+ihex.reclen;
break;
case 1: /* end of file record */
return maxaddr-offsetaddr;
return maxaddr;
break;
case 2: /* extended segment address record */
@ -330,7 +335,6 @@ static int ihex2b(char * infile, FILE * inf,
case 4: /* extended linear address record */
baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 16;
if(nextaddr == 0) offsetaddr = baseaddr; // if provided before any data, then remember it
break;
case 5: /* start linear address record */
@ -353,7 +357,7 @@ static int ihex2b(char * infile, FILE * inf,
"file \"%s\"\n",
progname, infile);
return maxaddr-offsetaddr;
return maxaddr;
}
static int b2srec(unsigned char * inbuf, int bufsize,
@ -539,10 +543,10 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
static int srec2b(char * infile, FILE * inf,
AVRMEM * mem, int bufsize)
AVRMEM * mem, int bufsize, unsigned int fileoffset)
{
char buffer [ MAX_LINE_LEN ];
unsigned int nextaddr, baseaddr, maxaddr;
unsigned int nextaddr, maxaddr;
int i;
int lineno;
int len;
@ -554,7 +558,6 @@ static int srec2b(char * infile, FILE * inf,
char * msg = 0;
lineno = 0;
baseaddr = 0;
maxaddr = 0;
reccount = 0;
@ -588,17 +591,17 @@ static int srec2b(char * infile, FILE * inf,
case 0x31: /* S1 - 16 bit address data record */
datarec=1;
msg="%s: ERROR: address 0x%04x out of range at line %d of %s\n";
msg="%s: ERROR: address 0x%04x out of range %sat line %d of %s\n";
break;
case 0x32: /* S2 - 24 bit address data record */
datarec=1;
msg="%s: ERROR: address 0x%06x out of range at line %d of %s\n";
msg="%s: ERROR: address 0x%06x out of range %sat line %d of %s\n";
break;
case 0x33: /* S3 - 32 bit address data record */
datarec=1;
msg="%s: ERROR: address 0x%08x out of range at line %d of %s\n";
msg="%s: ERROR: address 0x%08x out of range %sat line %d of %s\n";
break;
case 0x34: /* S4 - symbol record (LSI extension) */
@ -634,9 +637,17 @@ static int srec2b(char * infile, FILE * inf,
}
if (datarec == 1) {
nextaddr = srec.loadofs + baseaddr;
nextaddr = srec.loadofs;
if (nextaddr < fileoffset) {
fprintf(stderr, msg, progname, nextaddr,
"(below fileoffset) ",
lineno, infile);
return -1;
}
nextaddr -= fileoffset;
if (nextaddr + srec.reclen > bufsize) {
fprintf(stderr, msg, progname, nextaddr+srec.reclen, lineno, infile);
fprintf(stderr, msg, progname, nextaddr+srec.reclen, "",
lineno, infile);
return -1;
}
for (i=0; i<srec.reclen; i++) {
@ -786,14 +797,14 @@ static int fileio_ihex(struct fioparms * fio,
switch (fio->op) {
case FIO_WRITE:
rc = b2ihex(mem->buf, size, 32, 0, filename, f);
rc = b2ihex(mem->buf, size, 32, fio->fileoffset, filename, f);
if (rc < 0) {
return -1;
}
break;
case FIO_READ:
rc = ihex2b(filename, f, mem, size);
rc = ihex2b(filename, f, mem, size, fio->fileoffset);
if (rc < 0)
return -1;
break;
@ -816,14 +827,14 @@ static int fileio_srec(struct fioparms * fio,
switch (fio->op) {
case FIO_WRITE:
rc = b2srec(mem->buf, size, 32, 0, filename, f);
rc = b2srec(mem->buf, size, 32, fio->fileoffset, filename, f);
if (rc < 0) {
return -1;
}
break;
case FIO_READ:
rc = srec2b(filename, f, mem, size);
rc = srec2b(filename, f, mem, size, fio->fileoffset);
if (rc < 0)
return -1;
break;
@ -912,7 +923,8 @@ static int fileio_num(struct fioparms * fio,
}
int fileio_setparms(int op, struct fioparms * fp)
int fileio_setparms(int op, struct fioparms * fp,
struct avrpart * p, AVRMEM * m)
{
fp->op = op;
@ -938,6 +950,19 @@ int fileio_setparms(int op, struct fioparms * fp)
break;
}
/*
* AVR32 devices maintain their load offset within the file itself,
* but AVRDUDE maintains all memory images 0-based.
*/
if ((p->flags & AVRPART_AVR32) != 0)
{
fp->fileoffset = m->offset;
}
else
{
fp->fileoffset = 0;
}
return 0;
}
@ -1032,7 +1057,7 @@ int fileio(int op, char * filename, FILEFMT format,
return -1;
}
rc = fileio_setparms(op, &fio);
rc = fileio_setparms(op, &fio, p, mem);
if (rc < 0)
return -1;

View File

@ -40,6 +40,7 @@ struct fioparms {
char * iodesc;
char * dir;
char * rw;
unsigned int fileoffset;
};
enum {
@ -53,8 +54,6 @@ extern "C" {
char * fmtstr(FILEFMT format);
int fileio_setparms(int op, struct fioparms * fp);
int fileio(int op, char * filename, FILEFMT format,
struct avrpart * p, char * memtype, int size);