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]
Other format: [Raw text]

[committed] Fix dynamic name generation for local symbols on hppa64


The enclosed patch fixes a problem that was noticed in the parisc64
kernel.  The official procedure descriptors for FPTR64 relocations
for local symbols in different sections weren't unique.  This was
because the dynamic name for these symbols included the section id
of the section that they were in.

The following test program demonstrated the problem:

static int foo(void) { return 1; }

struct xyz {
	int (*baz)(void);
};

static struct xyz n = {
	.baz = foo,
};

int test(struct xyz *x)
{
	if (x->baz == foo)
		return 0;
	else
		return -1;
}

int main(void)
{
	return test(&n);
}

The patch uses the same techique as ia64.  We use the id of the
first section in the BFD for the generating the dynamic name used
for hashing.

Many thanks to Randolph Chung for developing the test program
and helping with the fix.

Tested with 3.5 gcc build.  Committed to 2.15 and trunk.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2004-03-15  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	* elf-hppa.h (elf_hppa_relocate_section): Pass input_bfd instead of
	input_section in calls to get_dyn_name.
	* elf64-hppa.c (get_dyn_name): Change type of first argument to "bfd *".	Use section id of first section in input BFD to build dynamic name for
	local symbols.
	(elf64_hppa_check_relocs): Pass abfd in call to get_dyn_name.

Index: elf-hppa.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-hppa.h,v
retrieving revision 1.67
diff -u -3 -p -r1.67 elf-hppa.h
--- elf-hppa.h	27 Nov 2003 18:49:37 -0000	1.67
+++ elf-hppa.h	15 Mar 2004 04:53:51 -0000
@@ -1350,7 +1372,7 @@ elf_hppa_relocate_section (bfd *output_b
 
 	  /* If this symbol has an entry in the PA64 dynamic hash
 	     table, then get it.  */
-	  dyn_name = get_dyn_name (input_section, h, rel,
+	  dyn_name = get_dyn_name (input_bfd, h, rel,
 				   &dynh_buf, &dynh_buflen);
 	  dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,
 					      dyn_name, FALSE, FALSE);
@@ -1373,7 +1395,7 @@ elf_hppa_relocate_section (bfd *output_b
 
 	      /* If this symbol has an entry in the PA64 dynamic hash
 		 table, then get it.  */
-	      dyn_name = get_dyn_name (input_section, h, rel,
+	      dyn_name = get_dyn_name (input_bfd, h, rel,
 				       &dynh_buf, &dynh_buflen);
 	      dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,
 						  dyn_name, FALSE, FALSE);
@@ -1410,7 +1432,7 @@ elf_hppa_relocate_section (bfd *output_b
 
 	      /* If this symbol has an entry in the PA64 dynamic hash
 		 table, then get it.  */
-	      dyn_name = get_dyn_name (input_section, h, rel,
+	      dyn_name = get_dyn_name (input_bfd, h, rel,
 				       &dynh_buf, &dynh_buflen);
 	      dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,
 						  dyn_name, FALSE, FALSE);
@@ -1426,7 +1448,7 @@ elf_hppa_relocate_section (bfd *output_b
 	    }
 	  else if (h->root.type == bfd_link_hash_undefweak)
             {
-	      dyn_name = get_dyn_name (input_section, h, rel,
+	      dyn_name = get_dyn_name (input_bfd, h, rel,
 				       &dynh_buf, &dynh_buflen);
 	      dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,
 						  dyn_name, FALSE, FALSE);
Index: elf64-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-hppa.c,v
retrieving revision 1.45
diff -u -3 -p -r1.45 elf64-hppa.c
--- elf64-hppa.c	12 Dec 2003 14:11:58 -0000	1.45
+++ elf64-hppa.c	15 Mar 2004 04:53:52 -0000
@@ -173,7 +173,7 @@ static void elf64_hppa_dyn_hash_traverse
 	   PTR info));
 
 static const char *get_dyn_name
-  PARAMS ((asection *, struct elf_link_hash_entry *,
+  PARAMS ((bfd *, struct elf_link_hash_entry *,
 	   const Elf_Internal_Rela *, char **, size_t *));
 
 /* This must follow the definitions of the various derived linker
@@ -446,13 +446,14 @@ elf64_hppa_section_from_shdr (abfd, hdr,
    allocate memory as necessary, possibly reusing PBUF/PLEN.  */
 
 static const char *
-get_dyn_name (sec, h, rel, pbuf, plen)
-     asection *sec;
+get_dyn_name (abfd, h, rel, pbuf, plen)
+     bfd *abfd;
      struct elf_link_hash_entry *h;
      const Elf_Internal_Rela *rel;
      char **pbuf;
      size_t *plen;
 {
+  asection *sec = abfd->sections;
   size_t nlen, tlen;
   char *buf;
   size_t len;
@@ -858,7 +859,7 @@ elf64_hppa_check_relocs (abfd, info, sec
 	continue;
 
       /* Collect a canonical name for this address.  */
-      addr_name = get_dyn_name (sec, h, rel, &buf, &buf_len);
+      addr_name = get_dyn_name (abfd, h, rel, &buf, &buf_len);
 
       /* Collect the canonical entry data for this address.  */
       dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,


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