public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* RFC: Don't use section name to set ELF section data
@ 2003-06-14 19:14 H. J. Lu
  2003-06-19 19:17 ` Andreas Schwab
       [not found] ` <m3y901rluw.fsf@redhat.com>
  0 siblings, 2 replies; 11+ messages in thread
From: H. J. Lu @ 2003-06-14 19:14 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 140 bytes --]

Here is my first attempt. It passed "make check" on Linux/i386. I'd
like to know if I am on the right track before I finish my work.


H.J.

[-- Attachment #2: binutils-type-1.patch --]
[-- Type: text/plain, Size: 16883 bytes --]

bfd/

2003-06-14  H.J. Lu <hongjiu.lu@intel.com>

	* elf-bfd.h (elf_section_type). New.
	(elf_section_flags): New.

	* elf.c (special_section): New.
	(_bfd_elf_new_section_hook): Check special_section to set
	elf_section_type and elf_section_flags.
	(elf_fake_sections): Don't use section name to set ELF section
	data.

	* section.c (bfd_abs_section): Remove const.
	(bfd_und_section): Likewise.
	(bfd_com_section): Likewise.
	(bfd_ind_section): Likewise.

gas/

2003-06-14  H.J. Lu <hongjiu.lu@intel.com>

	* config/obj-elf.c (elf_get_sec_type_attr): New function.
	(special_section): Updated.
	(elf_sec_set_private_data): New function.
	(obj_elf_change_section): Call elf_get_sec_type_attr. Set
	elf_section_type and elf_section_flags.
	(obj_elf_section): Initialize type to -1.
	(elf_frob_file): Set SHT_GROUP.

	* config/obj-elf.h (obj_sec_set_private_data): New.
	(elf_sec_set_private_data): Declared.

	* subsegs.c (subseg_get): Call obj_sec_set_private_data if it
	is defined.

--- binutils/bfd/elf-bfd.h.type	2003-06-13 08:34:09.000000000 -0700
+++ binutils/bfd/elf-bfd.h	2003-06-14 09:55:40.000000000 -0700
@@ -1050,6 +1050,8 @@ struct bfd_elf_section_data
 };
 
 #define elf_section_data(sec)  ((struct bfd_elf_section_data*)sec->used_by_bfd)
+#define elf_section_type(sec)  (elf_section_data(sec)->this_hdr.sh_type)
+#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags)
 #define elf_group_name(sec)    (elf_section_data(sec)->group.name)
 #define elf_group_id(sec)      (elf_section_data(sec)->group.id)
 #define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
--- binutils/bfd/elf.c.type	2003-06-13 08:34:09.000000000 -0700
+++ binutils/bfd/elf.c	2003-06-14 11:56:22.000000000 -0700
@@ -2231,6 +2231,35 @@ bfd_section_from_elf_index (abfd, index)
   return elf_elfsections (abfd)[index]->bfd_section;
 }
 
+struct special_section
+{
+  const char *name;
+  int type;
+  int attributes;
+  size_t length;
+};
+
+static struct special_section const special_sections[] =
+{
+  { ".dynamic",	SHT_DYNAMIC,	SHF_ALLOC,			0},
+  { ".dynstr",	SHT_STRTAB,	SHF_ALLOC,			0},
+  { ".dynsym",	SHT_DYNSYM,	SHF_ALLOC,			0},
+  { ".got",	SHT_PROGBITS,	0,				0},
+  { ".hash",	SHT_HASH,	SHF_ALLOC,			0},
+  { ".interp",	SHT_PROGBITS,	0,				0},
+  { ".plt",	SHT_PROGBITS,	0,				0},
+  { ".shstrtab",SHT_STRTAB,	0,				0},
+  { ".strtab",	SHT_STRTAB,	0,				0},
+  { ".symtab",	SHT_SYMTAB,	0,				0},
+  { ".gnu.version",SHT_GNU_versym,0,				0},
+  { ".gnu.version_d",SHT_GNU_verdef,0,				0},
+  { ".gnu.version_r",SHT_GNU_verneed,0,				0},
+  { ".note",	SHT_NOTE,	0,				5},
+  { ".rel",	SHT_REL,	0,				4},
+  { ".rela",	SHT_RELA,	0,				5},
+  { NULL,	0,		0,				0}
+};
+
 bfd_boolean
 _bfd_elf_new_section_hook (abfd, sec)
      bfd *abfd;
