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:
parent
57010bf9ba
commit
8770c07d35
11
ChangeLog
11
ChangeLog
|
@ -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>
|
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
* avrftdi.c: Remove stray printf()s by fprintf(stderr)
|
* avrftdi.c: Remove stray printf()s by fprintf(stderr)
|
||||||
|
|
85
fileio.c
85
fileio.c
|
@ -52,14 +52,14 @@ static int b2ihex(unsigned char * inbuf, int bufsize,
|
||||||
char * outfile, FILE * outf);
|
char * outfile, FILE * outf);
|
||||||
|
|
||||||
static int ihex2b(char * infile, FILE * inf,
|
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,
|
static int b2srec(unsigned char * inbuf, int bufsize,
|
||||||
int recsize, int startaddr,
|
int recsize, int startaddr,
|
||||||
char * outfile, FILE * outf);
|
char * outfile, FILE * outf);
|
||||||
|
|
||||||
static int srec2b(char * infile, FILE * inf,
|
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);
|
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,
|
static int ihex2b(char * infile, FILE * inf,
|
||||||
AVRMEM * mem, int bufsize)
|
AVRMEM * mem, int bufsize, unsigned int fileoffset)
|
||||||
{
|
{
|
||||||
char buffer [ MAX_LINE_LEN ];
|
char buffer [ MAX_LINE_LEN ];
|
||||||
unsigned int nextaddr, baseaddr, maxaddr, offsetaddr;
|
unsigned int nextaddr, baseaddr, maxaddr;
|
||||||
int i;
|
int i;
|
||||||
int lineno;
|
int lineno;
|
||||||
int len;
|
int len;
|
||||||
struct ihexrec ihex;
|
struct ihexrec ihex;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
lineno = 0;
|
lineno = 0;
|
||||||
baseaddr = 0;
|
baseaddr = 0;
|
||||||
maxaddr = 0;
|
maxaddr = 0;
|
||||||
offsetaddr = 0;
|
nextaddr = 0;
|
||||||
nextaddr = 0;
|
|
||||||
|
|
||||||
while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
|
while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
|
||||||
lineno++;
|
lineno++;
|
||||||
|
@ -301,23 +300,29 @@ static int ihex2b(char * infile, FILE * inf,
|
||||||
|
|
||||||
switch (ihex.rectyp) {
|
switch (ihex.rectyp) {
|
||||||
case 0: /* data record */
|
case 0: /* data record */
|
||||||
nextaddr = ihex.loadofs + baseaddr;
|
if (fileoffset != 0 && baseaddr < fileoffset) {
|
||||||
if ((nextaddr + ihex.reclen) > (bufsize+offsetaddr)) {
|
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,
|
fprintf(stderr,
|
||||||
"%s: ERROR: address 0x%04x out of range at line %d of %s\n",
|
"%s: ERROR: address 0x%04x out of range at line %d of %s\n",
|
||||||
progname, nextaddr+ihex.reclen, lineno, infile);
|
progname, nextaddr+ihex.reclen, lineno, infile);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (i=0; i<ihex.reclen; i++) {
|
for (i=0; i<ihex.reclen; i++) {
|
||||||
mem->buf[nextaddr+i-offsetaddr] = ihex.data[i];
|
mem->buf[nextaddr+i] = ihex.data[i];
|
||||||
mem->tags[nextaddr+i-offsetaddr] = TAG_ALLOCATED;
|
mem->tags[nextaddr+i] = TAG_ALLOCATED;
|
||||||
}
|
}
|
||||||
if (nextaddr+ihex.reclen > maxaddr)
|
if (nextaddr+ihex.reclen > maxaddr)
|
||||||
maxaddr = nextaddr+ihex.reclen;
|
maxaddr = nextaddr+ihex.reclen;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* end of file record */
|
case 1: /* end of file record */
|
||||||
return maxaddr-offsetaddr;
|
return maxaddr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* extended segment address record */
|
case 2: /* extended segment address record */
|
||||||
|
@ -330,7 +335,6 @@ static int ihex2b(char * infile, FILE * inf,
|
||||||
|
|
||||||
case 4: /* extended linear address record */
|
case 4: /* extended linear address record */
|
||||||
baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 16;
|
baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 16;
|
||||||
if(nextaddr == 0) offsetaddr = baseaddr; // if provided before any data, then remember it
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: /* start linear address record */
|
case 5: /* start linear address record */
|
||||||
|
@ -353,7 +357,7 @@ static int ihex2b(char * infile, FILE * inf,
|
||||||
"file \"%s\"\n",
|
"file \"%s\"\n",
|
||||||
progname, infile);
|
progname, infile);
|
||||||
|
|
||||||
return maxaddr-offsetaddr;
|
return maxaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int b2srec(unsigned char * inbuf, int bufsize,
|
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,
|
static int srec2b(char * infile, FILE * inf,
|
||||||
AVRMEM * mem, int bufsize)
|
AVRMEM * mem, int bufsize, unsigned int fileoffset)
|
||||||
{
|
{
|
||||||
char buffer [ MAX_LINE_LEN ];
|
char buffer [ MAX_LINE_LEN ];
|
||||||
unsigned int nextaddr, baseaddr, maxaddr;
|
unsigned int nextaddr, maxaddr;
|
||||||
int i;
|
int i;
|
||||||
int lineno;
|
int lineno;
|
||||||
int len;
|
int len;
|
||||||
|
@ -554,7 +558,6 @@ static int srec2b(char * infile, FILE * inf,
|
||||||
char * msg = 0;
|
char * msg = 0;
|
||||||
|
|
||||||
lineno = 0;
|
lineno = 0;
|
||||||
baseaddr = 0;
|
|
||||||
maxaddr = 0;
|
maxaddr = 0;
|
||||||
reccount = 0;
|
reccount = 0;
|
||||||
|
|
||||||
|
@ -588,17 +591,17 @@ static int srec2b(char * infile, FILE * inf,
|
||||||
|
|
||||||
case 0x31: /* S1 - 16 bit address data record */
|
case 0x31: /* S1 - 16 bit address data record */
|
||||||
datarec=1;
|
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;
|
break;
|
||||||
|
|
||||||
case 0x32: /* S2 - 24 bit address data record */
|
case 0x32: /* S2 - 24 bit address data record */
|
||||||
datarec=1;
|
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;
|
break;
|
||||||
|
|
||||||
case 0x33: /* S3 - 32 bit address data record */
|
case 0x33: /* S3 - 32 bit address data record */
|
||||||
datarec=1;
|
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;
|
break;
|
||||||
|
|
||||||
case 0x34: /* S4 - symbol record (LSI extension) */
|
case 0x34: /* S4 - symbol record (LSI extension) */
|
||||||
|
@ -634,9 +637,17 @@ static int srec2b(char * infile, FILE * inf,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (datarec == 1) {
|
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) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
for (i=0; i<srec.reclen; i++) {
|
for (i=0; i<srec.reclen; i++) {
|
||||||
|
@ -786,14 +797,14 @@ static int fileio_ihex(struct fioparms * fio,
|
||||||
|
|
||||||
switch (fio->op) {
|
switch (fio->op) {
|
||||||
case FIO_WRITE:
|
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) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIO_READ:
|
case FIO_READ:
|
||||||
rc = ihex2b(filename, f, mem, size);
|
rc = ihex2b(filename, f, mem, size, fio->fileoffset);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
@ -816,14 +827,14 @@ static int fileio_srec(struct fioparms * fio,
|
||||||
|
|
||||||
switch (fio->op) {
|
switch (fio->op) {
|
||||||
case FIO_WRITE:
|
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) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIO_READ:
|
case FIO_READ:
|
||||||
rc = srec2b(filename, f, mem, size);
|
rc = srec2b(filename, f, mem, size, fio->fileoffset);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
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;
|
fp->op = op;
|
||||||
|
|
||||||
|
@ -938,6 +950,19 @@ int fileio_setparms(int op, struct fioparms * fp)
|
||||||
break;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1032,7 +1057,7 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = fileio_setparms(op, &fio);
|
rc = fileio_setparms(op, &fio, p, mem);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
3
fileio.h
3
fileio.h
|
@ -40,6 +40,7 @@ struct fioparms {
|
||||||
char * iodesc;
|
char * iodesc;
|
||||||
char * dir;
|
char * dir;
|
||||||
char * rw;
|
char * rw;
|
||||||
|
unsigned int fileoffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -53,8 +54,6 @@ extern "C" {
|
||||||
|
|
||||||
char * fmtstr(FILEFMT format);
|
char * fmtstr(FILEFMT format);
|
||||||
|
|
||||||
int fileio_setparms(int op, struct fioparms * fp);
|
|
||||||
|
|
||||||
int fileio(int op, char * filename, FILEFMT format,
|
int fileio(int op, char * filename, FILEFMT format,
|
||||||
struct avrpart * p, char * memtype, int size);
|
struct avrpart * p, char * memtype, int size);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue