/* BFD back-end for mmo objects (MMIX-specific object-format).
- Copyright (C) 2001-2019 Free Software Foundation, Inc.
+ Copyright (C) 2001-2022 Free Software Foundation, Inc.
Written by Hans-Peter Nilsson (hp@bitrange.com).
Infrastructure and other bits originally copied from srec.c and
binary.c.
#include "elf/mmix.h"
#include "opcode/mmix.h"
-#define LOP 0x98
+#define LOP 0x98u
#define LOP_QUOTE 0
#define LOP_LOC 1
#define LOP_SKIP 2
/* When we're reading bytes recursively, check this occasionally.
Also holds write errors. */
- bfd_boolean have_error;
+ bool 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
/* Whether we've calculated symbol consistency requirement yet. We do this
when-needed, which must be at some time after all section
contents is known. */
- bfd_boolean symbol_consistency_override_calculated;
+ bool symbol_consistency_override_calculated;
/* Whether to consistency-check symbol values, in particular "Main". */
- bfd_boolean ignore_symbol_consistency;
+ bool ignore_symbol_consistency;
};
typedef struct mmo_data_struct tdata_type;
struct mmo_write_sec_info
{
asection *reg_section;
- bfd_boolean retval;
+ bool retval;
};
/* Used when trying to find a section corresponding to addr. */
bfd_vma addr;
};
-static bfd_boolean mmo_bfd_copy_private_bfd_data (bfd *, bfd *);
+static bool mmo_bfd_copy_private_bfd_data (bfd *, bfd *);
static void mmo_write_section_unless_reg_contents (bfd *, asection *, void *);
static void mmo_find_sec_w_addr (bfd *, asection *, void *);
static void mmo_find_sec_w_addr_grow (bfd *, asection *, void *);
static void mmo_print_symbol (bfd *, void *, asymbol *,
bfd_print_symbol_type);
static void mmo_init (void);
-static bfd_boolean mmo_mkobject (bfd *);
-static bfd_boolean mmo_scan (bfd *);
+static bool mmo_mkobject (bfd *);
+static bool mmo_scan (bfd *);
static asection *mmo_decide_section (bfd *, bfd_vma);
static asection *mmo_get_generic_spec_data_section (bfd *, int);
static asection *mmo_get_spec_section (bfd *, int);
-static INLINE bfd_byte *mmo_get_loc (asection *, bfd_vma, int);
-static void mmo_xore_64 (asection *, bfd_vma vma, bfd_vma value);
-static void mmo_xore_32 (asection *, bfd_vma vma, unsigned int);
-static void mmo_xore_16 (asection *, bfd_vma vma, unsigned int);
-static const bfd_target *mmo_object_p (bfd *);
+static bfd_byte *mmo_get_loc (asection *, bfd_vma, unsigned int);
+static bfd_cleanup mmo_object_p (bfd *);
static void mmo_map_set_sizes (bfd *, asection *, void *);
-static bfd_boolean mmo_get_symbols (bfd *);
-static bfd_boolean mmo_create_symbol (bfd *, const char *, bfd_vma,
- enum mmo_sym_type, unsigned int);
-static bfd_boolean mmo_get_section_contents (bfd *, asection *, void *,
- file_ptr, bfd_size_type);
+static bool mmo_get_symbols (bfd *);
+static bool mmo_create_symbol (bfd *, const char *, bfd_vma,
+ enum mmo_sym_type, unsigned int);
+static bool mmo_get_section_contents (bfd *, asection *, void *,
+ file_ptr, bfd_size_type);
static long mmo_get_symtab_upper_bound (bfd *);
static long mmo_canonicalize_symtab (bfd *, asymbol **);
static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *);
static void mmo_print_symbol (bfd *, void *, asymbol *,
bfd_print_symbol_type);
-static bfd_boolean mmo_set_section_contents (bfd *, sec_ptr, const void *,
- file_ptr, bfd_size_type);
+static bool mmo_set_section_contents (bfd *, sec_ptr, const void *,
+ file_ptr, bfd_size_type);
static int mmo_sizeof_headers (bfd *, struct bfd_link_info *);
-static bfd_boolean mmo_internal_write_header (bfd *);
-static bfd_boolean mmo_internal_write_post (bfd *, int, asection *);
-static bfd_boolean mmo_internal_add_3_sym (bfd *, struct mmo_symbol_trie *,
+static bool mmo_internal_write_header (bfd *);
+static bool mmo_internal_write_post (bfd *, int, asection *);
+static bool mmo_internal_add_3_sym (bfd *, struct mmo_symbol_trie *,
const struct mmo_symbol *);
static unsigned int mmo_internal_3_length (bfd *, struct mmo_symbol_trie *);
static void mmo_internal_3_dump (bfd *, struct mmo_symbol_trie *);
static void mmo_beb128_out (bfd *, int, int);
-static bfd_boolean mmo_internal_write_section (bfd *, asection *);
+static bool mmo_internal_write_section (bfd *, asection *);
static void mmo_write_tetra (bfd *, unsigned int);
static void mmo_write_tetra_raw (bfd *, unsigned int);
static void mmo_write_octa (bfd *, bfd_vma);
static void mmo_write_octa_raw (bfd *, bfd_vma);
-static bfd_boolean mmo_write_chunk (bfd *, const bfd_byte *, unsigned int);
-static bfd_boolean mmo_flush_chunk (bfd *);
-static bfd_boolean mmo_write_loc_chunk (bfd *, bfd_vma, const bfd_byte *,
- unsigned int, bfd_vma *);
-static bfd_boolean mmo_write_chunk_list (bfd *, mmo_data_list_type *);
-static bfd_boolean mmo_write_loc_chunk_list (bfd *, mmo_data_list_type *);
-static bfd_boolean mmo_write_symbols_and_terminator (bfd *);
+static bool mmo_write_chunk (bfd *, const bfd_byte *, unsigned int);
+static bool mmo_flush_chunk (bfd *);
+static bool mmo_write_loc_chunk (bfd *, bfd_vma, const bfd_byte *,
+ unsigned int, bfd_vma *);
+static bool mmo_write_chunk_list (bfd *, mmo_data_list_type *);
+static bool mmo_write_loc_chunk_list (bfd *, mmo_data_list_type *);
+static bool mmo_write_symbols_and_terminator (bfd *);
static flagword mmo_sec_flags_from_bfd_flags (flagword);
static flagword bfd_sec_flags_from_mmo_flags (flagword);
static bfd_byte mmo_get_byte (bfd *);
static void mmo_write_byte (bfd *, bfd_byte);
-static bfd_boolean mmo_new_section_hook (bfd *, asection *);
+static bool mmo_new_section_hook (bfd *, asection *);
static int mmo_sort_mmo_symbols (const void *, const void *);
-static bfd_boolean mmo_write_object_contents (bfd *);
-static bfd_boolean mmo_write_section_description (bfd *, asection *);
-static bfd_boolean mmo_has_leading_or_trailing_zero_tetra_p (bfd *,
- asection *);
+static bool mmo_write_object_contents (bfd *);
+static bool mmo_write_section_description (bfd *, asection *);
+static bool mmo_has_leading_or_trailing_zero_tetra_p (bfd *, asection *);
static const char
valid_mmo_symbol_character_set[] =
if (sec == NULL)
{
- char *newsecname = strdup (secname);
+ size_t len = strlen (secname) + 1;
+ char *newsecname = bfd_alloc (abfd, len);
if (newsecname == NULL)
{
- _bfd_error_handler
- /* xgettext:c-format */
- (_("%pB: no core to allocate section name %s"),
- abfd, secname);
- bfd_set_error (bfd_error_system_call);
+ bfd_set_error (bfd_error_no_memory);
return NULL;
}
+ memcpy (newsecname, secname, len);
sec = bfd_make_section (abfd, newsecname);
}
static void
mmo_init (void)
{
- static bfd_boolean inited = FALSE;
+ static bool inited = false;
if (inited)
return;
- inited = TRUE;
+ inited = true;
}
/* Check whether an existing file is an mmo file. */
-static const bfd_target *
+static bfd_cleanup
mmo_object_p (bfd *abfd)
{
struct stat statbuf;
if (! bfd_default_set_arch_mach (abfd, bfd_arch_mmix, 0))
goto bad_format_free;
- return abfd->xvec;
+ return _bfd_no_cleanup;
bad_format_free:
free (abfd->tdata.mmo_data->lop_stab_symbol);
/* Set up the mmo tdata information. */
-static bfd_boolean
+static bool
mmo_mkobject (bfd *abfd)
{
mmo_init ();
/* All fields are zero-initialized, so we don't have to explicitly
initialize most. */
- tdata_type *tdata = (tdata_type *) bfd_zmalloc (sizeof (tdata_type));
+ tdata_type *tdata = (tdata_type *) bfd_zalloc (abfd, 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 bfd_boolean
+static bool
mmo_section_has_contents (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p ATTRIBUTE_UNUSED)
{
/* The point is to match what --extract-symbols does (well, negated). */
known. However, calculating symbol consistency at the time the
private BFD data is initialized is too late for some uses. */
-static bfd_boolean
+static bool
mmo_ignore_symbol_consistency (bfd *abfd)
{
if (!abfd->tdata.mmo_data->symbol_consistency_override_calculated)
abfd->tdata.mmo_data->ignore_symbol_consistency =
bfd_sections_find_if (abfd, mmo_section_has_contents, NULL) == NULL;
- abfd->tdata.mmo_data->symbol_consistency_override_calculated = TRUE;
+ abfd->tdata.mmo_data->symbol_consistency_override_calculated = true;
}
return abfd->tdata.mmo_data->ignore_symbol_consistency;
}
-static bfd_boolean
+static bool
mmo_bfd_copy_private_bfd_data (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
sprintf (sec_name, ".MMIX.sec.%d", abfd->tdata.mmo_data->sec_no++);
sec = mmo_make_section (abfd, sec_name);
- if (!sec->user_set_vma && !bfd_set_section_vma (sec, vma))
+ if (!sec || (!sec->user_set_vma && !bfd_set_section_vma (sec, vma)))
return NULL;
if (!bfd_set_section_flags (sec, (bfd_section_flags (sec)
/* Xor in a 64-bit value VALUE at VMA. */
-static INLINE void
+static inline bfd_byte *
mmo_xore_64 (asection *sec, bfd_vma vma, bfd_vma value)
{
bfd_byte *loc = mmo_get_loc (sec, vma, 8);
- bfd_vma prev = bfd_get_64 (sec->owner, loc);
+ if (loc)
+ {
+ bfd_vma prev = bfd_get_64 (sec->owner, loc);
- value ^= prev;
- bfd_put_64 (sec->owner, value, loc);
+ value ^= prev;
+ bfd_put_64 (sec->owner, value, loc);
+ }
+ return loc;
}
/* Xor in a 32-bit value VALUE at VMA. */
-static INLINE void
+static inline bfd_byte *
mmo_xore_32 (asection *sec, bfd_vma vma, unsigned int value)
{
bfd_byte *loc = mmo_get_loc (sec, vma, 4);
- unsigned int prev = bfd_get_32 (sec->owner, loc);
+ if (loc)
+ {
+ unsigned int prev = bfd_get_32 (sec->owner, loc);
- value ^= prev;
- bfd_put_32 (sec->owner, value, loc);
+ value ^= prev;
+ bfd_put_32 (sec->owner, value, loc);
+ }
+ return loc;
}
/* Xor in a 16-bit value VALUE at VMA. */
-static INLINE void
+static inline bfd_byte *
mmo_xore_16 (asection *sec, bfd_vma vma, unsigned int value)
{
bfd_byte *loc = mmo_get_loc (sec, vma, 2);
- unsigned int prev = bfd_get_16 (sec->owner, loc);
+ if (loc)
+ {
+ unsigned int prev = bfd_get_16 (sec->owner, loc);
- value ^= prev;
- bfd_put_16 (sec->owner, value, loc);
+ value ^= prev;
+ bfd_put_16 (sec->owner, value, loc);
+ }
+ return loc;
}
/* Write a 32-bit word to output file, no lop_quote generated. */
-static INLINE void
+static inline void
mmo_write_tetra_raw (bfd *abfd, unsigned int value)
{
bfd_byte buf[4];
bfd_put_32 (abfd, value, buf);
if (bfd_bwrite (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. */
-static INLINE void
+static inline void
mmo_write_tetra (bfd *abfd, unsigned int value)
{
if (((value >> 24) & 0xff) == LOP)
/* Write a 64-bit word to output file, perhaps with lop_quoting. */
-static INLINE void
+static inline void
mmo_write_octa (bfd *abfd, bfd_vma value)
{
mmo_write_tetra (abfd, (unsigned int) (value >> 32));
/* Write a 64-bit word to output file, without lop_quoting. */
-static INLINE void
+static inline void
mmo_write_octa_raw (bfd *abfd, bfd_vma value)
{
mmo_write_tetra_raw (abfd, (unsigned int) (value >> 32));
/* Write quoted contents. Intended to be called multiple times in
sequence, followed by a call to mmo_flush_chunk. */
-static INLINE bfd_boolean
+static inline bool
mmo_write_chunk (bfd *abfd, const bfd_byte *loc, unsigned int len)
{
- bfd_boolean retval = TRUE;
+ bool retval = true;
struct mmo_data_struct *mmop = abfd->tdata.mmo_data;
/* Fill up a tetra from bytes remaining from a previous chunk. */
}
if (! retval)
- mmop->have_error = TRUE;
+ mmop->have_error = true;
return retval;
}
/* Flush remaining bytes, from a previous mmo_write_chunk, zero-padded to
4 bytes. */
-static INLINE bfd_boolean
+static inline bool
mmo_flush_chunk (bfd *abfd)
{
if (abfd->tdata.mmo_data->byte_no != 0)
/* Same, but from a list. */
-static INLINE bfd_boolean
+static inline bool
mmo_write_chunk_list (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 mmo_flush_chunk (abfd);
}
mmo_flush_chunk after calling this function. The location is only
output if different than *LAST_VMAP, which is updated after this call. */
-static bfd_boolean
+static bool
mmo_write_loc_chunk (bfd *abfd, bfd_vma vma, const bfd_byte *loc,
unsigned int len, bfd_vma *last_vmap)
{
" address %#" PRIx64 ""),
abfd, (uint64_t) vma);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
/* We always write the location as 64 bits; no use saving bytes
/* Same, but from a list. */
-static INLINE bfd_boolean
+static inline bool
mmo_write_loc_chunk_list (bfd *abfd, mmo_data_list_type *datap)
{
/* Get an address different than the address of the first chunk. */
for (; datap != NULL; datap = datap->next)
if (! mmo_write_loc_chunk (abfd, datap->where, datap->data, datap->size,
&last_vma))
- return FALSE;
+ return false;
return mmo_flush_chunk (abfd);
}
if (abfd->tdata.mmo_data->byte_no == 0)
{
- if (! abfd->tdata.mmo_data->have_error
+ 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. */
- return 128;
- }
+ /* A value somewhat safe against tripping on some inconsistency
+ when mopping up after this error. */
+ if (abfd->tdata.mmo_data->have_error)
+ return 128;
}
retval = abfd->tdata.mmo_data->buf[abfd->tdata.mmo_data->byte_no];
{
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 bfd_boolean
+static bool
mmo_create_symbol (bfd *abfd, 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 (n->name, symname);
" is not `Main'\n"),
abfd);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/* Read in symbols. */
-static bfd_boolean
+static bool
mmo_get_symbols (bfd *abfd)
{
/*
/* Check first if we have a bad hair day. */
if (abfd->tdata.mmo_data->have_error)
- return FALSE;
+ return false;
if (m & MMO3_LEFT)
/* Traverse left trie. */
" 0x%02X 0x%02X after symbol name starting with `%s'\n"),
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;
}
+ if (abfd->tdata.mmo_data->symbol_position
+ >= abfd->tdata.mmo_data->max_symbol_length)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: symbol name exceeds given max length of %d"),
+ abfd, abfd->tdata.mmo_data->max_symbol_length);
+ abfd->tdata.mmo_data->have_error = true;
+ return false;
+ }
abfd->tdata.mmo_data->lop_stab_symbol[abfd->tdata.mmo_data->symbol_position++] = c;
abfd->tdata.mmo_data->lop_stab_symbol[abfd->tdata.mmo_data->symbol_position] = 0;
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)
If there's new contents, allocate to the next multiple of
MMO_SEC_CONTENTS_CHUNK_SIZE. */
-static INLINE bfd_byte *
-mmo_get_loc (asection *sec, bfd_vma vma, int size)
+static bfd_byte *
+mmo_get_loc (asection *sec, bfd_vma vma, unsigned int size)
{
bfd_size_type allocated_size;
struct mmo_section_data_struct *sdatap = mmo_section_data (sec);
for (; datap != NULL; datap = datap->next)
{
if (datap->where <= vma
- && datap->where + datap->size >= vma + size)
- return datap->data + vma - datap->where;
+ && datap->size >= size
+ && datap->size - size >= vma - datap->where)
+ return datap->data + (vma - datap->where);
else if (datap->where <= vma
- && datap->where + datap->allocated_size >= vma + size
+ && datap->allocated_size >= size
+ && datap->allocated_size - size >= vma - datap->where
/* Only munch on the "allocated size" if it does not
overlap the next chunk. */
&& (datap->next == NULL || datap->next->where >= vma + size))
{
/* There was room allocated, but the size wasn't set to include
it. Do that now. */
- datap->size += (vma + size) - (datap->where + datap->size);
+ datap->size = vma - datap->where + 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);
+ if (vma - sec->vma + size > sec->size)
+ sec->size = vma - sec->vma + size;
- return datap->data + vma - datap->where;
+ return datap->data + (vma - datap->where);
}
}
for no more than MMO_SEC_CONTENTS_CHUNK_SIZE will always get resolved. */
for (datap = sdatap->head; datap != NULL; datap = datap->next)
- if ((datap->where <= vma && datap->where + datap->size > vma)
+ if ((datap->where <= vma && datap->size > vma - datap->where)
|| (datap->where < vma + size
&& datap->where + datap->size >= vma + size))
return NULL;
/* 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);
+ if (vma - sec->vma + size > sec->size)
+ sec->size = vma - sec->vma + size;
return entry->data;
}
/* Read the mmo file and turn it into sections. */
-static bfd_boolean
+static bool
mmo_scan (bfd *abfd)
{
unsigned int i;
unsigned int lineno = 1;
- bfd_boolean error = FALSE;
+ bool error = false;
bfd_vma vma = 0;
- asection *sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
+ asection *sec = NULL;
asection *non_spec_sec = NULL;
bfd_vma non_spec_vma = 0;
bfd_size_type nbytes_read = 0;
goto error_return;
vma &= ~3;
- mmo_xore_32 (sec, vma, bfd_get_32 (abfd, buf));
+ if (sec == NULL)
+ sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
+ if (!mmo_xore_32 (sec, vma, bfd_get_32 (abfd, buf)))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
vma += 4;
lineno++;
break;
fixosec = mmo_decide_section (abfd, p);
if (fixosec == NULL)
goto error_return;
- mmo_xore_64 (fixosec, p, vma);
+ if (!mmo_xore_64 (fixosec, p, vma))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
}
break;
asection *fixrsec = mmo_decide_section (abfd, p);
if (fixrsec == NULL)
goto error_return;
- mmo_xore_16 (fixrsec, p, yz);
+ if (!mmo_xore_16 (fixrsec, p, yz))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
}
break;
fixrsec = mmo_decide_section (abfd, vma);
if (fixrsec == NULL)
goto error_return;
- mmo_xore_32 (fixrsec, p, delta);
+ if (!mmo_xore_32 (fixrsec, p, delta))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
}
break;
rsec->flags |= SEC_LINKER_CREATED;
rsec->vma = z * 8;
loc = mmo_get_loc (rsec, z * 8, (255 - z) * 8);
+ if (!loc)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
bfd_put_64 (abfd, first_octa, loc);
for (i = z + 1; i < 255; i++)
else
{
/* This wasn't a lopcode, so store it in the current section. */
- mmo_xore_32 (sec, vma & ~3, bfd_get_32 (abfd, buf));
+ if (sec == NULL)
+ sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
+ if (!mmo_xore_32 (sec, vma & ~3, bfd_get_32 (abfd, buf)))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
vma += 4;
vma &= ~3;
lineno++;
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_section_flags (sec) & SEC_HAS_CONTENTS)
&& !bfd_set_section_flags (sec, (bfd_section_flags (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_section_flags (sec) & SEC_HAS_CONTENTS)
&& !bfd_set_section_flags (sec, (bfd_section_flags (sec)
- | SEC_ALLOC | SEC_LOAD)))
- error = TRUE;
+ | SEC_ALLOC | SEC_LOAD | SEC_DATA)))
+ 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]);
+ free (file_names[i]);
return ! error;
}
/* A hook to set up object file dependent section information. For mmo,
we point out the shape of allocated section contents. */
-static bfd_boolean
+static bool
mmo_new_section_hook (bfd *abfd, asection *newsect)
{
if (!newsect->used_by_bfd)
newsect->used_by_bfd
= 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. */
/* We already have section contents loaded for sections that have
contents. */
-static bfd_boolean
+static bool
mmo_get_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
asection *sec,
void * location,
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. */
/* Write the (section-neutral) file preamble. */
-static bfd_boolean
+static bool
mmo_internal_write_header (bfd *abfd)
{
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 bfd_boolean
+static bool
mmo_internal_write_post (bfd *abfd, int z, asection *sec)
{
int i;
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,
/* Return TRUE iff the leading or trailing tetrabyte in SEC is defined and
is 0. */
-static bfd_boolean
+static bool
mmo_has_leading_or_trailing_zero_tetra_p (bfd *abfd, asection *sec)
{
bfd_vma secaddr = bfd_section_vma (sec);
if (sec->size < 4)
- return FALSE;
+ return false;
if (bfd_get_32 (abfd, mmo_get_loc (sec, secaddr, 4)) == 0
&& bfd_get_32 (abfd,
mmo_get_loc (sec, secaddr + sec->size - 4, 4)) == 0)
- return TRUE;
+ return true;
- return FALSE;
+ return false;
}
/* Write a section. */
-static bfd_boolean
+static bool
mmo_internal_write_section (bfd *abfd, asection *sec)
{
/* We do it differently depending on what section this is:
|| mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
{
if (!mmo_write_section_description (abfd, sec))
- return FALSE;
+ return false;
}
/* FIXME: Output source file name and line number. */
|| mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
{
if (!mmo_write_section_description (abfd, sec))
- return FALSE;
+ return false;
}
return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
/* 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 (CONST_STRNEQ (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX))
+ else if (startswith (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX))
{
int n = atoi (sec->name + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX));
&& sec->size != 0)
{
if (!mmo_write_section_description (abfd, sec))
- return FALSE;
+ return false;
/* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually
loaded. */
}
/* Some section without contents. */
- return TRUE;
+ return true;
}
/* Write the description of a section, extended-mmo-style. */
-static bfd_boolean
+static bool
mmo_write_section_description (bfd *abfd, asection *sec)
{
/* Keep the following document-comment formatted the way it is. */
mmo_sec_flags_from_bfd_flags (bfd_section_flags (sec)));
mmo_write_octa (abfd, sec->size);
mmo_write_octa (abfd, bfd_section_vma (sec));
- return TRUE;
+ return true;
}
/* We save up all data before output. */
-static bfd_boolean
+static bool
mmo_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
const void *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 bfd_boolean
+static bool
mmo_internal_add_3_sym (bfd *abfd, struct mmo_symbol_trie *rootp,
const struct mmo_symbol *symp)
{
(_("%pB: invalid symbol table: duplicate symbol `%s'\n"),
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. */
/* Write symbols in mmo format. Also write the lop_end terminator. */
-static bfd_boolean
+static bool
mmo_write_symbols_and_terminator (bfd *abfd)
{
int count = bfd_get_symcount (abfd);
symbols. Make sure we have room for it. */
table = bfd_alloc (abfd, (count + 1) * sizeof (asymbol *));
if (table == NULL)
- return FALSE;
+ return false;
- memcpy (table, orig_table, count * sizeof (asymbol *));
+ if (count != 0)
+ 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
{
/* 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, mainvalue);
- sprintf_vma (vmas_start, vma_start);
-
_bfd_error_handler
/* xgettext:c-format */
- (_("%pB: bad symbol definition: `Main' set to %s rather"
- " than the start address %s\n"),
- abfd, vmas_main, vmas_start);
+ (_("%pB: bad symbol definition: `Main' set to %" PRIx64 " rather"
+ " than the start address %" PRIx64 "\n"),
+ abfd, mainvalue, vma_start);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
break;
}
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);
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);
" contents\n"),
abfd, sec);
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 bfd_boolean
+static bool
mmo_write_object_contents (bfd *abfd)
{
struct mmo_write_sec_info wsecinfo;
/* 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,
&wsecinfo);
if (! wsecinfo.retval)
- return FALSE;
+ return false;
if (wsecinfo.reg_section != NULL)
{
" length %" PRId64 ": %#" PRIx64),
abfd, (int64_t) sec->size, (uint64_t) 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);
}
/* FIXME: We can do better on this one, if we have a dwarf2 .debug_line
section or if MMO line numbers are implemented. */
#define mmo_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define mmo_find_nearest_line_with_alt _bfd_nosymbols_find_nearest_line_with_alt
#define mmo_find_line _bfd_nosymbols_find_line
#define mmo_find_inliner_info _bfd_nosymbols_find_inliner_info
#define mmo_make_empty_symbol _bfd_generic_make_empty_symbol
' ', /* ar_pad_char */
16, /* ar_max_namelen */
0, /* match priority. */
+ TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
bfd_getb64, bfd_getb_signed_64, bfd_putb64,
bfd_getb32, bfd_getb_signed_32, bfd_putb32,
bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */