blob: e703aeea2d086ec78e4af3badcf5ef115d8ad515 [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>
Vladimir Marko80afd022015-05-19 18:08:00 +010021#include "base/bit_utils.h"
David Srbecky15c19752015-03-31 14:53:55 +000022#include "base/logging.h"
Vladimir Marko80afd022015-05-19 18:08:00 +010023#include "leb128.h"
David Srbecky15c19752015-03-31 14:53:55 +000024
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
David Srbeckyb5362472015-04-08 19:37:39 +0100119 template<typename Allocator2>
120 void PushData(const std::vector<uint8_t, Allocator2>* buffer) {
121 data_->insert(data_->end(), buffer->begin(), buffer->end());
122 }
123
David Srbecky15c19752015-03-31 14:53:55 +0000124 void UpdateUint32(size_t offset, uint32_t value) {
125 DCHECK_LT(offset + 3, data_->size());
126 (*data_)[offset + 0] = (value >> 0) & 0xFF;
127 (*data_)[offset + 1] = (value >> 8) & 0xFF;
128 (*data_)[offset + 2] = (value >> 16) & 0xFF;
129 (*data_)[offset + 3] = (value >> 24) & 0xFF;
130 }
131
132 void UpdateUint64(size_t offset, uint64_t value) {
133 DCHECK_LT(offset + 7, data_->size());
134 (*data_)[offset + 0] = (value >> 0) & 0xFF;
135 (*data_)[offset + 1] = (value >> 8) & 0xFF;
136 (*data_)[offset + 2] = (value >> 16) & 0xFF;
137 (*data_)[offset + 3] = (value >> 24) & 0xFF;
138 (*data_)[offset + 4] = (value >> 32) & 0xFF;
139 (*data_)[offset + 5] = (value >> 40) & 0xFF;
140 (*data_)[offset + 6] = (value >> 48) & 0xFF;
141 (*data_)[offset + 7] = (value >> 56) & 0xFF;
142 }
143
David Srbeckyb5362472015-04-08 19:37:39 +0100144 void UpdateUleb128(size_t offset, uint32_t value) {
145 DCHECK_LE(offset + UnsignedLeb128Size(value), data_->size());
146 UpdateUnsignedLeb128(data_->data() + offset, value);
147 }
148
149 void Pop() {
150 return data_->pop_back();
151 }
152
David Srbecky15c19752015-03-31 14:53:55 +0000153 void Pad(int alignment) {
154 DCHECK_NE(alignment, 0);
155 data_->resize(RoundUp(data_->size(), alignment), 0);
156 }
157
158 const std::vector<uint8_t, Allocator>* data() const {
159 return data_;
160 }
161
162 explicit Writer(std::vector<uint8_t, Allocator>* buffer) : data_(buffer) { }
163
164 private:
165 std::vector<uint8_t, Allocator>* data_;
166
167 DISALLOW_COPY_AND_ASSIGN(Writer);
168};
169
170} // namespace dwarf
171} // namespace art
172
173#endif // ART_COMPILER_DWARF_WRITER_H_