public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* read Xtensa property tables more robustly
@ 2007-04-27 20:18 Bob Wilson
  0 siblings, 0 replies; only message in thread
From: Bob Wilson @ 2007-04-27 20:18 UTC (permalink / raw)
  To: binutils

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

The bug I just fixed (an extra increment in relax_property_section) caused some 
property table entries to have no relocations, and the code for reading property 
tables assumed that either all the entries have relocations or none of them do. 
  That assumption is normally true but it is good to handle unexpected inputs. 
I've committed this patch that changes the table reader to walk through the 
table entries and relocations at the same time so that it can deal with entries 
with no relocations.  (It still ignores relocations on the size and/or flags 
fields, though.)  I tested this before I fixed the other bug, since without the 
bug, this situation doesn't come up.

bfd/
	* elf32-xtensa.c (xtensa_read_table_entries): Step through table
	contents and relocs in parallel.

[-- Attachment #2: bfd-readtbl.patch --]
[-- Type: text/x-diff, Size: 4522 bytes --]

Index: elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.87
diff -u -p -r1.87 elf32-xtensa.c
--- elf32-xtensa.c	27 Apr 2007 18:28:22 -0000	1.87
+++ elf32-xtensa.c	27 Apr 2007 19:55:01 -0000
@@ -612,10 +612,10 @@ xtensa_read_table_entries (bfd *abfd,
   property_table_entry *blocks;
   int blk, block_count;
   bfd_size_type num_records;
-  Elf_Internal_Rela *internal_relocs;
-  bfd_vma section_addr;
+  Elf_Internal_Rela *internal_relocs, *irel, *rel_end;
+  bfd_vma section_addr, off;
   flagword predef_flags;
-  bfd_size_type table_entry_size;
+  bfd_size_type table_entry_size, section_limit;
 
   if (!section
       || !(section->flags & SEC_ALLOC)
@@ -651,67 +651,63 @@ xtensa_read_table_entries (bfd *abfd,
   else
     section_addr = section->vma;
 
-  /* If the file has not yet been relocated, process the relocations
-     and sort out the table entries that apply to the specified section.  */
   internal_relocs = retrieve_internal_relocs (abfd, table_section, TRUE);
   if (internal_relocs && !table_section->reloc_done)
     {
-      unsigned i;
+      qsort (internal_relocs, table_section->reloc_count,
+	     sizeof (Elf_Internal_Rela), internal_reloc_compare);
+      irel = internal_relocs;
+    }
+  else
+    irel = NULL;
+
+  section_limit = bfd_get_section_limit (abfd, section);
+  rel_end = internal_relocs + table_section->reloc_count;
+
+  for (off = 0; off < table_size; off += table_entry_size) 
+    {
+      bfd_vma address = bfd_get_32 (abfd, table_data + off);
 
-      for (i = 0; i < table_section->reloc_count; i++)
+      /* Skip any relocations before the current offset.  This should help
+	 avoid confusion caused by unexpected relocations for the preceding
+	 table entry.  */
+      while (irel &&
+	     (irel->r_offset < off
+	      || (irel->r_offset == off
+		  && ELF32_R_TYPE (irel->r_info) == R_XTENSA_NONE)))
 	{
-	  Elf_Internal_Rela *rel = &internal_relocs[i];
-	  unsigned long r_symndx;
+	  irel += 1;
+	  if (irel >= rel_end)
+	    irel = 0;
+	}
 
-	  if (ELF32_R_TYPE (rel->r_info) == R_XTENSA_NONE)
-	    continue;
+      if (irel && irel->r_offset == off)
+	{
+	  bfd_vma sym_off;
+	  unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
+	  BFD_ASSERT (ELF32_R_TYPE (irel->r_info) == R_XTENSA_32);
 
-	  BFD_ASSERT (ELF32_R_TYPE (rel->r_info) == R_XTENSA_32);
-	  r_symndx = ELF32_R_SYM (rel->r_info);
+	  if (get_elf_r_symndx_section (abfd, r_symndx) != section)
+	    continue;
 
-	  if (get_elf_r_symndx_section (abfd, r_symndx) == section)
-	    {
-	      bfd_vma sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
-	      BFD_ASSERT (sym_off == 0);
-	      blocks[block_count].address =
-		(section_addr + sym_off + rel->r_addend
-		 + bfd_get_32 (abfd, table_data + rel->r_offset));
-	      blocks[block_count].size =
-		bfd_get_32 (abfd, table_data + rel->r_offset + 4);
-	      if (predef_flags)
-		blocks[block_count].flags = predef_flags;
-	      else
-		blocks[block_count].flags =
-		  bfd_get_32 (abfd, table_data + rel->r_offset + 8);
-	      block_count++;
-	    }
+	  sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
+	  BFD_ASSERT (sym_off == 0);
+	  address += (section_addr + sym_off + irel->r_addend);
 	}
-    }
-  else
-    {
-      /* The file has already been relocated and the addresses are
-	 already in the table.  */
-      bfd_vma off;
-      bfd_size_type section_limit = bfd_get_section_limit (abfd, section);
-
-      for (off = 0; off < table_size; off += table_entry_size) 
-	{
-	  bfd_vma address = bfd_get_32 (abfd, table_data + off);
-
-	  if (address >= section_addr
-	      && address < section_addr + section_limit)
-	    {
-	      blocks[block_count].address = address;
-	      blocks[block_count].size =
-		bfd_get_32 (abfd, table_data + off + 4);
-	      if (predef_flags)
-		blocks[block_count].flags = predef_flags;
-	      else
-		blocks[block_count].flags =
-		  bfd_get_32 (abfd, table_data + off + 8);
-	      block_count++;
-	    }
+      else
+	{
+	  if (address < section_addr
+	      || address >= section_addr + section_limit)
+	    continue;
 	}
+
+      blocks[block_count].address = address;
+      blocks[block_count].size = bfd_get_32 (abfd, table_data + off + 4);
+      if (predef_flags)
+	blocks[block_count].flags = predef_flags;
+      else
+	blocks[block_count].flags = bfd_get_32 (abfd, table_data + off + 8);
+      block_count++;
     }
 
   release_contents (table_section, table_data);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-04-27 20:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-27 20:18 read Xtensa property tables more robustly Bob Wilson

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).