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]

RFC: .gnu.strtab (aka merging duplicate strings by ld)


Hi!

Instead of implemention new ABI mangling for strings in g++ and having a
single linkonce section per string I think it would be better to move this
work to the linker (both because it can save far more, it will work for both
C and C++ and also because we might get out of the ELF section limit if
every string constant is a linkonce section).
This patch is a quick attempt for this and I'm looking for comments.
It is incomplete, has ia32 support only.
Basically, gcc would emit string constants it otherwise emits into .rodata
into a special .gnu.strtab section with special semantics. Strings with
embedded NUL characters would have to be kept in .rodata.
The alignment of .gnu.strtab is what all string constants should be aligned
to. ld then attempts to merge duplicate strings.
At least so far, no non-local symbols into the .gnu.strtab section are
handled, the question is whether it would be worth the additional hooks to
support that.
What I'm wondering also is whether there shouldn't be several .gnu.strtab.x
sections with different semantics (e.g. for 1 byte, 2 byte and 4 byte wide char
strings).

2001-03-28  Jakub Jelinek  <jakub@redhat.com>

	* libbfd-in.h (_bfd_link_section_gnu_strtab): New.
	(_bfd_write_section_gnu_strtab): New.
	(_bfd_gnu_strtab_section_offset): New.
	* libbfd.h: Rebuilt.
	* elflink.h (elf_link_add_object_symbols): Call
	_bfd_link_section_gnu_strtab.
	(elf_link_input_bfd): Call _bfd_gnu_strtab_section_offset
	and _bfd_write_section_gnu_strtab.
	* elf-bfd.h (struct elf_link_hash_table): Add strtab_info
	field.
	(struct bfd_elf_section_data): Likewise.
	* elf.c (_bfd_elf_link_hash_table_init): Initialize strtab_info.
	* strtab.c: New file.
	* elf32-i386.c (elf_i386_relocate_section): Call
	_bfd_gnu_strtab_section_offset.
	* Makefile.am: Add strtab.lo.
	* Makefile.in: Rebuilt.

	* scripttempl/elf.sc: Add .gnu.strtab into default linker script.

--- bfd/libbfd-in.h.jj	Mon Mar 26 19:44:22 2001
+++ bfd/libbfd-in.h	Wed Mar 28 18:26:15 2001
@@ -462,6 +462,21 @@ extern boolean _bfd_write_stab_strings P
 extern bfd_vma _bfd_stab_section_offset
   PARAMS ((bfd *, PTR *, asection *, PTR *, bfd_vma));
 
+/* Link .gnu.strtab in section in the first pass.  */
+
+extern boolean _bfd_link_section_gnu_strtab
+  PARAMS ((bfd *, PTR *, asection *, PTR *));
+
+/* Write out the .gnu.strtab section.  */
+
+extern boolean _bfd_write_section_gnu_strtab
+  PARAMS ((bfd *, asection *, PTR));
+
+/* Find an offset within a .gnu.strtab section.  */
+
+extern bfd_vma _bfd_gnu_strtab_section_offset
+  PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_vma));
+
 /* Create a string table.  */
 extern struct bfd_strtab_hash *_bfd_stringtab_init PARAMS ((void));
 
--- bfd/elflink.h.jj	Mon Mar 26 19:44:22 2001
+++ bfd/elflink.h	Wed Mar 28 18:39:57 2001
@@ -2167,6 +2167,21 @@ elf_link_add_object_symbols (abfd, info)
 	}
     }
 
+  if (! info->relocateable
+      && info->hash->creator->flavour == bfd_target_elf_flavour)
+    {
+      asection *strtab = bfd_get_section_by_name (abfd, ".gnu.strtab");
+
+      if (strtab != NULL)
+	{
+	  if (! _bfd_link_section_gnu_strtab (abfd,
+					      &elf_hash_table (info)->strtab_info,
+					      strtab,
+					      &elf_section_data (strtab)->strtab_info))
+	    goto error_return;
+	}
+    }
+
   return true;
 
  error_return:
