1 |
/* BFD backend for Extended Tektronix Hex Format objects. |
/* BFD backend for Extended Tektronix Hex Format objects. |
2 |
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 |
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, |
3 |
Free Software Foundation, Inc. |
2003, 2004 Free Software Foundation, Inc. |
4 |
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>. |
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>. |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
29 |
relocations. Their main application is communication with |
relocations. Their main application is communication with |
30 |
devices like PROM programmers and ICE equipment. |
devices like PROM programmers and ICE equipment. |
31 |
|
|
32 |
It seems that the sections are descibed as being really big, |
It seems that the sections are described as being really big, |
33 |
the example I have says that the text section is 0..ffffffff. |
the example I have says that the text section is 0..ffffffff. |
34 |
BFD would barf with this, many apps would try to alloc 4GB to |
BFD would barf with this, many apps would try to alloc 4GB to |
35 |
read in the file. |
read in the file. |
104 |
PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type)); |
PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type)); |
105 |
static void tekhex_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); |
static void tekhex_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); |
106 |
static asymbol *tekhex_make_empty_symbol PARAMS ((bfd *)); |
static asymbol *tekhex_make_empty_symbol PARAMS ((bfd *)); |
107 |
static int tekhex_sizeof_headers PARAMS ((bfd *, boolean)); |
static int tekhex_sizeof_headers PARAMS ((bfd *, bfd_boolean)); |
108 |
static boolean tekhex_write_object_contents PARAMS ((bfd *)); |
static bfd_boolean tekhex_write_object_contents PARAMS ((bfd *)); |
109 |
static void out PARAMS ((bfd *, int, char *, char *)); |
static void out PARAMS ((bfd *, int, char *, char *)); |
110 |
static void writesym PARAMS ((char **, const char *)); |
static void writesym PARAMS ((char **, const char *)); |
111 |
static void writevalue PARAMS ((char **, bfd_vma)); |
static void writevalue PARAMS ((char **, bfd_vma)); |
112 |
static boolean tekhex_set_section_contents |
static bfd_boolean tekhex_set_section_contents |
113 |
PARAMS ((bfd*, sec_ptr, PTR, file_ptr, bfd_size_type)); |
PARAMS ((bfd*, sec_ptr, const PTR, file_ptr, bfd_size_type)); |
114 |
static boolean tekhex_set_arch_mach |
static bfd_boolean tekhex_set_arch_mach |
115 |
PARAMS ((bfd *, enum bfd_architecture, unsigned long)); |
PARAMS ((bfd *, enum bfd_architecture, unsigned long)); |
116 |
static boolean tekhex_get_section_contents |
static bfd_boolean tekhex_get_section_contents |
117 |
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); |
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); |
118 |
static void move_section_contents |
static void move_section_contents |
119 |
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type, boolean)); |
PARAMS ((bfd *, asection *, const PTR, file_ptr, bfd_size_type, bfd_boolean)); |
120 |
static const bfd_target *tekhex_object_p PARAMS ((bfd *)); |
static const bfd_target *tekhex_object_p PARAMS ((bfd *)); |
121 |
static boolean tekhex_mkobject PARAMS ((bfd *)); |
static bfd_boolean tekhex_mkobject PARAMS ((bfd *)); |
122 |
static long tekhex_get_symtab_upper_bound PARAMS ((bfd *)); |
static long tekhex_get_symtab_upper_bound PARAMS ((bfd *)); |
123 |
static long tekhex_get_symtab PARAMS ((bfd *, asymbol **)); |
static long tekhex_canonicalize_symtab PARAMS ((bfd *, asymbol **)); |
124 |
static void pass_over PARAMS ((bfd *, void (*) (bfd*, int, char *))); |
static void pass_over PARAMS ((bfd *, void (*) (bfd*, int, char *))); |
125 |
static void first_phase PARAMS ((bfd *, int, char *)); |
static void first_phase PARAMS ((bfd *, int, char *)); |
126 |
static void insert_byte PARAMS ((bfd *, int, bfd_vma)); |
static void insert_byte PARAMS ((bfd *, int, bfd_vma)); |
239 |
tekhex_init () |
tekhex_init () |
240 |
{ |
{ |
241 |
unsigned int i; |
unsigned int i; |
242 |
static boolean inited = false; |
static bfd_boolean inited = FALSE; |
243 |
int val; |
int val; |
244 |
|
|
245 |
if (! inited) |
if (! inited) |
246 |
{ |
{ |
247 |
inited = true; |
inited = TRUE; |
248 |
hex_init (); |
hex_init (); |
249 |
val = 0; |
val = 0; |
250 |
for (i = 0; i < 10; i++) |
for (i = 0; i < 10; i++) |
429 |
case '1': /* section range */ |
case '1': /* section range */ |
430 |
src++; |
src++; |
431 |
section->vma = getvalue (&src); |
section->vma = getvalue (&src); |
432 |
section->_raw_size = getvalue (&src) - section->vma; |
section->size = getvalue (&src) - section->vma; |
433 |
section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; |
section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; |
434 |
break; |
break; |
435 |
case '0': |
case '0': |
471 |
} |
} |
472 |
} |
} |
473 |
|
|
474 |
/* Pass over an tekhex, calling one of the above functions on each |
/* Pass over a tekhex, calling one of the above functions on each |
475 |
record. */ |
record. */ |
476 |
|
|
477 |
static void |
static void |
480 |
void (*func) PARAMS ((bfd *, int, char *)); |
void (*func) PARAMS ((bfd *, int, char *)); |
481 |
{ |
{ |
482 |
unsigned int chars_on_line; |
unsigned int chars_on_line; |
483 |
boolean eof = false; |
bfd_boolean eof = FALSE; |
484 |
|
|
485 |
/* To the front of the file */ |
/* To the front of the file */ |
486 |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
492 |
char type; |
char type; |
493 |
|
|
494 |
/* Find first '%' */ |
/* Find first '%' */ |
495 |
eof = (boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1); |
eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1); |
496 |
while (*src != '%' && !eof) |
while (*src != '%' && !eof) |
497 |
{ |
{ |
498 |
eof = (boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1); |
eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1); |
499 |
} |
} |
500 |
if (eof) |
if (eof) |
501 |
break; |
break; |
522 |
} |
} |
523 |
|
|
524 |
static long |
static long |
525 |
tekhex_get_symtab (abfd, table) |
tekhex_canonicalize_symtab (abfd, table) |
526 |
bfd *abfd; |
bfd *abfd; |
527 |
asymbol **table; |
asymbol **table; |
528 |
{ |
{ |
547 |
|
|
548 |
} |
} |
549 |
|
|
550 |
static boolean |
static bfd_boolean |
551 |
tekhex_mkobject (abfd) |
tekhex_mkobject (abfd) |
552 |
bfd *abfd; |
bfd *abfd; |
553 |
{ |
{ |
555 |
|
|
556 |
tdata = (tdata_type *) bfd_alloc (abfd, (bfd_size_type) sizeof (tdata_type)); |
tdata = (tdata_type *) bfd_alloc (abfd, (bfd_size_type) sizeof (tdata_type)); |
557 |
if (!tdata) |
if (!tdata) |
558 |
return false; |
return FALSE; |
559 |
abfd->tdata.tekhex_data = tdata; |
abfd->tdata.tekhex_data = tdata; |
560 |
tdata->type = 1; |
tdata->type = 1; |
561 |
tdata->head = (tekhex_data_list_type *) NULL; |
tdata->head = (tekhex_data_list_type *) NULL; |
562 |
tdata->symbols = (struct tekhex_symbol_struct *) NULL; |
tdata->symbols = (struct tekhex_symbol_struct *) NULL; |
563 |
tdata->data = (struct data_struct *) NULL; |
tdata->data = (struct data_struct *) NULL; |
564 |
return true; |
return TRUE; |
565 |
} |
} |
566 |
|
|
567 |
/* |
/* |
568 |
Return true if the file looks like it's in TekHex format. Just look |
Return TRUE if the file looks like it's in TekHex format. Just look |
569 |
for a percent sign and some hex digits */ |
for a percent sign and some hex digits */ |
570 |
|
|
571 |
static const bfd_target * |
static const bfd_target * |
593 |
move_section_contents (abfd, section, locationp, offset, count, get) |
move_section_contents (abfd, section, locationp, offset, count, get) |
594 |
bfd *abfd; |
bfd *abfd; |
595 |
asection *section; |
asection *section; |
596 |
PTR locationp; |
const PTR locationp; |
597 |
file_ptr offset; |
file_ptr offset; |
598 |
bfd_size_type count; |
bfd_size_type count; |
599 |
boolean get; |
bfd_boolean get; |
600 |
{ |
{ |
601 |
bfd_vma addr; |
bfd_vma addr; |
602 |
char *location = (char *) locationp; |
char *location = (char *) locationp; |
639 |
|
|
640 |
} |
} |
641 |
|
|
642 |
static boolean |
static bfd_boolean |
643 |
tekhex_get_section_contents (abfd, section, locationp, offset, count) |
tekhex_get_section_contents (abfd, section, locationp, offset, count) |
644 |
bfd *abfd; |
bfd *abfd; |
645 |
asection *section; |
asection *section; |
649 |
{ |
{ |
650 |
if (section->flags & (SEC_LOAD | SEC_ALLOC)) |
if (section->flags & (SEC_LOAD | SEC_ALLOC)) |
651 |
{ |
{ |
652 |
move_section_contents (abfd, section, locationp, offset, count, true); |
move_section_contents (abfd, section, locationp, offset, count, TRUE); |
653 |
return true; |
return TRUE; |
654 |
} |
} |
655 |
else |
else |
656 |
return false; |
return FALSE; |
657 |
} |
} |
658 |
|
|
659 |
static boolean |
static bfd_boolean |
660 |
tekhex_set_arch_mach (abfd, arch, machine) |
tekhex_set_arch_mach (abfd, arch, machine) |
661 |
bfd *abfd; |
bfd *abfd; |
662 |
enum bfd_architecture arch; |
enum bfd_architecture arch; |
668 |
/* we have to save up all the Tekhexords for a splurge before output, |
/* we have to save up all the Tekhexords for a splurge before output, |
669 |
*/ |
*/ |
670 |
|
|
671 |
static boolean |
static bfd_boolean |
672 |
tekhex_set_section_contents (abfd, section, locationp, offset, bytes_to_do) |
tekhex_set_section_contents (abfd, section, locationp, offset, bytes_to_do) |
673 |
bfd *abfd; |
bfd *abfd; |
674 |
sec_ptr section; |
sec_ptr section; |
675 |
PTR locationp; |
const PTR locationp; |
676 |
file_ptr offset; |
file_ptr offset; |
677 |
bfd_size_type bytes_to_do; |
bfd_size_type bytes_to_do; |
678 |
{ |
{ |
688 |
if (s->flags & SEC_LOAD) |
if (s->flags & SEC_LOAD) |
689 |
{ |
{ |
690 |
for (vma = s->vma & ~(bfd_vma) CHUNK_MASK; |
for (vma = s->vma & ~(bfd_vma) CHUNK_MASK; |
691 |
vma < s->vma + s->_raw_size; |
vma < s->vma + s->size; |
692 |
vma += CHUNK_MASK) |
vma += CHUNK_MASK) |
693 |
find_chunk (abfd, vma); |
find_chunk (abfd, vma); |
694 |
} |
} |
698 |
if (section->flags & (SEC_LOAD | SEC_ALLOC)) |
if (section->flags & (SEC_LOAD | SEC_ALLOC)) |
699 |
{ |
{ |
700 |
move_section_contents (abfd, section, locationp, offset, bytes_to_do, |
move_section_contents (abfd, section, locationp, offset, bytes_to_do, |
701 |
false); |
FALSE); |
702 |
return true; |
return TRUE; |
703 |
} |
} |
704 |
else |
else |
705 |
return false; |
return FALSE; |
706 |
|
|
707 |
} |
} |
708 |
|
|
804 |
abort (); |
abort (); |
805 |
} |
} |
806 |
|
|
807 |
static boolean |
static bfd_boolean |
808 |
tekhex_write_object_contents (abfd) |
tekhex_write_object_contents (abfd) |
809 |
bfd *abfd; |
bfd *abfd; |
810 |
{ |
{ |
862 |
writesym (&dst, s->name); |
writesym (&dst, s->name); |
863 |
*dst++ = '1'; |
*dst++ = '1'; |
864 |
writevalue (&dst, s->vma); |
writevalue (&dst, s->vma); |
865 |
writevalue (&dst, s->vma + s->_raw_size); |
writevalue (&dst, s->vma + s->size); |
866 |
out (abfd, '3', buffer, dst); |
out (abfd, '3', buffer, dst); |
867 |
} |
} |
868 |
|
|
907 |
case 'C': |
case 'C': |
908 |
case 'U': |
case 'U': |
909 |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
910 |
return false; |
return FALSE; |
911 |
} |
} |
912 |
|
|
913 |
writesym (&dst, sym->name); |
writesym (&dst, sym->name); |
920 |
/* And the terminator */ |
/* And the terminator */ |
921 |
if (bfd_bwrite ("%0781010\n", (bfd_size_type) 9, abfd) != 9) |
if (bfd_bwrite ("%0781010\n", (bfd_size_type) 9, abfd) != 9) |
922 |
abort (); |
abort (); |
923 |
return true; |
return TRUE; |
924 |
} |
} |
925 |
|
|
926 |
static int |
static int |
927 |
tekhex_sizeof_headers (abfd, exec) |
tekhex_sizeof_headers (abfd, exec) |
928 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
929 |
boolean exec ATTRIBUTE_UNUSED; |
bfd_boolean exec ATTRIBUTE_UNUSED; |
930 |
|
|
931 |
{ |
{ |
932 |
return 0; |
return 0; |
989 |
#define tekhex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info |
#define tekhex_bfd_free_cached_info _bfd_generic_bfd_free_cached_info |
990 |
#define tekhex_new_section_hook _bfd_generic_new_section_hook |
#define tekhex_new_section_hook _bfd_generic_new_section_hook |
991 |
|
|
992 |
|
#define tekhex_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) |
993 |
#define tekhex_bfd_is_local_label_name bfd_generic_is_local_label_name |
#define tekhex_bfd_is_local_label_name bfd_generic_is_local_label_name |
994 |
#define tekhex_get_lineno _bfd_nosymbols_get_lineno |
#define tekhex_get_lineno _bfd_nosymbols_get_lineno |
995 |
#define tekhex_find_nearest_line _bfd_nosymbols_find_nearest_line |
#define tekhex_find_nearest_line _bfd_nosymbols_find_nearest_line |
1002 |
#define tekhex_bfd_relax_section bfd_generic_relax_section |
#define tekhex_bfd_relax_section bfd_generic_relax_section |
1003 |
#define tekhex_bfd_gc_sections bfd_generic_gc_sections |
#define tekhex_bfd_gc_sections bfd_generic_gc_sections |
1004 |
#define tekhex_bfd_merge_sections bfd_generic_merge_sections |
#define tekhex_bfd_merge_sections bfd_generic_merge_sections |
1005 |
|
#define tekhex_bfd_is_group_section bfd_generic_is_group_section |
1006 |
#define tekhex_bfd_discard_group bfd_generic_discard_group |
#define tekhex_bfd_discard_group bfd_generic_discard_group |
1007 |
|
#define tekhex_section_already_linked \ |
1008 |
|
_bfd_generic_section_already_linked |
1009 |
#define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create |
#define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create |
1010 |
#define tekhex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free |
#define tekhex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free |
1011 |
#define tekhex_bfd_link_add_symbols _bfd_generic_link_add_symbols |
#define tekhex_bfd_link_add_symbols _bfd_generic_link_add_symbols |