diff options
Diffstat (limited to 'bfd/coff-alpha.c')
-rw-r--r-- | bfd/coff-alpha.c | 213 |
1 files changed, 106 insertions, 107 deletions
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c index e2f1a4d..3616a3e 100644 --- a/bfd/coff-alpha.c +++ b/bfd/coff-alpha.c @@ -97,7 +97,7 @@ static bfd_reloc_status_type reloc_nil (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc ATTRIBUTE_UNUSED, asymbol *sym ATTRIBUTE_UNUSED, - void * data ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, bfd *output_bfd ATTRIBUTE_UNUSED, char **error_message ATTRIBUTE_UNUSED) @@ -419,7 +419,7 @@ alpha_ecoff_object_p (bfd *abfd) On output we will set the lnnoptr field and force the alignment. */ sec = bfd_get_section_by_name (abfd, _PDATA); - if (sec != (asection *) NULL) + if (sec != NULL) { bfd_size_type size; @@ -438,7 +438,7 @@ alpha_ecoff_object_p (bfd *abfd) static bool alpha_ecoff_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED, - void * filehdr) + void *filehdr) { struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; @@ -458,15 +458,15 @@ alpha_ecoff_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED, specific information. */ static void * -alpha_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr) +alpha_ecoff_mkobject_hook (bfd *abfd, void *filehdr, void *aouthdr) { - void * ecoff; + void *ecoff; ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr); if (ecoff != NULL) { - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; + struct internal_filehdr *internal_f = filehdr; /* Set additional BFD flags according to the object type from the machine specific file header flags. */ @@ -491,10 +491,10 @@ alpha_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr) static void alpha_ecoff_swap_reloc_in (bfd *abfd, - void * ext_ptr, + void *ext_ptr, struct internal_reloc *intern) { - const RELOC *ext = (RELOC *) ext_ptr; + const RELOC *ext = ext_ptr; intern->r_vaddr = H_GET_64 (abfd, ext->r_vaddr); intern->r_symndx = H_GET_32 (abfd, ext->r_symndx); @@ -517,8 +517,7 @@ alpha_ecoff_swap_reloc_in (bfd *abfd, value is not actually a symbol index, but is instead a special code. We put the code in the r_size field, and clobber the symndx. */ - if (intern->r_size != 0) - abort (); + BFD_ASSERT (intern->r_size == 0); intern->r_size = intern->r_symndx; intern->r_symndx = RELOC_SECTION_NONE; } @@ -526,12 +525,16 @@ alpha_ecoff_swap_reloc_in (bfd *abfd, { /* The IGNORE reloc generally follows a GPDISP reloc, and is against the .lita section. The section is irrelevant. */ - if (! intern->r_extern && - intern->r_symndx == RELOC_SECTION_ABS) - abort (); + BFD_ASSERT (intern->r_extern || intern->r_symndx != RELOC_SECTION_ABS); if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA) intern->r_symndx = RELOC_SECTION_ABS; } + else if (intern->r_type == ALPHA_R_OP_STORE) + { + /* Size of 64 bits is encoded as 0 in this 6-bit field. */ + if (intern->r_size == 0) + intern->r_size = 64; + } } /* Swap a reloc out. */ @@ -539,9 +542,9 @@ alpha_ecoff_swap_reloc_in (bfd *abfd, static void alpha_ecoff_swap_reloc_out (bfd *abfd, const struct internal_reloc *intern, - void * dst) + void *dst) { - RELOC *ext = (RELOC *) dst; + RELOC *ext = dst; long symndx; unsigned char size; @@ -602,7 +605,7 @@ alpha_adjust_reloc_in (bfd *abfd, abfd, intern->r_type); bfd_set_error (bfd_error_bad_value); rptr->addend = 0; - rptr->howto = NULL; + rptr->howto = NULL; return; } @@ -713,6 +716,50 @@ alpha_adjust_reloc_out (bfd *abfd ATTRIBUTE_UNUSED, } } +/* Write VAL to a little-endian bitfield specified by BITOFFSET and + BITSIZE at CONTENTS + SECOFFSET. Verify that these parameter are + valid for SEC in ABFD. */ + +static bool +write_bit_field (bfd *abfd, asection *sec, + bfd_byte *contents, bfd_size_type secoffset, + unsigned int bitoffset, unsigned int bitsize, uint64_t val) +{ + if (bitsize == 0) + return true; + + bfd_size_type secsize = bfd_get_section_limit_octets (abfd, sec); + unsigned int startbyte = bitoffset >> 3; + unsigned int endbyte = (bitoffset + bitsize - 1) >> 3; + + if (secoffset > secsize || secsize - secoffset <= endbyte) + return false; + + unsigned int startbit = bitoffset & 7; + unsigned int endbit = (bitoffset + bitsize - 1) & 7; + unsigned int mask = -1u << startbit; + unsigned char *p = contents + secoffset; + if (startbyte != endbyte) + { + p[startbyte] = (p[startbyte] & ~mask) | ((val << startbit) & mask); + val = val >> (8 - startbit); + + for (unsigned int off = startbyte + 1; off < endbyte; ++off) + { + p[off] = val; + val >>= 8; + } + mask = ~(-1u << (1 + endbit)); + } + else + { + val = val << startbit; + mask = mask & ~(-1u << (1 + endbit)); + } + p[endbyte] = (p[endbyte] & ~mask) | (val & mask); + return true; +} + /* The size of the stack for the relocation evaluator. */ #define RELOC_STACKSIZE (10) @@ -735,7 +782,7 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd, long reloc_size; arelent **reloc_vector; long reloc_count; - bfd *output_bfd = relocatable ? abfd : (bfd *) NULL; + bfd *output_bfd = relocatable ? abfd : NULL; bfd_vma gp; bool gp_undefined; bfd_vma stack[RELOC_STACKSIZE]; @@ -755,7 +802,7 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd, if (reloc_size == 0) return data; - reloc_vector = (arelent **) bfd_malloc (reloc_size); + reloc_vector = bfd_malloc (reloc_size); if (reloc_vector == NULL) goto error_return; @@ -777,7 +824,7 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd, bfd_vma lo; /* Make up a value. */ - lo = (bfd_vma) -1; + lo = -1; for (sec = abfd->sections; sec != NULL; sec = sec->next) { if (sec->vma < lo @@ -797,7 +844,7 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd, h = bfd_link_hash_lookup (link_info->hash, "_gp", false, false, true); - if (h == (struct bfd_link_hash_entry *) NULL + if (h == NULL || h->type != bfd_link_hash_defined) gp_undefined = true; else @@ -1005,31 +1052,10 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd, into the addend field by alpha_adjust_reloc_in. */ unsigned int offset = (rel->addend >> 8) & 0xff; unsigned int size = rel->addend & 0xff; - unsigned int startbyte = offset >> 3; - unsigned int endbyte = (offset + size + 7) >> 3; - unsigned int bytes = endbyte + 1 - startbyte; - - if (bytes <= 8 - && rel->address + startbyte + bytes >= rel->address - && (rel->address + startbyte + bytes - <= bfd_get_section_limit_octets (input_bfd, input_section))) - { - uint64_t val = 0; - for (int off = bytes - 1; off >= 0; --off) - val = (val << 8) | data[rel->address + startbyte + off]; - - offset -= startbyte << 3; - size -= startbyte << 3; - uint64_t mask = (((uint64_t) 1 << size) - 1) << offset; - val = (val & ~mask) | ((stack[--tos] << offset) & mask); - - for (unsigned int off = 0; off < bytes; ++off) - { - data[rel->address + startbyte + off] = val & 0xff; - val >>= 8; - } - } - else + + if (!write_bit_field (input_bfd, input_section, + data, rel->address, + offset, size, stack[--tos])) r = bfd_reloc_outofrange; } break; @@ -1230,7 +1256,7 @@ alpha_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, alpha_type = ALPHA_R_SREL64; break; default: - return (reloc_howto_type *) NULL; + return NULL; } return &alpha_howto_table[alpha_type]; @@ -1284,7 +1310,7 @@ alpha_convert_external_reloc (bfd *output_bfd ATTRIBUTE_UNUSED, hsec = h->root.u.def.section; name = bfd_section_name (hsec->output_section); - r_symndx = (unsigned long) -1; + r_symndx = -1ul; switch (name[1]) { case 'A': @@ -1341,7 +1367,7 @@ alpha_convert_external_reloc (bfd *output_bfd ATTRIBUTE_UNUSED, break; } - if (r_symndx == (unsigned long) -1) + if (r_symndx == -1ul) abort (); /* Add the section VMA and the symbol value. */ @@ -1354,7 +1380,7 @@ alpha_convert_external_reloc (bfd *output_bfd ATTRIBUTE_UNUSED, /* Change the symndx value to the right one for the output BFD. */ r_symndx = h->indx; - if (r_symndx == (unsigned long) -1) + if (r_symndx == -1ul) { /* Caller must give an error. */ r_symndx = 0; @@ -1378,7 +1404,7 @@ alpha_relocate_section (bfd *output_bfd, bfd *input_bfd, asection *input_section, bfd_byte *contents, - void * external_relocs) + void *external_relocs) { asection **symndx_to_section, *lita_sec; struct ecoff_link_hash_entry **sym_hashes; @@ -1395,10 +1421,10 @@ alpha_relocate_section (bfd *output_bfd, the appropriate section. This is faster than looking up the section by name each time. */ symndx_to_section = ecoff_data (input_bfd)->symndx_to_section; - if (symndx_to_section == (asection **) NULL) + if (symndx_to_section == NULL) { amt = NUM_RELOC_SECTIONS * sizeof (asection *); - symndx_to_section = (asection **) bfd_alloc (input_bfd, amt); + symndx_to_section = bfd_alloc (input_bfd, amt); if (!symndx_to_section) return false; @@ -1455,9 +1481,7 @@ alpha_relocate_section (bfd *output_bfd, lita_sec_data = ecoff_section_data (input_bfd, lita_sec); if (lita_sec_data == NULL) { - amt = sizeof (struct ecoff_section_tdata); - lita_sec_data = ((struct ecoff_section_tdata *) - bfd_zalloc (input_bfd, amt)); + lita_sec_data = bfd_zalloc (input_bfd, sizeof (*lita_sec_data)); lita_sec->used_by_bfd = lita_sec_data; } @@ -1476,7 +1500,7 @@ alpha_relocate_section (bfd *output_bfd, lita_size = lita_sec->size; if (gp == 0 - || lita_vma < gp - 0x8000 + || lita_vma < gp - 0x8000 || lita_vma + lita_size >= gp + 0x8000) { /* Either gp hasn't been set at all or the current gp @@ -1487,8 +1511,7 @@ alpha_relocate_section (bfd *output_bfd, { (*info->callbacks->warning) (info, _("using multiple gp values"), - (char *) NULL, output_bfd, - (asection *) NULL, (bfd_vma) 0); + NULL, output_bfd, NULL, 0); ecoff_data (output_bfd)->issued_multiple_gp_warning = true; } if (lita_vma < gp - 0x8000) @@ -1509,7 +1532,7 @@ alpha_relocate_section (bfd *output_bfd, BFD_ASSERT (bfd_header_little_endian (output_bfd)); BFD_ASSERT (bfd_header_little_endian (input_bfd)); - ext_rel = (struct external_reloc *) external_relocs; + ext_rel = external_relocs; ext_rel_end = ext_rel + input_section->reloc_count; for (; ext_rel < ext_rel_end; ext_rel++) { @@ -1706,7 +1729,7 @@ alpha_relocate_section (bfd *output_bfd, relocated. */ (*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, - input_section, (bfd_vma) 0, true); + input_section, 0, true); addend = 0; } } @@ -1721,7 +1744,7 @@ alpha_relocate_section (bfd *output_bfd, above. */ (*info->callbacks->unattached_reloc) (info, h->root.root.string, - input_bfd, input_section, (bfd_vma) 0); + input_bfd, input_section, 0); } addend = alpha_convert_external_reloc (output_bfd, info, @@ -1779,33 +1802,12 @@ alpha_relocate_section (bfd *output_bfd, adjust the address of the reloc. */ if (! bfd_link_relocatable (info)) { - unsigned int startbyte = r_offset >> 3; - unsigned int endbyte = (r_offset + r_size + 7) >> 3; - unsigned int bytes = endbyte + 1 - startbyte; - - if (bytes <= 8 - && r_vaddr >= input_section->vma - && r_vaddr - input_section->vma < input_section->size - && (input_section->size - (r_vaddr - input_section->vma) - >= startbyte + bytes)) - { - bfd_byte *p = contents + (r_vaddr - input_section->vma); - uint64_t val = 0; - for (int off = bytes - 1; off >= 0; --off) - val = (val << 8) | p[startbyte + off]; - - r_offset -= startbyte << 3; - r_size -= startbyte << 3; - uint64_t mask = (((uint64_t) 1 << r_size) - 1) << r_offset; - val = (val & ~mask) | ((stack[--tos] << r_offset) & mask); - - for (unsigned int off = 0; off < bytes; ++off) - { - p[startbyte + off] = val & 0xff; - val >>= 8; - } - } - else + if (tos == 0) + r = bfd_reloc_notsupported; + else if (!write_bit_field (input_bfd, input_section, + contents, + r_vaddr - input_section->vma, + r_offset, r_size, stack[--tos])) r = bfd_reloc_outofrange; } break; @@ -1977,8 +1979,7 @@ alpha_relocate_section (bfd *output_bfd, name = bfd_section_name (symndx_to_section[r_symndx]); (*info->callbacks->reloc_overflow) (info, NULL, name, alpha_howto_table[r_type].name, - (bfd_vma) 0, input_bfd, input_section, - r_vaddr - input_section->vma); + 0, input_bfd, input_section, r_vaddr - input_section->vma); } break; case bfd_reloc_outofrange: @@ -2061,7 +2062,7 @@ alpha_ecoff_read_ar_hdr (bfd *abfd) struct areltdata *ret; struct ar_hdr *h; - ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG); + ret = _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG); if (ret == NULL) return NULL; @@ -2098,7 +2099,7 @@ alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos, struct ar_hdr *hdr; bfd_byte ab[8]; bfd_size_type size; - bfd_byte *buf, *p; + bfd_byte *buf; struct bfd_in_memory *bim; ufile_ptr filesize; @@ -2113,7 +2114,7 @@ alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos, return nbfd; } - tdata = (struct areltdata *) nbfd->arelt_data; + tdata = nbfd->arelt_data; hdr = (struct ar_hdr *) tdata->arch_header; if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0) return nbfd; @@ -2144,12 +2145,12 @@ alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos, if (size != 0) { + bfd_byte *p; bfd_size_type left; bfd_byte dict[4096]; unsigned int h; - bfd_byte b; - buf = (bfd_byte *) bfd_malloc (size); + buf = bfd_malloc (size); if (buf == NULL) goto error_return; p = buf; @@ -2168,11 +2169,13 @@ alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos, next eight bytes in the output stream. */ memset (dict, 0, sizeof dict); h = 0; - while (bfd_read (&b, 1, nbfd) == 1) + do { - unsigned int i; + bfd_byte b; + if (bfd_read (&b, 1, nbfd) != 1) + goto error_return; - for (i = 0; i < 8; i++, b >>= 1) + for (unsigned int i = 0; i < 8; i++, b >>= 1) { bfd_byte n; @@ -2195,22 +2198,19 @@ alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos, h ^= n; h &= sizeof dict - 1; } - - if (left == 0) - break; } + while (left != 0); } /* Now the uncompressed file contents are in buf. */ - bim = ((struct bfd_in_memory *) - bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory))); + bim = bfd_malloc (sizeof (*bim)); if (bim == NULL) goto error_return; bim->size = size; bim->buffer = buf; nbfd->mtime_set = true; - nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10); + nbfd->mtime = strtol (hdr->ar_date, NULL, 10); nbfd->flags |= BFD_IN_MEMORY; nbfd->iostream = bim; @@ -2247,7 +2247,7 @@ alpha_ecoff_openr_next_archived_file (bfd *archive, bfd *last_file) which is the uncompressed size. We need the compressed size. */ t = (struct areltdata *) last_file->arelt_data; h = (struct ar_hdr *) t->arch_header; - size = strtol (h->ar_size, (char **) NULL, 10); + size = strtol (h->ar_size, NULL, 10); /* Pad to an even boundary... Note that last_file->origin can be odd in the case of @@ -2273,8 +2273,7 @@ alpha_ecoff_get_elt_at_index (bfd *abfd, symindex sym_index) carsym *entry; entry = bfd_ardata (abfd)->symdefs + sym_index; - return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset, - NULL); + return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset, NULL); } static void |