@@ -5648,9 +5663,17 @@ elf_link_input_bfd (finfo, input_bfd)
 	 we assume that they also have a reasonable value for
 	 output_section.  Any special sections must be set up to meet
 	 these requirements.  */
-      osym.st_value += isec->output_offset;
-      if (! finfo->info->relocateable)
-	osym.st_value += isec->output_section->vma;
+      if (elf_section_data (isec) && elf_section_data (isec)->strtab_info)
+        osym.st_value =
+	  _bfd_gnu_strtab_section_offset (output_bfd, isec,
+					  elf_section_data (isec)->strtab_info,
+					  osym.st_value, (bfd_vma) 0);
+      else
+	{
+	  osym.st_value += isec->output_offset;
+	  if (! finfo->info->relocateable)
+	    osym.st_value += isec->output_section->vma;
+	}
 
       if (! elf_link_output_sym (finfo, name, &osym, isec))
 	return false;
@@ -5887,7 +5910,20 @@ elf_link_input_bfd (finfo, input_bfd)
 	}
 
       /* Write out the modified section contents.  */
-      if (elf_section_data (o)->stab_info == NULL)
+      if (elf_section_data (o)->stab_info)
+	{
+	  if (! (_bfd_write_section_stabs
+		 (output_bfd, &elf_hash_table (finfo->info)->stab_info,
+		  o, &elf_section_data (o)->stab_info, contents)))
+	    return false;
+	}
+      else if (elf_section_data (o)->strtab_info)
+	{
+	  if (! (_bfd_write_section_gnu_strtab
+		 (output_bfd, o, elf_section_data (o)->strtab_info)))
+	    return false;
+	}
+      else
 	{
 	  if (! (o->flags & SEC_EXCLUDE) &&
 	      ! bfd_set_section_contents (output_bfd, o->output_section,
@@ -5895,13 +5931,6 @@ elf_link_input_bfd (finfo, input_bfd)
 					  (o->_cooked_size != 0
 					   ? o->_cooked_size
 					   : o->_raw_size)))
-	    return false;
-	}
-      else
-	{
-	  if (! (_bfd_write_section_stabs
-		 (output_bfd, &elf_hash_table (finfo->info)->stab_info,
-		  o, &elf_section_data (o)->stab_info, contents)))
 	    return false;
 	}
     }
--- bfd/elf-bfd.h.jj	Mon Mar 26 19:44:08 2001
+++ bfd/elf-bfd.h	Wed Mar 28 16:21:23 2001
@@ -241,6 +241,8 @@ struct elf_link_hash_table
   struct elf_link_hash_entry *hgot;
   /* A pointer to information used to link stabs in sections.  */
   PTR stab_info;
+  /* A pointer to information used to link .gnu.strtab sections.  */
+  PTR strtab_info;
   /* A linked list of local symbols to be added to .dynsym.  */
   struct elf_link_local_dynamic_entry *dynlocal;
   /* A linked list of DT_RPATH/DT_RUNPATH names found in dynamic
@@ -712,6 +714,8 @@ struct bfd_elf_section_data
   long dynindx;
   /* A pointer used for .stab linking optimizations.  */
   PTR stab_info;
+  /* A pointer used for .gnu.strtab linking optimizations.  */
+  PTR strtab_info;
   /* A pointer available for the processor specific ELF backend.  */
   PTR tdata;
   /* Nonzero if this section uses RELA relocations, rather than REL.  */
--- bfd/elf.c.jj	Mon Mar 26 19:44:08 2001
+++ bfd/elf.c	Tue Mar 27 15:36:17 2001
@@ -1031,6 +1031,7 @@ _bfd_elf_link_hash_table_init (table, ab
   table->runpath = NULL;
   table->hgot = NULL;
   table->stab_info = NULL;
+  table->strtab_info = NULL;
   table->dynlocal = NULL;
   return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
 }
