148f512ceSopenharmony_ci/*
248f512ceSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
448f512ceSopenharmony_ci * you may not use this file except in compliance with the License.
548f512ceSopenharmony_ci * You may obtain a copy of the License at
648f512ceSopenharmony_ci *
748f512ceSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
848f512ceSopenharmony_ci *
948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and
1348f512ceSopenharmony_ci * limitations under the License.
1448f512ceSopenharmony_ci */
1548f512ceSopenharmony_ci#define HILOG_TAG "Dwarf"
1648f512ceSopenharmony_ci
1748f512ceSopenharmony_ci#include "dwarf_encoding.h"
1848f512ceSopenharmony_ci
1948f512ceSopenharmony_ci#include "utilities.h"
2048f512ceSopenharmony_cinamespace OHOS {
2148f512ceSopenharmony_cinamespace Developtools {
2248f512ceSopenharmony_cinamespace HiPerf {
2348f512ceSopenharmony_ciDwarfEncoding::DwarfEncoding(dw_encode_t dw, const unsigned char *&data, uint64_t vaddrBase,
2448f512ceSopenharmony_ci                             uint64_t vaddrPC, uint64_t vaddrText)
2548f512ceSopenharmony_ci    : dw_(dw), data_(data), vaddrBase_(vaddrBase), vaddrPC_(vaddrPC), vaddrText_(vaddrText)
2648f512ceSopenharmony_ci{
2748f512ceSopenharmony_ci    value_[0] = ReadValue(data);
2848f512ceSopenharmony_ci}
2948f512ceSopenharmony_ci
3048f512ceSopenharmony_ciconst std::string DwarfEncoding::ToString() const
3148f512ceSopenharmony_ci{
3248f512ceSopenharmony_ci    std::string debugString = ApplicationName() + ":" + FormatName() + " format:" + ToHex(dw_) +
3348f512ceSopenharmony_ci                              " value size:" + std::to_string(GetSize()) + " raw:";
3448f512ceSopenharmony_ci
3548f512ceSopenharmony_ci    size_t size = GetSize();
3648f512ceSopenharmony_ci    const unsigned char *data = data_;
3748f512ceSopenharmony_ci    while (size-- > 0) {
3848f512ceSopenharmony_ci        debugString.append(ToHex(data[0]) + " ");
3948f512ceSopenharmony_ci        data++;
4048f512ceSopenharmony_ci    }
4148f512ceSopenharmony_ci
4248f512ceSopenharmony_ci    debugString.append(" | " + ToHex(GetValue(), GetSize(), true));
4348f512ceSopenharmony_ci    debugString.append(" applied:" + ToHex(GetAppliedValue(), GetSize()));
4448f512ceSopenharmony_ci    return debugString;
4548f512ceSopenharmony_ci}
4648f512ceSopenharmony_ci
4748f512ceSopenharmony_ciconst unsigned char *DwarfEncoding::GetEnd() const
4848f512ceSopenharmony_ci{
4948f512ceSopenharmony_ci    return data_ + GetSize();
5048f512ceSopenharmony_ci}
5148f512ceSopenharmony_ci
5248f512ceSopenharmony_ciconst unsigned char *DwarfEncoding::GetData() const
5348f512ceSopenharmony_ci{
5448f512ceSopenharmony_ci    return data_;
5548f512ceSopenharmony_ci}
5648f512ceSopenharmony_ci
5748f512ceSopenharmony_cisize_t DwarfEncoding::GetSize() const
5848f512ceSopenharmony_ci{
5948f512ceSopenharmony_ci    return DWFormatSizeMap.at((dw_encode_t)Format());
6048f512ceSopenharmony_ci}
6148f512ceSopenharmony_ci
6248f512ceSopenharmony_ciuint64_t DwarfEncoding::GetValue() const
6348f512ceSopenharmony_ci{
6448f512ceSopenharmony_ci    return value_[0];
6548f512ceSopenharmony_ci}
6648f512ceSopenharmony_ci
6748f512ceSopenharmony_ciuint64_t DwarfEncoding::GetAppliedValue() const
6848f512ceSopenharmony_ci{
6948f512ceSopenharmony_ci    if ((Application() & DW_EH_PE_datarel) == DW_EH_PE_datarel) {
7048f512ceSopenharmony_ci        return value_[0] + vaddrBase_;
7148f512ceSopenharmony_ci    } else if ((Application() & DW_EH_PE_textrel) == DW_EH_PE_textrel) {
7248f512ceSopenharmony_ci        return value_[0] + vaddrText_;
7348f512ceSopenharmony_ci    } else if ((Application() & DW_EH_PE_pcrel) == DW_EH_PE_pcrel) {
7448f512ceSopenharmony_ci        return value_[0] + vaddrPC_;
7548f512ceSopenharmony_ci    }
7648f512ceSopenharmony_ci    HLOGM("Application is empty");
7748f512ceSopenharmony_ci
7848f512ceSopenharmony_ci    return value_[0];
7948f512ceSopenharmony_ci}
8048f512ceSopenharmony_ci
8148f512ceSopenharmony_cibool DwarfEncoding::IsOmit() const
8248f512ceSopenharmony_ci{
8348f512ceSopenharmony_ci    return (dw_ == DW_EH_PE_omit);
8448f512ceSopenharmony_ci}
8548f512ceSopenharmony_ci
8648f512ceSopenharmony_cidw_encode_t DwarfEncoding::Format() const
8748f512ceSopenharmony_ci{
8848f512ceSopenharmony_ci    return (dw_ & 0x0F);
8948f512ceSopenharmony_ci}
9048f512ceSopenharmony_cidw_encode_t DwarfEncoding::Application() const
9148f512ceSopenharmony_ci{
9248f512ceSopenharmony_ci    return (dw_ & 0xF0);
9348f512ceSopenharmony_ci}
9448f512ceSopenharmony_ciuint64_t DwarfEncoding::ReadValue(const unsigned char *&data) const
9548f512ceSopenharmony_ci{
9648f512ceSopenharmony_ci    switch (Format()) {
9748f512ceSopenharmony_ci        case DW_EH_PE_udata2:
9848f512ceSopenharmony_ci            return dwReadAnyTypeData(data, uint16_t());
9948f512ceSopenharmony_ci        case DW_EH_PE_udata4:
10048f512ceSopenharmony_ci            return dwReadAnyTypeData(data, uint32_t());
10148f512ceSopenharmony_ci        case DW_EH_PE_udata8:
10248f512ceSopenharmony_ci            return dwReadAnyTypeData(data, uint64_t());
10348f512ceSopenharmony_ci        case DW_EH_PE_sdata2:
10448f512ceSopenharmony_ci            return dwReadAnyTypeData(data, int16_t());
10548f512ceSopenharmony_ci        case DW_EH_PE_sdata4:
10648f512ceSopenharmony_ci            return dwReadAnyTypeData(data, int32_t());
10748f512ceSopenharmony_ci        case DW_EH_PE_sdata8:
10848f512ceSopenharmony_ci            return dwReadAnyTypeData(data, int64_t());
10948f512ceSopenharmony_ci        default:
11048f512ceSopenharmony_ci            return -1;
11148f512ceSopenharmony_ci    }
11248f512ceSopenharmony_ci}
11348f512ceSopenharmony_ciconst std::string DwarfEncoding::FormatName() const
11448f512ceSopenharmony_ci{
11548f512ceSopenharmony_ci    switch (Format()) {
11648f512ceSopenharmony_ci        case DW_EH_PE_absptr:
11748f512ceSopenharmony_ci            return "DW_EH_PE_absptr";
11848f512ceSopenharmony_ci        case DW_EH_PE_uleb128:
11948f512ceSopenharmony_ci            return "DW_EH_PE_uleb128";
12048f512ceSopenharmony_ci        case DW_EH_PE_udata2:
12148f512ceSopenharmony_ci            return "DW_EH_PE_udata2";
12248f512ceSopenharmony_ci        case DW_EH_PE_udata4:
12348f512ceSopenharmony_ci            return "DW_EH_PE_udata4";
12448f512ceSopenharmony_ci        case DW_EH_PE_udata8:
12548f512ceSopenharmony_ci            return "DW_EH_PE_udata8";
12648f512ceSopenharmony_ci        case DW_EH_PE_sleb128:
12748f512ceSopenharmony_ci            return "DW_EH_PE_sleb128";
12848f512ceSopenharmony_ci        case DW_EH_PE_sdata2:
12948f512ceSopenharmony_ci            return "DW_EH_PE_sdata2";
13048f512ceSopenharmony_ci        case DW_EH_PE_sdata4:
13148f512ceSopenharmony_ci            return "DW_EH_PE_sdata4";
13248f512ceSopenharmony_ci        case DW_EH_PE_sdata8:
13348f512ceSopenharmony_ci            return "DW_EH_PE_sdata8";
13448f512ceSopenharmony_ci        case DW_EH_PE_omit:
13548f512ceSopenharmony_ci            return "DW_EH_PE_omit";
13648f512ceSopenharmony_ci        default:
13748f512ceSopenharmony_ci            return "unknown format";
13848f512ceSopenharmony_ci    }
13948f512ceSopenharmony_ci}
14048f512ceSopenharmony_ciconst std::string DwarfEncoding::ApplicationName() const
14148f512ceSopenharmony_ci{
14248f512ceSopenharmony_ci    switch (Application()) {
14348f512ceSopenharmony_ci        case DW_EH_PE_pcrel:
14448f512ceSopenharmony_ci            return "DW_EH_PE_pcrel";
14548f512ceSopenharmony_ci        case DW_EH_PE_textrel:
14648f512ceSopenharmony_ci            return "DW_EH_PE_textrel";
14748f512ceSopenharmony_ci        case DW_EH_PE_datarel:
14848f512ceSopenharmony_ci            return "DW_EH_PE_datarel";
14948f512ceSopenharmony_ci        case DW_EH_PE_funcrel:
15048f512ceSopenharmony_ci            return "DW_EH_PE_funcrel";
15148f512ceSopenharmony_ci        case DW_EH_PE_aligned:
15248f512ceSopenharmony_ci            return "DW_EH_PE_aligned";
15348f512ceSopenharmony_ci        case DW_EH_PE_omit:
15448f512ceSopenharmony_ci            return "DW_EH_PE_omit";
15548f512ceSopenharmony_ci        case DW_EH_PE_nothing:
15648f512ceSopenharmony_ci            return "DW_EH_PE_empty";
15748f512ceSopenharmony_ci        default:
15848f512ceSopenharmony_ci            return "unknown format";
15948f512ceSopenharmony_ci    }
16048f512ceSopenharmony_ci}
16148f512ceSopenharmony_ci} // namespace HiPerf
16248f512ceSopenharmony_ci} // namespace Developtools
16348f512ceSopenharmony_ci} // namespace OHOS
164