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