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 more IRIX6 changes to elf32-mips.c



Here's the next batch 'o patch.  (Thanks to Richard & Ian for
processing these, and in pretty short order, too.)  We're getting
pretty close to the meaty stuff, now.

This chunk:

  o Uses macros instead of string literals for section names in 
    many places.  This is a) necessary (since IRIX6 uses different
    names than IRIX5 apparently did) and b) cleaner.

  o Adds support for .srdata and the .MIPS.options section.

  o Adjusts ELF_DYNAMIC_INTERPRETER to reflect the correct N32 
    interpreter.

  o Makes a few other minor tweaks required for N32 support.
    
--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-06-27  Mark Mitchell  <mark@codesourcery.com>

	* elf32-mips.c (MIPS_ELF_SRDATA_SECTION_NAME): New macro.
	(MIPS_ELF_OPTIONS_SECTION_NAME): Likewise.
	(MIPS_ELF_STUB_SECTION_NAME): Likewise.
	(_bfd_mips_elf_section_from_shdr): Use them.
	(_bfd_mips_elf_fake_sections): Likewise.  Add .srdata to the list
	of GP-relative sections.
	(_bfd_mips_elf_set_section_contents): Use them.
	(_bfd_mips_elf_section_processing): Share code between .sdata and
	.lit4/.lit8 sections.  Set appropriate flags for .srdata.
	(mips_elf_additional_program_headers): Add handling for
	PT_MIPS_OPTIONS segment on IRIX6.
	(mips_elf_modify_segment_map): Likeiwse.
	(mips_elf_final_link): Set EF_MIPS_CPIC when required by the ABI.
	Include the options sections on IRIX6.  Don't look for GP-relative
	sections by name; use SHF_MIPS_GPREL instead.
	(ELF_DYNAMIC_INTERPRETER): Adjust to use /usr/lib32/libc.so.1 for
	the N32 ABI.
	(mips_elf_create_dynamic_sections): Don't muck about with section
	alignments and such on IRIX6.
	(mips_elf_adjust_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
	(mips_elf_size_dynamic_sections): Likewise. Adjust to handle the
	fact that ELF_DYNAMIC_INTERPRETER is no longer a constant.  Use
	bfd_zalloc rather than bfd_alloc and memset.
	(mips_elf_finish_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
	Don't assert the existence of .rld_map on IRIX6.
	(mips_elf_finish_dynamic_sections): Use MIPS_ELF_STUB_SECTION_NAME.

Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.8
diff -u -p -r1.8 elf32-mips.c
--- elf32-mips.c	1999/06/27 16:11:13	1.8
+++ elf32-mips.c	1999/06/28 00:01:08
@@ -170,6 +170,17 @@ struct mips_got_info
 /* The name of the msym section.  */
 #define MIPS_ELF_MSYM_SECTION_NAME(abfd) ".msym"
 
+/* The name of the srdata section.  */
+#define MIPS_ELF_SRDATA_SECTION_NAME(abfd) ".srdata"
+
+/* The name of the options section.  */
+#define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \
+  (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.options" : ".options")
+
+/* The name of the stub section.  */
+#define MIPS_ELF_STUB_SECTION_NAME(abfd) \
+  (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.stubs" : ".stub")
+
 /* The number of local .got entries we reserve.  */
 #define MIPS_RESERVED_GOTNO (2)
 
@@ -2449,8 +2460,7 @@ _bfd_mips_elf_section_from_shdr (abfd, h
 	return false;
       break;
     case SHT_MIPS_OPTIONS:
-      if (strcmp (name, ".options") != 0
-	  && strcmp (name, ".MIPS.options") != 0)
+      if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) != 0)
 	return false;
       break;
     case SHT_MIPS_DWARF:
@@ -2627,6 +2637,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr, 
 #endif
     }
   else if (strcmp (name, ".got") == 0
+	   || strcmp (name, MIPS_ELF_SRDATA_SECTION_NAME (abfd)) == 0
 	   || strcmp (name, ".sdata") == 0
 	   || strcmp (name, ".sbss") == 0
 	   || strcmp (name, ".lit4") == 0
@@ -2643,8 +2654,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr, 
       hdr->sh_flags |= SHF_MIPS_NOSTRIP;
       /* The sh_info field is set in final_write_processing.  */
     }
-  else if (strcmp (name, ".options") == 0
-	   || strcmp (name, ".MIPS.options") == 0)
+  else if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
     {
       hdr->sh_type = SHT_MIPS_OPTIONS;
       hdr->sh_entsize = 1;
@@ -2714,8 +2724,7 @@ _bfd_mips_elf_set_section_contents (abfd
      file_ptr offset;
      bfd_size_type count;
 {
-  if (strcmp (section->name, ".options") == 0
-      || strcmp (section->name, ".MIPS.options") == 0)
+  if (strcmp (section->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
     {
       bfd_byte *c;
 
@@ -2762,7 +2771,9 @@ _bfd_mips_elf_section_processing (abfd, 
     {
       const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
 
-      if (strcmp (name, ".sdata") == 0)
+      if (strcmp (name, ".sdata") == 0
+	  || strcmp (name, ".lit8") == 0
+	  || strcmp (name, ".lit4") == 0)
 	{
 	  hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
 	  hdr->sh_type = SHT_PROGBITS;
@@ -2772,10 +2783,9 @@ _bfd_mips_elf_section_processing (abfd, 
 	  hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
 	  hdr->sh_type = SHT_NOBITS;
 	}
-      else if (strcmp (name, ".lit8") == 0
-	       || strcmp (name, ".lit4") == 0)
+      else if (strcmp (name, MIPS_ELF_SRDATA_SECTION_NAME (abfd)) == 0)
 	{
-	  hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
+	  hdr->sh_flags |= SHF_ALLOC | SHF_MIPS_GPREL;
 	  hdr->sh_type = SHT_PROGBITS;
 	}
       else if (strcmp (name, ".compact_rel") == 0)
@@ -2981,26 +2991,27 @@ mips_elf_additional_program_headers (abf
      bfd *abfd;
 {
   asection *s;
-  int ret;
+  int ret = 0;
 
-  ret = 0;
-
-  if (! SGI_COMPAT (abfd))
-    return ret;
+  if (!SGI_COMPAT (abfd))
+    return 0;
 
+  /* See if we need a PT_MIPS_REGINFO segment.  */
   s = bfd_get_section_by_name (abfd, ".reginfo");
-  if (s != NULL && (s->flags & SEC_LOAD) != 0)
-    {
-      /* We need a PT_MIPS_REGINFO segment.  */
-      ++ret;
-    }
+  if (s && (s->flags & SEC_LOAD))
+    ++ret;
 
-  if (bfd_get_section_by_name (abfd, ".dynamic") != NULL
-      && bfd_get_section_by_name (abfd, ".mdebug") != NULL)
-    {
-      /* We need a PT_MIPS_RTPROC segment.  */
-      ++ret;
-    }
+  /* See if we need a PT_MIPS_OPTIONS segment.  */
+  if (IRIX_COMPAT (abfd) == ict_irix6
+      && bfd_get_section_by_name (abfd, 
+				  MIPS_ELF_OPTIONS_SECTION_NAME (abfd)))
+    ++ret;
+
+  /* See if we need a PT_MIPS_RTPROC segment.  */
+  if (IRIX_COMPAT (abfd) == ict_irix5
+      && bfd_get_section_by_name (abfd, ".dynamic")
+      && bfd_get_section_by_name (abfd, ".mdebug"))
+    ++ret;
 
   return ret;
 }
@@ -3047,6 +3058,44 @@ mips_elf_modify_segment_map (abfd)
 	}
     }
 
+  /* For IRIX 6, we don't have .mdebug sections, nor does anything but
+     .dynamic end up in PT_DYNAMIC.  However, we do have to insert a
+     PT_OPTIONS segement immediately following the program header
+     table.  */
+  if (IRIX_COMPAT (abfd) == ict_irix6)
+    {
+      asection *s;
+
+      for (s = abfd->sections; s; s = s->next)
+	if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS)
+	  break;
+
+      if (s)
+	{
+	  struct elf_segment_map *options_segment;
+
+	  for (m = elf_tdata (abfd)->segment_map; m; m = m->next)
+	    if (m->p_type == PT_PHDR)
+	      break;
+
+	  /* There should always be a program header table.  */
+	  if (m == NULL)
+	    return false;
+
+	  options_segment = bfd_zalloc (abfd, 
+					sizeof (struct elf_segment_map));
+	  options_segment->next = m->next;
+	  options_segment->p_type = PT_MIPS_OPTIONS;
+	  options_segment->p_flags = PF_R;
+	  options_segment->p_flags_valid = true;
+	  options_segment->count = 1;
+	  options_segment->sections[0] = s;
+	  m->next = options_segment;
+	}
+
+      return true;
+    }
+
   /* If there are .dynamic and .mdebug sections, we make a room for
      the RTPROC header.  FIXME: Rewrite without section names.  */
   if (bfd_get_section_by_name (abfd, ".interp") == NULL
@@ -4121,21 +4170,35 @@ mips_elf_final_link (abfd, info)
   HDRR *symhdr = &debug.symbolic_header;
   PTR mdebug_handle = NULL;
 
-  /* Drop the .options section, since it has special semantics which I
-     haven't bothered to figure out.  */
-  for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next)
-    {
-      if (strcmp ((*secpp)->name, ".options") == 0)
-	{
-	  for (p = (*secpp)->link_order_head; p != NULL; p = p->next)
-	    if (p->type == bfd_indirect_link_order)
-	      p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS;
-	  (*secpp)->link_order_head = NULL;
-	  *secpp = (*secpp)->next;
-	  --abfd->section_count;
-	  break;
-	}
-    }
+  /* If all the things we linked together were PIC, but we're
+     producing an executable (rather than a shared object), then the
+     resulting file is CPIC (i.e., it calls PIC code.)  */
+  if (!info->shared && elf_elfheader (abfd)->e_flags & EF_MIPS_PIC)
+    {
+      elf_elfheader (abfd)->e_flags &= ~EF_MIPS_PIC;
+      elf_elfheader (abfd)->e_flags |= EF_MIPS_CPIC;
+      
+    }
+
+  /* On IRIX5, we omit the .options section.  On IRIX6, however, we
+     included it, even though we don't process it quite right.  (Some
+     entries are supposed to be merged.)  Emprically, we seem to be
+     better off including it then not.  */
+  if (IRIX_COMPAT (abfd) == ict_irix5)
+    for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next)
+      {
+	if (strcmp ((*secpp)->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
+	  {
+	    for (p = (*secpp)->link_order_head; p != NULL; p = p->next)
+	      if (p->type == bfd_indirect_link_order)
+		p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS;
+	    (*secpp)->link_order_head = NULL;
+	    *secpp = (*secpp)->next;
+	    --abfd->section_count;
+	    
+	    break;
+	  }
+      }
 
   /* Get a value for the GP register.  */
   if (elf_gp (abfd) == 0)
@@ -4152,17 +4215,14 @@ mips_elf_final_link (abfd, info)
 	{
 	  bfd_vma lo;
 
-	  /* Make up a value.  */
+	  /* Find the GP-relative section with the lowest offset.  */
 	  lo = (bfd_vma) -1;
 	  for (o = abfd->sections; o != (asection *) NULL; o = o->next)
-	    {
-	      if (o->vma < lo
-		  && (strcmp (o->name, ".sbss") == 0
-		      || strcmp (o->name, ".sdata") == 0
-		      || strcmp (o->name, ".lit4") == 0
-		      || strcmp (o->name, ".lit8") == 0))
-		lo = o->vma;
-	    }
+	    if (o->vma < lo 
+		&& (elf_section_data (o)->this_hdr.sh_flags & SHF_MIPS_GPREL))
+	      lo = o->vma;
+
+	  /* And calculate GP relative to that.  */
 	  elf_gp (abfd) = lo + ELF_MIPS_GP_OFFSET (abfd);
 	}
       else
@@ -5815,7 +5875,8 @@ mips_elf_link_output_symbol_hook (abfd, 
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
 
-#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+#define ELF_DYNAMIC_INTERPRETER(abfd) \
+   (ABI_N32_P (abfd) ? "/usr/lib32/libc.so.1" : "/usr/lib/libc.so.1")
 
 /* Create dynamic sections when linking against a dynamic object.  */
 
@@ -5872,7 +5933,11 @@ mips_elf_create_dynamic_sections (abfd, 
 	return false;
     }
 
-  if (SGI_COMPAT (abfd))
+  /* On IRIX5, we adjust add some additional symbols and change the
+     alignments of several sections.  There is no ABI documentation
+     indicating that this is necessary on IRIX6, nor any evidence that
+     the linker takes such action.  */
+  if (IRIX_COMPAT (abfd) == ict_irix5)
     {
       for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++)
 	{
@@ -6679,7 +6744,8 @@ mips_elf_adjust_dynamic_symbol (info, h)
       if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
 	{
 	  /* We need .stub section.  */
-	  s = bfd_get_section_by_name (dynobj, ".stub");
+	  s = bfd_get_section_by_name (dynobj, 
+				       MIPS_ELF_STUB_SECTION_NAME (dynobj));
 	  BFD_ASSERT (s != NULL);
 
 	  h->root.u.def.section = s;
@@ -6819,8 +6885,10 @@ mips_elf_size_dynamic_sections (output_b
 	{
 	  s = bfd_get_section_by_name (dynobj, ".interp");
 	  BFD_ASSERT (s != NULL);
-	  s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
-	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+	  s->_raw_size 
+	    = strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1;
+	  s->contents 
+	    = (unsigned char *) ELF_DYNAMIC_INTERPRETER (output_bfd);
 	}
     }
 
@@ -6929,7 +6997,7 @@ mips_elf_size_dynamic_sections (output_b
 	  i = elf_hash_table (info)->dynsymcount - g->global_gotsym;
 	  s->_raw_size += i * 4;
 	}
-      else if (strncmp (name, ".stub", 5) == 0)
+      else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0)
 	{
 	  /* Irix rld assumes that the function stub isn't at the end
 	     of .text section. So put a dummy. XXX  */
@@ -6964,13 +7032,12 @@ mips_elf_size_dynamic_sections (output_b
 	}
 
       /* Allocate memory for the section contents.  */
-      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
       if (s->contents == NULL && s->_raw_size != 0)
 	{
 	  bfd_set_error (bfd_error_no_memory);
 	  return false;
 	}
-      memset (s->contents, 0, s->_raw_size);
     }
 
   if (elf_hash_table (info)->dynamic_sections_created)
@@ -7203,7 +7270,8 @@ mips_elf_finish_dynamic_symbol (output_b
 
       BFD_ASSERT (h->dynindx != -1);
 
-      s = bfd_get_section_by_name (dynobj, ".stub");
+      s = bfd_get_section_by_name (dynobj, 
+				   MIPS_ELF_STUB_SECTION_NAME (dynobj));
       BFD_ASSERT (s != NULL);
 
       /* Fill the stub.  */
@@ -7333,8 +7401,10 @@ mips_elf_finish_dynamic_symbol (output_b
       else if (mips_elf_hash_table (info)->use_rld_obj_head
 	       && strcmp (name, "__rld_obj_head") == 0)
 	{
-	  asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
-	  BFD_ASSERT (s != NULL);
+	  /* IRIX6 does not use a .rld_map section.  */
+	  if (IRIX_COMPAT (output_bfd) == ict_irix5)
+	    BFD_ASSERT (bfd_get_section_by_name (dynobj, ".rld_map") 
+			!= NULL);
 	  mips_elf_hash_table (info)->rld_value = sym->st_value;
 	}
     }
@@ -7673,7 +7743,8 @@ mips_elf_finish_dynamic_sections (output
 					     s->contents));
 
 	    /* Clean up a dummy stub function entry in .text.  */
-	    s = bfd_get_section_by_name (dynobj, ".stub");
+	    s = bfd_get_section_by_name (dynobj, 
+					 MIPS_ELF_STUB_SECTION_NAME (dynobj));
 	    if (s != NULL)
 	      {
 		file_ptr dummy_offset;

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