This is the mail archive of the binutils@sourceware.cygnus.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]

PATCH for 64-bit MIPS ELF buglets



These patches improve the 64-bit MIPS ELF support.  They handle
DW_FORM_ref8, and handle the R_MIPS_64 relocation correctly.  (Like
R_MIPS_32 it must become a dynamic relocation if the relocation is
against an object in a shared library.)  Finally, we allow
elf_fake_sections to figure out that .rel.dyn is the dynamic
relocation section, even when using the 64-bit ABI, and even though
the 64-bit ABI uses SHT_RELA sections by default.

The only controversy I can spot in this patch is this hunk:

@@ -678,22 +679,19 @@ static reloc_howto_type elf_mips_howto_t
 	 0x000007c4,		/* dst_mask */
 	 false),		/* pcrel_offset */
 
-  /* A 64 bit relocation.  This is used in 32 bit ELF when addresses
-     are 64 bits long; the upper 32 bits are simply a sign extension.
-     The fields of the howto should be the same as for R_MIPS_32,
-     other than the type, name, and special_function.  */
+  /* A 64 bit relocation.  */
   HOWTO (R_MIPS_64,		/* type */
 	 0,			/* rightshift */
-	 2,			/* size (0 = byte, 1 = short, 2 = long) */
-	 32,			/* bitsize */
+	 4,			/* size (0 = byte, 1 = short, 2 = long) */
+	 64,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
 	 mips32_64bit_reloc,	/* special_function */
 	 "R_MIPS_64",		/* name */
 	 true,			/* partial_inplace */
-	 0xffffffff,		/* src_mask */
-	 0xffffffff,		/* dst_mask */
+	 MINUS_ONE,		/* src_mask */
+	 MINUS_ONE,		/* dst_mask */
 	 false),		/* pcrel_offset */
 
   /* Displacement in the global offset table.  */

I don't understand the comment; R_MIPS_64 is clearly documented as a
64-bit relocation in the MIPS ABI.  Period.

However, if someone thinks this patch is wrong, but approves the rest
of the patch, I will check in an alternative version in which we use a
special HOWTO only for the 64-bit ABI, and retain the current version
for the 32-bit ABIs.

OK to check in?

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-07-12  Mark Mitchell  <mark@codesourcery.com>

	* dwarf2.c (read_attribute): Support DW_FORM_ref8.
	* elf32-mips.c (mips_elf_link_hash_entry): Change mips_32_relocs
	to possibly_dynamic_relocs.  Adjust usage throughout code.
	(elf_mips_howto_table): Handle R_MIPS_64 correctly.
	(elf_mips_ctor64_howto): Likewise.
	(mips_elf_calculate_relocation): Handle R_MIPS_64 like R_MIPS_32.
	Adjust indentation.
	(_bfd_mips_elf_check_relocs): Handle R_MIPS_64 like R_MIPS_32.
	Use MIPS_ELF_GOT_SIZE to calculate the size of GOT entries.
	* elf64-mips.c (elf_backend_may_use_rel_p): Define.

Index: dwarf2.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/dwarf2.c,v
retrieving revision 1.7
diff -u -p -r1.7 dwarf2.c
--- dwarf2.c	1999/07/02 21:03:50	1.7
+++ dwarf2.c	1999/07/12 19:00:02
@@ -611,6 +611,10 @@ read_attribute (attr, abbrev, unit, info
       DW_UNSND (attr) = read_4_bytes (abfd, info_ptr);
       info_ptr += 4;
       break;
+    case DW_FORM_ref8:
+      DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
+      info_ptr += 8;
+      break;
     case DW_FORM_ref_udata:
       DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
       info_ptr += bytes_read;
Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.17
diff -u -p -r1.17 elf32-mips.c
--- elf32-mips.c	1999/07/12 07:35:06	1.17
+++ elf32-mips.c	1999/07/12 19:00:06
@@ -67,8 +67,9 @@ struct mips_elf_link_hash_entry
   /* External symbol information.  */
   EXTR esym;
 
-  /* Number of MIPS_32 or MIPS_REL32 relocs against this symbol.  */
-  unsigned int mips_32_relocs;
+  /* Number of R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 relocs against
+     this symbol.  */ 
+  unsigned int possibly_dynamic_relocs;
 
   /* The index of the first dynamic relocation (in the .rel.dyn
      section) against this symbol.  */
@@ -678,22 +679,19 @@ static reloc_howto_type elf_mips_howto_t
 	 0x000007c4,		/* dst_mask */
 	 false),		/* pcrel_offset */
 
-  /* A 64 bit relocation.  This is used in 32 bit ELF when addresses
-     are 64 bits long; the upper 32 bits are simply a sign extension.
-     The fields of the howto should be the same as for R_MIPS_32,
-     other than the type, name, and special_function.  */
+  /* A 64 bit relocation.  */
   HOWTO (R_MIPS_64,		/* type */
 	 0,			/* rightshift */
-	 2,			/* size (0 = byte, 1 = short, 2 = long) */
-	 32,			/* bitsize */
+	 4,			/* size (0 = byte, 1 = short, 2 = long) */
+	 64,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
 	 mips32_64bit_reloc,	/* special_function */
 	 "R_MIPS_64",		/* name */
 	 true,			/* partial_inplace */
-	 0xffffffff,		/* src_mask */
-	 0xffffffff,		/* dst_mask */
+	 MINUS_ONE,		/* src_mask */
+	 MINUS_ONE,		/* dst_mask */
 	 false),		/* pcrel_offset */
 
   /* Displacement in the global offset table.  */
@@ -901,8 +899,8 @@ static reloc_howto_type elf_mips_ctor64_
 	 mips32_64bit_reloc,	/* special_function */
 	 "R_MIPS_64",		/* name */
 	 true,			/* partial_inplace */
-	 0xffffffff,		/* src_mask */
-	 0xffffffff,		/* dst_mask */
+	 MINUS_ONE,		/* src_mask */
+	 MINUS_ONE,		/* dst_mask */
 	 false);		/* pcrel_offset */
 
 /* The reloc used for the mips16 jump instruction.  */
@@ -3766,7 +3764,7 @@ mips_elf_link_hash_newfunc (entry, table
       /* We use -2 as a marker to indicate that the information has
 	 not been set.  -1 means there is no associated ifd.  */
       ret->esym.ifd = -2;
-      ret->mips_32_relocs = 0;
+      ret->possibly_dynamic_relocs = 0;
       ret->min_dyn_reloc_index = 0;
       ret->fn_stub = NULL;
       ret->need_fn_stub = false;
@@ -5850,6 +5848,7 @@ mips_elf_calculate_relocation (abfd, 
 
     case R_MIPS_32:
     case R_MIPS_REL32:
+    case R_MIPS_64:
       /* If we're creating a shared library, or this relocation is
 	 against a symbol in a shared library, then we can't know
 	 where the symbol will end up.  So, we create a relocation
@@ -5862,11 +5861,11 @@ mips_elf_calculate_relocation (abfd, 
 	  BFD_ASSERT (h != NULL);
 	  reloc_index 
 	    = mips_elf_create_dynamic_relocation (abfd, 
-						   info, 
-						   relocation,
-						   h->root.dynindx,
-						   addend,
-						   input_section);
+						  info, 
+						  relocation,
+						  h->root.dynindx,
+						  addend,
+						  input_section);
 	  if (h->min_dyn_reloc_index == 0
 	      || reloc_index < h->min_dyn_reloc_index)
 	    h->min_dyn_reloc_index = reloc_index;
@@ -5874,7 +5873,7 @@ mips_elf_calculate_relocation (abfd, 
 	}
       else
 	{
-	  if (r_type == R_MIPS_32)
+	  if (r_type != R_MIPS_REL32)
 	    value = symbol + addend;
 	  else
 	    value = addend;
@@ -5975,10 +5974,6 @@ mips_elf_calculate_relocation (abfd, 
       value = g & howto->dst_mask;
       break;
 
-    case R_MIPS_64:
-      value = (symbol + addend) & howto->dst_mask;
-      break;
-
     case R_MIPS_GOT_PAGE:
       value = mips_elf_got_page (abfd, info, symbol + addend, NULL);
       if (value == (bfd_vma) -1)
@@ -6891,6 +6886,7 @@ _bfd_mips_elf_check_relocs (abfd, info, 
 
 	    case R_MIPS_32:
 	    case R_MIPS_REL32:
+	    case R_MIPS_64:
 	      if (dynobj == NULL
 		  && (info->shared || h != NULL)
 		  && (sec->flags & SEC_ALLOC) != 0)
@@ -6918,7 +6914,7 @@ _bfd_mips_elf_check_relocs (abfd, info, 
 	     conservative, we could actually build the GOT here,
 	     rather than in relocate_section.  */
 	  g->local_gotno++;
-	  sgot->_raw_size += 4;
+	  sgot->_raw_size += MIPS_ELF_GOT_SIZE (dynobj);
 	}
 
       switch (r_type)
@@ -6959,6 +6955,7 @@ _bfd_mips_elf_check_relocs (abfd, info, 
 
 	case R_MIPS_32:
 	case R_MIPS_REL32:
+	case R_MIPS_64:
 	  if ((info->shared || h != NULL)
 	      && (sec->flags & SEC_ALLOC) != 0)
 	    {
@@ -6996,7 +6993,7 @@ _bfd_mips_elf_check_relocs (abfd, info, 
 		  /* We only need to copy this reloc if the symbol is
                      defined in a dynamic object.  */
 		  hmips = (struct mips_elf_link_hash_entry *) h;
-		  ++hmips->mips_32_relocs;
+		  ++hmips->possibly_dynamic_relocs;
 		}
 	     
 	      /* Even though we don't directly need a GOT entry for
@@ -7189,9 +7186,10 @@ _bfd_mips_elf_adjust_dynamic_symbol (inf
      file.  */
   hmips = (struct mips_elf_link_hash_entry *) h;
   if (! info->relocateable
-      && hmips->mips_32_relocs != 0
+      && hmips->possibly_dynamic_relocs != 0
       && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
-    mips_elf_allocate_dynamic_relocations (dynobj, hmips->mips_32_relocs);
+    mips_elf_allocate_dynamic_relocations (dynobj, 
+					   hmips->possibly_dynamic_relocs);
 
   /* For a function, create a stub, if needed. */
   if (h->type == STT_FUNC
Index: elf64-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf64-mips.c,v
retrieving revision 1.6
diff -u -p -r1.6 elf64-mips.c
--- elf64-mips.c	1999/07/07 19:23:21	1.6
+++ elf64-mips.c	1999/07/12 19:00:07
@@ -2148,6 +2148,7 @@ const struct elf_size_info mips_elf64_si
 #define elf_backend_gc_sweep_hook	_bfd_mips_elf_gc_sweep_hook
 #define elf_backend_got_header_size	(4*MIPS_RESERVED_GOTNO)
 #define elf_backend_plt_header_size	0
+#define elf_backend_may_use_rel_p       1
 
 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit 
    MIPS-specific function only applies to IRIX5, which had no 64-bit

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