/* BFD back-end for mmo objects (MMIX-specific object-format).
- Copyright (C) 2001-2015 Free Software Foundation, Inc.
+ Copyright (C) 2001-2016 Free Software Foundation, Inc.
Written by Hans-Peter Nilsson (hp@bitrange.com).
Infrastructure and other bits originally copied from srec.c and
binary.c.
/* We also need a buffer to hold the bytes we count reading or writing. */
bfd_byte buf[4];
+
+ /* 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;
+
+ /* Whether to consistency-check symbol values, in particular "Main". */
+ bfd_boolean ignore_symbol_consistency;
};
typedef struct mmo_data_struct tdata_type;
return TRUE;
}
+static bfd_boolean
+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). */
+ return bfd_get_section_size (sec) != 0;
+}
+
+/* Find out whether we should omit symbol consistency checks for this
+ bfd and cache the value.
+
+ This function must only be called when all section contents is
+ known. However, calculating symbol consistency at the time the
+ private BFD data is initialized is too late for some uses. */
+
+static bfd_boolean
+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;
+ }
+
+ return abfd->tdata.mmo_data->ignore_symbol_consistency;
+}
+
static bfd_boolean
mmo_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
object. For written objects, we do it while setting the symbol
table. */
if (strcmp (symname, MMIX_START_SYMBOL_NAME) == 0
- && bfd_get_start_address (abfd) != addr)
+ && bfd_get_start_address (abfd) != addr
+ && !mmo_ignore_symbol_consistency (abfd))
{
(*_bfd_error_handler)
(_("%s: invalid mmo file: initialization value for $255 is not `Main'\n"),
memcpy (location, loc, chunk_size);
- location += chunk_size;
+ location = (bfd_byte *) location + chunk_size;
bytes_to_do -= chunk_size;
offset += chunk_size;
}
memcpy (loc, location, chunk_size);
- location += chunk_size;
+ location = (bfd_byte *) location + chunk_size;
bytes_to_do -= chunk_size;
offset += chunk_size;
}
&& (table[i]->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL)
{
asymbol *mainsym = table[i];
+ bfd_vma mainvalue
+ = (mainsym->value
+ + mainsym->section->output_section->vma
+ + mainsym->section->output_offset);
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))
+ if (mainvalue != bfd_get_start_address (abfd)
+ && !mmo_ignore_symbol_consistency (abfd))
{
/* Arbitrary buffer to hold the printable representation of a
vma. */
char vmas_start[40];
bfd_vma vma_start = bfd_get_start_address (abfd);
- sprintf_vma (vmas_main, mainsym->value);
+ sprintf_vma (vmas_main, mainvalue);
sprintf_vma (vmas_start, vma_start);
(*_bfd_error_handler)
_bfd_generic_copy_link_hash_symbol_type
#define mmo_bfd_final_link _bfd_generic_final_link
#define mmo_bfd_link_split_section _bfd_generic_link_split_section
+#define mmo_bfd_link_check_relocs _bfd_generic_link_check_relocs
/* Strictly speaking, only MMIX uses this restricted format, but let's not
stop anybody from shooting themselves in the foot. */