This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]