From d707219dc926126562ee29157c7afcb3c4a04735 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Tue, 20 Jan 1998 23:14:05 +0000 Subject: [PATCH] * reloc.c (BFD_RELOC_TXVU_11_PCREL): New reloc. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. * elf32-txvu.c (txvu_elf_howto_table): Add entry for it. (txvu_reloc_map): Likewise. --- bfd/ChangeLog | 10 ++ bfd/bfd-in2.h | 8 ++ bfd/elf32-txvu.c | 25 ++++- bfd/libbfd.h | 4 + bfd/reloc.c | 278 +++++++++++++++++++++++++++---------------------------- 5 files changed, 182 insertions(+), 143 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 16f04f2..cf23b73 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +start-sanitize-sky +Tue Jan 20 15:08:44 1998 Doug Evans + + * reloc.c (BFD_RELOC_TXVU_11_PCREL): New reloc. + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + * elf32-txvu.c (txvu_elf_howto_table): Add entry for it. + (txvu_reloc_map): Likewise. + +end-sanitize-sky Mon Jan 19 12:49:52 1998 Ian Lance Taylor * cpu-sh.c (arch_info_struct): Correct next field of sh3e. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 1a16e89..aa035b0 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2054,6 +2054,14 @@ instruction. */ /* This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the instruction. */ BFD_RELOC_MN10300_16_PCREL, +/* start-sanitize-sky */ + +/* SKY TXVU Relocations. +This is an 11-bit pc relative reloc. The recorded address is for the +lower instruction word. */ + BFD_RELOC_TXVU_11_PCREL, +/* end-sanitize-sky */ + BFD_RELOC_UNUSED }; typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; reloc_howto_type * diff --git a/bfd/elf32-txvu.c b/bfd/elf32-txvu.c index 96a067c..33cf6e4 100644 --- a/bfd/elf32-txvu.c +++ b/bfd/elf32-txvu.c @@ -1,5 +1,5 @@ /* TXVU-specific support for 32-bit ELF. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 1998 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -52,7 +52,26 @@ static reloc_howto_type txvu_elf_howto_table[] = 0, /* dst_mask */ false), /* pcrel_offset */ - /* insert reloc entries here */ + /* A PC Relative 11-bit relocation, shifted by 3. + This reloc is complicated because relocations are relative to the upper + instruction, and I don't think BFD handles 64 bit instructions easily. + We could set the address of the reloc as the address of the lower + instruction, but then we'd have to do what is done for R_M32R_10_PCREL + which is to mask off the lower 3 bits of the pc before performing the + reloc. */ + HOWTO (R_TXVU_11_PCREL, /* type */ + 3, /* rightshift */ + 3, /* size (0 = byte, 1 = short, 2 = long) */ + 11, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_TXVU_11_PCREL", /* name */ + false, /* partial_inplace */ + 0x1ff, /* src_mask */ + 0x1ff, /* dst_mask */ + true), /* pcrel_offset */ }; /* Map BFD reloc types to TXVU ELF reloc types. */ @@ -66,7 +85,7 @@ struct txvu_reloc_map static const struct txvu_reloc_map txvu_reloc_map[] = { { BFD_RELOC_NONE, R_TXVU_NONE }, - /* insert reloc entries here */ + { BFD_RELOC_TXVU_11_PCREL, R_TXVU_11_PCREL } }; static reloc_howto_type * diff --git a/bfd/libbfd.h b/bfd/libbfd.h index ccf2cca..c063c51 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -804,6 +804,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_MN10300_32_PCREL", "BFD_RELOC_MN10300_16_PCREL", +/* start-sanitize-sky */ + "BFD_RELOC_TXVU_11_PCREL", +/* end-sanitize-sky */ + "@@overflow: BFD_RELOC_UNUSED@@", }; #endif diff --git a/bfd/reloc.c b/bfd/reloc.c index 6a9e8ae..5675fbe 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -451,6 +451,110 @@ DESCRIPTION */ +/* +FUNCTION + bfd_check_overflow + +SYNOPSIS + bfd_reloc_status_type + bfd_check_overflow + (enum complain_overflow how, + unsigned int bitsize, + unsigned int rightshift, + bfd_vma relocation); + +DESCRIPTION + Perform overflow checking on @var{relocation} which has @var{bitsize} + significant bits and will be shifted right by @var{rightshift} bits. + The result is either of @code{bfd_reloc_ok} or + @code{bfd_reloc_overflow}. + +*/ + +bfd_reloc_status_type +bfd_check_overflow (how, bitsize, rightshift, relocation) + enum complain_overflow how; + unsigned int bitsize, rightshift; + bfd_vma relocation; +{ + bfd_vma check; + bfd_reloc_status_type flag = bfd_reloc_ok; + + /* Get the value that will be used for the relocation, but + starting at bit position zero. */ + check = relocation >> rightshift; + + switch (how) + { + case complain_overflow_dont: + break; + + case complain_overflow_signed: + { + /* Assumes two's complement. */ + bfd_signed_vma reloc_signed_max = (1 << (bitsize - 1)) - 1; + bfd_signed_vma reloc_signed_min = ~reloc_signed_max; + + /* The above right shift is incorrect for a signed value. + Fix it up by forcing on the upper bits. */ + if (rightshift > 0 + && (bfd_signed_vma) relocation < 0) + check |= ((bfd_vma) - 1 + & ~((bfd_vma) - 1 + >> rightshift)); + if ((bfd_signed_vma) check > reloc_signed_max + || (bfd_signed_vma) check < reloc_signed_min) + flag = bfd_reloc_overflow; + } + break; + + case complain_overflow_unsigned: + { + /* Assumes two's complement. This expression avoids + overflow if `bitsize' is the number of bits in + bfd_vma. */ + bfd_vma reloc_unsigned_max = (((1 << (bitsize - 1)) - 1) << 1) | 1; + + if ((bfd_vma) check > reloc_unsigned_max) + flag = bfd_reloc_overflow; + } + break; + + case complain_overflow_bitfield: + { + /* Assumes two's complement. This expression avoids + overflow if `bitsize' is the number of bits in + bfd_vma. */ + bfd_vma reloc_bits = (((1 << (bitsize - 1)) - 1) << 1) | 1; + + if (((bfd_vma) check & ~reloc_bits) != 0 + && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) + { + /* The above right shift is incorrect for a signed + value. See if turning on the upper bits fixes the + overflow. */ + if (rightshift > 0 + && (bfd_signed_vma) relocation < 0) + { + check |= ((bfd_vma) - 1 + & ~((bfd_vma) - 1 + >> rightshift)); + if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) + flag = bfd_reloc_overflow; + } + else + flag = bfd_reloc_overflow; + } + } + break; + + default: + abort (); + } + + return flag; +} + /* FUNCTION @@ -721,75 +825,8 @@ space consuming. For each target: adding in the value contained in the object file. */ if (howto->complain_on_overflow != complain_overflow_dont && flag == bfd_reloc_ok) - { - bfd_vma check; - - /* Get the value that will be used for the relocation, but - starting at bit position zero. */ - check = relocation >> howto->rightshift; - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - /* The above right shift is incorrect for a signed value. - Fix it up by forcing on the upper bits. */ - if (howto->rightshift > 0 - && (bfd_signed_vma) relocation < 0) - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> howto->rightshift)); - if ((bfd_signed_vma) check > reloc_signed_max - || (bfd_signed_vma) check < reloc_signed_min) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((bfd_vma) check > reloc_unsigned_max) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (((bfd_vma) check & ~reloc_bits) != 0 - && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - { - /* The above right shift is incorrect for a signed - value. See if turning on the upper bits fixes the - overflow. */ - if (howto->rightshift > 0 - && (bfd_signed_vma) relocation < 0) - { - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> howto->rightshift)); - if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - flag = bfd_reloc_overflow; - } - else - flag = bfd_reloc_overflow; - } - } - break; - default: - abort (); - } - } + flag = bfd_check_overflow (howto->complain_on_overflow, howto->bitsize, + howto->rightshift, relocation); /* Either we are relocating all the way, or we don't want to apply @@ -1172,79 +1209,11 @@ space consuming. For each target: need to compute the value in a size larger than bitsize, but we can't reasonably do that for a reloc the same size as a host machine word. - FIXME: We should also do overflow checking on the result after adding in the value contained in the object file. */ if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma check; - - /* Get the value that will be used for the relocation, but - starting at bit position zero. */ - check = relocation >> howto->rightshift; - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - /* The above right shift is incorrect for a signed value. - Fix it up by forcing on the upper bits. */ - if (howto->rightshift > 0 - && (bfd_signed_vma) relocation < 0) - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> howto->rightshift)); - if ((bfd_signed_vma) check > reloc_signed_max - || (bfd_signed_vma) check < reloc_signed_min) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((bfd_vma) check > reloc_unsigned_max) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (((bfd_vma) check & ~reloc_bits) != 0 - && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - { - /* The above right shift is incorrect for a signed - value. See if turning on the upper bits fixes the - overflow. */ - if (howto->rightshift > 0 - && (bfd_signed_vma) relocation < 0) - { - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> howto->rightshift)); - if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - flag = bfd_reloc_overflow; - } - else - flag = bfd_reloc_overflow; - } - } - break; - default: - abort (); - } - } + flag = bfd_check_overflow (howto->complain_on_overflow, howto->bitsize, + howto->rightshift, relocation); /* Either we are relocating all the way, or we don't want to apply @@ -1875,8 +1844,25 @@ ENUMX BFD_RELOC_SPARC_6 ENUMX BFD_RELOC_SPARC_5 +ENUMEQX + BFD_RELOC_SPARC_DISP64 + BFD_RELOC_64_PCREL +ENUMX + BFD_RELOC_SPARC_PLT64 +ENUMX + BFD_RELOC_SPARC_HIX22 +ENUMX + BFD_RELOC_SPARC_LOX10 +ENUMX + BFD_RELOC_SPARC_H44 +ENUMX + BFD_RELOC_SPARC_M44 +ENUMX + BFD_RELOC_SPARC_L44 +ENUMX + BFD_RELOC_SPARC_REGISTER ENUMDOC - Some relocations we're using for SPARC V9 -- subject to change. + SPARC64 relocations ENUM BFD_RELOC_ALPHA_GPDISP_HI16 @@ -2458,6 +2444,18 @@ ENUM ENUMDOC This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the instruction. + +COMMENT +{* start-sanitize-sky *} +ENUM + BFD_RELOC_TXVU_11_PCREL +ENUMDOC + SKY TXVU Relocations. + This is an 11-bit pc relative reloc. The recorded address is for the + lower instruction word. +COMMENT +{* end-sanitize-sky *} + ENDSENUM BFD_RELOC_UNUSED CODE_FRAGMENT -- 2.7.4