diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 961a3857f6..e647a2b8cc 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2015-10-22 Hans-Peter Nilsson + + * mmo.c (struct mmo_data_struct): New members + symbol_consistency_override_calculated and ignore_symbol_consistency. + (mmo_section_has_contents, mmo_ignore_symbol_consistency): New + functions. + (mmo_create_symbol): Check with mmo_ignore_symbol_consistency if to + report an error for unexpected value of Main. + (mmo_write_symbols_and_terminator): Similar. + 2015-10-22 H.J. Lu * elf32-i386.c (elf_i386_convert_load): Use call_nop_byte and diff --git a/bfd/mmo.c b/bfd/mmo.c index 484a370fd9..316afe8991 100644 --- a/bfd/mmo.c +++ b/bfd/mmo.c @@ -330,6 +330,14 @@ struct mmo_data_struct /* 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; @@ -585,6 +593,34 @@ mmo_mkobject (bfd *abfd) 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) { @@ -1208,7 +1244,8 @@ mmo_create_symbol (bfd *abfd, const char *symname, bfd_vma addr, enum 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"), @@ -2900,13 +2937,14 @@ mmo_write_symbols_and_terminator (bfd *abfd) = (mainsym->value + mainsym->section->output_section->vma + mainsym->section->output_offset); - memcpy (table + 1, orig_table, i * sizeof (asymbol *)); + 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 (mainvalue != 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. */