/* BFD back-end for mmo objects (MMIX-specific object-format).
- Copyright (C) 2001-2021 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.
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 bfd_byte *mmo_get_loc (asection *, bfd_vma, int);
static bfd_cleanup mmo_object_p (bfd *);
static void mmo_map_set_sizes (bfd *, asection *, void *);
static bool mmo_get_symbols (bfd *);
/* 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];
/* 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 bool
+static inline bool
mmo_write_chunk (bfd *abfd, const bfd_byte *loc, unsigned int len)
{
bool retval = true;
/* Flush remaining bytes, from a previous mmo_write_chunk, zero-padded to
4 bytes. */
-static INLINE bool
+static inline bool
mmo_flush_chunk (bfd *abfd)
{
if (abfd->tdata.mmo_data->byte_no != 0)
/* Same, but from a list. */
-static INLINE bool
+static inline bool
mmo_write_chunk_list (bfd *abfd, mmo_data_list_type *datap)
{
for (; datap != NULL; datap = datap->next)
/* Same, but from a list. */
-static INLINE bool
+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. */
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;
If there's new contents, allocate to the next multiple of
MMO_SEC_CONTENTS_CHUNK_SIZE. */
-static INLINE bfd_byte *
+static bfd_byte *
mmo_get_loc (asection *sec, bfd_vma vma, int size)
{
bfd_size_type allocated_size;
vma &= ~3;
if (sec == NULL)
sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
- mmo_xore_32 (sec, vma, bfd_get_32 (abfd, buf));
+ 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++)
/* This wasn't a lopcode, so store it in the current section. */
if (sec == NULL)
sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
- mmo_xore_32 (sec, vma & ~3, bfd_get_32 (abfd, buf));
+ 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++;