/* BFD back-end for mmo objects (MMIX-specific object-format).
- Copyright 2001, 2002
+ Copyright 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Hans-Peter Nilsson (hp@bitrange.com).
Infrastructure and other bits originally copied from srec.c and
struct mmo_symbol
{
struct mmo_symbol *next;
- CONST char *name;
+ const char *name;
bfd_vma value;
enum mmo_sym_type sym_type;
unsigned int serno;
/* When we're reading bytes recursively, check this occasionally.
Also holds write errors. */
- boolean have_error;
+ bfd_boolean have_error;
/* Max symbol length that may appear in the lop_stab table. Note that
this table might just hold a subset of symbols for not-really large
mmo_data_list_type *tail;
};
+#define mmo_section_data(sec) \
+ ((struct mmo_section_data_struct *) (sec)->used_by_bfd)
+
/* These structures are used in bfd_map_over_sections constructs. */
/* Used when writing out sections; all but the register contents section
struct mmo_write_sec_info
{
asection *reg_section;
- boolean retval;
+ bfd_boolean retval;
};
/* Used when trying to find a section corresponding to addr. */
bfd_vma addr;
};
-static boolean mmo_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
+static bfd_boolean mmo_bfd_copy_private_bfd_data
+ PARAMS ((bfd *, bfd *));
static void mmo_write_section_unless_reg_contents
PARAMS ((bfd *, asection *, PTR));
-static void mmo_find_sec_w_addr PARAMS ((bfd *, asection *, PTR));
-static void mmo_find_sec_w_addr_grow PARAMS ((bfd *, asection *, PTR));
-static asection *mmo_make_section PARAMS ((bfd *, CONST char *));
-static void mmo_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
+static void mmo_find_sec_w_addr
+ PARAMS ((bfd *, asection *, PTR));
+static void mmo_find_sec_w_addr_grow
+ PARAMS ((bfd *, asection *, PTR));
+static asection *mmo_make_section
+ PARAMS ((bfd *, const char *));
+static void mmo_get_symbol_info
+ PARAMS ((bfd *, asymbol *, symbol_info *));
static void mmo_print_symbol
- PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
-static void mmo_init PARAMS ((void));
-static boolean mmo_mkobject PARAMS ((bfd *));
-static boolean mmo_scan PARAMS ((bfd *));
-static asection *mmo_decide_section PARAMS ((bfd *, bfd_vma));
-static asection *mmo_get_generic_spec_data_section PARAMS ((bfd *, int));
-static asection *mmo_get_spec_section PARAMS ((bfd *, int));
-static INLINE bfd_byte *mmo_get_loc PARAMS ((asection *, bfd_vma, int));
-static void mmo_xore_64 PARAMS ((asection *, bfd_vma vma, bfd_vma value));
-static void mmo_xore_32 PARAMS ((asection *, bfd_vma vma, unsigned int));
-static void mmo_xore_16 PARAMS ((asection *, bfd_vma vma, unsigned int));
-static CONST bfd_target *mmo_object_p PARAMS ((bfd *));
-static void mmo_map_set_sizes PARAMS ((bfd *, asection *, PTR));
-static boolean mmo_get_symbols PARAMS ((bfd *));
-static boolean mmo_create_symbol PARAMS ((bfd *, CONST char *, bfd_vma,
- enum mmo_sym_type, unsigned int));
-static boolean mmo_get_section_contents
+ PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
+static void mmo_init
+ PARAMS ((void));
+static bfd_boolean mmo_mkobject
+ PARAMS ((bfd *));
+static bfd_boolean mmo_scan
+ PARAMS ((bfd *));
+static asection *mmo_decide_section
+ PARAMS ((bfd *, bfd_vma));
+static asection *mmo_get_generic_spec_data_section
+ PARAMS ((bfd *, int));
+static asection *mmo_get_spec_section
+ PARAMS ((bfd *, int));
+static INLINE bfd_byte *mmo_get_loc
+ PARAMS ((asection *, bfd_vma, int));
+static void mmo_xore_64
+ PARAMS ((asection *, bfd_vma vma, bfd_vma value));
+static void mmo_xore_32
+ PARAMS ((asection *, bfd_vma vma, unsigned int));
+static void mmo_xore_16
+ PARAMS ((asection *, bfd_vma vma, unsigned int));
+static const bfd_target *mmo_object_p
+ PARAMS ((bfd *));
+static void mmo_map_set_sizes
+ PARAMS ((bfd *, asection *, PTR));
+static bfd_boolean mmo_get_symbols
+ PARAMS ((bfd *));
+static bfd_boolean mmo_create_symbol
+ PARAMS ((bfd *, const char *, bfd_vma, enum mmo_sym_type, unsigned int));
+static bfd_boolean mmo_get_section_contents
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
-static long mmo_get_symtab_upper_bound PARAMS ((bfd *));
-static long mmo_get_symtab PARAMS ((bfd *, asymbol **));
-static void mmo_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
-static void mmo_print_symbol PARAMS ((bfd *, PTR, asymbol *,
- bfd_print_symbol_type));
-static boolean mmo_set_section_contents
- PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
-static int mmo_sizeof_headers PARAMS ((bfd *, boolean));
-static long mmo_get_reloc_upper_bound PARAMS ((bfd *, asection *));
-
-static boolean mmo_internal_write_header PARAMS ((bfd *));
-static boolean mmo_internal_write_post PARAMS ((bfd *, int, asection *));
-static boolean mmo_internal_add_3_sym
- PARAMS ((bfd *, struct mmo_symbol_trie *, CONST struct mmo_symbol *));
+static long mmo_get_symtab_upper_bound
+ PARAMS ((bfd *));
+static long mmo_canonicalize_symtab
+ PARAMS ((bfd *, asymbol **));
+static void mmo_get_symbol_info
+ PARAMS ((bfd *, asymbol *, symbol_info *));
+static void mmo_print_symbol
+ PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
+static bfd_boolean mmo_set_section_contents
+ PARAMS ((bfd *, sec_ptr, const PTR, file_ptr, bfd_size_type));
+static int mmo_sizeof_headers
+ PARAMS ((bfd *, bfd_boolean));
+static long mmo_get_reloc_upper_bound
+ PARAMS ((bfd *, asection *));
+
+static bfd_boolean mmo_internal_write_header
+ PARAMS ((bfd *));
+static bfd_boolean mmo_internal_write_post
+ PARAMS ((bfd *, int, asection *));
+static bfd_boolean mmo_internal_add_3_sym
+ PARAMS ((bfd *, struct mmo_symbol_trie *, const struct mmo_symbol *));
static unsigned int mmo_internal_3_length
- PARAMS ((bfd *, struct mmo_symbol_trie *));
+ PARAMS ((bfd *, struct mmo_symbol_trie *));
static void mmo_internal_3_dump
- PARAMS ((bfd *, struct mmo_symbol_trie *));
-static void mmo_beb128_out PARAMS ((bfd *, int, int));
-static boolean mmo_internal_write_section
+ PARAMS ((bfd *, struct mmo_symbol_trie *));
+static void mmo_beb128_out
+ PARAMS ((bfd *, int, int));
+static bfd_boolean mmo_internal_write_section
PARAMS ((bfd *, asection *));
-static void mmo_write_tetra PARAMS ((bfd *, unsigned int));
-static void mmo_write_tetra_raw PARAMS ((bfd *, unsigned int));
-static void mmo_write_octa PARAMS ((bfd *, bfd_vma));
-static void mmo_write_octa_raw PARAMS ((bfd *, bfd_vma));
-static boolean mmo_write_chunk
- PARAMS ((bfd *, CONST bfd_byte *, unsigned int));
-static boolean mmo_write_loc_chunk
- PARAMS ((bfd *, bfd_vma, CONST bfd_byte *, unsigned int));
-static boolean mmo_write_chunk_list PARAMS ((bfd *, mmo_data_list_type *));
-static boolean mmo_write_loc_chunk_list
+static void mmo_write_tetra
+ PARAMS ((bfd *, unsigned int));
+static void mmo_write_tetra_raw
+ PARAMS ((bfd *, unsigned int));
+static void mmo_write_octa
+ PARAMS ((bfd *, bfd_vma));
+static void mmo_write_octa_raw
+ PARAMS ((bfd *, bfd_vma));
+static bfd_boolean mmo_write_chunk
+ PARAMS ((bfd *, const bfd_byte *, unsigned int));
+static bfd_boolean mmo_flush_chunk
+ PARAMS ((bfd *));
+static bfd_boolean mmo_write_loc_chunk
+ PARAMS ((bfd *, bfd_vma, const bfd_byte *, unsigned int, bfd_vma *));
+static bfd_boolean mmo_write_chunk_list
PARAMS ((bfd *, mmo_data_list_type *));
-static boolean mmo_write_symbols_and_terminator PARAMS ((bfd *));
-static flagword mmo_sec_flags_from_bfd_flags PARAMS ((flagword));
-static flagword bfd_sec_flags_from_mmo_flags PARAMS ((flagword));
-static bfd_byte mmo_get_byte PARAMS ((bfd *));
-static void mmo_write_byte PARAMS ((bfd *, bfd_byte));
-static boolean mmo_new_section_hook PARAMS ((bfd *, asection *));
-static int mmo_sort_mmo_symbols PARAMS ((CONST PTR, CONST PTR));
-static boolean mmo_write_object_contents PARAMS ((bfd *));
+static bfd_boolean mmo_write_loc_chunk_list
+ PARAMS ((bfd *, mmo_data_list_type *));
+static bfd_boolean mmo_write_symbols_and_terminator
+ PARAMS ((bfd *));
+static flagword mmo_sec_flags_from_bfd_flags
+ PARAMS ((flagword));
+static flagword bfd_sec_flags_from_mmo_flags
+ PARAMS ((flagword));
+static bfd_byte mmo_get_byte
+ PARAMS ((bfd *));
+static void mmo_write_byte
+ PARAMS ((bfd *, bfd_byte));
+static bfd_boolean mmo_new_section_hook
+ PARAMS ((bfd *, asection *));
+static int mmo_sort_mmo_symbols
+ PARAMS ((const PTR, const PTR));
+static bfd_boolean mmo_write_object_contents
+ PARAMS ((bfd *));
static long mmo_canonicalize_reloc
PARAMS ((bfd *, sec_ptr, arelent **, asymbol **));
static asection *
mmo_make_section (abfd, secname)
bfd *abfd;
- CONST char *secname;
+ const char *secname;
{
asection *sec = bfd_get_section_by_name (abfd, secname);
static void
mmo_init ()
{
- static boolean inited = false;
+ static bfd_boolean inited = FALSE;
int i = 0;
int j = 0;
static const char letters[]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:_";
- if (inited == true)
+ if (inited)
return;
- inited = true;
+ inited = TRUE;
/* Fill in the set of valid symbol characters. */
strcpy (valid_mmo_symbol_character_set, letters);
/* Check whether an existing file is an mmo file. */
-static CONST bfd_target *
+static const bfd_target *
mmo_object_p (abfd)
bfd *abfd;
{
/* Set up the mmo tdata information. */
-static boolean
+static bfd_boolean
mmo_mkobject (abfd)
bfd *abfd;
{
initialize most. */
tdata_type *tdata = (tdata_type *) bfd_zmalloc (sizeof (tdata_type));
if (tdata == NULL)
- return false;
+ return FALSE;
created = time (NULL);
bfd_put_32 (abfd, created, tdata->created);
abfd->tdata.mmo_data = tdata;
}
- return true;
+ return TRUE;
}
-static boolean
+static bfd_boolean
mmo_bfd_copy_private_bfd_data (ibfd, obfd)
bfd *ibfd;
bfd *obfd;
{
if (bfd_get_flavour (ibfd) != bfd_target_mmo_flavour
|| bfd_get_flavour (obfd) != bfd_target_mmo_flavour)
- return true;
+ return TRUE;
/* Copy the time the copied-from file was created. If people want the
time the file was last *modified*, they have that in the normal file
information. */
memcpy (obfd->tdata.mmo_data->created, ibfd->tdata.mmo_data->created,
sizeof (obfd->tdata.mmo_data->created));
- return true;
+ return TRUE;
}
/* Helper functions for mmo_decide_section, used through
!= (SEC_LOAD | SEC_ALLOC))
return;
- if (infop->addr >= vma && infop->addr < vma + sec->_raw_size)
+ if (infop->addr >= vma && infop->addr < vma + sec->size)
infop->sec = sec;
}
bfd_put_32 (abfd, value, buf);
if (bfd_bwrite ((PTR) buf, 4, abfd) != 4)
- abfd->tdata.mmo_data->have_error = true;
+ abfd->tdata.mmo_data->have_error = TRUE;
}
/* Write a 32-bit word to output file; lop_quote if necessary. */
mmo_write_tetra_raw (abfd, (unsigned int) value);
}
-/* Write quoted contents, zero filled. */
+/* Write quoted contents. Intended to be called multiple times in
+ sequence, followed by a call to mmo_flush_chunk. */
-static INLINE boolean
+static INLINE bfd_boolean
mmo_write_chunk (abfd, loc, len)
bfd *abfd;
- CONST bfd_byte *loc;
+ const bfd_byte *loc;
unsigned int len;
{
- boolean retval = true;
- bfd_byte buf[4] = {0, 0, 0, 0};
+ bfd_boolean retval = TRUE;
+
+ /* Fill up a tetra from bytes remaining from a previous chunk. */
+ if (abfd->tdata.mmo_data->byte_no != 0)
+ {
+ while (abfd->tdata.mmo_data->byte_no < 4 && len != 0)
+ {
+ abfd->tdata.mmo_data->buf[abfd->tdata.mmo_data->byte_no++] = *loc++;
+ len--;
+ }
+
+ if (abfd->tdata.mmo_data->byte_no == 4)
+ {
+ mmo_write_tetra (abfd,
+ bfd_get_32 (abfd, abfd->tdata.mmo_data->buf));
+ abfd->tdata.mmo_data->byte_no = 0;
+ }
+ }
while (len >= 4)
{
if (loc[0] == LOP)
mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT);
- retval
- = (retval == true
- && abfd->tdata.mmo_data->have_error == false
- && 4 == bfd_bwrite ((PTR) loc, 4, abfd));
+ retval = (retval
+ && ! abfd->tdata.mmo_data->have_error
+ && 4 == bfd_bwrite ((PTR) loc, 4, abfd));
loc += 4;
len -= 4;
if (len)
{
- memcpy (buf, loc, len);
- if (buf[0] == LOP)
- mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT);
-
- retval
- = (retval == true
- && abfd->tdata.mmo_data->have_error == false
- && 4 == bfd_bwrite ((PTR) buf, 4, abfd));
+ memcpy (abfd->tdata.mmo_data->buf, loc, len);
+ abfd->tdata.mmo_data->byte_no = len;
}
+ if (! retval)
+ abfd->tdata.mmo_data->have_error = TRUE;
return retval;
}
+/* Flush remaining bytes, from a previous mmo_write_chunk, zero-padded to
+ 4 bytes. */
+
+static INLINE bfd_boolean
+mmo_flush_chunk (abfd)
+ bfd *abfd;
+{
+ if (abfd->tdata.mmo_data->byte_no != 0)
+ {
+ memset (abfd->tdata.mmo_data->buf + abfd->tdata.mmo_data->byte_no,
+ 0, 4 - abfd->tdata.mmo_data->byte_no);
+ mmo_write_tetra (abfd,
+ bfd_get_32 (abfd, abfd->tdata.mmo_data->buf));
+ abfd->tdata.mmo_data->byte_no = 0;
+ }
+
+ return ! abfd->tdata.mmo_data->have_error;
+}
+
/* Same, but from a list. */
-static INLINE boolean
+static INLINE bfd_boolean
mmo_write_chunk_list (abfd, datap)
bfd *abfd;
mmo_data_list_type *datap;
{
for (; datap != NULL; datap = datap->next)
if (! mmo_write_chunk (abfd, datap->data, datap->size))
- return false;
+ return FALSE;
- return true;
+ return mmo_flush_chunk (abfd);
}
-/* Write a lop_loc and some contents. */
+/* Write a lop_loc and some contents. A caller needs to call
+ mmo_flush_chunk after calling this function. The location is only
+ output if different than *LAST_VMAP, which is updated after this call. */
-static boolean
-mmo_write_loc_chunk (abfd, vma, loc, len)
+static bfd_boolean
+mmo_write_loc_chunk (abfd, vma, loc, len, last_vmap)
bfd *abfd;
bfd_vma vma;
- CONST bfd_byte *loc;
+ const bfd_byte *loc;
unsigned int len;
+ bfd_vma *last_vmap;
{
- /* We always write the location as 64 bits; no use saving bytes here. */
- mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_LOC << 16) | 2);
-
/* Find an initial and trailing section of zero tetras; we don't need to
write out zeros. FIXME: When we do this, we should emit section size
- and address specifiers, else objcopy can't perform a unity
- translation. */
- while (len >= 4 && bfd_get_32 (abfd, loc) == 0)
+ and address specifiers, else objcopy can't always perform an identity
+ translation. Only do this if we *don't* have left-over data from a
+ previous write or the vma of this chunk is *not* the next address,
+ because then data isn't tetrabyte-aligned and we're concatenating to
+ that left-over data. */
+
+ if (abfd->tdata.mmo_data->byte_no == 0 || vma != *last_vmap)
{
- vma += 4;
- len -= 4;
- loc += 4;
+ while (len >= 4 && bfd_get_32 (abfd, loc) == 0)
+ {
+ vma += 4;
+ len -= 4;
+ loc += 4;
+ }
+
+ while (len >= 4 && bfd_get_32 (abfd, loc + len - 4) == 0)
+ len -= 4;
+ }
+
+ /* Only write out the location if it's different than the one the caller
+ (supposedly) previously handled, accounting for omitted leading zeros. */
+ if (vma != *last_vmap)
+ {
+ /* We might be in the middle of a sequence. */
+ mmo_flush_chunk (abfd);
+
+ /* We always write the location as 64 bits; no use saving bytes
+ here. */
+ mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_LOC << 16) | 2);
+ mmo_write_octa_raw (abfd, vma);
}
- while (len >= 4 && bfd_get_32 (abfd, loc + len - 4) == 0)
- len -= 4;
+ /* Update to reflect end of this chunk, with trailing zeros omitted. */
+ *last_vmap = vma + len;
- mmo_write_octa_raw (abfd, vma);
- return
- abfd->tdata.mmo_data->have_error == false
- && mmo_write_chunk (abfd, loc, len);
+ return (! abfd->tdata.mmo_data->have_error
+ && mmo_write_chunk (abfd, loc, len));
}
/* Same, but from a list. */
-static INLINE boolean
+static INLINE bfd_boolean
mmo_write_loc_chunk_list (abfd, datap)
bfd *abfd;
mmo_data_list_type *datap;
{
+ /* Get an address different than the address of the first chunk. */
+ bfd_vma last_vma = datap ? datap->where - 1 : 0;
+
for (; datap != NULL; datap = datap->next)
- if (! mmo_write_loc_chunk (abfd, datap->where, datap->data, datap->size))
- return false;
+ if (! mmo_write_loc_chunk (abfd, datap->where, datap->data, datap->size,
+ &last_vma))
+ return FALSE;
- return true;
+ return mmo_flush_chunk (abfd);
}
/* Make a .MMIX.spec_data.N section. */
bfd_sec_flags_from_mmo_flags (flags)
| bfd_get_section_flags (abfd, sec)
| (section_length != 0 ? SEC_HAS_CONTENTS : 0))
- || ! bfd_set_section_size (abfd, sec,
- sec->_cooked_size + section_length)
+ || ! bfd_set_section_size (abfd, sec, sec->size + section_length)
/* Set VMA only for the first occurrence. */
|| (! sec->user_set_vma
&& ! bfd_set_section_vma (abfd, sec, section_vma)))
}
loc->next = NULL;
- if (((struct mmo_section_data_struct *) (sec->used_by_bfd))->tail != NULL)
- ((struct mmo_section_data_struct *) (sec->used_by_bfd))->tail->next
- = loc;
+ if (mmo_section_data (sec)->tail != NULL)
+ mmo_section_data (sec)->tail->next = loc;
else
- ((struct mmo_section_data_struct *) (sec->used_by_bfd))->head = loc;
- ((struct mmo_section_data_struct *) (sec->used_by_bfd))->tail = loc;
+ mmo_section_data (sec)->head = loc;
+ mmo_section_data (sec)->tail = loc;
loc->where = section_vma;
return sec;
if (abfd->tdata.mmo_data->byte_no == 0)
{
- if (abfd->tdata.mmo_data->have_error == false
+ if (! abfd->tdata.mmo_data->have_error
&& bfd_bread (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
{
- abfd->tdata.mmo_data->have_error = true;
+ abfd->tdata.mmo_data->have_error = TRUE;
/* A value somewhat safe against tripping on some inconsistency
when mopping up after this error. */
abfd->tdata.mmo_data->buf[(abfd->tdata.mmo_data->byte_no++ % 4)] = value;
if ((abfd->tdata.mmo_data->byte_no % 4) == 0)
{
- if (abfd->tdata.mmo_data->have_error == false
+ if (! abfd->tdata.mmo_data->have_error
&& bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
- abfd->tdata.mmo_data->have_error = true;
+ abfd->tdata.mmo_data->have_error = TRUE;
}
}
/* Create a symbol. */
-static boolean
+static bfd_boolean
mmo_create_symbol (abfd, symname, addr, sym_type, serno)
bfd *abfd;
- CONST char *symname;
+ const char *symname;
bfd_vma addr;
enum mmo_sym_type sym_type;
unsigned int serno;
n = (struct mmo_symbol *) bfd_alloc (abfd, sizeof (struct mmo_symbol));
if (n == NULL)
- return false;
+ return FALSE;
n->name = bfd_alloc (abfd, strlen (symname) + 1);
if (n->name == NULL)
- return false;
+ return FALSE;
strcpy ((PTR) n->name, symname);
(_("%s: invalid mmo file: initialization value for $255 is not `Main'\n"),
bfd_get_filename (abfd));
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
- return true;
+ return TRUE;
}
/* Read in symbols. */
-static boolean
+static bfd_boolean
mmo_get_symbols (abfd)
bfd *abfd;
{
bfd_byte m = mmo_get_byte (abfd);
/* Check first if we have a bad hair day. */
- if (abfd->tdata.mmo_data->have_error == true)
- return false;
+ if (abfd->tdata.mmo_data->have_error)
+ return FALSE;
if (m & MMO3_LEFT)
/* Traverse left trie. */
bfd_get_filename (abfd), c, c2,
abfd->tdata.mmo_data->lop_stab_symbol);
bfd_set_error (bfd_error_bad_value);
- abfd->tdata.mmo_data->have_error = true;
- return false;
+ abfd->tdata.mmo_data->have_error = TRUE;
+ return FALSE;
}
else
c = c2;
serno -= 128;
/* Got it. Now enter it. Skip a leading ":". */
- if (abfd->tdata.mmo_data->have_error == false
+ if (! abfd->tdata.mmo_data->have_error
&& ! mmo_create_symbol (abfd,
abfd->tdata.mmo_data->lop_stab_symbol
+ 1,
addr, sym_type, serno))
- abfd->tdata.mmo_data->have_error = true;
+ abfd->tdata.mmo_data->have_error = TRUE;
}
if (m & MMO3_MIDDLE)
/* Traverse right trie. */
mmo_get_symbols (abfd);
- return abfd->tdata.mmo_data->have_error == false;
+ return ! abfd->tdata.mmo_data->have_error;
}
/* Get the location of memory area [VMA..VMA + SIZE - 1], which we think
int size;
{
bfd_size_type allocated_size;
- struct mmo_section_data_struct *sdatap
- = (struct mmo_section_data_struct *) sec->used_by_bfd;
+ struct mmo_section_data_struct *sdatap = mmo_section_data (sec);
struct mmo_data_list_struct *datap = sdatap->head;
struct mmo_data_list_struct *entry;
+ /* First search the list to see if we have the requested chunk in one
+ piece, or perhaps if we have a suitable chunk with room to fit. */
for (; datap != NULL; datap = datap->next)
{
if (datap->where <= vma
it. Do that now. */
datap->size += (vma + size) - (datap->where + datap->size);
- /* Update the section size. */
- if (vma + size > sec->vma + sec->_raw_size)
- sec->_raw_size += (vma + size) - (sec->vma + sec->_raw_size);
+ /* Update the section size. This happens only if we update the
+ 32-bit-aligned chunk size. Callers that have
+ non-32-bit-aligned sections should do all allocation and
+ size-setting by themselves or at least set the section size
+ after the last allocating call to this function. */
+ if (vma + size > sec->vma + sec->size)
+ sec->size += (vma + size) - (sec->vma + sec->size);
return datap->data + vma - datap->where;
}
entry = (mmo_data_list_type *)
bfd_zalloc (sec->owner, sizeof (mmo_data_list_type) + allocated_size);
if (entry == NULL)
- return false;
+ return NULL;
entry->where = vma;
entry->size = size;
entry->allocated_size = allocated_size;
}
}
- /* Update the section size. */
- if (vma + size > sec->vma + sec->_raw_size)
- sec->_raw_size += (vma + size) - (sec->vma + sec->_raw_size);
+ /* Update the section size. This happens only when we add contents and
+ re-size as we go. The section size will then be aligned to 32 bits. */
+ if (vma + size > sec->vma + sec->size)
+ sec->size += (vma + size) - (sec->vma + sec->size);
return entry->data;
}
asection *sec;
PTR ignored ATTRIBUTE_UNUSED;
{
- sec->_cooked_size = sec->_raw_size;
sec->lma = sec->vma;
}
/* Read the mmo file and turn it into sections. */
-static boolean
+static bfd_boolean
mmo_scan (abfd)
bfd *abfd;
{
unsigned int i;
unsigned int lineno = 1;
- boolean error = false;
+ bfd_boolean error = FALSE;
bfd_vma vma = 0;
asection *sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
asection *non_spec_sec = NULL;
bfd_set_error (bfd_error_bad_value);
error_return:
- error = true;
+ error = TRUE;
done:
/* Mark the .text and .data section with their normal attribute if they
contain anything. This is not redundant wrt. mmo_decide_section,
&& ! bfd_set_section_flags (abfd, sec,
bfd_get_section_flags (abfd, sec)
| SEC_ALLOC | SEC_LOAD | SEC_CODE))
- error = true;
+ error = TRUE;
sec = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
if (sec != NULL
&& ! bfd_set_section_flags (abfd, sec,
bfd_get_section_flags (abfd, sec)
| SEC_ALLOC | SEC_LOAD))
- error = true;
+ error = TRUE;
/* Free whatever resources we took. */
for (i = 0; i < sizeof (file_names) / sizeof (file_names[0]); i++)
if (file_names[i])
free (file_names[i]);
- return error ? false : true;
+ return ! error;
}
/* A hook to set up object file dependent section information. For mmo,
we point out the shape of allocated section contents. */
-static boolean
+static bfd_boolean
mmo_new_section_hook (abfd, newsect)
bfd *abfd ATTRIBUTE_UNUSED;
asection *newsect;
(PTR) bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct));
if (!newsect->used_by_bfd)
- return false;
+ return FALSE;
/* Always align to at least 32-bit words. */
newsect->alignment_power = 2;
- return true;
+ return TRUE;
}
/* We already have section contents loaded for sections that have
contents. */
-static boolean
+static bfd_boolean
mmo_get_section_contents (abfd, sec, location, offset, bytes_to_do)
bfd *abfd ATTRIBUTE_UNUSED;
asection *sec ATTRIBUTE_UNUSED;
while (loc == NULL && (chunk_size /= 2) != 0);
if (chunk_size == 0)
- return false;
+ return FALSE;
memcpy (location, loc, chunk_size);
bytes_to_do -= chunk_size;
offset += chunk_size;
}
- return true;
+ return TRUE;
}
/* Return the amount of memory needed to read the symbol table. */
static int
mmo_sort_mmo_symbols (arg1, arg2)
- CONST PTR arg1;
- CONST PTR arg2;
+ const PTR arg1;
+ const PTR arg2;
{
- CONST struct mmo_symbol *sym1 = *(CONST struct mmo_symbol **) arg1;
- CONST struct mmo_symbol *sym2 = *(CONST struct mmo_symbol **) arg2;
+ const struct mmo_symbol *sym1 = *(const struct mmo_symbol **) arg1;
+ const struct mmo_symbol *sym2 = *(const struct mmo_symbol **) arg2;
/* Sort by serial number first. */
if (sym1->serno < sym2->serno)
return 1;
/* Then sort by address of the table entries. */
- return ((CONST char *) arg1 - (CONST char *) arg2);
+ return ((const char *) arg1 - (const char *) arg2);
}
/* Translate the symbol table. */
static long
-mmo_get_symtab (abfd, alocation)
+mmo_canonicalize_symtab (abfd, alocation)
bfd *abfd;
asymbol **alocation;
{
csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
if (csymbols == NULL && symcount != 0)
- return false;
+ return FALSE;
abfd->tdata.mmo_data->csymbols = csymbols;
for (msp = (struct mmo_symbol **) alocation, c = csymbols;
if (textsec != NULL
&& c->value >= textsec->vma
- && c->value <= textsec->vma + textsec->_cooked_size)
+ && c->value <= textsec->vma + textsec->size)
{
c->section = textsec;
c->value -= c->section->vma;
static int
mmo_sizeof_headers (abfd, exec)
bfd *abfd ATTRIBUTE_UNUSED;
- boolean exec ATTRIBUTE_UNUSED;
+ bfd_boolean exec ATTRIBUTE_UNUSED;
{
return 0;
}
/* Write the (section-neutral) file preamble. */
-static boolean
+static bfd_boolean
mmo_internal_write_header (abfd)
bfd *abfd;
{
- CONST char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1};
+ const char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1};
if (bfd_bwrite (lop_pre_bfd, 4, abfd) != 4)
- return false;
+ return FALSE;
/* Copy creation time of original file. */
if (bfd_bwrite (abfd->tdata.mmo_data->created, 4, abfd) != 4)
- return false;
+ return FALSE;
- return true;
+ return TRUE;
}
/* Write the LOP_POST record, with global register initializations.
registers at DATA. The Z = 255 field is filled in with the
start-address. */
-static boolean
+static bfd_boolean
mmo_internal_write_post (abfd, z, sec)
bfd *abfd;
int z;
bfd_byte *data = mmo_get_loc (sec, i * 8, 8);
if (bfd_bwrite (data, 8, abfd) != 8)
- return false;
+ return FALSE;
}
/* For Z == $255, we always emit the start location; supposedly Main,
Z == 255, don't assume DATA is valid. */
bfd_put_64 (abfd, bfd_get_start_address (abfd), buf);
- return
- abfd->tdata.mmo_data->have_error == false
- && bfd_bwrite (buf, 8, abfd) == 8;
+ return ! abfd->tdata.mmo_data->have_error && bfd_bwrite (buf, 8, abfd) == 8;
}
/* Translate to and from BFD flags. This is to make sure that we don't
/* Write a section. */
-static boolean
+static bfd_boolean
mmo_internal_write_section (abfd, sec)
bfd *abfd;
asection *sec;
if (strcmp (sec->name, MMO_TEXT_SECTION_NAME) == 0)
/* FIXME: Output source file name and line number. */
- return
- mmo_write_loc_chunk_list (abfd,
- ((struct mmo_section_data_struct *)
- (sec->used_by_bfd))->head);
+ return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
else if (strcmp (sec->name, MMO_DATA_SECTION_NAME) == 0)
- return
- mmo_write_loc_chunk_list (abfd,
- ((struct mmo_section_data_struct *)
- (sec->used_by_bfd))->head);
+ return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
else if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
/* Not handled here. */
{
/* This would normally be an abort call since this can't happen, but
we don't do that. */
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
else if (strncmp (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX,
strlen (MMIX_OTHER_SPEC_SECTION_PREFIX)) == 0)
{
int n = atoi (sec->name + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX));
mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_SPEC << 16) | n);
- return
- abfd->tdata.mmo_data->have_error == false
- && mmo_write_chunk_list (abfd,
- ((struct mmo_section_data_struct *)
- (sec->used_by_bfd))->head);
+ return (! abfd->tdata.mmo_data->have_error
+ && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
}
/* Ignore sections that are just allocated or empty; we write out
_contents_ here. */
else if ((bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS) != 0
- && sec->_raw_size != 0)
+ && sec->size != 0)
{
/* Keep the document-comment formatted the way it is. */
/*
| 0x00000000 - high 32 bits of section address
| 0x00000004 - section address is 4
| 0x98010002 - 64 bits with address of following data
-| 0x00000000 - high 64 bits of address
-| 0x00000004 - data starts at address 4
+| 0x00000000 - high 32 bits of address
+| 0x00000004 - low 32 bits: data starts at address 4
| 0x00000001 - 1
| 0x00000002 - 2
| 0x00000003 - 3
| 0x00000010 - flag READONLY
| 0x00000000 - high 32 bits of section length
| 0x0000000c - section length is 12 bytes; 2 * 4 + 2 + alignment to 32 bits
-| 0x20000000 - high 64 bits of address
-| 0x0000001c - low 64 bits of address 0x200000000000001c
+| 0x20000000 - high 32 bits of address
+| 0x0000001c - low 32 bits of address 0x200000000000001c
| 0x00030d41 - 200001
| 0x000186a2 - 100002
| 0x26280000 - 38, 40 as bytes, padded with zeros
- For the latter example, the section contents must not to appear
+ For the latter example, the section contents must not be
loaded in memory, and is therefore specified as part of the
special data. The address is usually unimportant but might
provide information for e.g.@: the DWARF 2 debugging format. */
mmo_write_tetra_raw (abfd, LOP_SPEC_SECTION);
mmo_write_tetra (abfd, (strlen (sec->name) + 3) / 4);
mmo_write_chunk (abfd, sec->name, strlen (sec->name));
+ mmo_flush_chunk (abfd);
/* FIXME: We can get debug sections (.debug_line & Co.) with a
section flag still having SEC_RELOC set. Investigate. This
might be true for all alien sections; perhaps mmo.em should clear
mmo_write_tetra (abfd,
mmo_sec_flags_from_bfd_flags
(bfd_get_section_flags (abfd, sec)));
- mmo_write_octa (abfd, sec->_raw_size);
+ mmo_write_octa (abfd, sec->size);
mmo_write_octa (abfd, bfd_get_section_vma (abfd, sec));
/* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually
loaded. */
if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
- return
- abfd->tdata.mmo_data->have_error == false
- && mmo_write_loc_chunk_list (abfd,
- ((struct mmo_section_data_struct *)
- (sec->used_by_bfd))->head);
- return
- abfd->tdata.mmo_data->have_error == false
- && mmo_write_chunk_list (abfd,
- ((struct mmo_section_data_struct *)
- (sec->used_by_bfd))->head);
+ return (! abfd->tdata.mmo_data->have_error
+ && mmo_write_loc_chunk_list (abfd,
+ mmo_section_data (sec)->head));
+ return (! abfd->tdata.mmo_data->have_error
+ && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
}
- return true;
+ return TRUE;
}
/* We save up all data before output. */
-static boolean
+static bfd_boolean
mmo_set_section_contents (abfd, sec, location, offset, bytes_to_do)
bfd *abfd ATTRIBUTE_UNUSED;
sec_ptr sec;
- PTR location;
+ const PTR location;
file_ptr offset;
bfd_size_type bytes_to_do;
{
while (loc == NULL && (chunk_size /= 2) != 0);
if (chunk_size == 0)
- return false;
+ return FALSE;
memcpy (loc, location, chunk_size);
bytes_to_do -= chunk_size;
offset += chunk_size;
}
- return true;
+ return TRUE;
}
/* Add a symbol to a trie-tree. */
-static boolean
+static bfd_boolean
mmo_internal_add_3_sym (abfd, rootp, symp)
bfd *abfd;
struct mmo_symbol_trie *rootp;
- CONST struct mmo_symbol *symp;
+ const struct mmo_symbol *symp;
{
- CONST char *name = symp->name;
+ const char *name = symp->name;
struct mmo_symbol_trie *trie = rootp;
struct mmo_symbol_trie **triep = NULL;
(_("%s: invalid symbol table: duplicate symbol `%s'\n"),
bfd_get_filename (abfd), trie->sym.name);
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
memcpy (&trie->sym, symp, sizeof *symp);
- return true;
+ return TRUE;
}
/* Find out the length of the serialized version of a trie in bytes. */
mmo_internal_3_dump (abfd, trie->right);
}
-/* Write symbols, either in mmo format or hidden in a lop_spec 80 section.
- Write the lop_end terminator also. */
+/* Write symbols in mmo format. Also write the lop_end terminator. */
-static boolean
+static bfd_boolean
mmo_write_symbols_and_terminator (abfd)
bfd *abfd;
{
int count = bfd_get_symcount (abfd);
- asymbol *fakemain[2];
+ asymbol *maintable[2];
asymbol **table;
- int serno = 2;
+ asymbol **orig_table = bfd_get_outsymbols (abfd);
+ int serno;
struct mmo_symbol_trie root;
int trie_len;
int i;
bfd_byte buf[4];
/* Create a symbol for "Main". */
- asymbol *mainsym = bfd_make_empty_symbol (abfd);
+ asymbol *fakemain = bfd_make_empty_symbol (abfd);
- mainsym->flags = BSF_GLOBAL;
- mainsym->value = bfd_get_start_address (abfd);
- mainsym->name = MMIX_START_SYMBOL_NAME;
- mainsym->section = bfd_abs_section_ptr;
- fakemain[0] = mainsym;
- fakemain[1] = NULL;
+ fakemain->flags = BSF_GLOBAL;
+ fakemain->value = bfd_get_start_address (abfd);
+ fakemain->name = MMIX_START_SYMBOL_NAME;
+ fakemain->section = bfd_abs_section_ptr;
+ maintable[0] = fakemain;
+ maintable[1] = NULL;
memset (&root, 0, sizeof (root));
/* Make all symbols take a left turn. */
root.symchar = 0xff;
- /* There must always be a ":Main", so we'll add one
- if there are no symbols. */
- if (count == 0)
+ /* There must always be a ":Main", so we'll add one if there are no
+ symbols. Make sure we have room for it. */
+ table = bfd_alloc (abfd, (count + 1) * sizeof (asymbol *));
+ if (table == NULL)
+ return FALSE;
+
+ memcpy (table, orig_table, count * sizeof (asymbol *));
+
+ /* Move :Main (if there is one) to the first position. This is
+ necessary to get the same layout of the trie-tree when linking as
+ when objcopying the result as in the objcopy.exp test "simple objcopy
+ of executable". It also automatically takes care of assigning serial
+ number 1 to :Main (as is mandatory). */
+ for (i = 0; i < count; i++)
+ if (table[i] != NULL
+ && strcmp (table[i]->name, MMIX_START_SYMBOL_NAME) == 0
+ && (table[i]->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL)
+ {
+ asymbol *mainsym = table[i];
+ memcpy (table + 1, orig_table, i * sizeof (asymbol *));
+ table[0] = mainsym;
+
+ /* Check that the value assigned to :Main is the same as the entry
+ address. The default linker script asserts this. This is as
+ good a place as any to check this consistency. */
+ if ((mainsym->value
+ + mainsym->section->output_section->vma
+ + mainsym->section->output_offset)
+ != bfd_get_start_address (abfd))
+ {
+ /* Arbitrary buffer to hold the printable representation of a
+ vma. */
+ char vmas_main[40];
+ char vmas_start[40];
+ bfd_vma vma_start = bfd_get_start_address (abfd);
+
+ sprintf_vma (vmas_main, mainsym->value);
+ sprintf_vma (vmas_start, vma_start);
+
+ (*_bfd_error_handler)
+ (_("%s: Bad symbol definition: `Main' set to %s rather\
+ than the start address %s\n"),
+ bfd_get_filename (abfd), vmas_main, vmas_start);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ break;
+ }
+ if (i == count && count != 0)
{
- table = fakemain;
- count = 1;
+ /* When there are symbols, there must be a :Main. There was no
+ :Main, so we need to add it manually. */
+ memcpy (table + 1, orig_table, count * sizeof (asymbol *));
+ table[0] = fakemain;
+ count++;
}
- else
- table = bfd_get_outsymbols (abfd);
- for (i = 0; i < count && table[i] != NULL; i++)
+ for (i = 0, serno = 1; i < count && table[i] != NULL; i++)
{
asymbol *s = table[i];
/* FIXME: We assume the order of the received symbols is an
ordered mapping of the serial numbers. This is not
necessarily true if we e.g. objcopy a mmo file to another and
- there are gaps in the numbering. Note sure if this can
+ there are gaps in the numbering. Not sure if this can
happen. Not sure what to do. */
- /* Make sure Main has serial number 1; others start at 2. */
- if (strcmp (s->name, MMIX_START_SYMBOL_NAME) == 0)
- {
- sym.serno = 1;
-
- /* Check that the value assigned to :Main is the same as the
- entry address. The default linker script asserts this.
- This is as good a place as any to check this consistency. */
- if (sym.value != bfd_get_start_address (abfd))
- {
- /* Arbitrary buffer to hold the printable representation
- of a vma. */
- char vmas_main[40];
- char vmas_start[40];
- bfd_vma vma_start = bfd_get_start_address (abfd);
-
- sprintf_vma (vmas_main, s->value);
- sprintf_vma (vmas_start, vma_start);
-
- (*_bfd_error_handler)
- (_("%s: Bad symbol definition: `Main' set to %s rather\
- than the start address %s\n"),
- bfd_get_filename (abfd), vmas_main, vmas_start);
- bfd_set_error (bfd_error_bad_value);
- return false;
- }
- }
- else
- sym.serno = serno++;
+ sym.serno = serno++;
if (! mmo_internal_add_3_sym (abfd, &root, &sym))
- return false;
+ return FALSE;
}
}
root.right = NULL;
if (! mmo_internal_add_3_sym (abfd, &root, &sym))
- return false;
+ return FALSE;
root.symchar = ':';
root.middle = root.left;
/* Put out the lop_stab mark. */
bfd_put_32 (abfd, (LOP << 24) | (LOP_STAB << 16), buf);
if (bfd_bwrite (buf, 4, abfd) != 4)
- return false;
+ return FALSE;
/* Dump out symbols. */
mmo_internal_3_dump (abfd, &root);
bfd_get_filename (abfd), trie_len,
(abfd->tdata.mmo_data->byte_no + 3)/4);
bfd_set_error (bfd_error_bad_value);
- return false;
+ return FALSE;
}
/* Dump out remaining bytes in the buffer and handle I/O errors by
if (abfd->tdata.mmo_data->have_error
|| bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
- return false;
+ return FALSE;
}
bfd_put_32 (abfd, (LOP << 24) | (LOP_END << 16) | trie_len, buf);
{
struct mmo_write_sec_info *infop = (struct mmo_write_sec_info *) p;
- if (infop->retval == false)
+ if (! infop->retval)
return;
if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
contents\n"),
bfd_get_filename (abfd), sec->name);
bfd_set_error (bfd_error_bad_value);
- infop->retval = false;
+ infop->retval = FALSE;
return;
}
/* Do the actual output of a file. Assumes mmo_set_section_contents is
already called. */
-static boolean
+static bfd_boolean
mmo_write_object_contents (abfd)
bfd *abfd;
{
/* First, there are a few words of preamble. */
if (! mmo_internal_write_header (abfd))
- return false;
+ return FALSE;
wsecinfo.reg_section = NULL;
- wsecinfo.retval = true;
+ wsecinfo.retval = TRUE;
bfd_map_over_sections (abfd, mmo_write_section_unless_reg_contents,
(PTR) &wsecinfo);
- if (wsecinfo.retval == false)
- return false;
+ if (! wsecinfo.retval)
+ return FALSE;
if (wsecinfo.reg_section != NULL)
{
of the register contents section and check that it corresponds to
the length of the section. */
if (z < 32 || z >= 255 || (sec->vma & 7) != 0
- || sec->vma != 256 * 8 - sec->_raw_size - 8)
+ || sec->vma != 256 * 8 - sec->size - 8)
{
bfd_set_error (bfd_error_bad_value);
- if (sec->_raw_size == 0)
+ if (sec->size == 0)
/* There must always be at least one such register. */
(*_bfd_error_handler)
(_("%s: no initialized registers; section length 0\n"),
(*_bfd_error_handler)
(_("%s: too many initialized registers; section length %ld\n"),
bfd_get_filename (abfd),
- (long) sec->_raw_size);
+ (long) sec->size);
else
(*_bfd_error_handler)
(_("%s: invalid start address for initialized registers of\
length %ld: 0x%lx%08lx\n"),
bfd_get_filename (abfd),
- (long) sec->_raw_size,
+ (long) sec->size,
(unsigned long) (sec->vma >> 32), (unsigned long) (sec->vma));
- return false;
+ return FALSE;
}
if (! mmo_internal_write_post (abfd, z, sec))
- return false;
+ return FALSE;
}
else
if (! mmo_internal_write_post (abfd, 255, NULL))
- return false;
+ return FALSE;
return mmo_write_symbols_and_terminator (abfd);
}
/* Perhaps we need to adjust this one; mmo labels (originally) without a
leading ':' might more appropriately be called local. */
#define mmo_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define mmo_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
/* Is this one really used or defined by anyone? */
#define mmo_get_lineno _bfd_nosymbols_get_lineno
bfd_generic_get_relocated_section_contents
#define mmo_bfd_gc_sections bfd_generic_gc_sections
#define mmo_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define mmo_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define mmo_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define mmo_bfd_link_just_syms _bfd_generic_link_just_syms
#define mmo_bfd_final_link _bfd_generic_final_link
#define mmo_bfd_link_split_section _bfd_generic_link_split_section
#define mmo_set_arch_mach bfd_default_set_arch_mach
#define mmo_bfd_relax_section bfd_generic_relax_section
#define mmo_bfd_merge_sections bfd_generic_merge_sections
+#define mmo_bfd_is_group_section bfd_generic_is_group_section
+#define mmo_bfd_discard_group bfd_generic_discard_group
+#define mmo_section_already_linked \
+ _bfd_generic_section_already_linked
/* objcopy will be upset if we return -1 from bfd_get_reloc_upper_bound by
using BFD_JUMP_TABLE_RELOCS (_bfd_norelocs) rather than 0. FIXME: Most
#define mmo_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
#define mmo_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
#define mmo_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
+#define mmo_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
#define mmo_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
#define mmo_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
-CONST bfd_target bfd_mmo_vec =
+const bfd_target bfd_mmo_vec =
{
"mmo", /* name */
bfd_target_mmo_flavour,