Fix a serious memory corruption problem resulting

out of the chaining of both, the stk500v2 and the jtagmkII
programmers for some programming hardware (JTAG ICE mkII and AVR
Dragon running in ISP, HVSP or PP mode), where both programmers
have to maintain their private programmer data.



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@834 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Joerg Wunsch 2009-07-06 22:10:20 +00:00
parent 606aa2d4fd
commit 1348900d7c
2 changed files with 84 additions and 7 deletions

View File

@ -1,3 +1,11 @@
2009-07-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* stk500v2.c: Fix a serious memory corruption problem resulting
out of the chaining of both, the stk500v2 and the jtagmkII
programmers for some programming hardware (JTAG ICE mkII and AVR
Dragon running in ISP, HVSP or PP mode), where both programmers
have to maintain their private programmer data.
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de> 2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* configure.ac: Post-release (is pre-release...) * configure.ac: Post-release (is pre-release...)

View File

@ -117,7 +117,14 @@ struct pdata
} }
pgmtype; pgmtype;
AVRPART *lastpart; AVRPART *lastpart;
/*
* Chained pdata for the JTAG ICE mkII backend. This is used when
* calling the backend functions for ISP/HVSP/PP programming
* functionality of the JTAG ICE mkII and AVR Dragon.
*/
void *chained_pdata;
}; };
#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) #define PDATA(pgm) ((struct pdata *)(pgm->cookie))
@ -278,11 +285,46 @@ static void stk500v2_setup(PROGRAMMER * pgm)
PDATA(pgm)->command_sequence = 1; PDATA(pgm)->command_sequence = 1;
} }
static void stk500v2_jtagmkII_setup(PROGRAMMER * pgm)
{
void *mycookie, *theircookie;
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
fprintf(stderr,
"%s: stk500v2_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
PDATA(pgm)->command_sequence = 1;
/*
* Now, have the JTAG ICE mkII backend allocate its own private
* data. Store our own cookie in a safe place for the time being.
*/
mycookie = pgm->cookie;
jtagmkII_setup(pgm);
theircookie = pgm->cookie;
pgm->cookie = mycookie;
PDATA(pgm)->chained_pdata = theircookie;
}
static void stk500v2_teardown(PROGRAMMER * pgm) static void stk500v2_teardown(PROGRAMMER * pgm)
{ {
free(pgm->cookie); free(pgm->cookie);
} }
static void stk500v2_jtagmkII_teardown(PROGRAMMER * pgm)
{
void *mycookie;
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
jtagmkII_teardown(pgm);
free(mycookie);
}
static unsigned short static unsigned short
b2_to_u16(unsigned char *b) b2_to_u16(unsigned char *b)
@ -326,6 +368,7 @@ static int stk500v2_jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t
unsigned char *cmdbuf; unsigned char *cmdbuf;
int rv; int rv;
unsigned short sz; unsigned short sz;
void *mycookie;
sz = get_jtagisp_return_size(data[0]); sz = get_jtagisp_return_size(data[0]);
if (sz == 0) { if (sz == 0) {
@ -353,12 +396,15 @@ static int stk500v2_jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t
progname); progname);
exit(1); exit(1);
} }
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
cmdbuf[0] = CMND_ISP_PACKET; cmdbuf[0] = CMND_ISP_PACKET;
cmdbuf[1] = sz & 0xff; cmdbuf[1] = sz & 0xff;
cmdbuf[2] = (sz >> 8) & 0xff; cmdbuf[2] = (sz >> 8) & 0xff;
memcpy(cmdbuf + 3, data, len); memcpy(cmdbuf + 3, data, len);
rv = jtagmkII_send(pgm, cmdbuf, len + 3); rv = jtagmkII_send(pgm, cmdbuf, len + 3);
free(cmdbuf); free(cmdbuf);
pgm->cookie = mycookie;
return rv; return rv;
} }
@ -423,8 +469,12 @@ static int stk500v2_jtagmkII_recv(PROGRAMMER * pgm, unsigned char msg[],
{ {
int rv; int rv;
unsigned char *jtagmsg; unsigned char *jtagmsg;
void *mycookie;
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
rv = jtagmkII_recv(pgm, &jtagmsg); rv = jtagmkII_recv(pgm, &jtagmsg);
pgm->cookie = mycookie;
if (rv <= 0) { if (rv <= 0) {
fprintf(stderr, "%s: stk500v2_jtagmkII_recv(): error in jtagmkII_recv()\n", fprintf(stderr, "%s: stk500v2_jtagmkII_recv(): error in jtagmkII_recv()\n",
progname); progname);
@ -2571,9 +2621,13 @@ static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
int prescale; int prescale;
double f; double f;
const char *unit; const char *unit;
void *mycookie;
if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) { if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) {
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget_jtag); jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget_jtag);
pgm->cookie = mycookie;
fprintf(stderr, "%sVtarget : %.1f V\n", p, fprintf(stderr, "%sVtarget : %.1f V\n", p,
b2_to_u16(vtarget_jtag) / 1000.0); b2_to_u16(vtarget_jtag) / 1000.0);
} else { } else {
@ -2681,6 +2735,7 @@ static int stk500v2_perform_osccal(PROGRAMMER * pgm)
static int stk500v2_jtagmkII_open(PROGRAMMER * pgm, char * port) static int stk500v2_jtagmkII_open(PROGRAMMER * pgm, char * port)
{ {
long baud; long baud;
void *mycookie;
if (verbose >= 2) if (verbose >= 2)
fprintf(stderr, "%s: stk500v2_jtagmkII_open()\n", progname); fprintf(stderr, "%s: stk500v2_jtagmkII_open()\n", progname);
@ -2717,12 +2772,16 @@ static int stk500v2_jtagmkII_open(PROGRAMMER * pgm, char * port)
*/ */
stk500v2_drain(pgm, 0); stk500v2_drain(pgm, 0);
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
if (jtagmkII_getsync(pgm, EMULATOR_MODE_SPI) != 0) { if (jtagmkII_getsync(pgm, EMULATOR_MODE_SPI) != 0) {
fprintf(stderr, "%s: failed to sync with the JTAG ICE mkII in ISP mode\n", fprintf(stderr, "%s: failed to sync with the JTAG ICE mkII in ISP mode\n",
progname); progname);
pgm->close(pgm); /* sign off correctly */ pgm->close(pgm); /* sign off correctly */
pgm->cookie = mycookie;
exit(1); exit(1);
} }
pgm->cookie = mycookie;
PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII; PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII;
@ -2748,6 +2807,7 @@ static int stk500v2_jtagmkII_open(PROGRAMMER * pgm, char * port)
static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port) static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port)
{ {
long baud; long baud;
void *mycookie;
if (verbose >= 2) if (verbose >= 2)
fprintf(stderr, "%s: stk500v2_dragon_isp_open()\n", progname); fprintf(stderr, "%s: stk500v2_dragon_isp_open()\n", progname);
@ -2784,12 +2844,16 @@ static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port)
*/ */
stk500v2_drain(pgm, 0); stk500v2_drain(pgm, 0);
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
if (jtagmkII_getsync(pgm, EMULATOR_MODE_SPI) != 0) { if (jtagmkII_getsync(pgm, EMULATOR_MODE_SPI) != 0) {
fprintf(stderr, "%s: failed to sync with the JTAG ICE mkII in ISP mode\n", fprintf(stderr, "%s: failed to sync with the JTAG ICE mkII in ISP mode\n",
progname); progname);
pgm->close(pgm); /* sign off correctly */ pgm->close(pgm); /* sign off correctly */
pgm->cookie = mycookie;
exit(1); exit(1);
} }
pgm->cookie = mycookie;
PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII; PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII;
@ -2815,6 +2879,7 @@ static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port)
static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port) static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port)
{ {
long baud; long baud;
void *mycookie;
if (verbose >= 2) if (verbose >= 2)
fprintf(stderr, "%s: stk500v2_dragon_hv_open()\n", progname); fprintf(stderr, "%s: stk500v2_dragon_hv_open()\n", progname);
@ -2851,12 +2916,16 @@ static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port)
*/ */
stk500v2_drain(pgm, 0); stk500v2_drain(pgm, 0);
mycookie = pgm->cookie;
pgm->cookie = PDATA(pgm)->chained_pdata;
if (jtagmkII_getsync(pgm, EMULATOR_MODE_HV) != 0) { if (jtagmkII_getsync(pgm, EMULATOR_MODE_HV) != 0) {
fprintf(stderr, "%s: failed to sync with the JTAG ICE mkII in HV mode\n", fprintf(stderr, "%s: failed to sync with the JTAG ICE mkII in HV mode\n",
progname); progname);
pgm->close(pgm); /* sign off correctly */ pgm->close(pgm); /* sign off correctly */
pgm->cookie = mycookie;
exit(1); exit(1);
} }
pgm->cookie = mycookie;
PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII; PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII;
@ -3486,8 +3555,8 @@ void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm)
pgm->print_parms = stk500v2_print_parms; pgm->print_parms = stk500v2_print_parms;
pgm->set_sck_period = stk500v2_set_sck_period_mk2; pgm->set_sck_period = stk500v2_set_sck_period_mk2;
pgm->perform_osccal = stk500v2_perform_osccal; pgm->perform_osccal = stk500v2_perform_osccal;
pgm->setup = jtagmkII_setup; pgm->setup = stk500v2_jtagmkII_setup;
pgm->teardown = jtagmkII_teardown; pgm->teardown = stk500v2_jtagmkII_teardown;
pgm->page_size = 256; pgm->page_size = 256;
} }
@ -3550,8 +3619,8 @@ void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm)
pgm->set_varef = stk500v2_set_varef; pgm->set_varef = stk500v2_set_varef;
pgm->set_fosc = stk500v2_set_fosc; pgm->set_fosc = stk500v2_set_fosc;
pgm->set_sck_period = stk500v2_set_sck_period_mk2; pgm->set_sck_period = stk500v2_set_sck_period_mk2;
pgm->setup = jtagmkII_setup; pgm->setup = stk500v2_jtagmkII_setup;
pgm->teardown = jtagmkII_teardown; pgm->teardown = stk500v2_jtagmkII_teardown;
pgm->page_size = 256; pgm->page_size = 256;
} }
@ -3583,8 +3652,8 @@ void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm)
pgm->set_varef = stk500v2_set_varef; pgm->set_varef = stk500v2_set_varef;
pgm->set_fosc = stk500v2_set_fosc; pgm->set_fosc = stk500v2_set_fosc;
pgm->set_sck_period = stk500v2_set_sck_period_mk2; pgm->set_sck_period = stk500v2_set_sck_period_mk2;
pgm->setup = jtagmkII_setup; pgm->setup = stk500v2_jtagmkII_setup;
pgm->teardown = jtagmkII_teardown; pgm->teardown = stk500v2_jtagmkII_teardown;
pgm->page_size = 256; pgm->page_size = 256;
} }