[committed] Fix readelf -u for hppa64-hp-hpux11

John David Anglin dave@hiauly1.hia.nrc.ca
Sun Aug 14 22:41:00 GMT 2005


readelf -u was segfaulting on hppa64-hp-hpux11.11.  The segfault was
caused by the fact that we were not allocating enough entries.  This
was caused by using the wrong entry size.  The enclosed change fixes
these problems.

Tested on hppa64-hp-hpux11.11 and hppa-unknown-linux-gnu.

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

2005-08-14  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	* readelf.c (slurp_hppa_unwind_table): Fix entry size on hppa64-hpux.
	Don't access table entries past the end of the table.

Index: readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.311
diff -u -3 -p -r1.311 readelf.c
--- readelf.c	13 Aug 2005 23:59:43 -0000	1.311
+++ readelf.c	14 Aug 2005 22:04:42 -0000
@@ -5198,7 +5198,7 @@ slurp_hppa_unwind_table (FILE *file,
 			 struct hppa_unw_aux_info *aux,
 			 Elf_Internal_Shdr *sec)
 {
-  unsigned long size, unw_ent_size, nrelas, i;
+  unsigned long size, unw_ent_size, nentries, nrelas, i;
   Elf_Internal_Phdr *seg;
   struct hppa_unw_table_entry *tep;
   Elf_Internal_Shdr *relsec;
@@ -5238,31 +5238,26 @@ slurp_hppa_unwind_table (FILE *file,
   if (!table)
     return 0;
 
-  unw_ent_size = 2 * eh_addr_size + 8;
+  unw_ent_size = 16;
+  nentries = size / unw_ent_size;
+  size = unw_ent_size * nentries;
 
-  tep = aux->table = xcmalloc (size / unw_ent_size, sizeof (aux->table[0]));
+  tep = aux->table = xcmalloc (nentries, sizeof (aux->table[0]));
 
-  for (tp = table; tp < table + size; tp += (2 * eh_addr_size + 8), ++tep)
+  for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
     {
       unsigned int tmp1, tmp2;
 
       tep->start.section = SHN_UNDEF;
       tep->end.section   = SHN_UNDEF;
 
-      if (is_32bit_elf)
-	{
-	  tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
-	  tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
-	  tmp1 = byte_get ((unsigned char *) tp + 8, 4);
-	  tmp2 = byte_get ((unsigned char *) tp + 12, 4);
-	}
-      else
-	{
-	  tep->start.offset = BYTE_GET ((unsigned char *) tp + 0);
-	  tep->end.offset = BYTE_GET ((unsigned char *) tp + 8);
-	  tmp1 = byte_get ((unsigned char *) tp + 16, 4);
-	  tmp2 = byte_get ((unsigned char *) tp + 20, 4);
-	}
+      tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
+      tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
+      tmp1 = byte_get ((unsigned char *) tp + 8, 4);
+      tmp2 = byte_get ((unsigned char *) tp + 12, 4);
+
+      tep->start.offset += aux->seg_base;
+      tep->end.offset   += aux->seg_base;
 
       tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
       tep->Millicode = (tmp1 >> 30) & 0x1;
@@ -5295,9 +5290,6 @@ slurp_hppa_unwind_table (FILE *file,
       tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
       tep->reserved4 = (tmp2 >> 27) & 0x1;
       tep->Total_frame_size = tmp2 & 0x7ffffff;
-
-      tep->start.offset += aux->seg_base;
-      tep->end.offset   += aux->seg_base;
     }
   free (table);
 
@@ -5356,7 +5348,7 @@ slurp_hppa_unwind_table (FILE *file,
       free (rela);
     }
 
-  aux->table_len = size / unw_ent_size;
+  aux->table_len = nentries;
 
   return 1;
 }



More information about the Binutils mailing list