@@ -2241,11 +2270,37 @@ _bfd_elf_new_section_hook (abfd, sec)
   sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
   if (sdata == NULL)
     {
+      int i;
+
       bfd_size_type amt = sizeof (*sdata);
       sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd, amt);
       if (sdata == NULL)
 	return FALSE;
       sec->used_by_bfd = (PTR) sdata;
+
+      /* See if this is one of the special sections.  */
+      for (i = 0; special_sections[i].name != NULL; i++)
+	if (sec->name
+	    && ((special_sections[i].length
+		 && strncmp (sec->name, special_sections[i].name,
+			     special_sections[i].length) == 0)
+		|| strcmp (sec->name, special_sections[i].name) == 0))
+	  {
+	    elf_section_type (sec) = special_sections[i].type;
+	    elf_section_flags (sec) = special_sections[i].attributes;
+	    break;
+	  }
+      
+      if (special_sections[i].name == NULL)
+	{
+	  if (strncmp (sec->name, ".stab", 5) == 0
+	      && strcmp (sec->name
+			 + strlen (sec->name) - 3, "str") == 0)
+	    elf_section_type (sec) = SHT_STRTAB;
+	}
+
+      if (!elf_section_type (sec))
+	elf_section_type (sec) = (unsigned int) -1;
     }
 
   /* Indicate whether or not this section should use RELA relocations.  */
