libabigail
abg-elf-helpers.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2// -*- Mode: C++ -*-
3//
4// Copyright (C) 2020-2025 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 <elfutils/libdwelf.h>
17#include <gelf.h>
18#include <string>
19
20#include "abg-ir.h"
21
22namespace abigail
23{
24
25namespace elf_helpers
26{
27
28/// A functor used by @ref dwfl_sptr.
30{
31 void
32 operator()(Dwfl* dwfl)
33 {dwfl_end(dwfl);}
34};//end struct dwfl_deleter
35
36/// A convenience typedef for a shared pointer to a Dwfl.
37typedef shared_ptr<Dwfl> dwfl_sptr;
38
39/// Convenience typedef for a map which key is an elf address and
40/// which value is an elf_symbol_sptr.
41typedef unordered_map<GElf_Addr, elf_symbol_sptr> addr_elf_symbol_sptr_map_type;
42
43/// Convenience typedef for a set of ELF addresses.
44typedef unordered_set<GElf_Addr> address_set_type;
45
46/// Convenience typedef for a shared pointer to an @ref address_set_type.
47typedef shared_ptr<address_set_type> address_set_sptr;
48
49//
50// ELF Value Converters
51//
52
54stt_to_elf_symbol_type(unsigned char stt);
55
57stb_to_elf_symbol_binding(unsigned char stb);
58
60stv_to_elf_symbol_visibility(unsigned char stv);
61
62std::string
63e_machine_to_string(GElf_Half e_machine);
64
65//
66// ELF section helpers
67//
68
69Elf_Scn*
70find_section(Elf* elf_handle,
71 const std::string& name,
72 Elf64_Word section_type);
73
74Elf_Scn*
75find_section_by_name(Elf* elf_handle, const std::string& name);
76
77Elf_Scn*
78find_section(Elf* elf_handle, Elf64_Word section_type);
79
80Elf_Scn*
81find_symtab_section(Elf* elf_handle);
82
83Elf_Scn*
84find_dynsym_section(Elf* elf_handle);
85
86Elf_Scn*
87find_symbol_table_section(Elf* elf_handle);
88
89bool
90find_symbol_table_section_index(Elf* elf_handle, size_t& symtab_index);
91
92enum hash_table_kind
93{
94 NO_HASH_TABLE_KIND = 0,
95 SYSV_HASH_TABLE_KIND,
96 GNU_HASH_TABLE_KIND
97};
98
99hash_table_kind
100find_hash_table_section_index(Elf* elf_handle,
101 size_t& ht_section_index,
102 size_t& symtab_section_index);
103
104Elf_Scn*
105find_text_section(Elf* elf_handle);
106
107Elf_Scn*
108find_bss_section(Elf* elf_handle);
109
110Elf_Scn*
111find_rodata_section(Elf* elf_handle);
112
113Elf_Scn*
114find_data_section(Elf* elf_handle);
115
116Elf_Scn*
117find_data1_section(Elf* elf_handle);
118
119Elf_Scn*
120find_opd_section(Elf* elf_handle);
121
122bool
123get_symbol_versionning_sections(Elf* elf_handle,
124 Elf_Scn*& versym_section,
125 Elf_Scn*& verdef_section,
126 Elf_Scn*& verneed_section);
127
128Elf_Scn*
129find_ksymtab_section(Elf* elf_handle);
130
131Elf_Scn*
132find_ksymtab_gpl_section(Elf* elf_handle);
133
134Elf_Scn*
135find_ksymtab_strings_section(Elf *elf_handle);
136
137Elf_Scn*
138find_relocation_section(Elf* elf_handle, Elf_Scn* target_section);
139
140Elf_Scn*
141find_strtab_for_symtab_section(Elf* elf_handle,
142 Elf_Scn* symtab_section);
143
144//
145// Helpers for symbol versioning
146//
147
148bool
150 GElf_Versym* versym,
151 Elf_Scn* verdef_section,
152 elf_symbol::version& version);
153
154bool
155get_version_needed_for_versym(Elf* elf_handle,
156 GElf_Versym* versym,
157 Elf_Scn* verneed_section,
158 elf_symbol::version& version);
159
160bool
161get_version_for_symbol(Elf* elf_handle,
162 size_t symbol_index,
163 bool get_def_version,
164 elf_symbol::version& version);
165
166bool
167get_crc_for_symbol(Elf* elf_handle, GElf_Sym* crc_symbol, uint32_t& crc_value);
168
169//
170// Architecture specific helpers
171//
172bool
173architecture_is_ppc64(Elf* elf_handle);
174
175bool
176architecture_is_ppc32(Elf* elf_handle);
177
178bool
179architecture_is_arm32(Elf* elf_handle);
180
181bool
182architecture_is_arm64(Elf* elf_handle);
183
184bool
185architecture_is_big_endian(Elf* elf_handle);
186
187GElf_Addr
189 GElf_Addr fn_desc_address);
190
191//
192// Helpers for Linux Kernel Binaries
193//
194
195bool
196is_linux_kernel_module(Elf *elf_handle);
197
198bool
199is_linux_kernel(Elf *elf_handle);
200
201//
202// elfutils helpers
203//
204
205const Dwfl_Callbacks&
206initialize_dwfl_callbacks(Dwfl_Callbacks&, char**);
207
209create_new_dwfl_handle(Dwfl_Callbacks&);
210
211//
212// Misc Helpers
213//
214
215bool
216get_binary_load_address(Elf* elf_handle, GElf_Addr& load_address);
217
218unsigned char
219get_architecture_word_size(Elf* elf_handle);
220
221bool
222is_executable(Elf* elf_handle);
223
224bool
225is_dso(Elf* elf_handle);
226
227GElf_Addr
228maybe_adjust_et_rel_sym_addr_to_abs_addr(Elf* elf_handle, GElf_Sym* sym);
229
230bool
231address_is_in_opd_section(Elf* elf_handle, Dwarf_Addr addr);
232
233bool
235 Elf64_Sxword data_tag,
236 vector<string>& dt_tag_data);
237
238bool
239get_soname_of_elf_file(const string& path, string &soname);
240} // end namespace elf_helpers
241} // end namespace abigail
242
243#endif // __ABG_ELF_HELPERS_H__
Elf_Scn * find_section_by_name(Elf *elf_handle, const std::string &name)
Find and return a section by its name.
bool get_crc_for_symbol(Elf *elf_handle, GElf_Sym *crc_symbol, uint32_t &crc_value)
Return the CRC from the "__crc_" symbol.
unsigned char get_architecture_word_size(Elf *elf_handle)
Return the size of a word for the current architecture.
bool get_version_definition_for_versym(Elf *elf_handle, GElf_Versym *versym, Elf_Scn *verdef_section, elf_symbol::version &version)
Get the version definition (from the SHT_GNU_verdef section) of a given symbol represented by a point...
bool lookup_data_tag_from_dynamic_segment(Elf *elf, Elf64_Sxword data_tag, vector< string > &dt_tag_data)
Get data tag information of an ELF file by looking up into its dynamic segment.
bool address_is_in_opd_section(Elf *elf_handle, Dwarf_Addr addr)
Return true if an address is in the ".opd" section that is present on the ppc64 platform.
bool architecture_is_arm64(Elf *elf_handle)
Test if the architecture of the current binary is arm64.
Elf_Scn * find_relocation_section(Elf *elf_handle, Elf_Scn *target_section)
Return the .rel{a,} section corresponding to a given section.
bool architecture_is_big_endian(Elf *elf_handle)
Test if the endianness of the current binary is Big Endian.
bool is_dso(Elf *elf_handle)
Test if the elf file being read is a dynamic shared / object.
bool architecture_is_ppc32(Elf *elf_handle)
Test if the architecture of the current binary is ppc32.
bool get_binary_load_address(Elf *elf_handle, GElf_Addr &load_address)
Get the address at which a given binary is loaded in memory.
GElf_Addr maybe_adjust_et_rel_sym_addr_to_abs_addr(Elf *elf_handle, GElf_Sym *sym)
Translate a section-relative symbol address (i.e, symbol value) into an absolute symbol address by ad...
bool get_version_needed_for_versym(Elf *elf_handle, GElf_Versym *versym, Elf_Scn *verneed_section, elf_symbol::version &version)
Get the version needed (from the SHT_GNU_verneed section) to resolve an undefined symbol represented ...
Elf_Scn * find_strtab_for_symtab_section(Elf *elf_handle, Elf_Scn *symtab_section)
Return the string table used by the given symbol table.
bool get_soname_of_elf_file(const string &path, string &soname)
Fetch the SONAME ELF property from an ELF binary file.
bool get_version_for_symbol(Elf *elf_handle, size_t symbol_index, bool get_def_version, elf_symbol::version &version)
Return the version for a symbol that is at a given index in its SHT_SYMTAB section.
elf_symbol::binding stb_to_elf_symbol_binding(unsigned char stb)
Convert an elf symbol binding (given by the ELF{32,64}_ST_BIND macros) into an elf_symbol::binding va...
Elf_Scn * find_ksymtab_gpl_section(Elf *elf_handle)
Return the __ksymtab_gpl section of a linux kernel ELF file (either a vmlinux binary or a kernel modu...
Elf_Scn * find_ksymtab_section(Elf *elf_handle)
Return the __ksymtab section of a linux kernel ELF file (either a vmlinux binary or a kernel module).
Elf_Scn * find_symtab_section(Elf *elf_handle)
Find and return the .symtab section.
std::string e_machine_to_string(GElf_Half e_machine)
Convert the value of the e_machine field of GElf_Ehdr into a string. This is to get a string represen...
Elf_Scn * find_text_section(Elf *elf_handle)
Find and return the .text section.
bool architecture_is_ppc64(Elf *elf_handle)
Test if the architecture of the current binary is ppc64.
Elf_Scn * find_rodata_section(Elf *elf_handle)
Find and return the .rodata section.
Elf_Scn * find_opd_section(Elf *elf_handle)
Return the "Official Procedure descriptors section." This section is named .opd, and is usually prese...
bool is_executable(Elf *elf_handle)
Test if the elf file being read is an executable.
Elf_Scn * find_data1_section(Elf *elf_handle)
Find and return the .data1 section.
GElf_Addr lookup_ppc64_elf_fn_entry_point_address(Elf *elf_handle, GElf_Addr fn_desc_address)
Lookup the address of the function entry point that corresponds to the address of a given function de...
elf_symbol::visibility stv_to_elf_symbol_visibility(unsigned char stv)
Convert an ELF symbol visiblity given by the symbols ->st_other data member as returned by the GELF_S...
bool find_symbol_table_section_index(Elf *elf_handle, size_t &symtab_index)
Find the index (in the section headers table) of the symbol table section.
bool get_symbol_versionning_sections(Elf *elf_handle, Elf_Scn *&versym_section, Elf_Scn *&verdef_section, Elf_Scn *&verneed_section)
Return the SHT_GNU_versym, SHT_GNU_verdef and SHT_GNU_verneed sections that are involved in symbol ve...
Elf_Scn * find_bss_section(Elf *elf_handle)
Find and return the .bss section.
Elf_Scn * find_dynsym_section(Elf *elf_handle)
Find and return the .symtab section.
Elf_Scn * find_section(Elf *elf_handle, const std::string &name, Elf64_Word section_type)
Find and return a section by its name and its type.
elf_symbol::type stt_to_elf_symbol_type(unsigned char stt)
Convert an elf symbol type (given by the ELF{32,64}_ST_TYPE macros) into an elf_symbol::type value.
bool architecture_is_arm32(Elf *elf_handle)
Test if the architecture of the current binary is arm32.
Elf_Scn * find_symbol_table_section(Elf *elf_handle)
Find the symbol table.
Elf_Scn * find_data_section(Elf *elf_handle)
Find and return the .data section.
bool is_linux_kernel_module(Elf *elf_handle)
Test if the ELF binary denoted by a given ELF handle is a Linux Kernel Module.
Elf_Scn * find_ksymtab_strings_section(Elf *elf_handle)
Find the __ksymtab_strings section of a Linux kernel binary.
bool is_linux_kernel(Elf *elf_handle)
Test if the ELF binary denoted by a given ELF handle is a Linux Kernel binary (either vmlinux or a ke...
hash_table_kind find_hash_table_section_index(Elf *elf_handle, size_t &ht_section_index, size_t &symtab_section_index)
Get the offset offset of the hash table section.
unordered_map< GElf_Addr, elf_symbol_sptr > addr_elf_symbol_sptr_map_type
Convenience typedef for a map which key is an elf address and which value is an elf_symbol_sptr.
unordered_set< GElf_Addr > address_set_type
Convenience typedef for a set of ELF addresses.
shared_ptr< address_set_type > address_set_sptr
Convenience typedef for a shared pointer to an address_set_type.
shared_ptr< Dwfl > dwfl_sptr
A convenience typedef for a shared pointer to a Dwfl.
Types of the main internal representation of libabigail.
The abstraction of the version of an ELF symbol.
Definition: abg-ir.h:1232
binding
The binding of a symbol.
Definition: abg-ir.h:978
type
The type of a symbol.
Definition: abg-ir.h:965
visibility
The visibility of the symbol.
Definition: abg-ir.h:987
Toplevel namespace for libabigail.
A functor used by dwfl_sptr.