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
37namespace google_breakpad {
38
39inline uint8_t ByteReader::ReadOneByte(const uint8_t* buffer) const {
40 return buffer[0];
41}
42
43inline 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
53inline 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
64inline 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
76inline 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
98inline 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
123inline 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
143inline uint64_t ByteReader::ReadOffset(const uint8_t* buffer) const {
144 assert(this->offset_reader_);
145 return (this->*offset_reader_)(buffer);
146}
147
148inline uint64_t ByteReader::ReadAddress(const uint8_t* buffer) const {
149 assert(this->address_reader_);
150 return (this->*address_reader_)(buffer);
151}
152
153inline 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
160inline void ByteReader::SetTextBase(uint64_t text_base) {
161 text_base_ = text_base;
162 have_text_base_ = true;
163}
164
165inline void ByteReader::SetDataBase(uint64_t data_base) {
166 data_base_ = data_base;
167 have_data_base_ = true;
168}
169
170inline void ByteReader::SetFunctionBase(uint64_t function_base) {
171 function_base_ = function_base;
172 have_function_base_ = true;
173}
174
175inline void ByteReader::ClearFunctionBase() {
176 have_function_base_ = false;
177}
178
179} // namespace google_breakpad
180
181#endif // UTIL_DEBUGINFO_BYTEREADER_INL_H__
182