From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32052 invoked by alias); 4 Apr 2002 03:05:23 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 32044 invoked from network); 4 Apr 2002 03:05:20 -0000 Received: from unknown (HELO mta01bw.bigpond.com) (139.134.6.78) by sources.redhat.com with SMTP; 4 Apr 2002 03:05:20 -0000 Received: from bubble.local ([144.135.24.87]) by mta01bw.bigpond.com (Netscape Messaging Server 4.15 mta01bw Feb 26 2002 03:44:21) with SMTP id GU0WKU00.1PU for ; Thu, 4 Apr 2002 13:05:18 +1000 Received: from CPE-144-136-176-14.sa.bigpond.net.au ([144.136.176.14]) by bwmam07.mailsvc.email.bigpond.com(MailRouter V3.0i 62/379238); 04 Apr 2002 13:05:18 Received: (qmail 14530 invoked by uid 179); 4 Apr 2002 03:05:17 -0000 Date: Wed, 03 Apr 2002 19:05:00 -0000 From: Alan Modra To: Hideki IWAMOTO Cc: binutils@sources.redhat.com Subject: Re: [PATCH] objcopy Segmentation fault Message-ID: <20020404030517.GN1042@bubble.sa.bigpond.net.au> Mail-Followup-To: Hideki IWAMOTO , binutils@sources.redhat.com References: <200204021348.AA00056@k7.kit.hi-ho.ne.jp> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200204021348.AA00056@k7.kit.hi-ho.ne.jp> User-Agent: Mutt/1.3.25i X-SW-Source: 2002-04/txt/msg00029.txt.bz2 On Tue, Apr 02, 2002 at 10:48:37PM +0900, Hideki IWAMOTO wrote: > > iwamoto@alpha:/tmp>objcopy -O srec --srec-len=121 a a.srec > Segmentation fault (core dumped) Thanks for the bug report and patch. I'm committing a slightly more comprehensive patch. * srec.c (MAXCHUNK, Chunk): Revise comments. (srec_write_record): Correct buffer size. (srec_write_header): Do without intermediate buffer. (srec_write_section): Validate Chunk. (srec_write_terminator): Pass NULL instead of dummy buffer. (srec_write_symbols): Pass file and symbol names directly to bfd_bwrite so sprintf won't overflow buffer. -- Alan Modra IBM OzLabs - Linux Technology Centre Index: bfd/srec.c =================================================================== RCS file: /cvs/src/src/bfd/srec.c,v retrieving revision 1.15 diff -u -p -r1.15 srec.c --- srec.c 2002/01/06 07:30:35 1.15 +++ srec.c 2002/04/04 02:40:43 @@ -167,13 +167,13 @@ srec_init () } } -/* The maximum number of bytes on a line is FF. */ +/* The maximum number of address+data+crc bytes on a line is FF. */ #define MAXCHUNK 0xff /* Default size for a CHUNK. */ #define DEFAULT_CHUNK 16 -/* The number of bytes we actually fit onto a line on output. +/* The number of data bytes we actually fit onto a line on output. This variable can be modified by objcopy's --srec-len parameter. For a 0x75 byte record you should set --srec-len=0x70. */ unsigned int Chunk = DEFAULT_CHUNK; @@ -936,7 +936,7 @@ srec_write_record (abfd, type, address, const bfd_byte *data; const bfd_byte *end; { - char buffer[MAXCHUNK]; + char buffer[2 * MAXCHUNK + 6]; unsigned int check_sum = 0; const bfd_byte *src = data; char *dst = buffer; @@ -994,15 +994,14 @@ static boolean srec_write_header (abfd) bfd *abfd; { - bfd_byte buffer[MAXCHUNK]; - bfd_byte *dst = buffer; - unsigned int i; + unsigned int len = strlen (abfd->filename); /* I'll put an arbitary 40 char limit on header size. */ - for (i = 0; i < 40 && abfd->filename[i]; i++) - *dst++ = abfd->filename[i]; + if (len > 40) + len = 40; - return srec_write_record (abfd, 0, (bfd_vma) 0, buffer, dst); + return srec_write_record (abfd, 0, (bfd_vma) 0, + abfd->filename, abfd->filename + len); } static boolean @@ -1014,6 +1013,17 @@ srec_write_section (abfd, tdata, list) unsigned int octets_written = 0; bfd_byte *location = list->data; + /* Validate number of data bytes to write. The srec length byte + counts the address, data and crc bytes. S1 (tdata->type == 1) + records have two address bytes, S2 (tdata->type == 2) records + have three, and S3 (tdata->type == 3) records have four. + The total length can't exceed 255, and a zero data length will + spin for a long time. */ + if (Chunk == 0) + Chunk = 1; + else if (Chunk > MAXCHUNK - tdata->type - 2) + Chunk = MAXCHUNK - tdata->type - 2; + while (octets_written < list->size) { bfd_vma address; @@ -1043,17 +1053,14 @@ srec_write_terminator (abfd, tdata) bfd *abfd; tdata_type *tdata; { - bfd_byte buffer[2]; - return srec_write_record (abfd, 10 - tdata->type, - abfd->start_address, buffer, buffer); + abfd->start_address, NULL, NULL); } static boolean srec_write_symbols (abfd) bfd *abfd; { - char buffer[MAXCHUNK]; /* Dump out the symbols of a bfd. */ int i; int count = bfd_get_symcount (abfd); @@ -1062,10 +1069,10 @@ srec_write_symbols (abfd) { bfd_size_type len; asymbol **table = bfd_get_outsymbols (abfd); - sprintf (buffer, "$$ %s\r\n", abfd->filename); - - len = strlen (buffer); - if (bfd_bwrite (buffer, len, abfd) != len) + len = strlen (abfd->filename); + if (bfd_bwrite ("$$ ", (bfd_size_type) 3, abfd) != 3 + || bfd_bwrite (abfd->filename, len, abfd) != len + || bfd_bwrite ("\r\n", (bfd_size_type) 2, abfd) != 2) return false; for (i = 0; i < count; i++) @@ -1075,23 +1082,29 @@ srec_write_symbols (abfd) && (s->flags & BSF_DEBUGGING) == 0) { /* Just dump out non debug symbols. */ - char buf2[40], *p; + char buf[42], *p; + + len = strlen (s->name); + if (bfd_bwrite (" ", (bfd_size_type) 2, abfd) != 2 + || bfd_bwrite (s->name, len, abfd) != len) + return false; - sprintf_vma (buf2, - s->value + s->section->output_section->lma - + s->section->output_offset); - p = buf2; + sprintf_vma (buf + 1, (s->value + + s->section->output_section->lma + + s->section->output_offset)); + p = buf + 1; while (p[0] == '0' && p[1] != 0) p++; - sprintf (buffer, " %s $%s\r\n", s->name, p); - len = strlen (buffer); - if (bfd_bwrite (buffer, len, abfd) != len) + len = strlen (p); + p[len] = '\r'; + p[len + 1] = '\n'; + *--p = ' '; + len += 3; + if (bfd_bwrite (p, len, abfd) != len) return false; } } - sprintf (buffer, "$$ \r\n"); - len = strlen (buffer); - if (bfd_bwrite (buffer, len, abfd) != len) + if (bfd_bwrite ("$$ \r\n", (bfd_size_type) 5, abfd) != 5) return false; }