1/*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#define HILOG_TAG "Dwarf"
16
17#include "dwarf_encoding.h"
18
19#include "utilities.h"
20namespace OHOS {
21namespace Developtools {
22namespace NativeDaemon {
23DwarfEncoding::DwarfEncoding(dw_encode_t dw, const unsigned char *&data, uint64_t vaddrBase,
24                             uint64_t vaddrPC, uint64_t vaddrText)
25    : dw_(dw), data_(data), vaddrBase_(vaddrBase), vaddrPC_(vaddrPC), vaddrText_(vaddrText)
26{
27    value_[0] = ReadValue(data);
28}
29
30const std::string DwarfEncoding::ToString() const
31{
32    std::string debugString = ApplicationName() + ":" + FormatName() + " format:" + ToHex(dw_) +
33                              " value size:" + std::to_string(GetSize()) + " raw:";
34
35    size_t size = GetSize();
36    const unsigned char *data = data_;
37    while (size-- > 0) {
38        debugString.append(ToHex(data[0]) + " ");
39        data++;
40    }
41
42    debugString.append(" | " + ToHex(GetValue(), GetSize(), true));
43    debugString.append(" applied:" + ToHex(GetAppliedValue(), GetSize()));
44    return debugString;
45}
46
47const unsigned char *DwarfEncoding::GetEnd() const
48{
49    return data_ + GetSize();
50}
51
52const unsigned char *DwarfEncoding::GetData() const
53{
54    return data_;
55}
56
57size_t DwarfEncoding::GetSize() const
58{
59    return DWFormatSizeMap.at((dw_encode_t)Format());
60}
61
62uint64_t DwarfEncoding::GetValue() const
63{
64    return value_[0];
65}
66
67uint64_t DwarfEncoding::GetAppliedValue() const
68{
69    if ((Application() & DW_EH_PE_datarel) == DW_EH_PE_datarel) {
70        return value_[0] + vaddrBase_;
71    } else if ((Application() & DW_EH_PE_textrel) == DW_EH_PE_textrel) {
72        return value_[0] + vaddrText_;
73    } else if ((Application() & DW_EH_PE_pcrel) == DW_EH_PE_pcrel) {
74        return value_[0] + vaddrPC_;
75    }
76    HLOGM("Application is empty");
77
78    return value_[0];
79}
80
81bool DwarfEncoding::IsOmit() const
82{
83    return (dw_ == DW_EH_PE_omit);
84}
85
86dw_encode_t DwarfEncoding::Format() const
87{
88    return (dw_ & 0x0F);
89}
90dw_encode_t DwarfEncoding::Application() const
91{
92    return (dw_ & 0xF0);
93}
94uint64_t DwarfEncoding::ReadValue(const unsigned char *&data) const
95{
96    switch (Format()) {
97        case DW_EH_PE_udata2:
98            return dwReadAnyTypeData(data, uint16_t());
99        case DW_EH_PE_udata4:
100            return dwReadAnyTypeData(data, uint32_t());
101        case DW_EH_PE_udata8:
102            return dwReadAnyTypeData(data, uint64_t());
103        case DW_EH_PE_sdata2:
104            return dwReadAnyTypeData(data, int16_t());
105        case DW_EH_PE_sdata4:
106            return dwReadAnyTypeData(data, int32_t());
107        case DW_EH_PE_sdata8:
108            return dwReadAnyTypeData(data, int64_t());
109        default:
110            return -1;
111    }
112}
113const std::string DwarfEncoding::FormatName() const
114{
115    switch (Format()) {
116        case DW_EH_PE_absptr:
117            return "DW_EH_PE_absptr";
118        case DW_EH_PE_uleb128:
119            return "DW_EH_PE_uleb128";
120        case DW_EH_PE_udata2:
121            return "DW_EH_PE_udata2";
122        case DW_EH_PE_udata4:
123            return "DW_EH_PE_udata4";
124        case DW_EH_PE_udata8:
125            return "DW_EH_PE_udata8";
126        case DW_EH_PE_sleb128:
127            return "DW_EH_PE_sleb128";
128        case DW_EH_PE_sdata2:
129            return "DW_EH_PE_data2";
130        case DW_EH_PE_sdata4:
131            return "DW_EH_PE_sdata4";
132        case DW_EH_PE_sdata8:
133            return "DW_EH_PE_sdata8";
134        case DW_EH_PE_omit:
135            return "DW_EH_PE_omit";
136        default:
137            return "unknow format";
138    }
139}
140const std::string DwarfEncoding::ApplicationName() const
141{
142    switch (Application()) {
143        case DW_EH_PE_pcrel:
144            return "DW_EH_PE_pcrel";
145        case DW_EH_PE_textrel:
146            return "DW_EH_PE_textrel";
147        case DW_EH_PE_datarel:
148            return "DW_EH_PE_datarel";
149        case DW_EH_PE_funcrel:
150            return "DW_EH_PE_funcrel";
151        case DW_EH_PE_aligned:
152            return "DW_EH_PE_aligned";
153        case DW_EH_PE_omit:
154            return "DW_EH_PE_omit";
155        case DW_EH_PE_nothing:
156            return "DW_EH_PE_empty";
157        default:
158            return "unknow format";
159    }
160}
161} // namespace HiPerf
162} // namespace Developtools
163} // namespace OHOS