Home | History | Annotate | Download | only in dwarf
      1 /*
      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_DEBUG_DWARF_WRITER_H_
     18 #define ART_COMPILER_DEBUG_DWARF_WRITER_H_
     19 
     20 #include <type_traits>
     21 #include <vector>
     22 
     23 #include <android-base/logging.h>
     24 
     25 #include "base/bit_utils.h"
     26 #include "base/leb128.h"
     27 
     28 namespace art {
     29 namespace dwarf {
     30 
     31 // The base class for all DWARF writers.
     32 template <typename Vector = std::vector<uint8_t>>
     33 class Writer {
     34   static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
     35 
     36  public:
     37   void PushUint8(int value) {
     38     DCHECK_GE(value, 0);
     39     DCHECK_LE(value, UINT8_MAX);
     40     data_->push_back(value & 0xff);
     41   }
     42 
     43   void PushUint16(int value) {
     44     DCHECK_GE(value, 0);
     45     DCHECK_LE(value, UINT16_MAX);
     46     data_->push_back((value >> 0) & 0xff);
     47     data_->push_back((value >> 8) & 0xff);
     48   }
     49 
     50   void PushUint32(uint32_t value) {
     51     data_->push_back((value >> 0) & 0xff);
     52     data_->push_back((value >> 8) & 0xff);
     53     data_->push_back((value >> 16) & 0xff);
     54     data_->push_back((value >> 24) & 0xff);
     55   }
     56 
     57   void PushUint32(int value) {
     58     DCHECK_GE(value, 0);
     59     PushUint32(static_cast<uint32_t>(value));
     60   }
     61 
     62   void PushUint32(uint64_t value) {
     63     DCHECK_LE(value, UINT32_MAX);
     64     PushUint32(static_cast<uint32_t>(value));
     65   }
     66 
     67   void PushUint64(uint64_t value) {
     68     data_->push_back((value >> 0) & 0xff);
     69     data_->push_back((value >> 8) & 0xff);
     70     data_->push_back((value >> 16) & 0xff);
     71     data_->push_back((value >> 24) & 0xff);
     72     data_->push_back((value >> 32) & 0xff);
     73     data_->push_back((value >> 40) & 0xff);
     74     data_->push_back((value >> 48) & 0xff);
     75     data_->push_back((value >> 56) & 0xff);
     76   }
     77 
     78   void PushInt8(int value) {
     79     DCHECK_GE(value, INT8_MIN);
     80     DCHECK_LE(value, INT8_MAX);
     81     PushUint8(static_cast<uint8_t>(value));
     82   }
     83 
     84   void PushInt16(int value) {
     85     DCHECK_GE(value, INT16_MIN);
     86     DCHECK_LE(value, INT16_MAX);
     87     PushUint16(static_cast<uint16_t>(value));
     88   }
     89 
     90   void PushInt32(int value) {
     91     PushUint32(static_cast<uint32_t>(value));
     92   }
     93 
     94   void PushInt64(int64_t value) {
     95     PushUint64(static_cast<uint64_t>(value));
     96   }
     97 
     98   // Variable-length encoders.
     99 
    100   void PushUleb128(uint32_t value) {
    101     EncodeUnsignedLeb128(data_, value);
    102   }
    103 
    104   void PushUleb128(int value) {
    105     DCHECK_GE(value, 0);
    106     EncodeUnsignedLeb128(data_, value);
    107   }
    108 
    109   void PushSleb128(int value) {
    110     EncodeSignedLeb128(data_, value);
    111   }
    112 
    113   // Miscellaneous functions.
    114 
    115   void PushString(const char* value) {
    116     data_->insert(data_->end(), value, value + strlen(value) + 1);
    117   }
    118 
    119   void PushData(const uint8_t* ptr, size_t num_bytes) {
    120     data_->insert(data_->end(), ptr, ptr + num_bytes);
    121   }
    122 
    123   void PushData(const char* ptr, size_t num_bytes) {
    124     data_->insert(data_->end(), ptr, ptr + num_bytes);
    125   }
    126 
    127   void PushData(const Vector* buffer) {
    128     data_->insert(data_->end(), buffer->begin(), buffer->end());
    129   }
    130 
    131   void UpdateUint32(size_t offset, uint32_t value) {
    132     DCHECK_LT(offset + 3, data_->size());
    133     (*data_)[offset + 0] = (value >> 0) & 0xFF;
    134     (*data_)[offset + 1] = (value >> 8) & 0xFF;
    135     (*data_)[offset + 2] = (value >> 16) & 0xFF;
    136     (*data_)[offset + 3] = (value >> 24) & 0xFF;
    137   }
    138 
    139   void UpdateUint64(size_t offset, uint64_t value) {
    140     DCHECK_LT(offset + 7, data_->size());
    141     (*data_)[offset + 0] = (value >> 0) & 0xFF;
    142     (*data_)[offset + 1] = (value >> 8) & 0xFF;
    143     (*data_)[offset + 2] = (value >> 16) & 0xFF;
    144     (*data_)[offset + 3] = (value >> 24) & 0xFF;
    145     (*data_)[offset + 4] = (value >> 32) & 0xFF;
    146     (*data_)[offset + 5] = (value >> 40) & 0xFF;
    147     (*data_)[offset + 6] = (value >> 48) & 0xFF;
    148     (*data_)[offset + 7] = (value >> 56) & 0xFF;
    149   }
    150 
    151   void UpdateUleb128(size_t offset, uint32_t value) {
    152     DCHECK_LE(offset + UnsignedLeb128Size(value), data_->size());
    153     UpdateUnsignedLeb128(data_->data() + offset, value);
    154   }
    155 
    156   void Pop() {
    157     return data_->pop_back();
    158   }
    159 
    160   void Pad(int alignment) {
    161     DCHECK_NE(alignment, 0);
    162     data_->resize(RoundUp(data_->size(), alignment), 0);
    163   }
    164 
    165   const Vector* data() const {
    166     return data_;
    167   }
    168 
    169   size_t size() const {
    170     return data_->size();
    171   }
    172 
    173   explicit Writer(Vector* buffer) : data_(buffer) { }
    174 
    175  private:
    176   Vector* const data_;
    177 
    178   DISALLOW_COPY_AND_ASSIGN(Writer);
    179 };
    180 
    181 }  // namespace dwarf
    182 }  // namespace art
    183 
    184 #endif  // ART_COMPILER_DEBUG_DWARF_WRITER_H_
    185