xref: /aosp_15_r20/external/google-breakpad/src/common/dwarf/bytereader-inl.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
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