@@ -2486,55 +2541,52 @@ elf_fake_sections (abfd, asect, failedpt
   this_hdr->bfd_section = asect;
   this_hdr->contents = NULL;
 
-  /* FIXME: This should not be based on section names.  */
-  if (strcmp (asect->name, ".dynstr") == 0)
-    this_hdr->sh_type = SHT_STRTAB;
-  else if (strcmp (asect->name, ".hash") == 0)
+  switch (this_hdr->sh_type)
     {
-      this_hdr->sh_type = SHT_HASH;
+    default:
+      (*_bfd_error_handler)
+       (_("%s: Section `%s' has unknown type 0x%0x"),
+	bfd_get_filename (asect->owner), asect->name,
+	this_hdr->sh_type);
+      abort ();
+      break;
+
+    case SHT_STRTAB:
+    case SHT_INIT_ARRAY:
+    case SHT_FINI_ARRAY:
+    case SHT_PREINIT_ARRAY:
+    case SHT_NOTE:
+    case SHT_NOBITS:
+    case SHT_PROGBITS:
+      break;
+
+    case SHT_HASH:
       this_hdr->sh_entsize = bed->s->sizeof_hash_entry;
-    }
-  else if (strcmp (asect->name, ".dynsym") == 0)
-    {
-      this_hdr->sh_type = SHT_DYNSYM;
+      break;
+  
+    case SHT_DYNSYM:
       this_hdr->sh_entsize = bed->s->sizeof_sym;
-    }
-  else if (strcmp (asect->name, ".dynamic") == 0)
-    {
-      this_hdr->sh_type = SHT_DYNAMIC;
+      break;
+
+    case SHT_DYNAMIC:
       this_hdr->sh_entsize = bed->s->sizeof_dyn;
-    }
-  else if (strncmp (asect->name, ".rela", 5) == 0
-	   && get_elf_backend_data (abfd)->may_use_rela_p)
-    {
-      this_hdr->sh_type = SHT_RELA;
-      this_hdr->sh_entsize = bed->s->sizeof_rela;
-    }
-  else if (strncmp (asect->name, ".rel", 4) == 0
-	   && get_elf_backend_data (abfd)->may_use_rel_p)
-    {
-      this_hdr->sh_type = SHT_REL;
-      this_hdr->sh_entsize = bed->s->sizeof_rel;
-    }
-  else if (strcmp (asect->name, ".init_array") == 0)
-    this_hdr->sh_type = SHT_INIT_ARRAY;
-  else if (strcmp (asect->name, ".fini_array") == 0)
-    this_hdr->sh_type = SHT_FINI_ARRAY;
-  else if (strcmp (asect->name, ".preinit_array") == 0)
-    this_hdr->sh_type = SHT_PREINIT_ARRAY;
-  else if (strncmp (asect->name, ".note", 5) == 0)
-    this_hdr->sh_type = SHT_NOTE;
-  else if (strncmp (asect->name, ".stab", 5) == 0
-	   && strcmp (asect->name + strlen (asect->name) - 3, "str") == 0)
-    this_hdr->sh_type = SHT_STRTAB;
-  else if (strcmp (asect->name, ".gnu.version") == 0)
-    {
-      this_hdr->sh_type = SHT_GNU_versym;
+      break;
+
+    case SHT_RELA:
+      if (get_elf_backend_data (abfd)->may_use_rela_p)
+	this_hdr->sh_entsize = bed->s->sizeof_rela;
+      break;
+
+     case SHT_REL:
+      if (get_elf_backend_data (abfd)->may_use_rel_p)
+	this_hdr->sh_entsize = bed->s->sizeof_rel;
+      break;
+
+     case SHT_GNU_versym:
       this_hdr->sh_entsize = sizeof (Elf_External_Versym);
-    }
-  else if (strcmp (asect->name, ".gnu.version_d") == 0)
-    {
-      this_hdr->sh_type = SHT_GNU_verdef;
+      break;
+
+     case SHT_GNU_verdef:
       this_hdr->sh_entsize = 0;
       /* objcopy or strip will copy over sh_info, but may not set
          cverdefs.  The linker will set cverdefs, but sh_info will be
@@ -2544,10 +2596,9 @@ elf_fake_sections (abfd, asect, failedpt
       else
 	BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0
 		    || this_hdr->sh_info == elf_tdata (abfd)->cverdefs);
-    }
-  else if (strcmp (asect->name, ".gnu.version_r") == 0)
-    {
-      this_hdr->sh_type = SHT_GNU_verneed;
+      break;
+
+    case SHT_GNU_verneed:
       this_hdr->sh_entsize = 0;
       /* objcopy or strip will copy over sh_info, but may not set
          cverrefs.  The linker will set cverrefs, but sh_info will be
@@ -2557,18 +2608,21 @@ elf_fake_sections (abfd, asect, failedpt
       else
 	BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
 		    || this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
-    }
-  else if ((asect->flags & SEC_GROUP) != 0)
-    {
-      this_hdr->sh_type = SHT_GROUP;
+      break;
+
+    case SHT_GROUP:
       this_hdr->sh_entsize = 4;
-    }
-  else if ((asect->flags & SEC_ALLOC) != 0
-	   && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+      break;
+
+    case (unsigned int) -1:
+      if ((asect->flags & SEC_ALLOC) != 0
+	  && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
 	       || (asect->flags & SEC_NEVER_LOAD) != 0))
-    this_hdr->sh_type = SHT_NOBITS;
-  else
-    this_hdr->sh_type = SHT_PROGBITS;
+	this_hdr->sh_type = SHT_NOBITS;
+      else
+	this_hdr->sh_type = SHT_PROGBITS;
+      break;
+    }
 
   if ((asect->flags & SEC_ALLOC) != 0)
     this_hdr->sh_flags |= SHF_ALLOC;
--- binutils/bfd/section.c.type	2003-06-13 09:41:32.000000000 -0700
+++ binutils/bfd/section.c	2003-06-14 09:47:21.000000000 -0700
@@ -532,18 +532,18 @@ CODE_FRAGMENT
 .#define BFD_IND_SECTION_NAME "*IND*"
 .
 .{* The absolute section.  *}
-.extern const asection bfd_abs_section;
+.extern asection bfd_abs_section;
 .#define bfd_abs_section_ptr ((asection *) &bfd_abs_section)
 .#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
 .{* Pointer to the undefined section.  *}
-.extern const asection bfd_und_section;
+.extern asection bfd_und_section;
 .#define bfd_und_section_ptr ((asection *) &bfd_und_section)
 .#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
 .{* Pointer to the common section.  *}
-.extern const asection bfd_com_section;
+.extern asection bfd_com_section;
 .#define bfd_com_section_ptr ((asection *) &bfd_com_section)
 .{* Pointer to the indirect section.  *}
-.extern const asection bfd_ind_section;
+.extern asection bfd_ind_section;
 .#define bfd_ind_section_ptr ((asection *) &bfd_ind_section)
 .#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
 .
@@ -616,7 +616,7 @@ static const asymbol global_syms[] =
 
 #define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX)				\
   const asymbol * const SYM = (asymbol *) &global_syms[IDX]; 		\
-  const asection SEC = 							\
+  asection SEC = 							\
     /* name, id,  index, next, flags, user_set_vma, reloc_done,      */	\
     { NAME,  IDX, 0,     NULL, FLAGS, 0,            0,			\
 									\
--- binutils/gas/config/obj-elf.c.type	2003-06-13 08:34:09.000000000 -0700
+++ binutils/gas/config/obj-elf.c	2003-06-14 11:53:17.000000000 -0700
@@ -86,6 +86,8 @@ static void obj_elf_symver PARAMS ((int)
 static void obj_elf_subsection PARAMS ((int));
 static void obj_elf_popsection PARAMS ((int));
 static void obj_elf_tls_common PARAMS ((int));
+static bfd_boolean elf_get_sec_type_attr (const char *, bfd_boolean,
+					  int *, int *);
 
 static const pseudo_typeS elf_pseudo_table[] =
 {
@@ -631,9 +633,13 @@ static struct special_section const spec
   { ".tbss",	SHT_NOBITS,	SHF_ALLOC + SHF_WRITE + SHF_TLS	},
   { ".tdata",	SHT_PROGBITS,	SHF_ALLOC + SHF_WRITE + SHF_TLS	},
   { ".text",	SHT_PROGBITS,	SHF_ALLOC + SHF_EXECINSTR	},
-  { ".init_array",SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE         },
-  { ".fini_array",SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE         },
-  { ".preinit_array",SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE   },
+  { ".init_array",SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE		},
+  { ".fini_array",SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE		},
+  { ".preinit_array",SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE	},
+  { ".debug_line",SHT_PROGBITS,	0				},
+  { ".debug_info",SHT_PROGBITS,	0				},
+  { ".debug_abbrev",SHT_PROGBITS,0				},
+  { ".debug_aranges",SHT_PROGBITS,0				},
 
 #ifdef ELF_TC_SPECIAL_SECTIONS
   ELF_TC_SPECIAL_SECTIONS
@@ -658,52 +664,22 @@ static struct special_section const spec
   { NULL,	0,		0				}
 };
 
-void
-obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push)
-     const char *name;
-     int type;
-     int attr;
-     int entsize;
-     const char *group_name;
-     int linkonce;
-     int push;
+static bfd_boolean
+elf_get_sec_type_attr (const char *name, bfd_boolean new,
+		       int *type, int *attr)
 {
-  asection *old_sec;
-  segT sec;
-  flagword flags;
   int i;
-
-#ifdef md_flush_pending_output
-  md_flush_pending_output ();
-#endif
-
-  /* Switch to the section, creating it if necessary.  */
-  if (push)
-    {
-      struct section_stack *elt;
-      elt = xmalloc (sizeof (struct section_stack));
-      elt->next = section_stack;
-      elt->seg = now_seg;
-      elt->prev_seg = previous_section;
-      elt->subseg = now_subseg;
-      elt->prev_subseg = previous_subsection;
-      section_stack = elt;
-    }
-  previous_section = now_seg;
-  previous_subsection = now_subseg;
-
-  old_sec = bfd_get_section_by_name (stdoutput, name);
-  sec = subseg_new (name, 0);
+  bfd_boolean found = FALSE;
 
   /* See if this is one of the special sections.  */
   for (i = 0; special_sections[i].name != NULL; i++)
     if (strcmp (name, special_sections[i].name) == 0)
       {
-	if (type == SHT_NULL)
-	  type = special_sections[i].type;
-	else if (type != special_sections[i].type)
+	if (*type == -1)
+	  *type = special_sections[i].type;
+	else if (*type != special_sections[i].type)
 	  {
-	    if (old_sec == NULL
+	    if (new
 		/* FIXME: gcc, as of 2002-10-22, will emit
 
 		   .section .init_array,"aw",@progbits
@@ -719,25 +695,89 @@ obj_elf_change_section (name, type, attr
 	    else
 	      {
 		as_warn (_("ignoring incorrect section type for %s"), name);
-		type = special_sections[i].type;
+		*type = special_sections[i].type;
 	      }
 	  }
-	if ((attr &~ special_sections[i].attributes) != 0
-	    && old_sec == NULL)
+	if (new && (*attr &~ special_sections[i].attributes) != 0)
 	  {
 	    /* As a GNU extension, we permit a .note section to be
 	       allocatable.  If the linker sees an allocateable .note
 	       section, it will create a PT_NOTE segment in the output
 	       file.  */
 	    if (strcmp (name, ".note") != 0
-		|| attr != SHF_ALLOC)
+		|| *attr != SHF_ALLOC)
 	      as_warn (_("setting incorrect section attributes for %s"),
 		       name);
 	  }
-	attr |= special_sections[i].attributes;
+	*attr |= special_sections[i].attributes;
+	found = TRUE;
 	break;
       }
 
+  return found;
+}
+
+void
+elf_sec_set_private_data (bfd *abfd, asection *sec)
+{
+  if (!_bfd_elf_new_section_hook (abfd, sec))
+    as_fatal (_("can't allocate ELF private section data: %s"),
+	      bfd_errmsg (bfd_get_error ()));
+
+  if (elf_section_type (sec) == (unsigned int) -1)
+    {
+      unsigned int type = -1, attr = 0;
+
+      if (elf_get_sec_type_attr (sec->name, TRUE, &type, &attr))
+	{
+	  elf_section_type (sec) = type;
+	  elf_section_flags (sec) = attr;
+	}
+    }
+}
+
+void
+obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push)
+     const char *name;
+     int type;
+     int attr;
+     int entsize;
+     const char *group_name;
+     int linkonce;
+     int push;
+{
+  asection *old_sec;
+  segT sec;
+  flagword flags;
+
+#ifdef md_flush_pending_output
+  md_flush_pending_output ();
+#endif
+
+  /* Switch to the section, creating it if necessary.  */
+  if (push)
+    {
+      struct section_stack *elt;
+      elt = xmalloc (sizeof (struct section_stack));
+      elt->next = section_stack;
+      elt->seg = now_seg;
+      elt->prev_seg = previous_section;
+      elt->subseg = now_subseg;
+      elt->prev_subseg = previous_subsection;
+      section_stack = elt;
+    }
+  previous_section = now_seg;
+  previous_subsection = now_subseg;
+
+  old_sec = bfd_get_section_by_name (stdoutput, name);
+  sec = subseg_new (name, 0);
+
+  if (elf_get_sec_type_attr (name, old_sec == NULL, &type, &attr))
+    {
+      elf_section_type (sec) = type;
+      elf_section_flags (sec) = attr;
+    }
+
   /* Convert ELF type and flags to BFD flags.  */
   flags = (SEC_RELOC
 	   | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
@@ -986,7 +1026,7 @@ obj_elf_section (push)
   name = obj_elf_section_name ();
   if (name == NULL)
     return;
-  type = SHT_NULL;
+  type = -1;
   attr = 0;
   group_name = NULL;
   entsize = 0;
@@ -2078,6 +2118,7 @@ elf_frob_file ()
 	  as_fatal (_("can't create group: %s"),
 		    bfd_errmsg (bfd_get_error ()));
 	}
+      elf_section_type (s) = SHT_GROUP;
 
       /* Pass a pointer to the first section in this group.  */
       elf_next_in_group (s) = list.head[i];
--- binutils/gas/config/obj-elf.h.type	2002-09-18 22:11:17.000000000 -0700
+++ binutils/gas/config/obj-elf.h	2003-06-14 11:06:34.000000000 -0700
@@ -134,6 +134,11 @@ int elf_s_get_other PARAMS ((symbolS *))
 
 extern asection *gdb_section;
 
+#ifndef obj_sec_set_private_data
+#define obj_sec_set_private_data elf_sec_set_private_data
+#endif
+extern void elf_sec_set_private_data (bfd *, asection *);
+
 #ifndef obj_frob_file
 #define obj_frob_file  elf_frob_file
 #endif
--- binutils/gas/subsegs.c.type	2002-12-08 13:41:58.000000000 -0800
+++ binutils/gas/subsegs.c	2003-06-14 11:06:45.000000000 -0700
@@ -422,6 +422,10 @@ subseg_get (segname, force_new)
   else
     secptr = bfd_make_section_anyway (stdoutput, segname);
 
+#ifdef obj_sec_set_private_data
+  obj_sec_set_private_data (stdoutput, secptr);
+#endif
+
   seginfo = seg_info (secptr);
   if (! seginfo)
     {

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2003-07-26  0:09 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-14 19:14 RFC: Don't use section name to set ELF section data H. J. Lu
2003-06-19 19:17 ` Andreas Schwab
     [not found] ` <m3y901rluw.fsf@redhat.com>
2003-07-25  1:36   ` PATCH: " H. J. Lu
2003-07-25  4:48     ` Alan Modra
2003-07-25 14:39       ` H. J. Lu
2003-07-25 12:29     ` Nick Clifton
2003-07-25 14:38       ` H. J. Lu
2003-07-25 16:10         ` H. J. Lu
2003-07-25 17:43           ` H. J. Lu
2003-07-25 17:59             ` H. J. Lu
2003-07-26  0:09               ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).