/* BFD back-end for ieee-695 objects.
- Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001
+ Free Software Foundation, Inc.
+
Written by Steve Chamberlain of Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#include "ieee.h"
#include "libieee.h"
-static boolean ieee_write_byte PARAMS ((bfd *, bfd_byte));
+#include <ctype.h>
+
+static boolean ieee_write_byte PARAMS ((bfd *, int));
static boolean ieee_write_2bytes PARAMS ((bfd *, int));
static boolean ieee_write_int PARAMS ((bfd *, bfd_vma));
static boolean ieee_write_id PARAMS ((bfd *, const char *));
static boolean ieee_write_data_part PARAMS ((bfd *));
static boolean ieee_write_debug_part PARAMS ((bfd *));
static boolean ieee_write_me_part PARAMS ((bfd *));
+static boolean ieee_write_processor PARAMS ((bfd *));
static boolean ieee_slurp_debug PARAMS ((bfd *));
+static boolean ieee_slurp_section_data PARAMS ((bfd *));
/* Functions for writing to ieee files in the strange way that the
standard requires. */
static boolean
-ieee_write_byte (abfd, byte)
+ieee_write_byte (abfd, barg)
bfd *abfd;
- bfd_byte byte;
+ int barg;
{
+ bfd_byte byte;
+
+ byte = barg;
if (bfd_write ((PTR) &byte, 1, 1, abfd) != 1)
return false;
return true;
else
{
(*_bfd_error_handler)
- ("%s: string too long (%d chars, max 65535)",
+ (_("%s: string too long (%d chars, max 65535)"),
bfd_get_filename (abfd), length);
bfd_set_error (bfd_error_invalid_operation);
return false;
{
/* Ref to defined symbol - */
- if (! ieee_write_byte (abfd, ieee_variable_R_enum)
- || ! ieee_write_byte (abfd,
- (bfd_byte) (symbol->section->index
- + IEEE_SECTION_NUMBER_BASE)))
- return false;
- term_count++;
if (symbol->flags & BSF_GLOBAL)
{
if (! ieee_write_byte (abfd, ieee_variable_I_enum)
{
/* This is a reference to a defined local symbol. We can
easily do a local as a section+offset. */
- if (! ieee_write_int (abfd, symbol->value))
+ if (! ieee_write_byte (abfd, ieee_variable_R_enum)
+ || ! ieee_write_byte (abfd,
+ (bfd_byte) (symbol->section->index
+ + IEEE_SECTION_NUMBER_BASE)))
return false;
term_count++;
+ if (symbol->value != 0)
+ {
+ if (! ieee_write_int (abfd, symbol->value))
+ return false;
+ term_count++;
+ }
}
else
{
(*_bfd_error_handler)
- ("%s: unrecognized symbol `%s' flags 0x%x",
+ (_("%s: unrecognized symbol `%s' flags 0x%x"),
bfd_get_filename (abfd), bfd_asymbol_name (symbol),
symbol->flags);
bfd_set_error (bfd_error_invalid_operation);
return false;
}
+ /* Handle the degenerate case of a 0 address. */
+ if (term_count == 0)
+ {
+ if (! ieee_write_int (abfd, 0))
+ return false;
+ }
+
while (term_count > 1)
{
if (! ieee_write_byte (abfd, ieee_function_plus_enum))
} ieee_value_type;
+#if KEEPMINUSPCININST
+
+#define SRC_MASK(arg) arg
+#define PCREL_OFFSET false
+
+#else
+
+#define SRC_MASK(arg) 0
+#define PCREL_OFFSET true
+
+#endif
+
static reloc_howto_type abs32_howto =
HOWTO (1,
0,
0,
"rel32",
true,
+ SRC_MASK (0xffffffff),
0xffffffff,
- 0xffffffff,
- false);
+ PCREL_OFFSET);
static reloc_howto_type rel16_howto =
HOWTO (1,
0,
"rel16",
true,
+ SRC_MASK (0x0000ffff),
0x0000ffff,
- 0x0000ffff,
- false);
+ PCREL_OFFSET);
static reloc_howto_type rel8_howto =
HOWTO (1,
0,
"rel8",
true,
+ SRC_MASK (0x000000ff),
0x000000ff,
- 0x000000ff,
- false);
+ PCREL_OFFSET);
static ieee_symbol_index_type NOSYMBOL = {0, 0};
next_byte (&(ieee->h));
*pcrel = true;
section_n = must_parse_int (&(ieee->h));
- PUSH (NOSYMBOL, bfd_abs_section_ptr,
- TOS.value = ieee->section_table[section_n]->vma +
- ieee_per_section (ieee->section_table[section_n])->pc);
+ PUSH (NOSYMBOL, bfd_abs_section_ptr, 0);
break;
}
case ieee_variable_L_enum:
ieee->section_table[must_parse_int (&(ieee->h))]->_raw_size);
break;
case ieee_variable_I_enum:
+ /* Push the address of variable n */
+ {
+ ieee_symbol_index_type sy;
+ next_byte (&(ieee->h));
+ sy.index = (int) must_parse_int (&(ieee->h));
+ sy.letter = 'I';
+
+ PUSH (sy, bfd_abs_section_ptr, 0);
+ }
+ break;
case ieee_variable_X_enum:
/* Push the address of external variable n */
{
POP (sy, section1, value1);
POP (sy, section_dummy, value2);
- PUSH (sy, section1 ? section1 : section_dummy, value1 - value2);
+ PUSH (sy, section1 ? section1 : section_dummy, value2 - value1);
}
break;
case ieee_function_plus_enum:
max_index,
this_type
)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
ieee_data_type *ieee;
ieee_symbol_type *last_symbol;
unsigned int *symbol_count;
*max_index = new_index;
}
last_type = this_type;
+ new_symbol->symbol.section = bfd_abs_section_ptr;
return new_symbol;
}
return last_symbol;
symbol = get_symbol (abfd, ieee, symbol, &symbol_count,
&prev_symbols_ptr,
- &ieee->external_symbol_max_index, 'D');
+ &ieee->external_symbol_max_index, 'I');
if (symbol == NULL)
return false;
unsigned int symbol_type_index;
unsigned int symbol_attribute_def;
bfd_vma value;
- next_byte (&(ieee->h)); /* Skip prefix */
- next_byte (&(ieee->h));
- symbol_name_index = must_parse_int (&(ieee->h));
- symbol_type_index = must_parse_int (&(ieee->h));
- symbol_attribute_def = must_parse_int (&(ieee->h));
- switch (symbol_attribute_def)
+ switch (read_2bytes (ieee))
{
- case 63:
- /* Module misc; followed by two fields which describe the
- current module block. The first fired is the type id
- number, the second is the number of asn records
- associated with the directive */
+ case ieee_attribute_record_enum:
+ symbol_name_index = must_parse_int (&(ieee->h));
+ symbol_type_index = must_parse_int (&(ieee->h));
+ symbol_attribute_def = must_parse_int (&(ieee->h));
+ switch (symbol_attribute_def)
+ {
+ case 8:
+ case 19:
+ parse_int (&ieee->h, &value);
+ break;
+ default:
+ (*_bfd_error_handler)
+ (_("%s: unimplemented ATI record %u for symbol %u"),
+ bfd_get_filename (abfd), symbol_attribute_def,
+ symbol_name_index);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ break;
+ }
+ break;
+ case ieee_external_reference_info_record_enum:
+ /* Skip over ATX record. */
+ parse_int (&(ieee->h), &value);
parse_int (&(ieee->h), &value);
parse_int (&(ieee->h), &value);
- break;
-
- default:
parse_int (&(ieee->h), &value);
break;
+ case ieee_atn_record_enum:
+ /* We may get call optimization information here,
+ which we just ignore. The format is
+ {$F1}${CE}{index}{$00}{$3F}{$3F}{#_of_ASNs} */
+ parse_int (&ieee->h, &value);
+ parse_int (&ieee->h, &value);
+ parse_int (&ieee->h, &value);
+ if (value != 0x3f)
+ {
+ (*_bfd_error_handler)
+ (_("%s: unexpected ATN type %d in external part"),
+ bfd_get_filename (abfd), (int) value);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ parse_int (&ieee->h, &value);
+ parse_int (&ieee->h, &value);
+ while (value > 0)
+ {
+ bfd_vma val1;
+
+ --value;
+
+ switch (read_2bytes (ieee))
+ {
+ case ieee_asn_record_enum:
+ parse_int (&ieee->h, &val1);
+ parse_int (&ieee->h, &val1);
+ break;
+
+ default:
+ (*_bfd_error_handler)
+ (_("%s: unexpected type after ATN"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
}
}
break;
&extra,
&symbol->symbol.section);
+ /* Fully linked IEEE-695 files tend to give every symbol
+ an absolute value. Try to convert that back into a
+ section relative value. FIXME: This won't always to
+ the right thing. */
+ if (bfd_is_abs_section (symbol->symbol.section)
+ && (abfd->flags & HAS_RELOC) == 0)
+ {
+ bfd_vma val;
+ asection *s;
+
+ val = symbol->symbol.value;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if (val >= s->vma && val < s->vma + s->_raw_size)
+ {
+ symbol->symbol.section = s;
+ symbol->symbol.value -= s->vma;
+ break;
+ }
+ }
+ }
+
symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
}
ieee_symbol_type *symp;
static bfd dummy_bfd;
static asymbol empty_symbol =
- /* the_bfd, name, value, attr, section */
- {&dummy_bfd, " ieee empty", (symvalue) 0, BSF_DEBUGGING, bfd_abs_section_ptr};
+ {
+ &dummy_bfd,
+ " ieee empty",
+ (symvalue) 0,
+ BSF_DEBUGGING,
+ bfd_abs_section_ptr
+#ifdef __STDC__
+ /* K&R compilers can't initialise unions. */
+ , { 0 }
+#endif
+ };
if (abfd->symcount)
{
ieee_data_type *ieee;
unsigned int index;
{
+ if (index >= ieee->section_table_size)
+ {
+ unsigned int c, i;
+ asection **n;
+
+ c = ieee->section_table_size;
+ if (c == 0)
+ c = 20;
+ while (c <= index)
+ c *= 2;
+
+ n = ((asection **)
+ bfd_realloc (ieee->section_table, c * sizeof (asection *)));
+ if (n == NULL)
+ return NULL;
+
+ for (i = ieee->section_table_size; i < c; i++)
+ n[i] = NULL;
+
+ ieee->section_table = n;
+ ieee->section_table_size = c;
+ }
+
if (ieee->section_table[index] == (asection *) NULL)
{
char *tmp = bfd_alloc (abfd, 11);
unsigned int section_index;
next_byte (&(ieee->h));
section_index = must_parse_int (&(ieee->h));
- /* Fixme to be nice about a silly number of sections */
- BFD_ASSERT (section_index < NSECTIONS);
section = get_section_entry (abfd, ieee, section_index);
section_type[0] = this_byte_and_next (&(ieee->h));
+
+ /* Set minimal section attributes. Attributes are
+ extended later, based on section contents. */
+
switch (section_type[0])
{
case 0xC1:
/* Normal attributes for absolute sections */
section_type[1] = this_byte (&(ieee->h));
- section->flags = SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
+ section->flags = SEC_ALLOC;
switch (section_type[1])
{
case 0xD3: /* AS Absolute section attributes */
case 0xD0:
/* Normal code */
next_byte (&(ieee->h));
- section->flags |= SEC_LOAD | SEC_CODE;
+ section->flags |= SEC_CODE;
break;
case 0xC4:
- next_byte (&(ieee->h));
- section->flags |= SEC_LOAD | SEC_DATA;
/* Normal data */
+ next_byte (&(ieee->h));
+ section->flags |= SEC_DATA;
break;
case 0xD2:
next_byte (&(ieee->h));
/* Normal rom data */
- section->flags |= SEC_LOAD | SEC_ROM | SEC_DATA;
+ section->flags |= SEC_ROM | SEC_DATA;
break;
default:
break;
break;
case 0xC3: /* Named relocatable sections (type C) */
section_type[1] = this_byte (&(ieee->h));
- section->flags = SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
+ section->flags = SEC_ALLOC;
switch (section_type[1])
{
case 0xD0: /* Normal code (CP) */
next_byte (&(ieee->h));
- section->flags |= SEC_LOAD | SEC_CODE;
+ section->flags |= SEC_CODE;
break;
case 0xC4: /* Normal data (CD) */
next_byte (&(ieee->h));
- section->flags |= SEC_LOAD | SEC_DATA;
+ section->flags |= SEC_DATA;
break;
case 0xD2: /* Normal rom data (CR) */
next_byte (&(ieee->h));
- section->flags |= SEC_LOAD | SEC_ROM | SEC_DATA;
+ section->flags |= SEC_ROM | SEC_DATA;
break;
default:
break;
{
ieee_data_type *ieee = IEEE_DATA (abfd);
asection *sec;
+ file_ptr debug_end;
if (ieee->w.r.debug_information_part == 0)
return true;
return false;
sec->flags |= SEC_DEBUGGING | SEC_HAS_CONTENTS;
sec->filepos = ieee->w.r.debug_information_part;
- sec->_raw_size = ieee->w.r.data_part - ieee->w.r.debug_information_part;
+
+ debug_end = ieee->w.r.data_part;
+ if (debug_end == 0)
+ debug_end = ieee->w.r.trailer_part;
+ if (debug_end == 0)
+ debug_end = ieee->w.r.me_record;
+ sec->_raw_size = debug_end - ieee->w.r.debug_information_part;
return true;
}
bfd *abfd;
{
char *library;
- boolean loop;
unsigned int i;
unsigned char buffer[512];
file_ptr buffer_offset = 0;
ieee_ar_data_type *save = abfd->tdata.ieee_ar_data;
ieee_ar_data_type *ieee;
- abfd->tdata.ieee_ar_data = (ieee_ar_data_type *) bfd_alloc (abfd, sizeof (ieee_ar_data_type));
+ unsigned int alc_elts;
+ ieee_ar_obstack_type *elts = NULL;
+
+ abfd->tdata.ieee_ar_data =
+ (ieee_ar_data_type *) bfd_alloc (abfd, sizeof (ieee_ar_data_type));
if (!abfd->tdata.ieee_ar_data)
- return NULL;
+ goto error_return;
ieee = IEEE_AR_DATA (abfd);
/* FIXME: Check return value. I'm not sure whether it needs to read
ieee->h.abfd = abfd;
if (this_byte (&(ieee->h)) != Module_Beginning)
- {
- abfd->tdata.ieee_ar_data = save;
- return (const bfd_target *) NULL;
- }
+ goto got_wrong_format_error;
next_byte (&(ieee->h));
library = read_id (&(ieee->h));
if (strcmp (library, "LIBRARY") != 0)
- {
- bfd_release (abfd, ieee);
- abfd->tdata.ieee_ar_data = save;
- return (const bfd_target *) NULL;
- }
- /* Throw away the filename */
+ goto got_wrong_format_error;
+
+ /* Throw away the filename. */
read_id (&(ieee->h));
ieee->element_count = 0;
ieee->element_index = 0;
- next_byte (&(ieee->h)); /* Drop the ad part */
- must_parse_int (&(ieee->h)); /* And the two dummy numbers */
+ next_byte (&(ieee->h)); /* Drop the ad part. */
+ must_parse_int (&(ieee->h)); /* And the two dummy numbers. */
must_parse_int (&(ieee->h));
- loop = true;
- /* Read the index of the BB table */
- while (loop)
+ alc_elts = 10;
+ elts = (ieee_ar_obstack_type *) bfd_malloc (alc_elts * sizeof *elts);
+ if (elts == NULL)
+ goto error_return;
+
+ /* Read the index of the BB table. */
+ while (1)
{
- ieee_ar_obstack_type t;
- int rec = read_2bytes (&(ieee->h));
- if (rec == (int) ieee_assign_value_to_variable_enum)
+ int rec;
+ ieee_ar_obstack_type *t;
+
+ rec = read_2bytes (&(ieee->h));
+ if (rec != (int) ieee_assign_value_to_variable_enum)
+ break;
+
+ if (ieee->element_count >= alc_elts)
{
- must_parse_int (&(ieee->h));
- t.file_offset = must_parse_int (&(ieee->h));
- t.abfd = (bfd *) NULL;
- ieee->element_count++;
+ ieee_ar_obstack_type *n;
+
+ alc_elts *= 2;
+ n = ((ieee_ar_obstack_type *)
+ bfd_realloc (elts, alc_elts * sizeof *elts));
+ if (n == NULL)
+ goto error_return;
+ elts = n;
+ }
- bfd_alloc_grow (abfd, (PTR) &t, sizeof t);
+ t = &elts[ieee->element_count];
+ ieee->element_count++;
- /* Make sure that we don't go over the end of the buffer */
+ must_parse_int (&(ieee->h));
+ t->file_offset = must_parse_int (&(ieee->h));
+ t->abfd = (bfd *) NULL;
- if ((size_t) ieee_pos (abfd) > sizeof (buffer) / 2)
- {
- /* Past half way, reseek and reprime */
- buffer_offset += ieee_pos (abfd);
- if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0)
- return NULL;
- /* FIXME: Check return value. I'm not sure whether it
- needs to read the entire buffer or not. */
- bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
- ieee->h.first_byte = buffer;
- ieee->h.input_p = buffer;
- }
+ /* Make sure that we don't go over the end of the buffer. */
+ if ((size_t) ieee_pos (abfd) > sizeof (buffer) / 2)
+ {
+ /* Past half way, reseek and reprime. */
+ buffer_offset += ieee_pos (abfd);
+ if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0)
+ goto error_return;
+
+ /* FIXME: Check return value. I'm not sure whether it needs
+ to read the entire buffer or not. */
+ bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
+ ieee->h.first_byte = buffer;
+ ieee->h.input_p = buffer;
}
- else
- loop = false;
}
- ieee->elements = (ieee_ar_obstack_type *) bfd_alloc_finish (abfd);
- if (!ieee->elements)
- return (const bfd_target *) NULL;
+ ieee->elements = ((ieee_ar_obstack_type *)
+ bfd_alloc (abfd,
+ ieee->element_count * sizeof *ieee->elements));
+ if (ieee->elements == NULL)
+ goto error_return;
- /* Now scan the area again, and replace BB offsets with file */
- /* offsets */
+ memcpy (ieee->elements, elts,
+ ieee->element_count * sizeof *ieee->elements);
+ free (elts);
+ elts = NULL;
+ /* Now scan the area again, and replace BB offsets with file offsets. */
for (i = 2; i < ieee->element_count; i++)
{
if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0)
- return NULL;
+ goto error_return;
+
/* FIXME: Check return value. I'm not sure whether it needs to
read the entire buffer or not. */
bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd);
ieee->h.first_byte = buffer;
ieee->h.input_p = buffer;
- next_byte (&(ieee->h)); /* Drop F8 */
- next_byte (&(ieee->h)); /* Drop 14 */
- must_parse_int (&(ieee->h)); /* Drop size of block */
+ next_byte (&(ieee->h)); /* Drop F8. */
+ next_byte (&(ieee->h)); /* Drop 14. */
+ must_parse_int (&(ieee->h)); /* Drop size of block. */
+
if (must_parse_int (&(ieee->h)) != 0)
- {
- /* This object has been deleted */
- ieee->elements[i].file_offset = 0;
- }
+ /* This object has been deleted. */
+ ieee->elements[i].file_offset = 0;
else
- {
- ieee->elements[i].file_offset = must_parse_int (&(ieee->h));
- }
+ ieee->elements[i].file_offset = must_parse_int (&(ieee->h));
}
-/* abfd->has_armap = ;*/
+ /* abfd->has_armap = ;*/
+
return abfd->xvec;
+
+ got_wrong_format_error:
+ bfd_release (abfd, ieee);
+ abfd->tdata.ieee_ar_data = save;
+ bfd_set_error (bfd_error_wrong_format);
+
+ error_return:
+ if (elts != NULL)
+ free (elts);
+
+ return NULL;
}
static boolean
ieee->external_reference_min_index = IEEE_REFERENCE_BASE;
ieee->external_reference_max_index = 0;
ieee->h.abfd = abfd;
- memset ((PTR) ieee->section_table, 0, sizeof (ieee->section_table));
+ ieee->section_table = NULL;
+ ieee->section_table_size = 0;
processor = ieee->mb.processor = read_id (&(ieee->h));
if (strcmp (processor, "LIBRARY") == 0)
/* Determine the architecture and machine type of the object file.
*/
{
- const bfd_arch_info_type *arch = bfd_scan_arch (processor);
+ const bfd_arch_info_type *arch;
+ char family[10];
+
+ /* IEEE does not specify the format of the processor identificaton
+ string, so the compiler is free to put in it whatever it wants.
+ We try here to recognize different processors belonging to the
+ m68k family. Code for other processors can be added here. */
+ if ((processor[0] == '6') && (processor[1] == '8'))
+ {
+ if (processor[2] == '3') /* 683xx integrated processors */
+ {
+ switch (processor[3])
+ {
+ case '0': /* 68302, 68306, 68307 */
+ case '2': /* 68322, 68328 */
+ case '5': /* 68356 */
+ strcpy (family, "68000"); /* MC68000-based controllers */
+ break;
+
+ case '3': /* 68330, 68331, 68332, 68333,
+ 68334, 68335, 68336, 68338 */
+ case '6': /* 68360 */
+ case '7': /* 68376 */
+ strcpy (family, "68332"); /* CPU32 and CPU32+ */
+ break;
+
+ case '4':
+ if (processor[4] == '9') /* 68349 */
+ strcpy (family, "68030"); /* CPU030 */
+ else /* 68340, 68341 */
+ strcpy (family, "68332"); /* CPU32 and CPU32+ */
+ break;
+
+ default: /* Does not exist yet */
+ strcpy (family, "68332"); /* Guess it will be CPU32 */
+ }
+ }
+ else if (toupper (processor[3]) == 'F') /* 68F333 */
+ strcpy (family, "68332"); /* CPU32 */
+ else if ((toupper (processor[3]) == 'C') /* Embedded controllers */
+ && ((toupper (processor[2]) == 'E')
+ || (toupper (processor[2]) == 'H')
+ || (toupper (processor[2]) == 'L')))
+ {
+ strcpy (family, "68");
+ strncat (family, processor + 4, 7);
+ family[9] = '\0';
+ }
+ else /* "Regular" processors */
+ {
+ strncpy (family, processor, 9);
+ family[9] = '\0';
+ }
+ }
+ else if ((strncmp (processor, "cpu32", 5) == 0) /* CPU32 and CPU32+ */
+ || (strncmp (processor, "CPU32", 5) == 0))
+ strcpy (family, "68332");
+ else
+ {
+ strncpy (family, processor, 9);
+ family[9] = '\0';
+ }
+
+ arch = bfd_scan_arch (family);
if (arch == 0)
goto got_wrong_format;
abfd->arch_info = arch;
}
}
- abfd->flags = HAS_SYMS;
-/* By now we know that this is a real IEEE file, we're going to read
- the whole thing into memory so that we can run up and down it
- quickly. We can work out how big the file is from the trailer
- record */
- IEEE_DATA (abfd)->h.first_byte = (unsigned char *) bfd_alloc (ieee->h.abfd, ieee->w.r.me_record
- + 50);
+ if (ieee->w.r.external_part != 0)
+ abfd->flags = HAS_SYMS;
+
+ /* By now we know that this is a real IEEE file, we're going to read
+ the whole thing into memory so that we can run up and down it
+ quickly. We can work out how big the file is from the trailer
+ record */
+
+ IEEE_DATA (abfd)->h.first_byte =
+ (unsigned char *) bfd_alloc (ieee->h.abfd, ieee->w.r.me_record + 1);
if (!IEEE_DATA (abfd)->h.first_byte)
goto fail;
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
goto fail;
/* FIXME: Check return value. I'm not sure whether it needs to read
the entire buffer or not. */
- bfd_read ((PTR) (IEEE_DATA (abfd)->h.first_byte), 1, ieee->w.r.me_record + 50, abfd);
+ bfd_read ((PTR) (IEEE_DATA (abfd)->h.first_byte), 1,
+ ieee->w.r.me_record + 1, abfd);
ieee_slurp_sections (abfd);
if (! ieee_slurp_debug (abfd))
goto fail;
+ /* Parse section data to activate file and section flags implied by
+ section contents. */
+
+ if (! ieee_slurp_section_data (abfd))
+ goto fail;
+
return abfd->xvec;
got_wrong_format:
bfd_set_error (bfd_error_wrong_format);
void
ieee_get_symbol_info (ignore_abfd, symbol, ret)
- bfd *ignore_abfd;
+ bfd *ignore_abfd ATTRIBUTE_UNUSED;
asymbol *symbol;
symbol_info *ret;
{
void
ieee_print_symbol (ignore_abfd, afile, symbol, how)
- bfd *ignore_abfd;
+ bfd *ignore_abfd ATTRIBUTE_UNUSED;
PTR afile;
asymbol *symbol;
bfd_print_symbol_type how;
}
static boolean
-do_one (ieee, current_map, location_ptr, s)
+do_one (ieee, current_map, location_ptr, s, iterations)
ieee_data_type *ieee;
ieee_per_section_type *current_map;
unsigned char *location_ptr;
asection *s;
+ int iterations;
{
switch (this_byte (&(ieee->h)))
{
&r->symbol,
&pcrel, &extra, §ion);
r->relent.address = current_map->pc;
+ s->flags |= SEC_RELOC;
+ s->owner->flags |= HAS_RELOC;
s->reloc_count++;
- if (r->relent.sym_ptr_ptr == 0)
- {
- r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;
- }
+ if (r->relent.sym_ptr_ptr == NULL && section != NULL)
+ r->relent.sym_ptr_ptr = section->symbol_ptr_ptr;
if (this_byte (&(ieee->h)) == (int) ieee_comma)
{
default:
BFD_FAIL ();
- break;
+ return false;
}
}
break;
}
}
}
+
+ /* Prevent more than the first load-item of an LR record
+ from being repeated (MRI convention). */
+ if (iterations != 1)
+ loop = false;
}
}
}
next_byte (&(ieee->h));
section_number = must_parse_int (&(ieee->h));
s = ieee->section_table[section_number];
+ s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
current_map = (ieee_per_section_type *) s->used_by_bfd;
location_ptr = current_map->data - s->vma;
/* The document I have says that Microtec's compilers reset */
break;
case ieee_value_starting_address_enum & 0xff:
+ next_byte (&(ieee->h));
+ if (this_byte (&(ieee->h)) == ieee_function_either_open_b_enum)
+ next_byte (&(ieee->h));
+ abfd->start_address = must_parse_int (&(ieee->h));
/* We've got to the end of the data now - */
return true;
default:
BFD_FAIL ();
- return true;
+ return false;
}
break;
case ieee_repeat_data_enum:
while (iterations != 0)
{
ieee->h.input_p = start;
- if (!do_one (ieee, current_map, location_ptr, s))
+ if (!do_one (ieee, current_map, location_ptr, s,
+ iterations))
return false;
iterations--;
}
case ieee_load_constant_bytes_enum:
case ieee_load_with_relocation_enum:
{
- if (!do_one (ieee, current_map, location_ptr, s))
+ if (!do_one (ieee, current_map, location_ptr, s, 1))
return false;
}
}
/* Work out which symbol to attach it this reloc to */
switch (src->symbol.letter)
{
+ case 'I':
+ src->relent.sym_ptr_ptr =
+ symbols + src->symbol.index + ieee->external_symbol_base_offset;
+ break;
case 'X':
src->relent.sym_ptr_ptr =
symbols + src->symbol.index + ieee->external_reference_base_offset;
break;
case 0:
- src->relent.sym_ptr_ptr =
- src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
+ if (src->relent.sym_ptr_ptr != NULL)
+ src->relent.sym_ptr_ptr =
+ src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr;
break;
default:
((bfd_byte)
(s->index
+ IEEE_SECTION_NUMBER_BASE)))
- || ! ieee_write_int (abfd, s->vma))
+ || ! ieee_write_int (abfd, s->lma))
return false;
}
}
bfd *abfd;
asection *s;
{
+ unsigned int number_of_maus_in_address =
+ bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd);
unsigned int relocs_to_go = s->reloc_count;
bfd_byte *stream = ieee_per_section (s)->data;
arelent **p = s->orelocation;
(bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))
|| ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum)
|| ! ieee_write_byte (abfd,
- (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))
- || ! ieee_write_expression (abfd, 0, s->symbol, 0, 0))
+ (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)))
return false;
+ if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0)
+ {
+ if (! ieee_write_int (abfd, s->lma))
+ return false;
+ }
+ else
+ {
+ if (! ieee_write_expression (abfd, 0, s->symbol, 0, 0))
+ return false;
+ }
if (relocs_to_go == 0)
{
while (current_byte_index < s->_raw_size)
{
bfd_size_type run;
- unsigned int MAXRUN = 32;
+ unsigned int MAXRUN = 127;
run = MAXRUN;
if (run > s->_raw_size - current_byte_index)
{
while (current_byte_index < s->_raw_size)
{
bfd_size_type run;
- unsigned int MAXRUN = 32;
+ unsigned int MAXRUN = 127;
if (relocs_to_go)
{
run = (*p)->address - current_byte_index;
+ if (run > MAXRUN)
+ run = MAXRUN;
}
else
{
&& (*p) && (*p)->address == current_byte_index)
{
arelent *r = *p;
- bfd_vma ov;
+ bfd_signed_vma ov;
#if 0
if (r->howto->pc_relative)
{
case 2:
- ov = bfd_get_32 (abfd,
- stream + current_byte_index);
+ ov = bfd_get_signed_32 (abfd,
+ stream + current_byte_index);
current_byte_index += 4;
break;
case 1:
- ov = bfd_get_16 (abfd,
- stream + current_byte_index);
+ ov = bfd_get_signed_16 (abfd,
+ stream + current_byte_index);
current_byte_index += 2;
break;
case 0:
- ov = bfd_get_8 (abfd,
- stream + current_byte_index);
+ ov = bfd_get_signed_8 (abfd,
+ stream + current_byte_index);
current_byte_index++;
break;
default:
ov = 0;
BFD_FAIL ();
+ return false;
}
+
+ ov &= r->howto->src_mask;
+
+ if (r->howto->pc_relative
+ && ! r->howto->pcrel_offset)
+ ov += r->address;
+
if (! ieee_write_byte (abfd,
ieee_function_either_open_b_enum))
return false;
return false;
}
- if (1 || r->howto->size != 2)
+ if (number_of_maus_in_address
+ != bfd_get_reloc_size (r->howto))
{
- if (! ieee_write_byte (abfd, ieee_comma)
- || ! ieee_write_int (abfd, 1 << r->howto->size))
+ if (! ieee_write_int (abfd,
+ bfd_get_reloc_size (r->howto)))
return false;
}
if (! ieee_write_byte (abfd,
|| ! ieee_write_byte (abfd,
(bfd_byte) (s->index
+ IEEE_SECTION_NUMBER_BASE))
- || ! ieee_write_int (abfd, s->vma)
+ || ! ieee_write_int (abfd, s->lma)
|| ! ieee_write_byte (abfd, ieee_repeat_data_enum)
|| ! ieee_write_int (abfd, s->_raw_size)
|| ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)
s = ieee->section_table[section_number];
if (s->output_section)
{
- value = s->output_section->vma;
+ value = s->output_section->lma;
}
else
{
static void
relocate_debug (output, input)
- bfd *output;
+ bfd *output ATTRIBUTE_UNUSED;
bfd *input;
{
#define IBS 400
block ();
}
-/*
- During linking, we we told about the bfds which made up our
- contents, we have a list of them. They will still be open, so go to
- the debug info in each, and copy it out, relocating it as we go.
-*/
+/* Gather together all the debug information from each input BFD into
+ one place, relocating it and emitting it as we go. */
static boolean
ieee_write_debug_part (abfd)
ieee->w.r.data_part = bfd_tell (abfd);
for (s = abfd->sections; s != (asection *) NULL; s = s->next)
{
- if ((s->flags & SEC_DEBUGGING) != 0)
+ /* Skip sections that have no loadable contents (.bss,
+ debugging, etc.) */
+ if ((s->flags & SEC_LOAD) == 0)
continue;
+
/* Sort the reloc records so we can insert them in the correct
- places */
+ places */
if (s->reloc_count != 0)
{
if (! do_with_relocs (abfd, s))
{
if (section->contents == NULL)
{
- section->contents = bfd_alloc (abfd, section->_raw_size);
+ section->contents = ((unsigned char *)
+ bfd_alloc (abfd, section->_raw_size));
if (section->contents == NULL)
return false;
}
for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++)
{
asymbol *p = *q;
- hadone = true;
if (bfd_is_und_section (p->section))
{
/* This must be a symbol reference .. */
return false;
p->value = reference_index;
reference_index++;
+ hadone = true;
}
else if (bfd_is_com_section (p->section))
{
|| ! ieee_write_byte (abfd,
ieee_weak_external_reference_enum)
|| ! ieee_write_int (abfd, reference_index)
- || ! ieee_write_int (abfd, p->value)
- || ! ieee_write_int (abfd, BFD_FORT_COMM_DEFAULT_VALUE))
+ || ! ieee_write_int (abfd, p->value))
return false;
p->value = reference_index;
reference_index++;
+ hadone = true;
}
else if (p->flags & BSF_GLOBAL)
{
}
p->value = public_index;
public_index++;
+ hadone = true;
}
else
{
ieee->w.r.trailer_part = bfd_tell (abfd);
if (abfd->start_address)
{
- ieee->w.r.me_record = bfd_tell (abfd);
if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum)
|| ! ieee_write_byte (abfd, ieee_function_either_open_b_enum)
|| ! ieee_write_int (abfd, abfd->start_address)
|| ! ieee_write_byte (abfd, ieee_function_either_close_b_enum))
return false;
}
- else
- {
- ieee->w.r.me_record = bfd_tell (abfd);
- }
+ ieee->w.r.me_record = bfd_tell (abfd);
if (! ieee_write_byte (abfd, ieee_module_end_enum))
return false;
return true;
}
+/* Write out the IEEE processor ID. */
+
+static boolean
+ieee_write_processor (abfd)
+ bfd *abfd;
+{
+ const bfd_arch_info_type *arch;
+
+ arch = bfd_get_arch_info (abfd);
+ switch (arch->arch)
+ {
+ default:
+ if (! ieee_write_id (abfd, bfd_printable_name (abfd)))
+ return false;
+ break;
+
+ case bfd_arch_a29k:
+ if (! ieee_write_id (abfd, "29000"))
+ return false;
+ break;
+
+ case bfd_arch_h8300:
+ if (! ieee_write_id (abfd, "H8/300"))
+ return false;
+ break;
+
+ case bfd_arch_h8500:
+ if (! ieee_write_id (abfd, "H8/500"))
+ return false;
+ break;
+
+ case bfd_arch_i960:
+ switch (arch->mach)
+ {
+ default:
+ case bfd_mach_i960_core:
+ case bfd_mach_i960_ka_sa:
+ if (! ieee_write_id (abfd, "80960KA"))
+ return false;
+ break;
+
+ case bfd_mach_i960_kb_sb:
+ if (! ieee_write_id (abfd, "80960KB"))
+ return false;
+ break;
+
+ case bfd_mach_i960_ca:
+ if (! ieee_write_id (abfd, "80960CA"))
+ return false;
+ break;
+
+ case bfd_mach_i960_mc:
+ case bfd_mach_i960_xa:
+ if (! ieee_write_id (abfd, "80960MC"))
+ return false;
+ break;
+ }
+ break;
+
+ case bfd_arch_m68k:
+ {
+ const char *id;
+
+ switch (arch->mach)
+ {
+ default: id = "68020"; break;
+ case bfd_mach_m68000: id = "68000"; break;
+ case bfd_mach_m68008: id = "68008"; break;
+ case bfd_mach_m68010: id = "68010"; break;
+ case bfd_mach_m68020: id = "68020"; break;
+ case bfd_mach_m68030: id = "68030"; break;
+ case bfd_mach_m68040: id = "68040"; break;
+ case bfd_mach_m68060: id = "68060"; break;
+ case bfd_mach_cpu32: id = "cpu32"; break;
+ case bfd_mach_mcf5200:id = "5200"; break;
+ case bfd_mach_mcf5206e:id = "5206e"; break;
+ case bfd_mach_mcf5307:id = "5307"; break;
+ case bfd_mach_mcf5407:id = "5407"; break;
+ }
+
+ if (! ieee_write_id (abfd, id))
+ return false;
+ }
+ break;
+ }
+
+ return true;
+}
+
boolean
ieee_write_object_contents (abfd)
bfd *abfd;
/* Fast forward over the header area */
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
return false;
+
if (! ieee_write_byte (abfd, ieee_module_beginning_enum)
- || ! ieee_write_id (abfd, bfd_printable_name (abfd))
+ || ! ieee_write_processor (abfd)
|| ! ieee_write_id (abfd, abfd->filename))
return false;
ieee->w.r.environmental_record = bfd_tell (abfd);
if (bfd_write ((char *) envi, 1, sizeof (envi), abfd) != sizeof (envi))
return false;
+
+ /* The HP emulator database requires a timestamp in the file. */
+ {
+ time_t now;
+ const struct tm *t;
+
+ time (&now);
+ t = (struct tm *) localtime (&now);
+ if (! ieee_write_2bytes (abfd, (int) ieee_atn_record_enum)
+ || ! ieee_write_byte (abfd, 0x21)
+ || ! ieee_write_byte (abfd, 0)
+ || ! ieee_write_byte (abfd, 50)
+ || ! ieee_write_int (abfd, t->tm_year + 1900)
+ || ! ieee_write_int (abfd, t->tm_mon + 1)
+ || ! ieee_write_int (abfd, t->tm_mday)
+ || ! ieee_write_int (abfd, t->tm_hour)
+ || ! ieee_write_int (abfd, t->tm_min)
+ || ! ieee_write_int (abfd, t->tm_sec))
+ return false;
+ }
+
output_bfd = abfd;
flush ();
bfd *abfd;
{
ieee_symbol_type *new =
- (ieee_symbol_type *) bfd_zmalloc (sizeof (ieee_symbol_type));
+ (ieee_symbol_type *) bfd_zalloc (abfd, sizeof (ieee_symbol_type));
if (!new)
return NULL;
new->symbol.the_bfd = abfd;
filename_ptr,
functionname_ptr,
line_ptr)
- bfd *abfd;
- asection *section;
- asymbol **symbols;
- bfd_vma offset;
- char **filename_ptr;
- char **functionname_ptr;
- int *line_ptr;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *section ATTRIBUTE_UNUSED;
+ asymbol **symbols ATTRIBUTE_UNUSED;
+ bfd_vma offset ATTRIBUTE_UNUSED;
+ const char **filename_ptr ATTRIBUTE_UNUSED;
+ const char **functionname_ptr ATTRIBUTE_UNUSED;
+ unsigned int *line_ptr ATTRIBUTE_UNUSED;
{
return false;
}
bfd *abfd;
struct stat *buf;
{
- ieee_ar_data_type *ar = abfd->my_archive->tdata.ieee_ar_data;
+ ieee_ar_data_type *ar = (ieee_ar_data_type *) NULL;
+ ieee_data_type *ieee;
+
+ if (abfd->my_archive != NULL)
+ ar = abfd->my_archive->tdata.ieee_ar_data;
if (ar == (ieee_ar_data_type *) NULL)
{
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
- else
+
+ if (IEEE_DATA (abfd) == NULL)
{
- buf->st_size = 0x1;
- buf->st_mode = 0666;
- return !ieee_object_p (abfd);
+ if (ieee_object_p (abfd) == NULL)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return -1;
+ }
}
+
+ ieee = IEEE_DATA (abfd);
+
+ buf->st_size = ieee->w.r.me_record + 1;
+ buf->st_mode = 0644;
+ return 0;
}
static int
ieee_sizeof_headers (abfd, x)
- bfd *abfd;
- boolean x;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ boolean x ATTRIBUTE_UNUSED;
{
return 0;
}
bfd_true)
#define ieee_read_ar_hdr bfd_nullvoidptr
#define ieee_update_armap_timestamp bfd_true
+#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index
-#define ieee_bfd_is_local_label bfd_generic_is_local_label
+#define ieee_bfd_is_local_label_name bfd_generic_is_local_label_name
#define ieee_get_lineno _bfd_nosymbols_get_lineno
#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
#define ieee_read_minisymbols _bfd_generic_read_minisymbols
#define ieee_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#define ieee_bfd_relax_section bfd_generic_relax_section
+#define ieee_bfd_gc_sections bfd_generic_gc_sections
+#define ieee_bfd_merge_sections bfd_generic_merge_sections
#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols
#define ieee_bfd_final_link _bfd_generic_final_link
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
(SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
| SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
- 0, /* leading underscore */
+ '_', /* leading underscore */
' ', /* ar_pad_char */
16, /* ar_max_namelen */
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
BFD_JUMP_TABLE_LINK (ieee),
BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+ NULL,
+
(PTR) 0
};