This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Committed, MMIX: Fix bad handling of undefined symbols.
- From: Hans-Peter Nilsson <hp at bitrange dot com>
- To: <binutils at sources dot redhat dot com>
- Date: Sat, 9 Feb 2002 00:08:22 -0500 (EST)
- Subject: Committed, MMIX: Fix bad handling of undefined symbols.
An internal inconsistency would cause accesses beyond the end of
a dynamically allocated array when there was a global register
reloc for an undefined symbol. Depending on left-over contents,
the invalid access would most often not have abortive
consequences. Having lots of global registers allocated would
make the probability of a SEGV higher. The gcc test-suite made
the bug visible.
bfd:
* elf64-mmix.c (_bfd_mmix_finalize_linker_allocated_gregs): Check
that base-plus-offset reloc accounting is consistent.
(mmix_elf_relax_section): Keep base-plus-offset reloc accounting
up to date for undefined symbols.
ld:
* emultempl/mmix-elfnmmo.em (mmix_after_allocation): Adjust
register section vma to a sane value after emitting error. Make
fatal conditions cause program exit when emitting message.
ld/testsuite:
* ld-mmix/bpo-21.d, ld-mmix/bpo-21m.d, ld-mmix/bpo-11.s: New
tests.
Index: mmix-elfnmmo.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/mmix-elfnmmo.em,v
retrieving revision 1.3
diff -p -c -r1.3 mmix-elfnmmo.em
*** mmix-elfnmmo.em 2002/02/04 04:42:29 1.3
--- mmix-elfnmmo.em 2002/02/09 04:53:03
*************** mmix_after_allocation ()
*** 67,76 ****
regvma = 256 * 8 - sec->_raw_size - 8;
! /* If we start on a local register, we have too many global registers. */
if (regvma < 32 * 8)
! einfo ("%X%P: Too many global registers: %u, max 223\n",
! (unsigned) sec->_raw_size / 8);
/* Set vma to correspond to first such register number * 8. */
bfd_set_section_vma (output_bfd, sec, (bfd_vma) regvma);
--- 67,82 ----
regvma = 256 * 8 - sec->_raw_size - 8;
! /* If we start on a local register, we have too many global registers.
! We treat this error as nonfatal (meaning processing will continue in
! search for other errors), because it's a link error in the same way
! as an undefined symbol. */
if (regvma < 32 * 8)
! {
! einfo ("%X%P: Too many global registers: %u, max 223\n",
! (unsigned) sec->_raw_size / 8);
! regvma = 32 * 8;
! }
/* Set vma to correspond to first such register number * 8. */
bfd_set_section_vma (output_bfd, sec, (bfd_vma) regvma);
*************** mmix_after_allocation ()
*** 80,88 ****
if (sec->_cooked_size == 0
&& ! bfd_set_section_size (output_bfd, sec, sec->_raw_size))
{
! einfo ("%X%P: Can't set section %s size to %u\n",
MMIX_REG_CONTENTS_SECTION_NAME, (unsigned) sec->_raw_size);
- return;
}
/* Simplify symbol output for the register section (without contents;
--- 86,94 ----
if (sec->_cooked_size == 0
&& ! bfd_set_section_size (output_bfd, sec, sec->_raw_size))
{
! /* This is a fatal error; make the einfo call not return. */
! einfo ("%F%P: Can't set section %s size to %u\n",
MMIX_REG_CONTENTS_SECTION_NAME, (unsigned) sec->_raw_size);
}
/* Simplify symbol output for the register section (without contents;
*************** mmix_after_allocation ()
*** 94,102 ****
if (!_bfd_mmix_finalize_linker_allocated_gregs (output_bfd, &link_info))
{
! einfo ("%X%P: Can't finalize linker-allocated global registers\n");
! /* In case stuff is added after this conditional. */
! return;
}
}
EOF
--- 100,107 ----
if (!_bfd_mmix_finalize_linker_allocated_gregs (output_bfd, &link_info))
{
! /* This is a fatal error; make einfo call not return. */
! einfo ("%F%P: Can't finalize linker-allocated global registers\n");
}
}
EOF
Index: elf64-mmix.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-mmix.c,v
retrieving revision 1.9
diff -p -c -r1.9 elf64-mmix.c
*** elf64-mmix.c 2002/02/04 04:45:08 1.9
--- elf64-mmix.c 2002/02/09 04:17:17
*************** _bfd_mmix_finalize_linker_allocated_greg
*** 2177,2182 ****
--- 2177,2197 ----
if (contents == NULL)
return false;
+ /* Sanity check: If these numbers mismatch, some relocation has not been
+ accounted for and the rest of gregdata is probably inconsistent.
+ It's a bug, but it's more helpful to identify it than segfaulting
+ below. */
+ if (gregdata->n_remaining_bpo_relocs_this_relaxation_round
+ != gregdata->n_bpo_relocs)
+ {
+ (*_bfd_error_handler)
+ (_("Internal inconsistency: remaining %u != max %u.\n\
+ Please report this bug."),
+ gregdata->n_remaining_bpo_relocs_this_relaxation_round,
+ gregdata->n_bpo_relocs);
+ return false;
+ }
+
for (lastreg = 255, i = 0, j = 0; j < n_gregs; i++)
if (gregdata->reloc_request[i].regindex != lastreg)
{
*************** mmix_elf_relax_section (abfd, sec, link_
*** 2287,2293 ****
struct bfd_link_info *link_info;
boolean *again;
{
-
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Rela *internal_relocs;
--- 2302,2307 ----
*************** mmix_elf_relax_section (abfd, sec, link_
*** 2431,2439 ****
if (h->root.type != bfd_link_hash_defined
&& h->root.type != bfd_link_hash_defweak)
{
! /* This appears to be a reference to an undefined
! symbol. Just ignore it--it will be caught by the
! regular reloc processing. */
continue;
}
--- 2445,2456 ----
if (h->root.type != bfd_link_hash_defined
&& h->root.type != bfd_link_hash_defweak)
{
! /* This appears to be a reference to an undefined symbol.
! Just ignore it--it will be caught by the regular reloc
! processing. We need to keep BPO reloc accounting
! consistent, though. */
! gregdata->n_remaining_bpo_relocs_this_relaxation_round--;
! bpono++;
continue;
}
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-21.d Sat Feb 9 05:49:51 2002
***************
*** 0 ****
--- 1,10 ----
+ #source: start.s
+ #source: bpo-11.s
+ #source: bpo-7.s
+ #as: -linker-allocated-gregs
+ #ld: -m elf64mmix
+ #error: ^[^c][^h][^i][^l][^d].* undefined reference to `areg'$
+
+ # A BPO reloc against an undefined symbol, with a full set of normal
+ # BPO:s.
+
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-11.s Sat Feb 9 00:17:31 2002
***************
*** 0 ****
--- 1,5 ----
+ .set i,0
+ .rept 222
+ LDA $11,_start+i*256
+ .set i,i+1
+ .endr
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-21m.d Sat Feb 9 05:50:01 2002
***************
*** 0 ****
--- 1,9 ----
+ #source: start.s
+ #source: bpo-11.s
+ #source: bpo-7.s
+ #as: -linker-allocated-gregs
+ #ld: -m mmo
+ #error: ^[^c][^h][^i][^l][^d].* undefined reference to `areg'$
+
+ # A BPO reloc against an undefined symbol, with a full set of normal
+ # BPO:s.
brgds, H-P