X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fversados.c;h=cef4b68466286bc0c6220ae5e0bb0d6814a05724;hb=1a0670f37442b7ae904932b347353046126b990c;hp=2d49458566a1568bc1971ce05bfd47713026ffce;hpb=6d00b590316c0b08de21a264893b0fd627c54686;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/versados.c b/bfd/versados.c index 2d49458566..cef4b68466 100644 --- a/bfd/versados.c +++ b/bfd/versados.c @@ -1,5 +1,5 @@ /* BFD back-end for VERSAdos-E objects. - Copyright (C) 1995-2014 Free Software Foundation, Inc. + Copyright (C) 1995-2016 Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support . Versados is a Motorola trademark. @@ -57,6 +57,7 @@ struct esdid { asection *section; /* Ptr to bfd version. */ unsigned char *contents; /* Used to build image. */ + bfd_size_type content_size; /* The size of the contents buffer. */ int pc; int relocs; /* Reloc count, valid end of pass 1. */ int donerel; /* Have relocs been translated. */ @@ -85,8 +86,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 +182,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 @@ -287,6 +296,7 @@ process_esd (bfd *abfd, struct ext_esd *esd, int pass) break; case ESD_XDEF_IN_ABS: sec = bfd_abs_section_ptr; + /* Fall through. */ case ESD_XDEF_IN_SEC: { int snum = VDATA (abfd)->def_idx++; @@ -364,10 +374,18 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) | (otr->map[2] << 8) | (otr->map[3] << 0); - struct esdid *esdid = &EDATA (abfd, otr->esdid - 1); - unsigned char *contents = esdid->contents; - int need_contents = 0; - unsigned int dst_idx = esdid->pc; + struct esdid *esdid; + unsigned char *contents; + bfd_boolean need_contents = FALSE; + unsigned int dst_idx; + + /* PR 17512: file: ac7da425. */ + if (otr->esdid == 0) + return; + + esdid = &EDATA (abfd, otr->esdid - 1); + contents = esdid->contents; + dst_idx = esdid->pc; for (shift = ((unsigned long) 1 << 31); shift && srcp < endp; shift >>= 1) { @@ -390,8 +408,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 && dst_idx < esdid->content_size - sizeinwords * 2) for (j = 0; j < sizeinwords * 2; j++) { contents[dst_idx + (sizeinwords * 2) - j - 1] = val; @@ -413,10 +431,13 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) } else { - arelent *n = - EDATA (abfd, otr->esdid - 1).section->relocation + rn; - n->address = dst_idx; + arelent *n; + /* PR 17512: file: 54f733e0. */ + if (EDATA (abfd, otr->esdid - 1).section == NULL) + continue; + n = EDATA (abfd, otr->esdid - 1).section->relocation + rn; + n->address = dst_idx; n->sym_ptr_ptr = (asymbol **) (size_t) id; n->addend = 0; n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1); @@ -429,31 +450,42 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass) } else { - need_contents = 1; - if (dst_idx < esdid->section->size) + need_contents = TRUE; + + if (esdid->section && contents && dst_idx < esdid->content_size - 1) 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) { - bfd_size_type size = esdid->section->size; - esdid->contents = bfd_alloc (abfd, size); + if (esdid->section) + { + bfd_size_type size; + + size = esdid->section->size; + esdid->contents = bfd_alloc (abfd, size); + esdid->content_size = size; + } + else + esdid->contents = NULL; } } static bfd_boolean versados_scan (bfd *abfd) { - int loop = 1; + bfd_boolean loop = TRUE; int i; int j; int nsecs = 0; @@ -471,13 +503,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); @@ -504,7 +536,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) @@ -563,7 +594,7 @@ versados_scan (bfd *abfd) VDATA (abfd)->ref_idx = 0; - return 1; + return TRUE; } /* Check whether an existing file is a versados file. */ @@ -585,6 +616,13 @@ versados_object_p (bfd *abfd) return NULL; } + /* PR 17512: file: 726-2128-0.004. */ + if (len < 13) + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + if (bfd_bread (&ext.type, (bfd_size_type) len, abfd) != len) { if (bfd_get_error () != bfd_error_system_call) @@ -652,12 +690,20 @@ versados_get_section_contents (bfd *abfd, file_ptr offset, bfd_size_type count) { + struct esdid *esdid; + if (!versados_pass_2 (abfd)) return FALSE; - memcpy (location, - EDATA (abfd, section->target_index).contents + offset, - (size_t) count); + esdid = &EDATA (abfd, section->target_index); + + if (esdid->contents == NULL + || offset < 0 + || (bfd_size_type) offset > esdid->content_size + || offset + count > esdid->content_size) + return FALSE; + + memcpy (location, esdid->contents + offset, (size_t) count); return TRUE; } @@ -758,6 +804,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; @@ -773,8 +820,15 @@ versados_canonicalize_reloc (bfd *abfd, /* Section relative thing. */ struct esdid *e = &EDATA (abfd, esdid - 1); - src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr; + /* PR 17512: file:cd92277c. */ + if (e->section) + src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr; + else + src[count].sym_ptr_ptr = bfd_und_section_ptr->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; } @@ -794,7 +848,9 @@ versados_canonicalize_reloc (bfd *abfd, #define versados_bfd_is_local_label_name bfd_generic_is_local_label_name #define versados_get_lineno _bfd_nosymbols_get_lineno #define versados_find_nearest_line _bfd_nosymbols_find_nearest_line +#define versados_find_line _bfd_nosymbols_find_line #define versados_find_inliner_info _bfd_nosymbols_find_inliner_info +#define versados_get_symbol_version_string _bfd_nosymbols_get_symbol_version_string #define versados_make_empty_symbol _bfd_generic_make_empty_symbol #define versados_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol #define versados_read_minisymbols _bfd_generic_read_minisymbols @@ -812,13 +868,13 @@ versados_canonicalize_reloc (bfd *abfd, #define versados_section_already_linked _bfd_generic_section_already_linked #define versados_bfd_define_common_symbol bfd_generic_define_common_symbol #define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define versados_bfd_link_hash_table_free _bfd_generic_link_hash_table_free #define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols #define versados_bfd_link_just_syms _bfd_generic_link_just_syms #define versados_bfd_copy_link_hash_symbol_type \ _bfd_generic_copy_link_hash_symbol_type #define versados_bfd_final_link _bfd_generic_final_link #define versados_bfd_link_split_section _bfd_generic_link_split_section +#define versados_bfd_link_check_relocs _bfd_generic_link_check_relocs const bfd_target m68k_versados_vec = {