1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 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 #ifndef DWARF_ENCODING_H 16 #define DWARF_ENCODING_H 17 18 #include "utilities.h" 19 20 // now we only support 64 bit. 21 using uleb128_t = uint64_t; 22 using sleb128_t = int64_t; 23 24 namespace OHOS { 25 namespace Developtools { 26 namespace HiPerf { 27 static constexpr const int LEB_BYTE_EFFECTIVE_LENGTH = 7; 28 static constexpr const int SIGN_BIT_OF_BYTE = 0x40; 29 static constexpr const int MAX_VALUE_OF_BYTE = 0x7f; 30 static constexpr const int MORE_BIT_OF_BYTE = 0x80; 31 32 /* 33 10.5.1. DWARF Exception Header Encoding 34 The DWARF Exception Header Encoding is used to describe the type of data used in the .eh_frame and 35 .eh_frame_hdr section. The upper 4 bits indicate how the value is to be applied. The lower 4 bits 36 indicate the format of the data. 37 using dw_encode_t = unsigned char; // 4 bits + 4 bits 38 */ 39 40 using dw_encode_t = unsigned char; // 4 bits + 4 bits 41 42 // Table 10-5. DWARF Exception Header value format 43 44 enum DW_EH_PE_VF { 45 DW_EH_PE_absptr = 0x00, // a literal pointer whose size is determined by the architecture. 46 DW_EH_PE_uleb128 = 0x01, // Unsigned value is encoded using the Little Endian Base 128 (LEB128) 47 DW_EH_PE_udata2 = 0x02, // A 2 bytes unsigned value. 48 DW_EH_PE_udata4 = 0x03, // A 4 bytes unsigned value. 49 DW_EH_PE_udata8 = 0x04, // An 8 bytes unsigned value. 50 DW_EH_PE_sleb128 = 0x09, // Signed value is encoded using the Little Endian Base 128(LEB128) 51 DW_EH_PE_sdata2 = 0x0A, // A 2 bytes signed value. 52 DW_EH_PE_sdata4 = 0x0B, // A 4 bytes signed value. 53 DW_EH_PE_sdata8 = 0x0C, // An 8 bytes signed value. 54 }; 55 56 // Table 10-6. DWARF Exception Header application 57 enum DW_EH_PE_A { 58 DW_EH_PE_nothing = 0x00, // nothing to do 59 DW_EH_PE_pcrel = 0x10, // relative to the current program counter. 60 DW_EH_PE_textrel = 0x20, // relative to the beginning of the .text section. 61 DW_EH_PE_datarel = 0x30, // relative to the beginning of the .got or .eh_frame_hdr section. 62 DW_EH_PE_funcrel = 0x40, // relative to the beginning of the function. 63 DW_EH_PE_aligned = 0x50, // aligned to an address unit sized boundary. 64 DW_EH_PE_omit = 0xff, // indicate that no value ispresent. 65 }; 66 67 const std::map<dw_encode_t, size_t> DWFormatSizeMap = { 68 #ifdef ARM 69 {DW_EH_PE_absptr, 4}, 70 #else 71 {DW_EH_PE_absptr, 8}, 72 #endif 73 #ifdef NOT_USE 74 {DW_EH_PE_uleb128, sizeof(char) * 128}, 75 #endif 76 {DW_EH_PE_udata2, sizeof(char) * 2}, 77 {DW_EH_PE_udata4, sizeof(char) * 4}, 78 {DW_EH_PE_udata8, sizeof(char) * 8}, 79 #ifdef NOT_USE 80 {DW_EH_PE_sleb128, sizeof(char) * 128}, 81 #endif 82 {DW_EH_PE_sdata2, sizeof(char) * 2}, 83 {DW_EH_PE_sdata4, sizeof(char) * 4}, 84 {DW_EH_PE_sdata8, sizeof(char) * 8}, 85 }; 86 87 template<class T> dwReadAnyTypeData(const unsigned char * & buffer,T)88 uint64_t dwReadAnyTypeData(const unsigned char *&buffer, T) 89 { 90 T value; 91 if (memcpy_s(&value, sizeof(T), buffer, sizeof(T)) != 0) { 92 return 0; 93 } 94 buffer += sizeof(T); 95 return static_cast<uint64_t>(value); 96 } 97 98 class DwarfEncoding { 99 public: 100 DwarfEncoding(dw_encode_t dw, const unsigned char *&data, uint64_t vaddrBase = 0, 101 uint64_t vaddrPC = 0, uint64_t vaddrText = 0); 102 103 const std::string ToString() const; 104 105 const unsigned char *GetEnd() const; 106 107 const unsigned char *GetData() const; 108 109 size_t GetSize() const; 110 111 uint64_t GetValue() const; 112 113 uint64_t GetAppliedValue() const; 114 115 bool IsOmit() const; 116 117 private: 118 dw_encode_t dw_; 119 const unsigned char *data_; 120 uint64_t vaddrBase_ = 0; 121 uint64_t vaddrPC_ = 0; 122 uint64_t vaddrText_ = 0; 123 uint64_t value_[2] = {0, 0}; 124 125 dw_encode_t Format() const; 126 127 dw_encode_t Application() const; 128 129 uint64_t ReadValue(const unsigned char *&data) const; 130 131 const std::string FormatName() const; 132 133 const std::string ApplicationName() const; 134 }; 135 136 /* 137 Linux Standard Base Core Specification 4.1 138 Chapter 10. Object Format 139 10.6.2. The .eh_frame_hdr section 140 141 Table 10-11. .eh_frame_hdr Section Format 142 143 Encoding Field 144 unsigned byte version 145 unsigned byte eh_frame_ptr_enc 146 unsigned byte fde_count_enc 147 unsigned byte table_enc 148 encoded eh_frame_ptr 149 encoded fde_count 150 binary search table 151 */ 152 153 struct binary_search_table { 154 uint64_t ipVaddrOffset; 155 uint64_t fdeVaddrOffset; 156 }; 157 158 struct eh_frame_hdr { 159 // Version of the .eh_frame_hdr format. This value shall be 1. 160 dw_encode_t version; 161 162 // The encoding format of the eh_frame_ptr field. 163 dw_encode_t eh_frame_ptr_enc; 164 165 // The encoding format of the fde_count field. A value of DW_EH_PE_omit indicates the binary 166 // search table is not present. 167 dw_encode_t fde_count_enc; 168 169 // The encoding format of the entries in the binary search table. A value of DW_EH_PE_omit 170 // indicates the binary search table is not present. 171 dw_encode_t table_enc; 172 173 // The encoded value of the pointer to the start of the .eh_frame section. 174 /* 175 dw_encode_t eh_frame_ptr 176 dw_encode_t fde_count 177 */ 178 // A binary search table containing fde_count entries. Each entry of the table consist of two 179 // encoded values, the initial location, and the address. The entries are sorted in an 180 // increasing order by the initial location value. 181 182 /* 183 * struct { 184 * encoded start_ip 185 * encoded fde_addr 186 * } binary_search_table[fde_count] 187 */ 188 unsigned char encode_data[0]; 189 } PACKED; 190 } // namespace HiPerf 191 } // namespace Developtools 192 } // namespace OHOS 193 #endif // DWARF_ENCODING_H 194