xref: /aosp_15_r20/art/libelffile/dwarf/writer.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBELFFILE_DWARF_WRITER_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_LIBELFFILE_DWARF_WRITER_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <type_traits>
21*795d594fSAndroid Build Coastguard Worker #include <vector>
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker #include "base/bit_utils.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/leb128.h"
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker namespace art {
29*795d594fSAndroid Build Coastguard Worker namespace dwarf {
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker // The base class for all DWARF writers.
32*795d594fSAndroid Build Coastguard Worker template <typename Vector = std::vector<uint8_t>>
33*795d594fSAndroid Build Coastguard Worker class Writer {
34*795d594fSAndroid Build Coastguard Worker   static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
35*795d594fSAndroid Build Coastguard Worker 
36*795d594fSAndroid Build Coastguard Worker  public:
PushUint8(int value)37*795d594fSAndroid Build Coastguard Worker   void PushUint8(int value) {
38*795d594fSAndroid Build Coastguard Worker     DCHECK_GE(value, 0);
39*795d594fSAndroid Build Coastguard Worker     DCHECK_LE(value, UINT8_MAX);
40*795d594fSAndroid Build Coastguard Worker     data_->push_back(value & 0xff);
41*795d594fSAndroid Build Coastguard Worker   }
42*795d594fSAndroid Build Coastguard Worker 
PushUint16(int value)43*795d594fSAndroid Build Coastguard Worker   void PushUint16(int value) {
44*795d594fSAndroid Build Coastguard Worker     DCHECK_GE(value, 0);
45*795d594fSAndroid Build Coastguard Worker     DCHECK_LE(value, UINT16_MAX);
46*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 0) & 0xff);
47*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 8) & 0xff);
48*795d594fSAndroid Build Coastguard Worker   }
49*795d594fSAndroid Build Coastguard Worker 
PushUint32(uint32_t value)50*795d594fSAndroid Build Coastguard Worker   void PushUint32(uint32_t value) {
51*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 0) & 0xff);
52*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 8) & 0xff);
53*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 16) & 0xff);
54*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 24) & 0xff);
55*795d594fSAndroid Build Coastguard Worker   }
56*795d594fSAndroid Build Coastguard Worker 
PushUint32(int value)57*795d594fSAndroid Build Coastguard Worker   void PushUint32(int value) {
58*795d594fSAndroid Build Coastguard Worker     DCHECK_GE(value, 0);
59*795d594fSAndroid Build Coastguard Worker     PushUint32(static_cast<uint32_t>(value));
60*795d594fSAndroid Build Coastguard Worker   }
61*795d594fSAndroid Build Coastguard Worker 
PushUint32(uint64_t value)62*795d594fSAndroid Build Coastguard Worker   void PushUint32(uint64_t value) {
63*795d594fSAndroid Build Coastguard Worker     DCHECK_LE(value, UINT32_MAX);
64*795d594fSAndroid Build Coastguard Worker     PushUint32(static_cast<uint32_t>(value));
65*795d594fSAndroid Build Coastguard Worker   }
66*795d594fSAndroid Build Coastguard Worker 
PushUint64(uint64_t value)67*795d594fSAndroid Build Coastguard Worker   void PushUint64(uint64_t value) {
68*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 0) & 0xff);
69*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 8) & 0xff);
70*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 16) & 0xff);
71*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 24) & 0xff);
72*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 32) & 0xff);
73*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 40) & 0xff);
74*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 48) & 0xff);
75*795d594fSAndroid Build Coastguard Worker     data_->push_back((value >> 56) & 0xff);
76*795d594fSAndroid Build Coastguard Worker   }
77*795d594fSAndroid Build Coastguard Worker 
PushInt8(int value)78*795d594fSAndroid Build Coastguard Worker   void PushInt8(int value) {
79*795d594fSAndroid Build Coastguard Worker     DCHECK_GE(value, INT8_MIN);
80*795d594fSAndroid Build Coastguard Worker     DCHECK_LE(value, INT8_MAX);
81*795d594fSAndroid Build Coastguard Worker     PushUint8(static_cast<uint8_t>(value));
82*795d594fSAndroid Build Coastguard Worker   }
83*795d594fSAndroid Build Coastguard Worker 
PushInt16(int value)84*795d594fSAndroid Build Coastguard Worker   void PushInt16(int value) {
85*795d594fSAndroid Build Coastguard Worker     DCHECK_GE(value, INT16_MIN);
86*795d594fSAndroid Build Coastguard Worker     DCHECK_LE(value, INT16_MAX);
87*795d594fSAndroid Build Coastguard Worker     PushUint16(static_cast<uint16_t>(value));
88*795d594fSAndroid Build Coastguard Worker   }
89*795d594fSAndroid Build Coastguard Worker 
PushInt32(int value)90*795d594fSAndroid Build Coastguard Worker   void PushInt32(int value) {
91*795d594fSAndroid Build Coastguard Worker     PushUint32(static_cast<uint32_t>(value));
92*795d594fSAndroid Build Coastguard Worker   }
93*795d594fSAndroid Build Coastguard Worker 
PushInt64(int64_t value)94*795d594fSAndroid Build Coastguard Worker   void PushInt64(int64_t value) {
95*795d594fSAndroid Build Coastguard Worker     PushUint64(static_cast<uint64_t>(value));
96*795d594fSAndroid Build Coastguard Worker   }
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker   // Variable-length encoders.
99*795d594fSAndroid Build Coastguard Worker 
PushUleb128(uint32_t value)100*795d594fSAndroid Build Coastguard Worker   void PushUleb128(uint32_t value) {
101*795d594fSAndroid Build Coastguard Worker     EncodeUnsignedLeb128(data_, value);
102*795d594fSAndroid Build Coastguard Worker   }
103*795d594fSAndroid Build Coastguard Worker 
PushUleb128(int value)104*795d594fSAndroid Build Coastguard Worker   void PushUleb128(int value) {
105*795d594fSAndroid Build Coastguard Worker     DCHECK_GE(value, 0);
106*795d594fSAndroid Build Coastguard Worker     EncodeUnsignedLeb128(data_, value);
107*795d594fSAndroid Build Coastguard Worker   }
108*795d594fSAndroid Build Coastguard Worker 
PushSleb128(int value)109*795d594fSAndroid Build Coastguard Worker   void PushSleb128(int value) {
110*795d594fSAndroid Build Coastguard Worker     EncodeSignedLeb128(data_, value);
111*795d594fSAndroid Build Coastguard Worker   }
112*795d594fSAndroid Build Coastguard Worker 
113*795d594fSAndroid Build Coastguard Worker   // Miscellaneous functions.
114*795d594fSAndroid Build Coastguard Worker 
PushString(const char * value)115*795d594fSAndroid Build Coastguard Worker   void PushString(const char* value) {
116*795d594fSAndroid Build Coastguard Worker     data_->insert(data_->end(), value, value + strlen(value) + 1);
117*795d594fSAndroid Build Coastguard Worker   }
118*795d594fSAndroid Build Coastguard Worker 
PushData(const uint8_t * ptr,size_t num_bytes)119*795d594fSAndroid Build Coastguard Worker   void PushData(const uint8_t* ptr, size_t num_bytes) {
120*795d594fSAndroid Build Coastguard Worker     data_->insert(data_->end(), ptr, ptr + num_bytes);
121*795d594fSAndroid Build Coastguard Worker   }
122*795d594fSAndroid Build Coastguard Worker 
PushData(const char * ptr,size_t num_bytes)123*795d594fSAndroid Build Coastguard Worker   void PushData(const char* ptr, size_t num_bytes) {
124*795d594fSAndroid Build Coastguard Worker     data_->insert(data_->end(), ptr, ptr + num_bytes);
125*795d594fSAndroid Build Coastguard Worker   }
126*795d594fSAndroid Build Coastguard Worker 
PushData(const Vector * buffer)127*795d594fSAndroid Build Coastguard Worker   void PushData(const Vector* buffer) {
128*795d594fSAndroid Build Coastguard Worker     data_->insert(data_->end(), buffer->begin(), buffer->end());
129*795d594fSAndroid Build Coastguard Worker   }
130*795d594fSAndroid Build Coastguard Worker 
UpdateUint32(size_t offset,uint32_t value)131*795d594fSAndroid Build Coastguard Worker   void UpdateUint32(size_t offset, uint32_t value) {
132*795d594fSAndroid Build Coastguard Worker     DCHECK_LT(offset + 3, data_->size());
133*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 0] = (value >> 0) & 0xFF;
134*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 1] = (value >> 8) & 0xFF;
135*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 2] = (value >> 16) & 0xFF;
136*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 3] = (value >> 24) & 0xFF;
137*795d594fSAndroid Build Coastguard Worker   }
138*795d594fSAndroid Build Coastguard Worker 
UpdateUint64(size_t offset,uint64_t value)139*795d594fSAndroid Build Coastguard Worker   void UpdateUint64(size_t offset, uint64_t value) {
140*795d594fSAndroid Build Coastguard Worker     DCHECK_LT(offset + 7, data_->size());
141*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 0] = (value >> 0) & 0xFF;
142*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 1] = (value >> 8) & 0xFF;
143*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 2] = (value >> 16) & 0xFF;
144*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 3] = (value >> 24) & 0xFF;
145*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 4] = (value >> 32) & 0xFF;
146*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 5] = (value >> 40) & 0xFF;
147*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 6] = (value >> 48) & 0xFF;
148*795d594fSAndroid Build Coastguard Worker     (*data_)[offset + 7] = (value >> 56) & 0xFF;
149*795d594fSAndroid Build Coastguard Worker   }
150*795d594fSAndroid Build Coastguard Worker 
UpdateUleb128(size_t offset,uint32_t value)151*795d594fSAndroid Build Coastguard Worker   void UpdateUleb128(size_t offset, uint32_t value) {
152*795d594fSAndroid Build Coastguard Worker     DCHECK_LE(offset + UnsignedLeb128Size(value), data_->size());
153*795d594fSAndroid Build Coastguard Worker     UpdateUnsignedLeb128(data_->data() + offset, value);
154*795d594fSAndroid Build Coastguard Worker   }
155*795d594fSAndroid Build Coastguard Worker 
Pop()156*795d594fSAndroid Build Coastguard Worker   void Pop() {
157*795d594fSAndroid Build Coastguard Worker     return data_->pop_back();
158*795d594fSAndroid Build Coastguard Worker   }
159*795d594fSAndroid Build Coastguard Worker 
Pad(int alignment)160*795d594fSAndroid Build Coastguard Worker   void Pad(int alignment) {
161*795d594fSAndroid Build Coastguard Worker     DCHECK_NE(alignment, 0);
162*795d594fSAndroid Build Coastguard Worker     data_->resize(RoundUp(data_->size(), alignment), 0);
163*795d594fSAndroid Build Coastguard Worker   }
164*795d594fSAndroid Build Coastguard Worker 
data()165*795d594fSAndroid Build Coastguard Worker   const Vector* data() const {
166*795d594fSAndroid Build Coastguard Worker     return data_;
167*795d594fSAndroid Build Coastguard Worker   }
168*795d594fSAndroid Build Coastguard Worker 
size()169*795d594fSAndroid Build Coastguard Worker   size_t size() const {
170*795d594fSAndroid Build Coastguard Worker     return data_->size();
171*795d594fSAndroid Build Coastguard Worker   }
172*795d594fSAndroid Build Coastguard Worker 
Writer(Vector * buffer)173*795d594fSAndroid Build Coastguard Worker   explicit Writer(Vector* buffer) : data_(buffer) { }
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker  private:
176*795d594fSAndroid Build Coastguard Worker   Vector* const data_;
177*795d594fSAndroid Build Coastguard Worker 
178*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Writer);
179*795d594fSAndroid Build Coastguard Worker };
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker }  // namespace dwarf
182*795d594fSAndroid Build Coastguard Worker }  // namespace art
183*795d594fSAndroid Build Coastguard Worker 
184*795d594fSAndroid Build Coastguard Worker #endif  // ART_LIBELFFILE_DWARF_WRITER_H_
185