--- bfd/strtab.c.jj	Tue Mar 27 16:16:20 2001
+++ bfd/strtab.c	Wed Mar 28 19:15:06 2001
@@ -0,0 +1,411 @@
+/* .gnu.strtab support.
+   Copyright 2001 Free Software Foundation, Inc.
+   Written by Jakub Jelinek <jakub@redhat.com>.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* This file contains support for linking .gnu.strtab section, as used
+   in ELF.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include <ctype.h>
+
+/* An entry in the .gnu.strtab hash table.  */
+
+struct gnu_strtab_hash_entry
+{
+  struct bfd_hash_entry root;
+  /* Index in string table.  */
+  bfd_size_type index;
+  /* Which section is it in.  */
+  asection *sec;
+  /* Next string in strtab.  */
+  struct gnu_strtab_hash_entry *next;
+};
+
+/* The .gnu.strtab hash table.  */
+
+struct gnu_strtab_hash
+{
+  struct bfd_hash_table table;
+  /* Next available index.  */
+  bfd_size_type size;
+  /* First string in .gnu.strtab.  */
+  struct gnu_strtab_hash_entry *first;
+  /* Last string in .gnu.strtab.  */
+  struct gnu_strtab_hash_entry *last;
+  /* Start of each string needs to be aligned to 1 << alignment_power
+     octets.  */
+  unsigned int alignment_power;
+};
+
+static struct bfd_hash_entry *gnu_strtab_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+
+/* Routine to create an entry in a .gnu.strtab.  */
+
+static struct bfd_hash_entry *
+gnu_strtab_hash_newfunc (entry, table, string)
+     struct bfd_hash_entry *entry;
+     struct bfd_hash_table *table;
+     const char *string;
+{
+  struct gnu_strtab_hash_entry *ret = (struct gnu_strtab_hash_entry *) entry;
+
+  /* Allocate the structure if it has not already been allocated by a
+     subclass.  */
+  if (ret == (struct gnu_strtab_hash_entry *) NULL)
+    ret = ((struct gnu_strtab_hash_entry *)
+	   bfd_hash_allocate (table, sizeof (struct gnu_strtab_hash_entry)));
+  if (ret == (struct gnu_strtab_hash_entry *) NULL)
+    return NULL;
+
+  /* Call the allocation method of the superclass.  */
+  ret = ((struct gnu_strtab_hash_entry *)
+	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+  if (ret)
+    {
+      /* Initialize the local fields.  */
+      ret->index = (bfd_size_type) -1;
+      ret->sec = NULL;
+      ret->next = NULL;
+    }
+
+  return (struct bfd_hash_entry *) ret;
+}
+
+/* Look up an entry in an .gnu.strtab.  */
+
+#define gnu_strtab_hash_lookup(t, string, create) \
+  ((struct gnu_strtab_hash_entry *) \
+   bfd_hash_lookup (&(t)->table, (string), (create), false))
+
+/* Create a new strtab.  */
+
+static struct gnu_strtab_hash *
+gnu_strtab_init (alignment_power)
+     unsigned int alignment_power;
+{
+  struct gnu_strtab_hash *table;
+
+  table = ((struct gnu_strtab_hash *)
+	   bfd_malloc (sizeof (struct gnu_strtab_hash)));
+  if (table == NULL)
+    return NULL;
+
+  if (! bfd_hash_table_init (&table->table, gnu_strtab_hash_newfunc))
+    {
+      free (table);
+      return NULL;
+    }
+
+  table->size = 0;
+  table->first = NULL;
+  table->last = NULL;
+  table->alignment_power = alignment_power;
+
+  return table;
+}
+
+/* Get the index of a string in a strtab, adding it if it is not
+   already present.  If HASH is false, we don't really use the hash
+   table, and we don't eliminate duplicate strings.  */
+
+static struct gnu_strtab_hash_entry *
+gnu_strtab_add (tab, str)
+     struct gnu_strtab_hash *tab;
+     const char *str;
+{
+  register struct gnu_strtab_hash_entry *entry;
+
+  entry = gnu_strtab_hash_lookup (tab, str, true);
+  if (entry == NULL)
+    return NULL;
+
+  if (entry->index == (bfd_size_type) -1)
+    {
+      entry->index = tab->size;
+      tab->size += strlen (str) + 1;
+      tab->size = align_power (tab->size, tab->alignment_power);
+      if (tab->first == NULL)
+	tab->first = entry;
+      else
+	tab->last->next = entry;
+      tab->last = entry;
+    }
+
+  return entry;
+}
+
+static boolean
+gnu_strtab_emit (abfd, tab, entry)
+     register bfd *abfd;
+     struct gnu_strtab_hash *tab;
+     struct gnu_strtab_hash_entry *entry;
+{
+  asection *sec = entry->sec;
+  char *pad = "";
+
+  if (tab->alignment_power)
+    pad = alloca (1 << tab->alignment_power);
+
+  for (; entry != NULL && entry->sec == sec; entry = entry->next)
+    {
+      register const char *str;
+      register size_t len;
+
+      str = entry->root.string;
+      len = strlen (str) + 1;
+
+      if (bfd_write ((PTR) str, 1, len, abfd) != len)
+	return false;
+
+      if (tab->alignment_power)
+	{
+	  len &= (1 << tab->alignment_power) - 1;
+	  if (len && bfd_write ((PTR) pad, 1, tab->alignment_power - len,
+				abfd) != tab->alignment_power - len)
+	    return false;
+	}
+    }
+
+  return true;
+}
+
+struct gnu_strtab_info
+{
+  /* A hash table used to hold stabs strings.  */
+  struct gnu_strtab_hash *strings;
+  /* The last .gnu.strtab section.  */
+  asection *last;
+};
+
+struct gnu_strtab_sec_info
+{
+  /* A hash table used to hold stabs strings.  */
+  struct gnu_strtab_hash *strings;
+  /* First string in this section.  */
+  struct gnu_strtab_hash_entry *first;
+  /* Original section content.  */
+  unsigned char contents[1];
+};
+
+/* This function is called for each input file from the add_symbols
+   pass of the linker.  */
+
+boolean
+_bfd_link_section_gnu_strtab (abfd, psinfo, strsec, psecinfo)
+     bfd *abfd;
+     PTR *psinfo;
+     asection *strsec;
+     PTR *psecinfo;
+{
+  boolean first, nul;
+  struct gnu_strtab_info *sinfo;
+  struct gnu_strtab_sec_info *secinfo;
+  unsigned char *p, *end;
+  bfd_vma mask;
+
+  if (strsec->_raw_size == 0)
+    return true;
+
+  if ((strsec->flags & SEC_RELOC) != 0)
+    {
+      /* We shouldn't see relocations in the strings, and we aren't
+         prepared to handle them.  */
+      return true;
+    }
+
+  if (strsec->output_section != NULL
+      && bfd_is_abs_section (strsec->output_section))
+    {
+      /* The section is being discarded from the link, so we should
+	 just ignore it.  */
+      return true;
+    }
+
+  first = false;
+
+  if (*psinfo == NULL)
+    {
+      /* Initialize the strtab information we need to keep track of.  */
+      first = true;
+      *psinfo = (PTR) bfd_alloc (abfd, sizeof (struct gnu_strtab_info));
+      if (*psinfo == NULL)
+	goto error_return;
+      sinfo = (struct gnu_strtab_info *) *psinfo;
+      sinfo->strings =
+	gnu_strtab_init (bfd_get_section_alignment (abfd, strsec));
+      if (sinfo->strings == NULL)
+	goto error_return;
+    }
+
+  sinfo = (struct gnu_strtab_info *) *psinfo;
+
+  if (!first
+      && bfd_get_section_alignment (abfd, sinfo->last)
+	 != bfd_get_section_alignment (abfd, strsec))
+    {
+      /* We cannot optimize if different .gnu.strtab sections have different
+	 alignment.  */
+      return true;
+    }
+
+  /* Read the section from abfd.  */
+
+  *psecinfo = bfd_malloc (sizeof (struct gnu_strtab_sec_info)
+			  + strsec->_raw_size - 1);
+  if (*psecinfo == NULL)
+    goto error_return;
+
+  secinfo = (struct gnu_strtab_sec_info *)*psecinfo;
+  secinfo->strings = sinfo->strings;
+  sinfo->strings->size = 0;
+  secinfo->first = NULL;
+
+  if (! bfd_get_section_contents (abfd, strsec, secinfo->contents, 0,
+				  strsec->_raw_size))
+    goto error_return;
+
+  end = secinfo->contents + strsec->_raw_size;
+  nul = false;
+  mask = ((bfd_vma)1 << sinfo->strings->alignment_power) - 1;
+  for (p = secinfo->contents; p < end; )
+    {
+      struct gnu_strtab_hash_entry *entry;
+
+      entry = gnu_strtab_add (sinfo->strings, p);
+      if (entry->sec == NULL)
+	{
+	  if (secinfo->first == NULL)
+	    secinfo->first = entry;
+	  entry->sec = strsec;
+	}
+      p = strchr (p, 0) + 1;
+      while (p < end && *p == 0)
+	{
+	  if (!nul && !((p - secinfo->contents) & mask))
+	    {
+	      nul = true;
+	      entry = gnu_strtab_add (sinfo->strings, "");
+	      if (entry->sec == NULL)
+		{
+		  if (secinfo->first == NULL)
+		    secinfo->first = entry;
+		  entry->sec = strsec;
+		}
+	    }
+	  p++;
+	}
+    }
+
+  strsec->_cooked_size = sinfo->strings->size;
+  if (!strsec->_cooked_size)
+    strsec->flags |= SEC_EXCLUDE;
+  sinfo->last = strsec;
+  return true;
+
+ error_return:
+  if (*psecinfo != NULL)
+    free (*psecinfo);
+  *psecinfo = NULL;
+  return false;
+}
+
+/* Write out the .stabstr section.  */
+
+boolean
+_bfd_write_section_gnu_strtab (output_bfd, sec, psecinfo)
+     bfd *output_bfd;
+     asection *sec;
+     PTR psecinfo;
+{
+  struct gnu_strtab_sec_info *secinfo;
+
+  secinfo = (struct gnu_strtab_sec_info *) psecinfo;
+
+  if (!sec->_cooked_size)
+    return true;
+
+  if (bfd_seek (output_bfd,
+		(sec->output_section->filepos + sec->output_offset),
+		SEEK_SET) != 0)
+    return false;
+
+  if (! gnu_strtab_emit (output_bfd, secinfo->strings, secinfo->first))
+    return false;
+
+  return true;
+}
+
+/* Adjust an address in the .gnu.strtab section.  Given OFFSET within
+   STRSEC, this returns the new offset in the adjusted .gnu.strtab
+   section.  */
+
+bfd_vma
+_bfd_gnu_strtab_section_offset (output_bfd, strsec, psecinfo, offset, addend)
+     bfd *output_bfd ATTRIBUTE_UNUSED;
+     asection *strsec;
+     PTR psecinfo;
+     bfd_vma offset, addend;
+{
+  struct gnu_strtab_sec_info *secinfo;
+  struct gnu_strtab_hash_entry *entry;
+  unsigned char *p;
+
+  secinfo = (struct gnu_strtab_sec_info *) psecinfo;
+
+  if (offset + addend >= strsec->_raw_size)
+    {
+      if (offset + addend > strsec->_raw_size)
+	(*_bfd_error_handler) (_("%s: access beyond end of .gnu.strtab section %ld %ld"),
+			       bfd_get_filename (strsec->owner), (long)offset,
+			       (long) addend);
+      return strsec->output_offset + strsec->output_section->vma
+	     + (secinfo->first ? strsec->_cooked_size : 0);
+    }
+
+  p = secinfo->contents + offset + addend - 1;
+  while (*p && p >= secinfo->contents)
+    --p;
+  ++p;
+  entry = gnu_strtab_hash_lookup (secinfo->strings, p, false);
+  if (!entry)
+    {
+      /* This should only happen if somebody points into the padding
+	 after a NUL byte but before next string.  */
+      if (*p)
+	abort ();
+      if (!secinfo->strings->first)
+	abort ();
+      entry = secinfo->strings->first;
+      p = secinfo->contents + offset + addend;
+    }
+
+  if (strsec->output_section->vma != entry->sec->output_section->vma
+      && secinfo->first)
+    (*_bfd_error_handler) (_("%s(.gnu.strtab) and %s(.gnu.strtab) sections not in the same output section"),
+			     bfd_get_filename (strsec->owner),
+			     bfd_get_filename (entry->sec->owner));
+
+  return entry->index + entry->sec->output_offset
+	 + entry->sec->output_section->vma - addend;
+}
--- bfd/elf32-i386.c.jj	Mon Mar 26 19:44:20 2001
+++ bfd/elf32-i386.c	Wed Mar 28 18:37:27 2001
@@ -1392,9 +1392,16 @@ elf_i386_relocate_section (output_bfd, i
 	{
 	  sym = local_syms + r_symndx;
 	  sec = local_sections[r_symndx];
-	  relocation = (sec->output_section->vma
-			+ sec->output_offset
-			+ sym->st_value);
+	  if (elf_section_data (sec) && elf_section_data (sec)->strtab_info)
+	    relocation =
+	      _bfd_gnu_strtab_section_offset
+		(output_bfd, sec, elf_section_data (sec)->strtab_info,
+		 sym->st_value, bfd_get_32 (input_bfd,
+					    contents + rel->r_offset));
+	  else
+	    relocation = (sec->output_section->vma
+			  + sec->output_offset
+			  + sym->st_value);
 	}
       else
 	{
--- bfd/Makefile.am.jj	Mon Mar 26 19:44:02 2001
+++ bfd/Makefile.am	Wed Mar 28 18:17:35 2001
@@ -30,14 +30,14 @@ BFD_LIBS = \
 	format.lo init.lo libbfd.lo opncls.lo reloc.lo \
 	section.lo syms.lo targets.lo hash.lo linker.lo \
 	srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \
-	dwarf2.lo
+	strtab.lo dwarf2.lo
 
 BFD_LIBS_CFILES = \
 	archive.c archures.c bfd.c cache.c coffgen.c corefile.c \
 	format.c init.c libbfd.c opncls.c reloc.c \
 	section.c syms.c targets.c hash.c linker.c \
 	srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \
-	dwarf2.c
+	strtab.c dwarf2.c
 
 # This list is alphabetized to make it easier to keep in sync
 # with the decls and initializer in archures.c.
@@ -780,6 +780,7 @@ stabs.lo: stabs.c $(INCDIR)/filenames.h 
   $(INCDIR)/aout/stab.def
 stab-syms.lo: stab-syms.c libaout.h $(INCDIR)/bfdlink.h \
   $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab.def
+strtab.lo: strtab.c $(INCDIR)/filenames.h
 dwarf2.lo: dwarf2.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/dwarf2.h
--- bfd/Makefile.in.jj	Mon Mar 26 19:44:02 2001
+++ bfd/Makefile.in	Wed Mar 28 18:18:32 2001
@@ -144,10 +144,10 @@ BFD_H = bfd.h
 # for the debugger, so if you are downloading things as S-records you
 # need two copies of the executable, one to download and one for the
 # debugger).
-BFD_LIBS =  	archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo 	format.lo init.lo libbfd.lo opncls.lo reloc.lo 	section.lo syms.lo targets.lo hash.lo linker.lo 	srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo 	dwarf2.lo
+BFD_LIBS =  	archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo 	format.lo init.lo libbfd.lo opncls.lo reloc.lo 	section.lo syms.lo targets.lo hash.lo linker.lo 	srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo 	strtab.lo dwarf2.lo
 
 
-BFD_LIBS_CFILES =  	archive.c archures.c bfd.c cache.c coffgen.c corefile.c 	format.c init.c libbfd.c opncls.c reloc.c 	section.c syms.c targets.c hash.c linker.c 	srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c 	dwarf2.c
+BFD_LIBS_CFILES =  	archive.c archures.c bfd.c cache.c coffgen.c corefile.c 	format.c init.c libbfd.c opncls.c reloc.c 	section.c syms.c targets.c hash.c linker.c 	srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c 	strtab.c dwarf2.c
 
 
 # This list is alphabetized to make it easier to keep in sync
@@ -261,7 +261,7 @@ LTLIBRARIES =  $(lib_LTLIBRARIES)
 libbfd_la_OBJECTS =  archive.lo archures.lo bfd.lo cache.lo coffgen.lo \
 corefile.lo format.lo init.lo libbfd.lo opncls.lo reloc.lo section.lo \
 syms.lo targets.lo hash.lo linker.lo srec.lo binary.lo tekhex.lo \
-ihex.lo stabs.lo stab-syms.lo dwarf2.lo
+ihex.lo stabs.lo stab-syms.lo strtab.lo dwarf2.lo
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -887,6 +887,7 @@ stabs.lo: stabs.c $(INCDIR)/filenames.h 
   $(INCDIR)/aout/stab.def
 stab-syms.lo: stab-syms.c libaout.h $(INCDIR)/bfdlink.h \
   $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab.def
+strtab.lo: strtab.c $(INCDIR)/filenames.h
 dwarf2.lo: dwarf2.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/dwarf2.h
--- bfd/libbfd.h.jj	Mon Mar 26 19:44:22 2001
+++ bfd/libbfd.h	Wed Mar 28 18:26:07 2001
@@ -462,6 +462,21 @@ extern boolean _bfd_write_stab_strings P
 extern bfd_vma _bfd_stab_section_offset
   PARAMS ((bfd *, PTR *, asection *, PTR *, bfd_vma));
 
+/* Link .gnu.strtab in section in the first pass.  */
+
+extern boolean _bfd_link_section_gnu_strtab
+  PARAMS ((bfd *, PTR *, asection *, PTR *));
+
+/* Write out the .gnu.strtab section.  */
+
+extern boolean _bfd_write_section_gnu_strtab
+  PARAMS ((bfd *, asection *, PTR));
+
+/* Find an offset within a .gnu.strtab section.  */
+
+extern bfd_vma _bfd_gnu_strtab_section_offset
+  PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_vma));
+
 /* Create a string table.  */
 extern struct bfd_strtab_hash *_bfd_stringtab_init PARAMS ((void));
 
--- ld/scripttempl/elf.sc.jj	Sat Sep  2 22:43:22 2000
+++ ld/scripttempl/elf.sc	Wed Mar 28 18:55:55 2001
@@ -67,7 +67,7 @@ test "$LD_FLAG" = "N" && DATA_ADDR=.
 INTERP=".interp   ${RELOCATING-0} : { *(.interp) 	}"
 PLT=".plt    ${RELOCATING-0} : { *(.plt)	}"
 DYNAMIC=".dynamic     ${RELOCATING-0} : { *(.dynamic) }"
-RODATA=".rodata ${RELOCATING-0} : { *(.rodata) ${RELOCATING+*(.rodata.*)} ${RELOCATING+*(.gnu.linkonce.r.*)} }"
+RODATA=".rodata ${RELOCATING-0} : { *(.rodata .gnu.strtab) ${RELOCATING+*(.rodata.*)} ${RELOCATING+*(.gnu.linkonce.r.*)} }"
 SBSS2=".sbss2 ${RELOCATING-0} : { *(.sbss2) ${RELOCATING+*(.sbss2.*)} ${RELOCATING+*(.gnu.linkonce.sb2.*)} }"
 SDATA2=".sdata2 ${RELOCATING-0} : { *(.sdata2) ${RELOCATING+*(.sdata2.*)} ${RELOCATING+*(.gnu.linkonce.s2.*)} }"
 CTOR=".ctors ${CONSTRUCTING-0} : 

	Jakub


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