bloaty/src/util.h
Go to the documentation of this file.
1 // Copyright 2016 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef BLOATY_UTIL_H_
16 #define BLOATY_UTIL_H_
17 
18 #include <stdexcept>
19 
20 #include "absl/numeric/int128.h"
21 #include "absl/strings/string_view.h"
22 #include "absl/strings/substitute.h"
23 
24 namespace bloaty {
25 
26 class Error : public std::runtime_error {
27  public:
28  Error(const char* msg, const char* file, int line)
29  : std::runtime_error(msg), file_(file), line_(line) {}
30 
31  // TODO(haberman): add these to Bloaty's error message when verbose is
32  // enabled.
33  const char* file() const { return file_; }
34  int line() const { return line_; }
35 
36  private:
37  const char* file_;
38  int line_;
39 };
40 
41 // Throwing emits a lot of code, so we do it out-of-line.
43 void Throw(const char *str, int line);
44 
45 #define THROW(msg) Throw(msg, __LINE__)
46 #define THROWF(...) Throw(absl::Substitute(__VA_ARGS__).c_str(), __LINE__)
47 #define WARN(...) \
48  if (verbose_level > 0) { \
49  printf("WARNING: %s\n", absl::Substitute(__VA_ARGS__).c_str()); \
50  }
51 
52 #if !defined(_MSC_VER)
53 #define BLOATY_UNREACHABLE() do { \
54  assert(false); \
55  __builtin_unreachable(); \
56 } while (0)
57 #else
58 #define BLOATY_UNREACHABLE() do { \
59  assert(false); \
60  __assume(0); \
61 } while (0)
62 #endif
63 
64 #ifdef NDEBUG
65 // Prevent "unused variable" warnings.
66 #define BLOATY_ASSERT(expr) do {} while (false && (expr))
67 #else
68 #define BLOATY_ASSERT(expr) assert(expr)
69 #endif
70 
72  absl::uint128 a_128(a), b_128(b);
73  absl::uint128 c_128 = a_128 + b_128;
74  if (c_128 > UINT64_MAX) {
75  THROW("integer overflow in addition");
76  }
77  return static_cast<uint64_t>(c_128);
78 }
79 
81  absl::uint128 a_128(a), b_128(b);
82  absl::uint128 c = a_128 * b_128;
83  if (c > UINT64_MAX) {
84  THROW("integer overflow in multiply");
85  }
86  return static_cast<uint64_t>(c);
87 }
88 
90  size_t n) {
91  uint64_t end = CheckedAdd(off, n);
92  if (end > data.size()) {
93  THROW("region out-of-bounds");
94  }
95  return data.substr(off, n);
96 }
97 
99  if (off > data.size()) {
100  THROW("region out-of-bounds");
101  }
102  return data.substr(off);
103 }
104 
105 inline size_t AlignUp(size_t offset, size_t granularity) {
106  // Granularity must be a power of two.
107  BLOATY_ASSERT((granularity & (granularity - 1)) == 0);
108  return (offset + granularity - 1) & ~(granularity - 1);
109 }
110 
111 // Endianness utilities ////////////////////////////////////////////////////////
112 
113 enum class Endian { kBig, kLittle };
114 
116  int x = 1;
117  return *(char *)&x == 1 ? Endian::kLittle : Endian::kBig;
118 }
119 
120 // Generic algorithm for byte-swapping an integer of arbitrary size.
121 //
122 // With modern GCC/Clang this optimizes to a "bswap" instruction.
123 template <size_t N, class T> constexpr T _BS(T val) {
124  if constexpr (N == 1) {
125  return val & 0xff;
126  } else {
127  size_t bits = 8 * (N / 2);
128  return (_BS<N / 2>(val) << bits) | _BS<N / 2>(val >> bits);
129  }
130 };
131 
132 // Byte swaps the given integer, and returns the byte-swapped value.
133 template <class T> constexpr T ByteSwap(T val) {
134  return _BS<sizeof(T)>(val);
135 }
136 
137 template <class T, size_t N = sizeof(T)> T ReadFixed(absl::string_view *data) {
138  static_assert(N <= sizeof(T), "N too big for this data type");
139  T val = 0;
140  if (data->size() < N) {
141  THROW("premature EOF reading fixed-length data");
142  }
143  memcpy(&val, data->data(), N);
144  data->remove_prefix(N);
145  return val;
146 }
147 
148 template <class T> T ReadEndian(absl::string_view *data, Endian endian) {
149  T val = ReadFixed<T>(data);
150  return endian == GetMachineEndian() ? val : ByteSwap(val);
151 }
152 
153 template <class T> T ReadLittleEndian(absl::string_view *data) {
154  return ReadEndian<T>(data, Endian::kLittle);
155 }
156 
157 template <class T> T ReadBigEndian(absl::string_view *data) {
158  return ReadEndian<T>(data, Endian::kBig);
159 }
160 
161 // General data reading ///////////////////////////////////////////////////////
162 
164 
166  if (data->size() < bytes) {
167  THROW("premature EOF reading variable-length DWARF data");
168  }
169  absl::string_view ret = data->substr(0, bytes);
170  data->remove_prefix(bytes);
171  return ret;
172 }
173 
174 inline void SkipBytes(size_t bytes, absl::string_view* data) {
175  ReadBytes(bytes, data); // Discard result.
176 }
177 
178 } // namespace bloaty
179 
180 #endif // BLOATY_UTIL_H_
xds_interop_client.str
str
Definition: xds_interop_client.py:487
bloaty
Definition: bloaty.cc:69
ABSL_ATTRIBUTE_NORETURN
#define ABSL_ATTRIBUTE_NORETURN
Definition: abseil-cpp/absl/base/attributes.h:203
bloaty::_BS
constexpr T _BS(T val)
Definition: bloaty/src/util.h:123
bloaty::Error::line_
int line_
Definition: bloaty/src/util.h:38
bloaty::Error::Error
Error(const char *msg, const char *file, int line)
Definition: bloaty/src/util.h:28
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
UINT64_MAX
#define UINT64_MAX
Definition: stdint-msvc2008.h:143
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
bloaty::ReadEndian
T ReadEndian(absl::string_view *data, Endian endian)
Definition: bloaty/src/util.h:148
bloaty::Error
Definition: bloaty/src/util.h:26
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
T
#define T(upbtypeconst, upbtype, ctype, default_value)
bloaty::Error::line
int line() const
Definition: bloaty/src/util.h:34
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
bloaty::SkipBytes
void SkipBytes(size_t bytes, absl::string_view *data)
Definition: bloaty/src/util.h:174
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
bloaty::Endian::kLittle
@ kLittle
THROW
#define THROW(msg)
Definition: bloaty/src/util.h:45
bloaty::CheckedAdd
void CheckedAdd(int64_t *accum, int64_t val)
Definition: bloaty.cc:124
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
bloaty::ReadFixed
T ReadFixed(absl::string_view *data)
Definition: bloaty/src/util.h:137
bits
OPENSSL_EXPORT ASN1_BIT_STRING * bits
Definition: x509v3.h:482
bloaty::CheckedMul
uint64_t CheckedMul(uint64_t a, uint64_t b)
Definition: bloaty/src/util.h:80
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
bloaty::ReadLittleEndian
T ReadLittleEndian(absl::string_view *data)
Definition: bloaty/src/util.h:153
bloaty::AlignUp
size_t AlignUp(size_t offset, size_t granularity)
Definition: bloaty/src/util.h:105
N
#define N
Definition: sync_test.cc:37
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
bloaty::Error::file
const char * file() const
Definition: bloaty/src/util.h:33
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
bloaty::ReadNullTerminated
absl::string_view ReadNullTerminated(absl::string_view *data)
Definition: third_party/bloaty/src/util.cc:26
BLOATY_ASSERT
#define BLOATY_ASSERT(expr)
Definition: bloaty/src/util.h:68
regen-readme.line
line
Definition: regen-readme.py:30
bloaty::ReadBigEndian
T ReadBigEndian(absl::string_view *data)
Definition: bloaty/src/util.h:157
bloaty::Endian::kBig
@ kBig
bloaty::GetMachineEndian
Endian GetMachineEndian()
Definition: bloaty/src/util.h:115
bloaty::Throw
ABSL_ATTRIBUTE_NORETURN void Throw(const char *str, int line)
Definition: third_party/bloaty/src/util.cc:22
bloaty::Endian
Endian
Definition: bloaty/src/util.h:113
bloaty::Error::file_
const char * file_
Definition: bloaty/src/util.h:37
bloaty::StrictSubstr
absl::string_view StrictSubstr(absl::string_view data, size_t off, size_t n)
Definition: bloaty/src/util.h:89
bloaty::ReadBytes
absl::string_view ReadBytes(size_t bytes, absl::string_view *data)
Definition: bloaty/src/util.h:165
offset
voidpf uLong offset
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:142
absl::uint128
Definition: abseil-cpp/absl/numeric/int128.h:104
bloaty::ByteSwap
constexpr T ByteSwap(T val)
Definition: bloaty/src/util.h:133


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:48