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