X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gold%2Freloc.h;h=db5cdf676921d109a0bd5e25a2a04edefef35773;hb=f5a0f5b503c43ed3e146bc0d3eca37784892b47e;hp=fce73136375465e10eb8fec1ef97a31365f40a0a;hpb=2bf48941a7987cd1abedfb4ddbb45b75201381ad;p=binutils-gdb.git diff --git a/gold/reloc.h b/gold/reloc.h index fce73136375..db5cdf67692 100644 --- a/gold/reloc.h +++ b/gold/reloc.h @@ -1,6 +1,6 @@ // reloc.h -- relocate input files for gold -*- C++ -*- -// Copyright (C) 2006-2016 Free Software Foundation, Inc. +// Copyright (C) 2006-2022 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -336,9 +336,14 @@ class Relocate_functions enum Overflow_check { + // No overflow checking. CHECK_NONE, + // Check for overflow of a signed value. CHECK_SIGNED, + // Check for overflow of an unsigned value. CHECK_UNSIGNED, + // Check for overflow of a signed or unsigned value. + // (i.e., no error if either signed or unsigned fits.) CHECK_SIGNED_OR_UNSIGNED }; @@ -969,6 +974,26 @@ class Relocate_functions CHECK_NONE); } }; +// Convenience class for min and max values of a given BITS length. + +template +class Limits +{ + public: + static const uint64_t MAX_UNSIGNED = (1ULL << bits) - 1; + static const int64_t MAX_SIGNED = MAX_UNSIGNED >> 1; + static const int64_t MIN_SIGNED = -MAX_SIGNED - 1; +}; + +template<> +class Limits<64> +{ + public: + static const uint64_t MAX_UNSIGNED = ~0ULL; + static const int64_t MAX_SIGNED = MAX_UNSIGNED >> 1; + static const int64_t MIN_SIGNED = -MAX_SIGNED - 1; +}; + // Integer manipulation functions used by various targets when // performing relocations. @@ -1001,8 +1026,8 @@ class Bits gold_assert(bits > 0 && bits <= 32); if (bits == 32) return false; - int32_t max = (1 << (bits - 1)) - 1; - int32_t min = -(1 << (bits - 1)); + const int32_t max = static_cast(Limits::MAX_SIGNED); + const int32_t min = static_cast(Limits::MIN_SIGNED); int32_t as_signed = static_cast(val); return as_signed > max || as_signed < min; } @@ -1015,7 +1040,7 @@ class Bits gold_assert(bits > 0 && bits <= 32); if (bits == 32) return false; - uint32_t max = static_cast((1U << bits) - 1); + const uint32_t max = static_cast(Limits::MAX_UNSIGNED); return val > max; } @@ -1029,8 +1054,8 @@ class Bits gold_assert(bits > 0 && bits <= 32); if (bits == 32) return false; - int32_t max = static_cast((1U << bits) - 1); - int32_t min = -(1 << (bits - 1)); + const int32_t max = static_cast(Limits::MAX_UNSIGNED); + const int32_t min = static_cast(Limits::MIN_SIGNED); int32_t as_signed = static_cast(val); return as_signed > max || as_signed < min; } @@ -1067,8 +1092,8 @@ class Bits gold_assert(bits > 0 && bits <= 64); if (bits == 64) return false; - int64_t max = (static_cast(1) << (bits - 1)) - 1; - int64_t min = -(static_cast(1) << (bits - 1)); + const int64_t max = Limits::MAX_SIGNED; + const int64_t min = Limits::MIN_SIGNED; int64_t as_signed = static_cast(val); return as_signed > max || as_signed < min; } @@ -1081,7 +1106,7 @@ class Bits gold_assert(bits > 0 && bits <= 64); if (bits == 64) return false; - uint64_t max = static_cast((static_cast(1) << bits) - 1); + const uint64_t max = Limits::MAX_UNSIGNED; return val > max; } @@ -1095,8 +1120,8 @@ class Bits gold_assert(bits > 0 && bits <= 64); if (bits == 64) return false; - int64_t max = static_cast((static_cast(1) << bits) - 1); - int64_t min = -(static_cast(1) << (bits - 1)); + const int64_t max = static_cast(Limits::MAX_UNSIGNED); + const int64_t min = Limits::MIN_SIGNED; int64_t as_signed = static_cast(val); return as_signed > max || as_signed < min; } @@ -1146,7 +1171,7 @@ class Track_relocs next_addend() const; // Advance to OFFSET within the data section, and return the number - // of relocs which would be skipped. + // of relocs which would be skipped, excluding r_info==0 relocs. int advance(off_t offset);