1 | // Copyright 2006 Google Inc. All Rights Reserved. |
2 | // |
3 | // Redistribution and use in source and binary forms, with or without |
4 | // modification, are permitted provided that the following conditions are |
5 | // met: |
6 | // |
7 | // * Redistributions of source code must retain the above copyright |
8 | // notice, this list of conditions and the following disclaimer. |
9 | // * Redistributions in binary form must reproduce the above |
10 | // copyright notice, this list of conditions and the following disclaimer |
11 | // in the documentation and/or other materials provided with the |
12 | // distribution. |
13 | // * Neither the name of Google Inc. nor the names of its |
14 | // contributors may be used to endorse or promote products derived from |
15 | // this software without specific prior written permission. |
16 | // |
17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | |
29 | #ifndef UTIL_DEBUGINFO_BYTEREADER_INL_H__ |
30 | #define UTIL_DEBUGINFO_BYTEREADER_INL_H__ |
31 | |
32 | #include "common/dwarf/bytereader.h" |
33 | |
34 | #include <assert.h> |
35 | #include <stdint.h> |
36 | |
37 | namespace google_breakpad { |
38 | |
39 | inline uint8_t ByteReader::ReadOneByte(const uint8_t* buffer) const { |
40 | return buffer[0]; |
41 | } |
42 | |
43 | inline uint16_t ByteReader::ReadTwoBytes(const uint8_t* buffer) const { |
44 | const uint16_t buffer0 = buffer[0]; |
45 | const uint16_t buffer1 = buffer[1]; |
46 | if (endian_ == ENDIANNESS_LITTLE) { |
47 | return buffer0 | buffer1 << 8; |
48 | } else { |
49 | return buffer1 | buffer0 << 8; |
50 | } |
51 | } |
52 | |
53 | inline uint64_t ByteReader::ReadThreeBytes(const uint8_t* buffer) const { |
54 | const uint32_t buffer0 = buffer[0]; |
55 | const uint32_t buffer1 = buffer[1]; |
56 | const uint32_t buffer2 = buffer[2]; |
57 | if (endian_ == ENDIANNESS_LITTLE) { |
58 | return buffer0 | buffer1 << 8 | buffer2 << 16; |
59 | } else { |
60 | return buffer2 | buffer1 << 8 | buffer0 << 16; |
61 | } |
62 | } |
63 | |
64 | inline uint64_t ByteReader::ReadFourBytes(const uint8_t* buffer) const { |
65 | const uint32_t buffer0 = buffer[0]; |
66 | const uint32_t buffer1 = buffer[1]; |
67 | const uint32_t buffer2 = buffer[2]; |
68 | const uint32_t buffer3 = buffer[3]; |
69 | if (endian_ == ENDIANNESS_LITTLE) { |
70 | return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24; |
71 | } else { |
72 | return buffer3 | buffer2 << 8 | buffer1 << 16 | buffer0 << 24; |
73 | } |
74 | } |
75 | |
76 | inline uint64_t ByteReader::ReadEightBytes(const uint8_t* buffer) const { |
77 | const uint64_t buffer0 = buffer[0]; |
78 | const uint64_t buffer1 = buffer[1]; |
79 | const uint64_t buffer2 = buffer[2]; |
80 | const uint64_t buffer3 = buffer[3]; |
81 | const uint64_t buffer4 = buffer[4]; |
82 | const uint64_t buffer5 = buffer[5]; |
83 | const uint64_t buffer6 = buffer[6]; |
84 | const uint64_t buffer7 = buffer[7]; |
85 | if (endian_ == ENDIANNESS_LITTLE) { |
86 | return buffer0 | buffer1 << 8 | buffer2 << 16 | buffer3 << 24 | |
87 | buffer4 << 32 | buffer5 << 40 | buffer6 << 48 | buffer7 << 56; |
88 | } else { |
89 | return buffer7 | buffer6 << 8 | buffer5 << 16 | buffer4 << 24 | |
90 | buffer3 << 32 | buffer2 << 40 | buffer1 << 48 | buffer0 << 56; |
91 | } |
92 | } |
93 | |
94 | // Read an unsigned LEB128 number. Each byte contains 7 bits of |
95 | // information, plus one bit saying whether the number continues or |
96 | // not. |
97 | |
98 | inline uint64_t ByteReader::ReadUnsignedLEB128(const uint8_t* buffer, |
99 | size_t* len) const { |
100 | uint64_t result = 0; |
101 | size_t num_read = 0; |
102 | unsigned int shift = 0; |
103 | uint8_t byte; |
104 | |
105 | do { |
106 | byte = *buffer++; |
107 | num_read++; |
108 | |
109 | result |= (static_cast<uint64_t>(byte & 0x7f)) << shift; |
110 | |
111 | shift += 7; |
112 | |
113 | } while (byte & 0x80); |
114 | |
115 | *len = num_read; |
116 | |
117 | return result; |
118 | } |
119 | |
120 | // Read a signed LEB128 number. These are like regular LEB128 |
121 | // numbers, except the last byte may have a sign bit set. |
122 | |
123 | inline int64_t ByteReader::ReadSignedLEB128(const uint8_t* buffer, |
124 | size_t* len) const { |
125 | int64_t result = 0; |
126 | unsigned int shift = 0; |
127 | size_t num_read = 0; |
128 | uint8_t byte; |
129 | |
130 | do { |
131 | byte = *buffer++; |
132 | num_read++; |
133 | result |= (static_cast<uint64_t>(byte & 0x7f) << shift); |
134 | shift += 7; |
135 | } while (byte & 0x80); |
136 | |
137 | if ((shift < 8 * sizeof (result)) && (byte & 0x40)) |
138 | result |= -((static_cast<int64_t>(1)) << shift); |
139 | *len = num_read; |
140 | return result; |
141 | } |
142 | |
143 | inline uint64_t ByteReader::ReadOffset(const uint8_t* buffer) const { |
144 | assert(this->offset_reader_); |
145 | return (this->*offset_reader_)(buffer); |
146 | } |
147 | |
148 | inline uint64_t ByteReader::ReadAddress(const uint8_t* buffer) const { |
149 | assert(this->address_reader_); |
150 | return (this->*address_reader_)(buffer); |
151 | } |
152 | |
153 | inline void ByteReader::SetCFIDataBase(uint64_t section_base, |
154 | const uint8_t* buffer_base) { |
155 | section_base_ = section_base; |
156 | buffer_base_ = buffer_base; |
157 | have_section_base_ = true; |
158 | } |
159 | |
160 | inline void ByteReader::SetTextBase(uint64_t text_base) { |
161 | text_base_ = text_base; |
162 | have_text_base_ = true; |
163 | } |
164 | |
165 | inline void ByteReader::SetDataBase(uint64_t data_base) { |
166 | data_base_ = data_base; |
167 | have_data_base_ = true; |
168 | } |
169 | |
170 | inline void ByteReader::SetFunctionBase(uint64_t function_base) { |
171 | function_base_ = function_base; |
172 | have_function_base_ = true; |
173 | } |
174 | |
175 | inline void ByteReader::ClearFunctionBase() { |
176 | have_function_base_ = false; |
177 | } |
178 | |
179 | } // namespace google_breakpad |
180 | |
181 | #endif // UTIL_DEBUGINFO_BYTEREADER_INL_H__ |
182 | |