1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 // -*- Mode: C++ -*- 3 // 4 // Copyright (C) 2020-2022 Google, Inc. 5 6 /// @file 7 /// 8 /// This contains a set of ELF utilities used by the dwarf reader. 9 10 #ifndef __ABG_ELF_HELPERS_H__ 11 #define __ABG_ELF_HELPERS_H__ 12 13 #include "config.h" 14 15 #include <elfutils/libdwfl.h> 16 #include <gelf.h> 17 #include <string> 18 19 #include "abg-ir.h" 20 21 namespace abigail 22 { 23 24 namespace elf_helpers 25 { 26 27 /// A functor used by @ref dwfl_sptr. 28 struct dwfl_deleter 29 { 30 void operatordwfl_deleter31 operator()(Dwfl* dwfl) 32 {dwfl_end(dwfl);} 33 };//end struct dwfl_deleter 34 35 /// A convenience typedef for a shared pointer to a Dwfl. 36 typedef shared_ptr<Dwfl> dwfl_sptr; 37 38 /// Convenience typedef for a map which key is an elf address and 39 /// which value is an elf_symbol_sptr. 40 typedef unordered_map<GElf_Addr, elf_symbol_sptr> addr_elf_symbol_sptr_map_type; 41 42 /// Convenience typedef for a set of ELF addresses. 43 typedef unordered_set<GElf_Addr> address_set_type; 44 45 /// Convenience typedef for a shared pointer to an @ref address_set_type. 46 typedef shared_ptr<address_set_type> address_set_sptr; 47 48 // 49 // ELF Value Converters 50 // 51 52 elf_symbol::type 53 stt_to_elf_symbol_type(unsigned char stt); 54 55 elf_symbol::binding 56 stb_to_elf_symbol_binding(unsigned char stb); 57 58 elf_symbol::visibility 59 stv_to_elf_symbol_visibility(unsigned char stv); 60 61 std::string 62 e_machine_to_string(GElf_Half e_machine); 63 64 // 65 // ELF section helpers 66 // 67 68 Elf_Scn* 69 find_section(Elf* elf_handle, 70 const std::string& name, 71 Elf64_Word section_type); 72 73 Elf_Scn* 74 find_section_by_name(Elf* elf_handle, const std::string& name); 75 76 Elf_Scn* 77 find_section(Elf* elf_handle, Elf64_Word section_type); 78 79 Elf_Scn* 80 find_symtab_section(Elf* elf_handle); 81 82 Elf_Scn* 83 find_dynsym_section(Elf* elf_handle); 84 85 Elf_Scn* 86 find_symbol_table_section(Elf* elf_handle); 87 88 bool 89 find_symbol_table_section_index(Elf* elf_handle, size_t& symtab_index); 90 91 enum hash_table_kind 92 { 93 NO_HASH_TABLE_KIND = 0, 94 SYSV_HASH_TABLE_KIND, 95 GNU_HASH_TABLE_KIND 96 }; 97 98 hash_table_kind 99 find_hash_table_section_index(Elf* elf_handle, 100 size_t& ht_section_index, 101 size_t& symtab_section_index); 102 103 Elf_Scn* 104 find_text_section(Elf* elf_handle); 105 106 Elf_Scn* 107 find_bss_section(Elf* elf_handle); 108 109 Elf_Scn* 110 find_rodata_section(Elf* elf_handle); 111 112 Elf_Scn* 113 find_data_section(Elf* elf_handle); 114 115 Elf_Scn* 116 find_data1_section(Elf* elf_handle); 117 118 Elf_Scn* 119 find_opd_section(Elf* elf_handle); 120 121 bool 122 get_symbol_versionning_sections(Elf* elf_handle, 123 Elf_Scn*& versym_section, 124 Elf_Scn*& verdef_section, 125 Elf_Scn*& verneed_section); 126 127 Elf_Scn* 128 find_ksymtab_section(Elf* elf_handle); 129 130 Elf_Scn* 131 find_ksymtab_gpl_section(Elf* elf_handle); 132 133 Elf_Scn* 134 find_ksymtab_strings_section(Elf *elf_handle); 135 136 Elf_Scn* 137 find_relocation_section(Elf* elf_handle, Elf_Scn* target_section); 138 139 Elf_Scn* 140 find_strtab_for_symtab_section(Elf* elf_handle, 141 Elf_Scn* symtab_section); 142 143 // 144 // Helpers for symbol versioning 145 // 146 147 bool 148 get_version_definition_for_versym(Elf* elf_handle, 149 GElf_Versym* versym, 150 Elf_Scn* verdef_section, 151 elf_symbol::version& version); 152 153 bool 154 get_version_needed_for_versym(Elf* elf_handle, 155 GElf_Versym* versym, 156 Elf_Scn* verneed_section, 157 elf_symbol::version& version); 158 159 bool 160 get_version_for_symbol(Elf* elf_handle, 161 size_t symbol_index, 162 bool get_def_version, 163 elf_symbol::version& version); 164 165 bool 166 get_crc_for_symbol(Elf* elf_handle, GElf_Sym* crc_symbol, uint32_t& crc_value); 167 168 // 169 // Architecture specific helpers 170 // 171 bool 172 architecture_is_ppc64(Elf* elf_handle); 173 174 bool 175 architecture_is_ppc32(Elf* elf_handle); 176 177 bool 178 architecture_is_arm32(Elf* elf_handle); 179 180 bool 181 architecture_is_arm64(Elf* elf_handle); 182 183 bool 184 architecture_is_big_endian(Elf* elf_handle); 185 186 GElf_Addr 187 lookup_ppc64_elf_fn_entry_point_address(Elf* elf_handle, 188 GElf_Addr fn_desc_address); 189 190 // 191 // Helpers for Linux Kernel Binaries 192 // 193 194 bool 195 is_linux_kernel_module(Elf *elf_handle); 196 197 bool 198 is_linux_kernel(Elf *elf_handle); 199 200 // 201 // elfutils helpers 202 // 203 204 const Dwfl_Callbacks& 205 initialize_dwfl_callbacks(Dwfl_Callbacks&, char**); 206 207 dwfl_sptr 208 create_new_dwfl_handle(Dwfl_Callbacks&); 209 210 // 211 // Misc Helpers 212 // 213 214 bool 215 get_binary_load_address(Elf* elf_handle, GElf_Addr& load_address); 216 217 unsigned char 218 get_architecture_word_size(Elf* elf_handle); 219 220 bool 221 is_executable(Elf* elf_handle); 222 223 bool 224 is_dso(Elf* elf_handle); 225 226 GElf_Addr 227 maybe_adjust_et_rel_sym_addr_to_abs_addr(Elf* elf_handle, GElf_Sym* sym); 228 229 bool 230 address_is_in_opd_section(Elf* elf_handle, Dwarf_Addr addr); 231 232 bool 233 lookup_data_tag_from_dynamic_segment(Elf* elf, 234 Elf64_Sxword data_tag, 235 vector<string>& dt_tag_data); 236 237 bool 238 get_soname_of_elf_file(const string& path, string &soname); 239 } // end namespace elf_helpers 240 } // end namespace abigail 241 242 #endif // __ABG_ELF_HELPERS_H__ 243