xref: /aosp_15_r20/external/google-breakpad/src/common/dwarf/bytereader-inl.h (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1 // Copyright 2006 Google LLC
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 LLC 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 
ReadOneByte(const uint8_t * buffer)39 inline uint8_t ByteReader::ReadOneByte(const uint8_t* buffer) const {
40   return buffer[0];
41 }
42 
ReadTwoBytes(const uint8_t * buffer)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 
ReadThreeBytes(const uint8_t * buffer)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 
ReadFourBytes(const uint8_t * buffer)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 
ReadEightBytes(const uint8_t * buffer)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 
ReadUnsignedLEB128(const uint8_t * buffer,size_t * len)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 
ReadSignedLEB128(const uint8_t * buffer,size_t * len)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 
ReadOffset(const uint8_t * buffer)143 inline uint64_t ByteReader::ReadOffset(const uint8_t* buffer) const {
144   assert(this->offset_reader_);
145   return (this->*offset_reader_)(buffer);
146 }
147 
ReadAddress(const uint8_t * buffer)148 inline uint64_t ByteReader::ReadAddress(const uint8_t* buffer) const {
149   assert(this->address_reader_);
150   return (this->*address_reader_)(buffer);
151 }
152 
SetCFIDataBase(uint64_t section_base,const uint8_t * buffer_base)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 
SetTextBase(uint64_t text_base)160 inline void ByteReader::SetTextBase(uint64_t text_base) {
161   text_base_ = text_base;
162   have_text_base_ = true;
163 }
164 
SetDataBase(uint64_t data_base)165 inline void ByteReader::SetDataBase(uint64_t data_base) {
166   data_base_ = data_base;
167   have_data_base_ = true;
168 }
169 
SetFunctionBase(uint64_t function_base)170 inline void ByteReader::SetFunctionBase(uint64_t function_base) {
171   function_base_ = function_base;
172   have_function_base_ = true;
173 }
174 
ClearFunctionBase()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