Lint (detected on hp300bsd & sconix)
This commit is contained in:
parent
1d0709e2a5
commit
9898b92969
@ -421,7 +421,8 @@ DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
|
||||
#endif
|
||||
|
||||
#ifdef SWAP_IN_RELOC_OFFSET
|
||||
reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd, reloc_src->r_offset);
|
||||
reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd,
|
||||
(bfd_byte *) reloc_src->r_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -3168,42 +3169,24 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
|
||||
bfd_swap_reloc_in(abfd, src, &dst);
|
||||
|
||||
|
||||
#ifdef RELOC_PROCESSING
|
||||
RELOC_PROCESSING(cache_ptr, &dst, symbols, abfd, asect);
|
||||
#else
|
||||
|
||||
cache_ptr->address = dst.r_vaddr;
|
||||
|
||||
if (dst.r_symndx != -1)
|
||||
{
|
||||
cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
|
||||
cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
|
||||
ptr = *(cache_ptr->sym_ptr_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cache_ptr->sym_ptr_ptr = 0;
|
||||
ptr = 0;
|
||||
goto puke_logic;
|
||||
cache_ptr->sym_ptr_ptr = 0;
|
||||
ptr = 0;
|
||||
|
||||
}
|
||||
|
||||
#ifdef A29K
|
||||
/* AMD has two relocation entries for the 'consth' instruction.
|
||||
* The first is R_IHIHALF (part 1), the second is R_IHCONST
|
||||
* (part 2). The second entry's r_symndx does not contain
|
||||
* an index to a symbol but rather a value (apparently).
|
||||
* Also, see the ifdef below for saving the r_symndx value in addend.
|
||||
*/
|
||||
if (dst.r_type == R_IHCONST) {
|
||||
ptr = NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
ptr = *(cache_ptr->sym_ptr_ptr);
|
||||
cache_ptr->address = dst.r_vaddr;
|
||||
/*
|
||||
The symbols definitions that we have read in have been
|
||||
relocated as if their sections started at 0. But the offsets
|
||||
refering to the symbols in the raw data have not been
|
||||
modified, so we have to have a negative addend to compensate.
|
||||
|
||||
Note that symbols which used to be common must be left alone */
|
||||
|
||||
puke_logic:
|
||||
cache_ptr->address = dst.r_vaddr;
|
||||
/*
|
||||
The symbols definitions that we have read in have been
|
||||
relocated as if their sections started at 0. But the offsets
|
||||
@ -3220,7 +3203,9 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
|
||||
|
||||
/* Fill in the cache_ptr->howto field from dst.r_type */
|
||||
RTYPE2HOWTO(cache_ptr, dst);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
asect->relocation = reloc_cache;
|
||||
return true;
|
||||
|
719
bfd/srec.c
719
bfd/srec.c
@ -1,6 +1,6 @@
|
||||
/* BFD backend for s-record objects.
|
||||
Copyright (C) 1990-1991 Free Software Foundation, Inc.
|
||||
Written by Steve Chamberlain of Cygnus Support <steve@cygnus.com>.
|
||||
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
@ -18,83 +18,138 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* S-records cannot hold anything but addresses and data, so that's all
|
||||
that we implement.
|
||||
/*
|
||||
SUBSECTION
|
||||
S-record handling
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
S-records cannot hold anything but addresses and data, so
|
||||
that's all that we implement.
|
||||
|
||||
The only interesting thing is that s-records may come out of order and
|
||||
there is no header, so an initial scan is required to discover the
|
||||
minimum and maximum addresses used to create the vma and size of the
|
||||
only section we create. We arbitrarily call this section ".text".
|
||||
The only interesting thing is that s-records may come out of
|
||||
order and there is no header, so an initial scan is required
|
||||
to discover the minimum and maximum addresses used to create
|
||||
the vma and size of the only section we create. We
|
||||
arbitrarily call this section ".text".
|
||||
|
||||
When bfd_get_section_contents is called the file is read again, and
|
||||
this time the data is placed into a bfd_alloc'd area.
|
||||
When bfd_get_section_contents is called the file is read
|
||||
again, and this time the data is placed into a bfd_alloc'd
|
||||
area.
|
||||
|
||||
Any number of sections may be created for output, we just output them
|
||||
in the order provided to bfd_set_section_contents. */
|
||||
Any number of sections may be created for output, we save them
|
||||
up and output them when it's time to close the bfd.
|
||||
|
||||
An s record looks like:
|
||||
|
||||
EXAMPLE
|
||||
S<length><type><address><data><checksum>
|
||||
|
||||
DESCRIPTION
|
||||
Where
|
||||
o length
|
||||
is the number of bytes following upto the checksum. Note that
|
||||
this is not the number of chars following, since it takes two
|
||||
chars to represent a byte.
|
||||
o type
|
||||
is one of:
|
||||
0) header record
|
||||
1) two byte address data record
|
||||
2) three byte address data record
|
||||
3) four byte address data record
|
||||
7) four byte address termination record
|
||||
8) three byte address termination record
|
||||
9) two byte address termination record
|
||||
|
||||
o address
|
||||
is the start address of the data following, or in the case of
|
||||
a termination record, the start address of the image
|
||||
o data
|
||||
is the data.
|
||||
o checksum
|
||||
is the sum of all the raw byte data in the record, from the length
|
||||
upwards, modulo 256 and subtracted from 255.
|
||||
|
||||
*/
|
||||
|
||||
#include <sysdep.h>
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
|
||||
static char digs[] = "0123456789ABCDEF";
|
||||
|
||||
/* Macros for converting between hex and binary */
|
||||
/* Horrible ascii dependent macros for converting between hex and
|
||||
binary */
|
||||
|
||||
#define NIBBLE(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : ((x) - 'A' + 10))
|
||||
#define HEX(buffer) ((NIBBLE((buffer)->high) <<4) + NIBBLE((buffer)->low))
|
||||
#define TOHEX(d,x) \
|
||||
((d)->low = digs[(x) & 0xf], (d)->high = digs[((x)>>4)&0xf], (x))
|
||||
#define ISHEX(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'A' && (x) <= 'F'))
|
||||
#define CHARS_IN_SET 256
|
||||
static char hex_value[CHARS_IN_SET];
|
||||
#define NOT_HEX 20
|
||||
#define NIBBLE(x) hex_value[x]
|
||||
#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1]))
|
||||
#define TOHEX(d,x, ch) \
|
||||
d[1] = digs[(x) & 0xf]; \
|
||||
d[0] = digs[((x)>>4)&0xf]; ch += (x & 0xff);
|
||||
#define ISHEX(x) (hex_value[x] != NOT_HEX)
|
||||
|
||||
|
||||
|
||||
static
|
||||
DEFUN_VOID(srec_init)
|
||||
{
|
||||
unsigned int i;
|
||||
static boolean inited = false;
|
||||
|
||||
if (inited == false)
|
||||
{
|
||||
|
||||
inited = true;
|
||||
|
||||
for (i = 0; i < CHARS_IN_SET; i++)
|
||||
{
|
||||
hex_value[i] = NOT_HEX;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
hex_value[i + '0'] = i;
|
||||
|
||||
}
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
hex_value[i + 'a'] = i+10;
|
||||
hex_value[i + 'A'] = i+10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char high;
|
||||
char low;
|
||||
} byte_as_two_char_type;
|
||||
|
||||
/* The maximum number of bytes on a line is FF */
|
||||
#define MAXCHUNK 0xff
|
||||
/* The number of bytes we fit onto a line on output */
|
||||
#define CHUNK 16
|
||||
#define CHUNK 21
|
||||
|
||||
/* We cannot output our srecords as we see them, we have to glue them
|
||||
together, this is done in this structure : */
|
||||
|
||||
struct srec_data_list_struct
|
||||
{
|
||||
unsigned char *data;
|
||||
bfd_vma where;
|
||||
bfd_size_type size;
|
||||
struct srec_data_list_struct *next;
|
||||
|
||||
} ;
|
||||
typedef struct srec_data_list_struct srec_data_list_type;
|
||||
|
||||
|
||||
/* The shape of an s-record .. */
|
||||
typedef struct
|
||||
{
|
||||
char S;
|
||||
char type;
|
||||
byte_as_two_char_type size;
|
||||
union {
|
||||
struct {
|
||||
byte_as_two_char_type address[4];
|
||||
byte_as_two_char_type data[MAXCHUNK];
|
||||
/* If there isn't MAXCHUNK bytes of data then the checksum will
|
||||
appear earlier */
|
||||
byte_as_two_char_type checksum;
|
||||
char nl;
|
||||
} type_3;
|
||||
struct {
|
||||
byte_as_two_char_type address[4];
|
||||
byte_as_two_char_type data[MAXCHUNK];
|
||||
byte_as_two_char_type checksum;
|
||||
char nl;
|
||||
} type_6;
|
||||
srec_data_list_type *head;
|
||||
unsigned int type;
|
||||
|
||||
} tdata_type;
|
||||
|
||||
struct {
|
||||
byte_as_two_char_type address[3];
|
||||
byte_as_two_char_type data[MAXCHUNK];
|
||||
byte_as_two_char_type checksum;
|
||||
char nl;
|
||||
} type_2;
|
||||
|
||||
struct {
|
||||
byte_as_two_char_type address[2];
|
||||
byte_as_two_char_type data[MAXCHUNK];
|
||||
byte_as_two_char_type checksum;
|
||||
char nl;
|
||||
} type_1;
|
||||
byte_as_two_char_type data[MAXCHUNK];
|
||||
} u;
|
||||
} srec_type;
|
||||
|
||||
#define enda(x) (x->vma + x->size)
|
||||
/*
|
||||
@ -102,18 +157,19 @@ typedef struct
|
||||
*/
|
||||
|
||||
static bfd_vma low,high;
|
||||
|
||||
static void
|
||||
size_srec(abfd, section, address, raw, length)
|
||||
bfd *abfd;
|
||||
asection *section;
|
||||
bfd_vma address;
|
||||
byte_as_two_char_type *raw;
|
||||
unsigned int length;
|
||||
DEFUN(size_srec,(abfd, section, address, raw, length),
|
||||
bfd *abfd AND
|
||||
asection *section AND
|
||||
bfd_vma address AND
|
||||
bfd_byte *raw AND
|
||||
unsigned int length)
|
||||
{
|
||||
if (address < low)
|
||||
low = address;
|
||||
if (address + length > high)
|
||||
high = address + length;
|
||||
high = address + length -1;
|
||||
}
|
||||
|
||||
|
||||
@ -122,99 +178,112 @@ unsigned int length;
|
||||
*/
|
||||
|
||||
static void
|
||||
fillup(abfd, section, address, raw, length)
|
||||
bfd *abfd;
|
||||
asection *section;
|
||||
bfd_vma address;
|
||||
byte_as_two_char_type *raw;
|
||||
unsigned int length;
|
||||
DEFUN(fillup,(abfd, section, address, raw, length),
|
||||
bfd *abfd AND
|
||||
asection *section AND
|
||||
bfd_vma address AND
|
||||
bfd_byte *raw AND
|
||||
unsigned int length)
|
||||
{
|
||||
unsigned int i;
|
||||
bfd_byte *dst = (bfd_byte *)(section->used_by_bfd) + address - section->vma;
|
||||
for (i = 0; i < length; i++) {
|
||||
*dst = HEX(raw);
|
||||
dst++;
|
||||
raw++;
|
||||
}
|
||||
unsigned int i;
|
||||
bfd_byte *dst =
|
||||
(bfd_byte *)(section->used_by_bfd) +
|
||||
address - section->vma;
|
||||
/* length -1 because we don't read in the checksum */
|
||||
for (i = 0; i < length -1 ; i++) {
|
||||
*dst = HEX(raw);
|
||||
dst++;
|
||||
raw+=2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass over an s-record file, calling one of the above functions on each
|
||||
record. */
|
||||
|
||||
static void
|
||||
pass_over(abfd, func, section)
|
||||
bfd *abfd;
|
||||
void (*func)();
|
||||
asection *section;
|
||||
DEFUN(pass_over,(abfd, func, section),
|
||||
bfd *abfd AND
|
||||
void (*func)() AND
|
||||
asection *section)
|
||||
{
|
||||
unsigned int bytes_on_line;
|
||||
boolean eof = false;
|
||||
bfd_vma address;
|
||||
/* To the front of the file */
|
||||
bfd_seek(abfd, (file_ptr)0, SEEK_SET);
|
||||
while (eof == false)
|
||||
unsigned int bytes_on_line;
|
||||
boolean eof = false;
|
||||
bfd_vma address;
|
||||
/* To the front of the file */
|
||||
bfd_seek(abfd, (file_ptr)0, SEEK_SET);
|
||||
while (eof == false)
|
||||
{
|
||||
srec_type buffer;
|
||||
char buffer[MAXCHUNK];
|
||||
char *src = buffer;
|
||||
char type;
|
||||
bfd_vma address = 0;
|
||||
|
||||
/* Find first 'S' */
|
||||
eof = bfd_read(&buffer.S, 1, 1, abfd) != 1;
|
||||
while (buffer.S != 'S' && !eof) {
|
||||
eof = bfd_read(&buffer.S, 1, 1, abfd) != 1;
|
||||
}
|
||||
if (eof) break;
|
||||
/* Find first 'S' */
|
||||
eof = (boolean)(bfd_read(src, 1, 1, abfd) != 1);
|
||||
while (*src!= 'S' && !eof) {
|
||||
eof = (boolean)(bfd_read(src, 1, 1, abfd) != 1);
|
||||
}
|
||||
if (eof) break;
|
||||
src++;
|
||||
|
||||
bfd_read(&buffer.type, 1, 3, abfd);
|
||||
/* Fetch the type and the length */
|
||||
bfd_read(src, 1, 3, abfd);
|
||||
|
||||
if (!ISHEX (buffer.size.high) || !ISHEX (buffer.size.low))
|
||||
break;
|
||||
bytes_on_line = HEX(&buffer.size);
|
||||
if (bytes_on_line > MAXCHUNK/2)
|
||||
break;
|
||||
|
||||
bfd_read((PTR)buffer.u.data, 1 , bytes_on_line * 2, abfd);
|
||||
type = *src++;
|
||||
|
||||
switch (buffer.type) {
|
||||
case '6':
|
||||
/* Prologue - ignore */
|
||||
break;
|
||||
if (!ISHEX (src[0]) || !ISHEX (src[1]))
|
||||
break;
|
||||
|
||||
case '3':
|
||||
address = (HEX(buffer.u.type_3.address+0) << 24)
|
||||
+ (HEX(buffer.u.type_3.address+1) << 16)
|
||||
+ (HEX(buffer.u.type_3.address+2) << 8)
|
||||
+ (HEX(buffer.u.type_3.address+3));
|
||||
func(abfd,section, address, buffer.u.type_3.data, bytes_on_line -1);
|
||||
break;
|
||||
bytes_on_line = HEX(src);
|
||||
|
||||
case '2':
|
||||
address = (HEX(buffer.u.type_2.address+0) << 16)
|
||||
+ (HEX(buffer.u.type_2.address+1) << 8)
|
||||
+ (HEX(buffer.u.type_2.address+2));
|
||||
func(abfd,section, address, buffer.u.type_2.data, bytes_on_line -1);
|
||||
break;
|
||||
if (bytes_on_line > MAXCHUNK/2)
|
||||
break;
|
||||
src+=2 ;
|
||||
|
||||
case '1':
|
||||
address = (HEX(buffer.u.type_1.address+0) << 8)
|
||||
+ (HEX(buffer.u.type_1.address+1));
|
||||
func(abfd, section, address, buffer.u.type_1.data, bytes_on_line -1);
|
||||
break;
|
||||
bfd_read(src, 1 , bytes_on_line * 2, abfd);
|
||||
|
||||
default:
|
||||
goto end_of_file;
|
||||
}
|
||||
switch (type) {
|
||||
case '0':
|
||||
case '5':
|
||||
/* Prologue - ignore */
|
||||
break;
|
||||
case '3':
|
||||
address = HEX(src);
|
||||
src+=2;
|
||||
bytes_on_line--;
|
||||
|
||||
case '2':
|
||||
address = HEX(src) | (address<<8) ;
|
||||
src+=2;
|
||||
bytes_on_line--;
|
||||
case '1':
|
||||
address = HEX(src) | (address<<8) ;
|
||||
src+=2;
|
||||
address = HEX(src) | (address<<8) ;
|
||||
src+=2;
|
||||
bytes_on_line-=2;
|
||||
func(abfd,section, address, src, bytes_on_line);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
end_of_file: ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bfd_target *
|
||||
srec_object_p (abfd)
|
||||
bfd *abfd;
|
||||
|
||||
static bfd_target *
|
||||
DEFUN(srec_object_p, (abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
char b[4];
|
||||
asection *section;
|
||||
srec_init();
|
||||
|
||||
bfd_seek(abfd, (file_ptr)0, SEEK_SET);
|
||||
bfd_read(b, 1, 4, abfd);
|
||||
|
||||
if (b[0] != 'S' || !ISHEX(b[1]) || !ISHEX(b[2]) || !ISHEX(b[3]))
|
||||
return (bfd_target*) NULL;
|
||||
|
||||
@ -229,129 +298,255 @@ bfd *abfd;
|
||||
pass_over(abfd, size_srec, section);
|
||||
section->size = high - low;
|
||||
section->vma = low;
|
||||
section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
|
||||
|
||||
return abfd->xvec;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
srec_get_section_contents (abfd, section, location, offset, count)
|
||||
bfd *abfd;
|
||||
sec_ptr section;
|
||||
void *location;
|
||||
file_ptr offset;
|
||||
unsigned int count;
|
||||
DEFUN(srec_get_section_contents,(abfd, section, location, offset, count),
|
||||
bfd *abfd AND
|
||||
asection *section AND
|
||||
PTR location AND
|
||||
file_ptr offset AND
|
||||
bfd_size_type count)
|
||||
{
|
||||
if (section->used_by_bfd == (PTR)NULL) {
|
||||
section->used_by_bfd = (PTR)bfd_alloc (abfd, section->size);
|
||||
pass_over(abfd, fillup, section);
|
||||
}
|
||||
(void) memcpy((PTR)location, (PTR)((char *)(section->used_by_bfd) + offset), count);
|
||||
return true;
|
||||
if (section->used_by_bfd == (PTR)NULL)
|
||||
{
|
||||
section->used_by_bfd = (PTR)bfd_alloc (abfd, section->size);
|
||||
pass_over(abfd, fillup, section);
|
||||
}
|
||||
(void) memcpy((PTR)location,
|
||||
(PTR)((char *)(section->used_by_bfd) + offset),
|
||||
count);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean
|
||||
srec_set_arch_mach (abfd, arch, machine)
|
||||
bfd *abfd;
|
||||
enum bfd_architecture arch;
|
||||
unsigned long machine;
|
||||
DEFUN(srec_set_arch_mach,(abfd, arch, machine),
|
||||
bfd *abfd AND
|
||||
enum bfd_architecture arch AND
|
||||
unsigned long machine)
|
||||
{
|
||||
abfd->obj_arch = arch;
|
||||
abfd->obj_machine = machine;
|
||||
return true;
|
||||
return bfd_default_set_arch_mach(abfd, arch, machine);
|
||||
}
|
||||
|
||||
|
||||
/* we have to save up all the Srecords for a splurge before output,
|
||||
also remember */
|
||||
|
||||
static boolean
|
||||
DEFUN(srec_set_section_contents,(abfd, section, location, offset, bytes_to_do),
|
||||
bfd *abfd AND
|
||||
sec_ptr section AND
|
||||
PTR location AND
|
||||
file_ptr offset AND
|
||||
bfd_size_type bytes_to_do)
|
||||
{
|
||||
tdata_type *tdata = (tdata_type *)(abfd->tdata);
|
||||
srec_data_list_type *entry = (srec_data_list_type *)
|
||||
bfd_alloc(abfd, sizeof(srec_data_list_type));
|
||||
unsigned char *data = (unsigned char *) bfd_alloc(abfd, bytes_to_do);
|
||||
memcpy(data, location, bytes_to_do);
|
||||
|
||||
if ((section->vma + offset + bytes_to_do) <= 0xffff)
|
||||
{
|
||||
|
||||
}
|
||||
else if ((section->vma + offset + bytes_to_do) <= 0xffffff
|
||||
&& tdata->type < 2)
|
||||
{
|
||||
tdata->type = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdata->type = 3;
|
||||
}
|
||||
|
||||
entry->data = data;
|
||||
entry->where = section->vma + offset;
|
||||
entry->size = bytes_to_do;
|
||||
entry->next = tdata->head;
|
||||
tdata->head = entry;
|
||||
|
||||
}
|
||||
|
||||
/* Write a record of type, of the supplied number of bytes. The
|
||||
supplied bytes and length don't have a checksum. That's worked out
|
||||
here
|
||||
*/
|
||||
static
|
||||
void DEFUN(srec_write_record,(abfd, type, address, data, end),
|
||||
bfd *abfd AND
|
||||
char type AND
|
||||
bfd_vma address AND
|
||||
CONST unsigned char *data AND
|
||||
CONST unsigned char *end)
|
||||
|
||||
{
|
||||
char buffer[MAXCHUNK];
|
||||
|
||||
unsigned int check_sum = 0;
|
||||
unsigned CONST char *src = data;
|
||||
char *dst =buffer;
|
||||
char *length;
|
||||
|
||||
|
||||
*dst++ = 'S';
|
||||
*dst++ = '0' + type;
|
||||
|
||||
length = dst;
|
||||
dst+=2; /* leave room for dst*/
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 3:
|
||||
case 7:
|
||||
TOHEX(dst, (address >> 24), check_sum);
|
||||
dst+=2;
|
||||
case 8:
|
||||
case 2:
|
||||
TOHEX(dst, (address >> 16), check_sum);
|
||||
dst+=2;
|
||||
case 9:
|
||||
case 1:
|
||||
case 0:
|
||||
TOHEX(dst, (address >> 8), check_sum);
|
||||
dst+=2;
|
||||
TOHEX(dst, (address), check_sum);
|
||||
dst+=2;
|
||||
break;
|
||||
|
||||
}
|
||||
for (src = data; src < end; src++)
|
||||
{
|
||||
TOHEX(dst, *src, check_sum);
|
||||
dst+=2;
|
||||
|
||||
}
|
||||
|
||||
/* Fill in the length */
|
||||
TOHEX(length, (dst - length)/2, check_sum);
|
||||
check_sum &= 0xff;
|
||||
check_sum = 255 - check_sum;
|
||||
TOHEX(dst, check_sum, check_sum);
|
||||
dst+=2;
|
||||
|
||||
*dst ++ = '\n';
|
||||
bfd_write((PTR)buffer, 1, dst - buffer , abfd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean
|
||||
srec_set_section_contents (abfd, section, location, offset, bytes_to_do)
|
||||
bfd *abfd;
|
||||
sec_ptr section;
|
||||
unsigned char *location;
|
||||
file_ptr offset;
|
||||
int bytes_to_do;
|
||||
static void
|
||||
DEFUN(srec_write_header,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
bfd_vma address;
|
||||
int bytes_written;
|
||||
unsigned char buffer[MAXCHUNK];
|
||||
unsigned char *dst = buffer;
|
||||
unsigned int i;
|
||||
|
||||
int type;
|
||||
unsigned int i;
|
||||
srec_type buffer;
|
||||
bytes_written = 0;
|
||||
if (section->vma <= 0xffff)
|
||||
type = 1;
|
||||
else if (section->vma <= 0xffffff)
|
||||
type = 2;
|
||||
else
|
||||
type = 3;
|
||||
|
||||
buffer.S = 'S';
|
||||
buffer.type = '0' + type;
|
||||
|
||||
while (bytes_written < bytes_to_do) {
|
||||
unsigned int size;
|
||||
unsigned int check_sum;
|
||||
byte_as_two_char_type *data;
|
||||
unsigned int bytes_this_chunk = bytes_to_do - bytes_written;
|
||||
|
||||
if (bytes_this_chunk > CHUNK) {
|
||||
bytes_this_chunk = CHUNK;
|
||||
/* I'll put an arbitary 40 char limit on header size */
|
||||
for (i = 0; i < 40 && abfd->filename[i]; i++)
|
||||
{
|
||||
*dst++ = abfd->filename[i];
|
||||
}
|
||||
|
||||
address = section->vma + offset + bytes_written;
|
||||
|
||||
switch (type) {
|
||||
case 3:
|
||||
check_sum = TOHEX(buffer.u.type_3.address, address >> 24);
|
||||
check_sum += TOHEX(buffer.u.type_3.address+1, address >> 16);
|
||||
check_sum += TOHEX(buffer.u.type_3.address+2, address >> 8);
|
||||
check_sum += TOHEX(buffer.u.type_3.address+3, address >> 0);
|
||||
size = bytes_this_chunk + 5;
|
||||
data = buffer.u.type_3.data;
|
||||
break;
|
||||
case 2:
|
||||
check_sum = TOHEX(buffer.u.type_3.address, address >> 16);
|
||||
check_sum += TOHEX(buffer.u.type_3.address+1, address >> 8);
|
||||
check_sum += TOHEX(buffer.u.type_3.address+2, address >> 0);
|
||||
size = bytes_this_chunk + 4;
|
||||
data = buffer.u.type_2.data;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
check_sum = TOHEX(buffer.u.type_3.address+0, address >> 8);
|
||||
check_sum += TOHEX(buffer.u.type_3.address+1, address >> 0);
|
||||
size = bytes_this_chunk + 3;
|
||||
data = buffer.u.type_1.data;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < bytes_this_chunk; i++) {
|
||||
check_sum += TOHEX(data, (location[i]));
|
||||
data++;
|
||||
}
|
||||
|
||||
check_sum += TOHEX(&(buffer.size), size );
|
||||
(void) TOHEX(data, ~check_sum);
|
||||
data++;
|
||||
|
||||
* ( (char *)(data)) = '\n';
|
||||
bfd_write((PTR)&buffer, 1, (char *)data - (char *)&buffer + 1 , abfd);
|
||||
|
||||
bytes_written += bytes_this_chunk;
|
||||
location += bytes_this_chunk;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
srec_write_record(abfd,0, 0, buffer, dst);
|
||||
}
|
||||
|
||||
boolean
|
||||
srec_write_object_contents (abfd)
|
||||
bfd *abfd;
|
||||
static void
|
||||
DEFUN(srec_write_section,(abfd, tdata, list),
|
||||
bfd *abfd AND
|
||||
tdata_type *tdata AND
|
||||
srec_data_list_type *list)
|
||||
{
|
||||
bfd_write("S9030000FC\n", 1,11,abfd);
|
||||
return true;
|
||||
unsigned int bytes_written = 0;
|
||||
unsigned char *location = list->data;
|
||||
|
||||
while (bytes_written < list->size)
|
||||
{
|
||||
char buffer[MAXCHUNK];
|
||||
char *dst = buffer;
|
||||
bfd_vma address;
|
||||
unsigned int i;
|
||||
|
||||
unsigned int bytes_this_chunk = list->size - bytes_written;
|
||||
|
||||
if (bytes_this_chunk > CHUNK)
|
||||
{
|
||||
bytes_this_chunk = CHUNK;
|
||||
}
|
||||
|
||||
address = list->where + bytes_written;
|
||||
|
||||
srec_write_record(abfd,
|
||||
tdata->type,
|
||||
address,
|
||||
location,
|
||||
location + bytes_this_chunk);
|
||||
|
||||
bytes_written += bytes_this_chunk;
|
||||
location += bytes_this_chunk;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
DEFUN(srec_write_terminator,(abfd, tdata),
|
||||
bfd *abfd AND
|
||||
tdata_type *tdata)
|
||||
{
|
||||
unsigned char buffer[2];
|
||||
|
||||
srec_write_record(abfd, 10 - tdata->type,
|
||||
abfd->start_address, buffer, buffer);
|
||||
|
||||
|
||||
}
|
||||
static boolean
|
||||
DEFUN(srec_mkobject, (abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
tdata_type *tdata = (tdata_type *)bfd_alloc(abfd, sizeof(tdata_type));
|
||||
abfd->tdata = (PTR)tdata;
|
||||
tdata->type = 1;
|
||||
tdata->head = (srec_data_list_type *)NULL;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
DEFUN(srec_write_object_contents,(abfd),
|
||||
bfd *abfd)
|
||||
{
|
||||
bfd_vma address;
|
||||
int bytes_written;
|
||||
|
||||
int type;
|
||||
unsigned int i;
|
||||
tdata_type *tdata = (tdata_type *)(abfd->tdata);
|
||||
srec_data_list_type *list;
|
||||
|
||||
bytes_written = 0;
|
||||
|
||||
|
||||
|
||||
srec_write_header(abfd);
|
||||
|
||||
/* Now wander though all the sections provided and output them */
|
||||
list = tdata->head;
|
||||
|
||||
while (list != (srec_data_list_type*)NULL)
|
||||
{
|
||||
srec_write_section(abfd, tdata, list);
|
||||
list = list->next;
|
||||
}
|
||||
srec_write_terminator(abfd, tdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -377,7 +572,7 @@ DEFUN(srec_make_empty_symbol, (abfd),
|
||||
#define srec_get_reloc_upper_bound (FOO(unsigned int, (*),(bfd*, asection *)))bfd_false
|
||||
#define srec_canonicalize_reloc (FOO(unsigned int, (*),(bfd*,asection *, arelent **, asymbol **))) bfd_0
|
||||
|
||||
#define srec_print_symbol (FOO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_enum_type))) bfd_void
|
||||
#define srec_print_symbol (FOO(void,(*),(bfd *, PTR, asymbol *, bfd_print_symbol_type))) bfd_void
|
||||
|
||||
#define srec_openr_next_archived_file (FOO(bfd *, (*), (bfd*,bfd*))) bfd_nullvoidptr
|
||||
#define srec_find_nearest_line (FOO(boolean, (*),(bfd*,asection*,asymbol**,bfd_vma, CONST char**, CONST char**, unsigned int *))) bfd_false
|
||||
@ -390,7 +585,7 @@ DEFUN(srec_make_empty_symbol, (abfd),
|
||||
#define srec_slurp_armap bfd_true
|
||||
#define srec_slurp_extended_name_table bfd_true
|
||||
#define srec_truncate_arname (void (*)())bfd_nullvoidptr
|
||||
#define srec_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, int, int))) bfd_nullvoidptr
|
||||
#define srec_write_armap (FOO( boolean, (*),(bfd *, unsigned int, struct orl *, unsigned int, int))) bfd_nullvoidptr
|
||||
#define srec_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
|
||||
#define srec_close_and_cleanup bfd_generic_close_and_cleanup
|
||||
#define srec_bfd_debug_info_start bfd_void
|
||||
@ -400,37 +595,41 @@ DEFUN(srec_make_empty_symbol, (abfd),
|
||||
|
||||
bfd_target srec_vec =
|
||||
{
|
||||
"srec", /* name */
|
||||
bfd_target_srec_flavour_enum,
|
||||
true, /* target byte order */
|
||||
true, /* target headers byte order */
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
|
||||
(SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
|
||||
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||
' ', /* ar_pad_char */
|
||||
16, /* ar_max_namelen */
|
||||
"srec", /* name */
|
||||
bfd_target_srec_flavour,
|
||||
true, /* target byte order */
|
||||
true, /* target headers byte order */
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
|
||||
(SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
|
||||
|SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
||||
' ', /* ar_pad_char */
|
||||
16, /* ar_max_namelen */
|
||||
1, /* minimum alignment */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
|
||||
_do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
||||
_do_getb64, _do_putb64, _do_getb32,
|
||||
_do_putb32, _do_getb16, _do_putb16, /* data */
|
||||
_do_getb64, _do_putb64, _do_getb32,
|
||||
_do_putb32, _do_getb16, _do_putb16, /* hdrs */
|
||||
|
||||
{_bfd_dummy_target,
|
||||
srec_object_p, /* bfd_check_format */
|
||||
(struct bfd_target *(*)()) bfd_nullvoidptr,
|
||||
(struct bfd_target *(*)()) bfd_nullvoidptr,
|
||||
},
|
||||
{
|
||||
{
|
||||
_bfd_dummy_target,
|
||||
srec_object_p, /* bfd_check_format */
|
||||
(struct bfd_target *(*)()) bfd_nullvoidptr,
|
||||
(struct bfd_target *(*)()) bfd_nullvoidptr,
|
||||
},
|
||||
{
|
||||
bfd_false,
|
||||
bfd_true, /* mkobject */
|
||||
srec_mkobject,
|
||||
_bfd_generic_mkarchive,
|
||||
bfd_false,
|
||||
},
|
||||
{ /* bfd_write_contents */
|
||||
},
|
||||
{ /* bfd_write_contents */
|
||||
bfd_false,
|
||||
srec_write_object_contents,
|
||||
_bfd_write_archive_contents,
|
||||
bfd_false,
|
||||
},
|
||||
JUMP_TABLE(srec)
|
||||
};
|
||||
},
|
||||
JUMP_TABLE(srec)
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user