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