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 different-sized hash-entries



The 64-bit MIPS ELF ABI uses 4-byte hash-table entries (in .hash),
rather than the 8-byte entries assumed by BFD.  This patch allows a
back-end to override the default.  Note that the
size_info::hash_entry_size member was added in my previous patch.
However, should you approve this patch, and not the other, I will move
those couple of lines here.

OK to check in?

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

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

	* elflink.h (elf_link_create_dynamic_sections): Handle non-standard
	hash-entry sizes.
	(size_dynamic_sections): Likewise.
	(elf_link_output_extsym): Likewise.
	* libbfd.c (bfd_get): New macro.
	(bfd_put): Likewise.
	* bfd-in2.h: Regenerated.

Index: elflink.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elflink.h,v
retrieving revision 1.9
diff -u -p -r1.9 elflink.h
--- elflink.h	1999/07/01 23:20:07	1.9
+++ elflink.h	1999/07/07 18:16:50
@@ -1945,16 +1945,18 @@ elf_link_create_dynamic_sections (abfd, 
       && ! _bfd_elf_link_record_dynamic_symbol (info, h))
     return false;
 
+  bed = get_elf_backend_data (abfd);
+
   s = bfd_make_section (abfd, ".hash");
   if (s == NULL
       || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
       || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN))
     return false;
+  elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry;
 
   /* Let the backend create the rest of the sections.  This lets the
      backend set the right flags.  The backend will normally create
      the .got and .plt sections.  */
-  bed = get_elf_backend_data (abfd);
   if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info))
     return false;
 
@@ -2647,6 +2671,7 @@ NAME(bfd_elf,size_dynamic_sections) (out
       asection *s;
       size_t bucketcount = 0;
       Elf_Internal_Sym isym;
+      size_t hash_entry_size;
 
       /* Set up the version definition section.  */
       s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
@@ -2995,14 +3020,16 @@ NAME(bfd_elf,size_dynamic_sections) (out
 
       s = bfd_get_section_by_name (dynobj, ".hash");
       BFD_ASSERT (s != NULL);
-      s->_raw_size = (2 + bucketcount + dynsymcount) * (ARCH_SIZE / 8);
+      hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
+      s->_raw_size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
       s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
       if (s->contents == NULL)
 	return false;
       memset (s->contents, 0, (size_t) s->_raw_size);
 
-      put_word (output_bfd, bucketcount, s->contents);
-      put_word (output_bfd, dynsymcount, s->contents + (ARCH_SIZE / 8));
+      bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents);
+      bfd_put (8 * hash_entry_size, output_bfd, dynsymcount, 
+	       s->contents + hash_entry_size);
 
       elf_hash_table (info)->bucketcount = bucketcount;
 
@@ -4685,6 +4713,7 @@ elf_link_output_extsym (h, data)
     {
       size_t bucketcount;
       size_t bucket;
+      size_t hash_entry_size;
       bfd_byte *bucketpos;
       bfd_vma chain;
 
@@ -4697,13 +4726,15 @@ elf_link_output_extsym (h, data)
 
       bucketcount = elf_hash_table (finfo->info)->bucketcount;
       bucket = h->elf_hash_value % bucketcount;
+      hash_entry_size 
+	= elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize;
       bucketpos = ((bfd_byte *) finfo->hash_sec->contents
-		   + (bucket + 2) * (ARCH_SIZE / 8));
-      chain = get_word (finfo->output_bfd, bucketpos);
-      put_word (finfo->output_bfd, h->dynindx, bucketpos);
-      put_word (finfo->output_bfd, chain,
-		((bfd_byte *) finfo->hash_sec->contents
-		 + (bucketcount + 2 + h->dynindx) * (ARCH_SIZE / 8)));
+		   + (bucket + 2) * hash_entry_size);
+      chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos);
+      bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos);
+      bfd_put (8 * hash_entry_size, finfo->output_bfd, chain,
+	       ((bfd_byte *) finfo->hash_sec->contents
+		+ (bucketcount + 2 + h->dynindx) * hash_entry_size));
 
       if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL)
 	{
Index: libbfd.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/libbfd.c,v
retrieving revision 1.2
diff -u -p -r1.2 libbfd.c
--- libbfd.c	1999/06/03 18:48:23	1.2
+++ libbfd.c	1999/07/07 18:16:51
@@ -827,6 +827,20 @@ DESCRIPTION
 .#define bfd_get_signed_64(abfd, ptr) \
 .		 BFD_SEND(abfd, bfd_getx_signed_64, (ptr))
 .
+.#define bfd_get(bits, abfd, ptr)				\
+.                ((bits) == 8 ? bfd_get_8 (abfd, ptr)		\
+.		 : (bits) == 16 ? bfd_get_16 (abfd, ptr)	\
+.		 : (bits) == 32 ? bfd_get_32 (abfd, ptr)	\
+.		 : (bits) == 64 ? bfd_get_64 (abfd, ptr)	\
+.		 : (abort (), (bfd_vma) - 1))
+.
+.#define bfd_put(bits, abfd, val, ptr)				\
+.                ((bits) == 8 ? bfd_put_8 (abfd, val, ptr)	\
+.		 : (bits) == 16 ? bfd_put_16 (abfd, val, ptr)	\
+.		 : (bits) == 32 ? bfd_put_32 (abfd, val, ptr)	\
+.		 : (bits) == 64 ? bfd_put_64 (abfd, val, ptr)	\
+.		 : (abort (), (void) 0))
+.
 */ 
 
 /*

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