summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog40
-rw-r--r--bfd/coff-h8300.c2
-rw-r--r--bfd/coff-h8500.c2
-rw-r--r--bfd/coff-ia64.c2
-rw-r--r--bfd/coff-m68k.c1
-rw-r--r--bfd/coff-mcore.c16
-rw-r--r--bfd/coff-tic30.c2
-rw-r--r--bfd/coff-w65.c29
-rw-r--r--bfd/coff-we32k.c9
-rw-r--r--bfd/coff-x86_64.c13
-rw-r--r--bfd/coff-z80.c2
-rw-r--r--bfd/coff-z8k.c2
-rw-r--r--bfd/coffcode.h2
-rw-r--r--bfd/coffgen.c7
-rw-r--r--bfd/ecoff.c8
-rw-r--r--bfd/mach-o.c26
-rw-r--r--bfd/pe-mips.c7
-rw-r--r--bfd/reloc.c9
-rw-r--r--bfd/versados.c45
19 files changed, 169 insertions, 55 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d188bd7cefa..c379fcae2b8 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,43 @@
+2014-11-26 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * coff-h8300.c (rtype2howto): Replace abort with returning a NULL
+ value.
+ * coff-h8500.c (rtype2howto): Likewise.
+ * coff-tic30.c (rtype2howto): Likewise.
+ * coff-z80.c (rtype2howto): Likewise.
+ * coff-z8k.c (rtype2howto): Likewise.
+ * coff-ia64.c (RTYPE2HOWTO): Always return a valid howto.
+ * coff-m68k.c (m68k_rtype2howto): Return a NULL howto if none
+ could be found.
+ * coff-mcore.c (RTYPE2HOWTO): Add range checking.
+ * coff-w65.c (rtype2howto): Likewise.
+ * coff-we32k.c (RTYPE2HOWTO): Likewise.
+ * pe-mips.c (RTYPE2HOWTO): Likewise.
+ * coff-x86_64.c (coff_amd64_reloc): Likewise. Replace abort with
+ an error return.
+ * coffcode.h (coff_slurp_reloc_table): Allow the rel parameter to
+ be unused.
+ * coffgen.c (make_a_section_from_file): Check the length of a
+ section name before testing to see if it is a debug section name.
+ (coff_object_p): Zero out any uninitialised bytes in the opt
+ header.
+ * ecoff.c (_bfd_ecoff_slurp_symbolic_info): Test for the raw
+ source being empty when there are values to be processed.
+ (_bfd_ecoff_slurp_symbol_table): Add range check.
+ * mach-o.c (bfd_mach_o_canonicalize_one_reloc): Likewise.
+ (bfd_mach_o_mangle_sections): Move test for too many sections to
+ before the allocation of the section table.
+ (bfd_mach_o_read_symtab_strtab): If the read fails, free the
+ memory and nullify the symbol pointer.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Add
+ handling of a bfd_reloc_notsupported return value.
+ * versados.c (EDATA): Add range checking.
+ (get_record): Likewise.
+ (process_otr): Check for contents being available before updating
+ them.
+ (versados_canonicalize_reloc): Add range check.
+
2014-11-26 Alan Modra <amodra@gmail.com>
* elf.c (_bfd_elf_slurp_version_tables): Delay allocation of
diff --git a/bfd/coff-h8300.c b/bfd/coff-h8300.c
index 5ec48c960db..10123d3e52a 100644
--- a/bfd/coff-h8300.c
+++ b/bfd/coff-h8300.c
@@ -337,7 +337,7 @@ rtype2howto (arelent *internal, struct internal_reloc *dst)
internal->howto = howto_table + 19;
break;
default:
- abort ();
+ internal->howto = NULL;
break;
}
}
diff --git a/bfd/coff-h8500.c b/bfd/coff-h8500.c
index 574f95648b9..b6a996e943a 100644
--- a/bfd/coff-h8500.c
+++ b/bfd/coff-h8500.c
@@ -95,7 +95,7 @@ rtype2howto (arelent * internal, struct internal_reloc *dst)
switch (dst->r_type)
{
default:
- abort ();
+ internal->howto = NULL;
break;
case R_H8500_IMM8:
internal->howto = &r_imm8;
diff --git a/bfd/coff-ia64.c b/bfd/coff-ia64.c
index 38a0a381f13..f1641dbbdad 100644
--- a/bfd/coff-ia64.c
+++ b/bfd/coff-ia64.c
@@ -47,7 +47,7 @@ static reloc_howto_type howto_table[] =
#endif
#define RTYPE2HOWTO(cache_ptr, dst) \
- (cache_ptr)->howto = howto_table + (dst)->r_type;
+ (cache_ptr)->howto = howto_table;
#ifdef COFF_WITH_PE
/* Return TRUE if this relocation should
diff --git a/bfd/coff-m68k.c b/bfd/coff-m68k.c
index f7089a681b0..5ebf52c3c9a 100644
--- a/bfd/coff-m68k.c
+++ b/bfd/coff-m68k.c
@@ -143,6 +143,7 @@ m68k_rtype2howto (arelent *internal, int relocentry)
case R_PCRWORD: internal->howto = m68kcoff_howto_table + 4; break;
case R_PCRLONG: internal->howto = m68kcoff_howto_table + 5; break;
case R_RELLONG_NEG: internal->howto = m68kcoff_howto_table + 6; break;
+ default: internal->howto = NULL; break;
}
}
diff --git a/bfd/coff-mcore.c b/bfd/coff-mcore.c
index 7dad44fdcec..9f30cfcb623 100644
--- a/bfd/coff-mcore.c
+++ b/bfd/coff-mcore.c
@@ -273,16 +273,15 @@ mcore_coff_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
}
#undef HOW2MAP
+#define NUM_HOWTOS NUM_ELEM (mcore_coff_howto_table)
+
static reloc_howto_type *
mcore_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
const char *r_name)
{
unsigned int i;
- for (i = 0;
- i < (sizeof (mcore_coff_howto_table)
- / sizeof (mcore_coff_howto_table[0]));
- i++)
+ for (i = 0; i < NUM_HOWTOS; i++)
if (mcore_coff_howto_table[i].name != NULL
&& strcasecmp (mcore_coff_howto_table[i].name, r_name) == 0)
return &mcore_coff_howto_table[i];
@@ -290,8 +289,11 @@ mcore_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
return NULL;
}
-#define RTYPE2HOWTO(cache_ptr, dst) \
- (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ ((cache_ptr)->howto = \
+ ((dst)->r_type < NUM_HOWTOS \
+ ? mcore_coff_howto_table + (dst)->r_type \
+ : NULL))
static reloc_howto_type *
coff_mcore_rtype_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
@@ -303,7 +305,7 @@ coff_mcore_rtype_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
{
reloc_howto_type * howto;
- if (rel->r_type >= NUM_ELEM (mcore_coff_howto_table))
+ if (rel->r_type >= NUM_HOWTOS)
return NULL;
howto = mcore_coff_howto_table + rel->r_type;
diff --git a/bfd/coff-tic30.c b/bfd/coff-tic30.c
index 740c82c867a..ab953088c75 100644
--- a/bfd/coff-tic30.c
+++ b/bfd/coff-tic30.c
@@ -136,7 +136,7 @@ rtype2howto (arelent *internal, struct internal_reloc *dst)
internal->howto = &tic30_coff_howto_table[4];
break;
default:
- abort ();
+ internal->howto = NULL;
break;
}
}
diff --git a/bfd/coff-w65.c b/bfd/coff-w65.c
index f2087308aa1..483ae8048b5 100644
--- a/bfd/coff-w65.c
+++ b/bfd/coff-w65.c
@@ -31,16 +31,18 @@
static reloc_howto_type howto_table[] =
{
HOWTO (R_W65_ABS8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "abs8", TRUE, 0x000000ff, 0x000000ff, FALSE),
- HOWTO (R_W65_ABS16, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
- HOWTO (R_W65_ABS24, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "abs24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
- HOWTO (R_W65_ABS8S8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, ">abs8", TRUE, 0x000000ff, 0x000000ff, FALSE),
- HOWTO (R_W65_ABS8S16, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "^abs8", TRUE, 0x000000ff, 0x000000ff, FALSE),
- HOWTO (R_W65_ABS16S8, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, ">abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
- HOWTO (R_W65_ABS16S16,1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "^abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
- HOWTO (R_W65_PCR8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "pcrel8", TRUE, 0x000000ff, 0x000000ff, TRUE),
- HOWTO (R_W65_PCR16, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "pcrel16", TRUE, 0x0000ffff, 0x0000ffff, TRUE),
- HOWTO (R_W65_DP, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "dp", TRUE, 0x000000ff, 0x000000ff, FALSE),
- };
+ HOWTO (R_W65_ABS16, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO (R_W65_ABS24, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "abs24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
+ HOWTO (R_W65_ABS8S8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, ">abs8", TRUE, 0x000000ff, 0x000000ff, FALSE),
+ HOWTO (R_W65_ABS8S16, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "^abs8", TRUE, 0x000000ff, 0x000000ff, FALSE),
+ HOWTO (R_W65_ABS16S8, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, ">abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO (R_W65_ABS16S16,1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "^abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO (R_W65_PCR8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "pcrel8", TRUE, 0x000000ff, 0x000000ff, TRUE),
+ HOWTO (R_W65_PCR16, 1, 0, 16, FALSE, 0, complain_overflow_bitfield, 0, "pcrel16", TRUE, 0x0000ffff, 0x0000ffff, TRUE),
+ HOWTO (R_W65_DP, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, 0, "dp", TRUE, 0x000000ff, 0x000000ff, FALSE),
+};
+
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
/* Turn a howto into a reloc number. */
@@ -61,7 +63,7 @@ static reloc_howto_type howto_table[] =
static int
select_reloc (reloc_howto_type *howto)
{
- return howto->type ;
+ return howto->type;
}
/* Code to turn a r_type into a howto ptr, uses the above howto table. */
@@ -70,7 +72,10 @@ static void
rtype2howto (arelent *internal,
struct internal_reloc *dst)
{
- internal->howto = howto_table + dst->r_type - 1;
+ if (dst->r_type > 0 && dst->r_type <= NUM_HOWTOS)
+ internal->howto = howto_table + dst->r_type - 1;
+ else
+ internal->howto = NULL;
}
#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
diff --git a/bfd/coff-we32k.c b/bfd/coff-we32k.c
index d5481b8ff2e..b754815e701 100644
--- a/bfd/coff-we32k.c
+++ b/bfd/coff-we32k.c
@@ -53,14 +53,19 @@ static reloc_howto_type howto_table[] =
HOWTO(R_PCRLONG, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "DISP32", TRUE, 0xffffffff,0xffffffff, FALSE),
};
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
+
/* Turn a howto into a reloc nunmber */
#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
#define BADMAG(x) WE32KBADMAG(x)
#define WE32K 1
-#define RTYPE2HOWTO(cache_ptr, dst) \
- (cache_ptr)->howto = howto_table + (dst)->r_type;
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ ((cache_ptr)->howto = \
+ ((dst)->r_type < NUM_HOWTOS \
+ ? howto_table + (dst)->r_type \
+ : NULL))
#ifndef bfd_pe_print_pdata
#define bfd_pe_print_pdata NULL
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index 2a21bb8be69..742adc29e03 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -143,6 +143,16 @@ coff_amd64_reloc (bfd *abfd,
reloc_howto_type *howto = reloc_entry->howto;
unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+ /* FIXME: We do not have an end address for data, so we cannot
+ accurately range check any addresses computed against it.
+ cf: PR binutils/17512: file: 1085-1761-0.004.
+ For now we do the best that we can. */
+ if (addr < (unsigned char *) data || addr > ((unsigned char *) data) + input_section->size)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return bfd_reloc_notsupported;
+ }
+
switch (howto->size)
{
case 0:
@@ -177,7 +187,8 @@ coff_amd64_reloc (bfd *abfd,
break;
default:
- abort ();
+ bfd_set_error (bfd_error_bad_value);
+ return bfd_reloc_notsupported;
}
}
diff --git a/bfd/coff-z80.c b/bfd/coff-z80.c
index 7b62cdf149e..fd68b124342 100644
--- a/bfd/coff-z80.c
+++ b/bfd/coff-z80.c
@@ -81,7 +81,7 @@ rtype2howto (arelent *internal, struct internal_reloc *dst)
switch (dst->r_type)
{
default:
- abort ();
+ internal->howto = NULL;
break;
case R_IMM8:
internal->howto = &r_imm8;
diff --git a/bfd/coff-z8k.c b/bfd/coff-z8k.c
index c85713ff8df..7f67ee8f5b9 100644
--- a/bfd/coff-z8k.c
+++ b/bfd/coff-z8k.c
@@ -85,7 +85,7 @@ rtype2howto (arelent *internal, struct internal_reloc *dst)
switch (dst->r_type)
{
default:
- abort ();
+ internal->howto = NULL;
break;
case R_IMM8:
internal->howto = &r_imm8;
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 9990b169ecc..1719b2d9008 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -5310,7 +5310,7 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
static reloc_howto_type *
coff_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
asection *sec ATTRIBUTE_UNUSED,
- struct internal_reloc *rel,
+ struct internal_reloc *rel ATTRIBUTE_UNUSED,
struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
struct internal_syment *sym ATTRIBUTE_UNUSED,
bfd_vma *addendp ATTRIBUTE_UNUSED)
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 4f3f86219cc..2b8884d3ad9 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -146,8 +146,9 @@ make_a_section_from_file (bfd *abfd,
/* Compress/decompress DWARF debug sections with names: .debug_* and
.zdebug_*, after the section flags is set. */
if ((flags & SEC_DEBUGGING)
+ && strlen (name) > 7
&& ((name[1] == 'd' && name[6] == '_')
- || (name[1] == 'z' && name[7] == '_')))
+ || (strlen (name) > 8 && name[1] == 'z' && name[7] == '_')))
{
enum { nothing, compress, decompress } action = nothing;
char *new_name = NULL;
@@ -365,6 +366,10 @@ coff_object_p (bfd *abfd)
bfd_release (abfd, opthdr);
return NULL;
}
+ /* PR 17512: file: 11056-1136-0.004. */
+ if (internal_f.f_opthdr < aoutsz)
+ memset (((char *) opthdr) + internal_f.f_opthdr, 0, aoutsz - internal_f.f_opthdr);
+
bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a);
bfd_release (abfd, opthdr);
}
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index 01f51e644e4..33e213491a3 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -615,6 +615,9 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
external_fdr_size = backend->debug_swap.external_fdr_size;
fdr_ptr = debug->fdr;
fraw_src = (char *) debug->external_fdr;
+ /* PR 17512: file: 3372-1243-0.004. */
+ if (fraw_src == NULL && internal_symhdr->ifdMax > 0)
+ return FALSE;
fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size;
for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
(*backend->debug_swap.swap_fdr_in) (abfd, (void *) fraw_src, fdr_ptr);
@@ -891,6 +894,11 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
EXTR internal_esym;
(*swap_ext_in) (abfd, (void *) eraw_src, &internal_esym);
+
+ /* PR 17512: file: 3372-1000-0.004. */
+ if (internal_esym.asym.iss >= ecoff_data (abfd)->debug_info.symbolic_header.issExtMax)
+ return FALSE;
+
internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext
+ internal_esym.asym.iss);
if (!ecoff_set_symbol_info (abfd, &internal_esym.asym,
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index c13fff33536..31ffa84966c 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -1349,8 +1349,12 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
if (reloc.r_extern)
{
- /* An external symbol number. */
- sym = syms + num;
+ /* PR 17512: file: 8396-1185-0.004. */
+ if (num >= bfd_get_symcount (abfd))
+ sym = bfd_und_section_ptr->symbol_ptr_ptr;
+ else
+ /* An external symbol number. */
+ sym = syms + num;
}
else if (num == 0x00ffffff || num == 0)
{
@@ -2336,17 +2340,20 @@ bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
&& (mdata->nsects == 0 || mdata->sections != NULL))
return TRUE;
+ /* We need to check that this can be done... */
+ if (nsect > 255)
+ {
+ (*_bfd_error_handler) (_("mach-o: there are too many sections (%u)"
+ " maximum is 255,\n"), nsect);
+ return FALSE;
+ }
+
mdata->nsects = nsect;
mdata->sections = bfd_alloc (abfd,
mdata->nsects * sizeof (bfd_mach_o_section *));
if (mdata->sections == NULL)
return FALSE;
- /* We need to check that this can be done... */
- if (nsect > 255)
- (*_bfd_error_handler) (_("mach-o: there are too many sections (%d)"
- " maximum is 255,\n"), nsect);
-
/* Create Mach-O sections.
Section type, attribute and align should have been set when the
section was created - either read in or specified. */
@@ -3646,6 +3653,9 @@ bfd_mach_o_read_symtab_strtab (bfd *abfd)
if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
|| bfd_bread (sym->strtab, sym->strsize, abfd) != sym->strsize)
{
+ /* PR 17512: file: 10888-1609-0.004. */
+ bfd_release (abfd, sym->strtab);
+ sym->strtab = NULL;
bfd_set_error (bfd_error_file_truncated);
return FALSE;
}
@@ -3675,6 +3685,7 @@ bfd_mach_o_read_symtab_symbols (bfd *abfd)
if (!bfd_mach_o_read_symtab_strtab (abfd))
{
+ bfd_release (abfd, sym->symbols);
sym->symbols = NULL;
return FALSE;
}
@@ -3683,6 +3694,7 @@ bfd_mach_o_read_symtab_symbols (bfd *abfd)
{
if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
{
+ bfd_release (abfd, sym->symbols);
sym->symbols = NULL;
return FALSE;
}
diff --git a/bfd/pe-mips.c b/bfd/pe-mips.c
index 57ec51fe19c..d7edc2b6837 100644
--- a/bfd/pe-mips.c
+++ b/bfd/pe-mips.c
@@ -349,8 +349,11 @@ static reloc_howto_type howto_table[] =
/* Customize coffcode.h. */
#define MIPS 1
-#define RTYPE2HOWTO(cache_ptr, dst) \
- (cache_ptr)->howto = howto_table + (dst)->r_type;
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ ((cache_ptr)->howto = \
+ ((dst)->r_type < NUM_HOWTOS \
+ ? howto_table + (dst)->r_type \
+ : NULL))
/* Compute the addend of a reloc. If the reloc is to a common symbol,
the object file contains the value of the common symbol. By the
diff --git a/bfd/reloc.c b/bfd/reloc.c
index dc471734f61..dedfb6a4f98 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -7655,6 +7655,15 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
abfd, input_section, * parent);
goto error_return;
+ case bfd_reloc_notsupported:
+ /* PR ld/17512
+ This error can result when processing a corrupt binary.
+ Do not abort. Issue an error message instead. */
+ link_info->callbacks->einfo
+ (_("%X%P: %B(%A): relocation \"%R\" is not supported\n"),
+ abfd, input_section, * parent);
+ goto error_return;
+
default:
abort ();
break;
diff --git a/bfd/versados.c b/bfd/versados.c
index 236899822c3..1dfe7483778 100644
--- a/bfd/versados.c
+++ b/bfd/versados.c
@@ -85,8 +85,8 @@ typedef struct versados_data_struct
tdata_type;
#define VDATA(abfd) (abfd->tdata.versados_data)
-#define EDATA(abfd, n) (abfd->tdata.versados_data->e[n])
-#define RDATA(abfd, n) (abfd->tdata.versados_data->rest[n])
+#define EDATA(abfd, n) (abfd->tdata.versados_data->e[(n) < 16 ? (n) : 0])
+#define RDATA(abfd, n) (abfd->tdata.versados_data->rest[(n) < 240 ? (n) : 0])
struct ext_otr
{
@@ -181,14 +181,22 @@ versados_new_symbol (bfd *abfd,
return n;
}
-static int
+static bfd_boolean
get_record (bfd *abfd, union ext_any *ptr)
{
if (bfd_bread (&ptr->size, (bfd_size_type) 1, abfd) != 1
|| (bfd_bread ((char *) ptr + 1, (bfd_size_type) ptr->size, abfd)
!= ptr->size))
- return 0;
- return 1;
+ return FALSE;
+
+ {
+ bfd_size_type amt = ptr->size + 1;
+
+ if (amt < sizeof (* ptr))
+ memset ((char *) ptr + amt, 0, sizeof (* ptr) - amt);
+ }
+
+ return TRUE;
}
static int
@@ -366,7 +374,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
struct esdid *esdid = &EDATA (abfd, otr->esdid - 1);
unsigned char *contents = esdid->contents;
- int need_contents = 0;
+ bfd_boolean need_contents = FALSE;
unsigned int dst_idx = esdid->pc;
for (shift = ((unsigned long) 1 << 31); shift && srcp < endp; shift >>= 1)
@@ -390,8 +398,8 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
int val = get_offset (offsetlen, srcp + esdids);
if (pass == 1)
- need_contents = 1;
- else
+ need_contents = TRUE;
+ else if (contents)
for (j = 0; j < sizeinwords * 2; j++)
{
contents[dst_idx + (sizeinwords * 2) - j - 1] = val;
@@ -429,19 +437,21 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
}
else
{
- need_contents = 1;
-
- if (esdid->section && dst_idx < esdid->section->size)
+ need_contents = TRUE;
+
+ if (esdid->section && contents && dst_idx < esdid->section->size)
if (pass == 2)
{
/* Absolute code, comes in 16 bit lumps. */
contents[dst_idx] = srcp[0];
contents[dst_idx + 1] = srcp[1];
}
+
dst_idx += 2;
srcp += 2;
}
}
+
EDATA (abfd, otr->esdid - 1).pc = dst_idx;
if (!contents && need_contents)
@@ -461,7 +471,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
static bfd_boolean
versados_scan (bfd *abfd)
{
- int loop = 1;
+ bfd_boolean loop = TRUE;
int i;
int j;
int nsecs = 0;
@@ -479,13 +489,13 @@ versados_scan (bfd *abfd)
union ext_any any;
if (!get_record (abfd, &any))
- return TRUE;
+ return FALSE;
switch (any.header.type)
{
case VHEADER:
break;
case VEND:
- loop = 0;
+ loop = FALSE;
break;
case VESTDEF:
process_esd (abfd, &any.esd, 1);
@@ -512,7 +522,6 @@ versados_scan (bfd *abfd)
{
amt = (bfd_size_type) esdid->relocs * sizeof (arelent);
esdid->section->relocation = bfd_alloc (abfd, amt);
-
esdid->pc = 0;
if (esdid->contents)
@@ -571,7 +580,7 @@ versados_scan (bfd *abfd)
VDATA (abfd)->ref_idx = 0;
- return 1;
+ return TRUE;
}
/* Check whether an existing file is a versados file. */
@@ -773,6 +782,7 @@ versados_canonicalize_reloc (bfd *abfd,
versados_pass_2 (abfd);
src = section->relocation;
+
if (!EDATA (abfd, section->target_index).donerel)
{
EDATA (abfd, section->target_index).donerel = 1;
@@ -790,6 +800,9 @@ versados_canonicalize_reloc (bfd *abfd,
src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr;
}
+ /* PR 17512: file:3757-2936-0.004. */
+ else if ((unsigned) (esdid - ES_BASE) >= bfd_get_symcount (abfd))
+ src[count].sym_ptr_ptr = bfd_und_section_ptr->symbol_ptr_ptr;
else
src[count].sym_ptr_ptr = symbols + esdid - ES_BASE;
}