115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky/*
215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky * Copyright (C) 2015 The Android Open Source Project
315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky *
415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky * Licensed under the Apache License, Version 2.0 (the "License");
515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky * you may not use this file except in compliance with the License.
615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky * You may obtain a copy of the License at
715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky *
815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky *      http://www.apache.org/licenses/LICENSE-2.0
915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky *
1015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky * Unless required by applicable law or agreed to in writing, software
1115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky * distributed under the License is distributed on an "AS IS" BASIS,
1215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky * See the License for the specific language governing permissions and
1415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky * limitations under the License.
1515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky */
1615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
174fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#ifndef ART_COMPILER_DEBUG_DWARF_WRITER_H_
184fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#define ART_COMPILER_DEBUG_DWARF_WRITER_H_
1915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
2035831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko#include <type_traits>
2115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky#include <vector>
2280afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/bit_utils.h"
2315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky#include "base/logging.h"
2480afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "leb128.h"
2515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
2615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbeckynamespace art {
2715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbeckynamespace dwarf {
2815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
2915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky// The base class for all DWARF writers.
30ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Markotemplate <typename Vector = std::vector<uint8_t>>
3115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbeckyclass Writer {
32ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko  static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
33ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko
3415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky public:
3515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushUint8(int value) {
3615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_GE(value, 0);
3715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_LE(value, UINT8_MAX);
3815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back(value & 0xff);
3915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
4015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
4115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushUint16(int value) {
4215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_GE(value, 0);
4315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_LE(value, UINT16_MAX);
4415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 0) & 0xff);
4515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 8) & 0xff);
4615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
4715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
4815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushUint32(uint32_t value) {
4915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 0) & 0xff);
5015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 8) & 0xff);
5115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 16) & 0xff);
5215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 24) & 0xff);
5315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
5415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
5515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushUint32(int value) {
5615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_GE(value, 0);
5715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    PushUint32(static_cast<uint32_t>(value));
5815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
5915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
6015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushUint32(uint64_t value) {
6115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_LE(value, UINT32_MAX);
6215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    PushUint32(static_cast<uint32_t>(value));
6315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
6415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
6515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushUint64(uint64_t value) {
6615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 0) & 0xff);
6715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 8) & 0xff);
6815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 16) & 0xff);
6915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 24) & 0xff);
7015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 32) & 0xff);
7115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 40) & 0xff);
7215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 48) & 0xff);
7315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->push_back((value >> 56) & 0xff);
7415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
7515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
7615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushInt8(int value) {
7715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_GE(value, INT8_MIN);
7815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_LE(value, INT8_MAX);
7915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    PushUint8(static_cast<uint8_t>(value));
8015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
8115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
8215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushInt16(int value) {
8315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_GE(value, INT16_MIN);
8415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_LE(value, INT16_MAX);
8515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    PushUint16(static_cast<uint16_t>(value));
8615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
8715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
8815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushInt32(int value) {
8915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    PushUint32(static_cast<uint32_t>(value));
9015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
9115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
9215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushInt64(int64_t value) {
9315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    PushUint64(static_cast<uint64_t>(value));
9415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
9515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
9615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  // Variable-length encoders.
9715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
9815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushUleb128(uint32_t value) {
9915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    EncodeUnsignedLeb128(data_, value);
10015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
10115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
10215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushUleb128(int value) {
10315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_GE(value, 0);
10415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    EncodeUnsignedLeb128(data_, value);
10515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
10615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
10715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushSleb128(int value) {
10815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    EncodeSignedLeb128(data_, value);
10915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
11015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
11115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  // Miscellaneous functions.
11215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
11315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void PushString(const char* value) {
11415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->insert(data_->end(), value, value + strlen(value) + 1);
11515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
11615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
11791cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky  void PushData(const uint8_t* ptr, size_t num_bytes) {
11891cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky    data_->insert(data_->end(), ptr, ptr + num_bytes);
11915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
12015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
12191cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky  void PushData(const char* ptr, size_t num_bytes) {
12291cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky    data_->insert(data_->end(), ptr, ptr + num_bytes);
12391cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky  }
12491cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky
12591cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky  void PushData(const Vector* buffer) {
12691cb54e6caf8b06546c416e7f7467f1c03b3a757David Srbecky    data_->insert(data_->end(), buffer->begin(), buffer->end());
127b536247b1ce5de640eec81dddac47802cd074363David Srbecky  }
128b536247b1ce5de640eec81dddac47802cd074363David Srbecky
12915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void UpdateUint32(size_t offset, uint32_t value) {
13015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_LT(offset + 3, data_->size());
13115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 0] = (value >> 0) & 0xFF;
13215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 1] = (value >> 8) & 0xFF;
13315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 2] = (value >> 16) & 0xFF;
13415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 3] = (value >> 24) & 0xFF;
13515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
13615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
13715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void UpdateUint64(size_t offset, uint64_t value) {
13815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_LT(offset + 7, data_->size());
13915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 0] = (value >> 0) & 0xFF;
14015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 1] = (value >> 8) & 0xFF;
14115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 2] = (value >> 16) & 0xFF;
14215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 3] = (value >> 24) & 0xFF;
14315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 4] = (value >> 32) & 0xFF;
14415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 5] = (value >> 40) & 0xFF;
14515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 6] = (value >> 48) & 0xFF;
14615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    (*data_)[offset + 7] = (value >> 56) & 0xFF;
14715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
14815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
149b536247b1ce5de640eec81dddac47802cd074363David Srbecky  void UpdateUleb128(size_t offset, uint32_t value) {
150b536247b1ce5de640eec81dddac47802cd074363David Srbecky    DCHECK_LE(offset + UnsignedLeb128Size(value), data_->size());
151b536247b1ce5de640eec81dddac47802cd074363David Srbecky    UpdateUnsignedLeb128(data_->data() + offset, value);
152b536247b1ce5de640eec81dddac47802cd074363David Srbecky  }
153b536247b1ce5de640eec81dddac47802cd074363David Srbecky
154b536247b1ce5de640eec81dddac47802cd074363David Srbecky  void Pop() {
155b536247b1ce5de640eec81dddac47802cd074363David Srbecky    return data_->pop_back();
156b536247b1ce5de640eec81dddac47802cd074363David Srbecky  }
157b536247b1ce5de640eec81dddac47802cd074363David Srbecky
15815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  void Pad(int alignment) {
15915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    DCHECK_NE(alignment, 0);
16015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    data_->resize(RoundUp(data_->size(), alignment), 0);
16115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
16215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
163ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko  const Vector* data() const {
16415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    return data_;
16515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
16615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
16704b0526d60de4e9979fc486d2ba655247d211d0bDavid Srbecky  size_t size() const {
16804b0526d60de4e9979fc486d2ba655247d211d0bDavid Srbecky    return data_->size();
16904b0526d60de4e9979fc486d2ba655247d211d0bDavid Srbecky  }
17004b0526d60de4e9979fc486d2ba655247d211d0bDavid Srbecky
171ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko  explicit Writer(Vector* buffer) : data_(buffer) { }
17215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
17315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky private:
174ec7802a102d49ab5c17495118d4fe0bcc7287bebVladimir Marko  Vector* const data_;
17515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
17615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  DISALLOW_COPY_AND_ASSIGN(Writer);
17715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky};
17815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
17915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky}  // namespace dwarf
18015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky}  // namespace art
18115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
1824fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#endif  // ART_COMPILER_DEBUG_DWARF_WRITER_H_
183