From: Matthias Maennich <maennich@google.com>
To: libabigail@sourceware.org
Cc: dodji@seketeli.org, gprocida@google.com, kernel-team@android.com,
maennich@google.com
Subject: [PATCH 6/8] abg-dwarf-reader: migrate more ELF helpers to elf-helpers
Date: Mon, 20 Apr 2020 13:08:44 +0200 [thread overview]
Message-ID: <20200420110846.218792-7-maennich@google.com> (raw)
In-Reply-To: <20200420110846.218792-1-maennich@google.com>
This change migrates all ELF helpers related to section lookup to
abg-elf-helpers.{cc,h}. It also homogenizes the interface of those to
always return Elf_Scn* and NULL in case that section can't be found.
Though this smells like a functional change, this latter change is
purely cosmetic.
* src/abg-dwarf-reader.cc (read_context::find_symbol_table_section):
adjust to new interface of elf_helpers::find_symbol_table_section.
(find_opd_section): use elf_helpers::find_opd_section for lookup.
(find_ksymtab_section): use elf_helpers::find_ksymtab_section.
(find_ksymtab_gpl_section): use elf_helpers::find_ksymtab_gpl_section.
(find_relocation_section): Move out function.
(get_binary_load_address): Move out function.
(find_ksymtab_reloc_section): use elf_helpers::find_relocation_section
(find_ksymtab_gpl_reloc_section): use elf_helpers::find_relocation_section
* src/elf-helpers.cc (find_symbol_table_section): change
interface to match other find_*_section functions.
(find_symbol_table_section_index): Adjust for the new interface
of find_symbol_table_section.
(find_opd_section): New function.
(find_ksymtab_section): New function.
(find_ksymtab_gpl_section): New function.
(find_relocation_section): New function.
(get_binary_load_address): New function.
* src/elf-helpers.h (find_symbol_table_section): Change declaration.
(find_opd_section): New function declation.
(find_ksymtab_section): New function declation.
(find_ksymtab_gpl_section): New function declation.
(find_relocation_section): New function declation.
(get_binary_load_address): New function declation.
Signed-off-by: Matthias Maennich <maennich@google.com>
---
src/abg-dwarf-reader.cc | 112 ++++++----------------------------
src/abg-elf-helpers.cc | 129 +++++++++++++++++++++++++++++++++++++---
src/abg-elf-helpers.h | 22 ++++++-
3 files changed, 157 insertions(+), 106 deletions(-)
diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
index ec1f9f3fe8f3..56da03a60940 100644
--- a/src/abg-dwarf-reader.cc
+++ b/src/abg-dwarf-reader.cc
@@ -542,53 +542,6 @@ compare_dies(const read_context& ctxt,
bool update_canonical_dies_on_the_fly);
-/// Get the address at which a given binary is loaded in memory⋅
-///
-/// @param elf_handle the elf handle for the binary to consider.
-///
-/// @param load_address the address where the binary is loaded. This
-/// is set by the function iff it returns true.
-///
-/// @return true if the function could get the binary load address
-/// and assign @p load_address to it.
-static bool
-get_binary_load_address(Elf *elf_handle,
- GElf_Addr &load_address)
-{
- GElf_Ehdr eh_mem;
- GElf_Ehdr *elf_header = gelf_getehdr(elf_handle, &eh_mem);
- size_t num_segments = elf_header->e_phnum;
- GElf_Phdr *program_header = 0;
- GElf_Addr result;
- bool found_loaded_segment = false;
- GElf_Phdr ph_mem;
-
- for (unsigned i = 0; i < num_segments; ++i)
- {
- program_header = gelf_getphdr(elf_handle, i, &ph_mem);
- if (program_header && program_header->p_type == PT_LOAD)
- {
- if (!found_loaded_segment)
- {
- result = program_header->p_vaddr;
- found_loaded_segment = true;
- }
-
- if (program_header->p_vaddr < result)
- // The resulting load address we want is the lowest
- // load address of all the loaded segments.
- result = program_header->p_vaddr;
- }
- }
-
- if (found_loaded_segment)
- {
- load_address = result;
- return true;
- }
- return false;
-}
-
/// Find the file name of the alternate debug info file.
///
/// @param elf_module the elf module to consider.
@@ -5282,8 +5235,8 @@ public:
find_symbol_table_section() const
{
if (!symtab_section_)
- dwarf_reader::find_symbol_table_section(elf_handle(),
- const_cast<read_context*>(this)->symtab_section_);
+ const_cast<read_context*>(this)->symtab_section_ =
+ elf_helpers::find_symbol_table_section(elf_handle());
return symtab_section_;
}
@@ -5296,8 +5249,8 @@ public:
find_opd_section() const
{
if (!opd_section_)
- const_cast<read_context*>(this)->opd_section_=
- find_section(elf_handle(), ".opd", SHT_PROGBITS);
+ const_cast<read_context*>(this)->opd_section_ =
+ elf_helpers::find_opd_section(elf_handle());
return opd_section_;
}
@@ -5310,39 +5263,21 @@ public:
{
if (!ksymtab_section_)
const_cast<read_context*>(this)->ksymtab_section_ =
- find_section(elf_handle(), "__ksymtab", SHT_PROGBITS);
+ elf_helpers::find_ksymtab_section(elf_handle());
return ksymtab_section_;
}
- /// Return the .rel{a,} section corresponding to a given section.
- ///
- /// @param target_section the section to search the relocation section for
+ /// Return the __ksymtab_gpl section of a linux kernel ELF file
+ /// (either a vmlinux binary or a kernel module).
///
- /// @return the .rel{a,} section if found, null otherwise.
+ /// @return the __ksymtab_gpl section if found, nil otherwise.
Elf_Scn*
- find_relocation_section(Elf_Scn* target_section) const
+ find_ksymtab_gpl_section() const
{
- if (target_section)
- {
- // the relo section we are searching for has this index as sh_info
- size_t target_index = elf_ndxscn(target_section);
-
- // now iterate over all the sections, look for relocation sections and
- // find the one that points to the section we are searching for
- Elf_Scn* section = 0;
- GElf_Shdr header_mem, *header;
- while ((section = elf_nextscn(elf_handle(), section)) != 0)
- {
- header = gelf_getshdr(section, &header_mem);
- if (header == NULL
- || (header->sh_type != SHT_RELA && header->sh_type != SHT_REL))
- continue;
-
- if (header->sh_info == target_index)
- return section;
- }
- }
- return NULL;
+ if (!ksymtab_gpl_section_)
+ const_cast<read_context*>(this)->ksymtab_gpl_section_ =
+ elf_helpers::find_ksymtab_gpl_section(elf_handle());
+ return ksymtab_gpl_section_;
}
/// Return the .rel{a,}__ksymtab section of a linux kernel ELF file (either
@@ -5354,25 +5289,12 @@ public:
{
if (!ksymtab_reloc_section_)
{
- const_cast<read_context*>(this)->ksymtab_reloc_section_
- = find_relocation_section(find_ksymtab_section());
+ const_cast<read_context*>(this)->ksymtab_reloc_section_ =
+ find_relocation_section(elf_handle(), find_ksymtab_section());
}
return ksymtab_reloc_section_;
}
- /// Return the __ksymtab_gpl section of a linux kernel ELF file
- /// (either a vmlinux binary or a kernel module).
- ///
- /// @return the __ksymtab_gpl section if found, nil otherwise.
- Elf_Scn*
- find_ksymtab_gpl_section() const
- {
- if (!ksymtab_gpl_section_)
- const_cast<read_context*>(this)->ksymtab_gpl_section_ =
- find_section(elf_handle(), "__ksymtab_gpl", SHT_PROGBITS);
- return ksymtab_gpl_section_;
- }
-
/// Return the .rel{a,}__ksymtab_gpl section of a linux kernel ELF file
/// (either a vmlinux binary or a kernel module).
///
@@ -5382,8 +5304,8 @@ public:
{
if (!ksymtab_gpl_reloc_section_)
{
- const_cast<read_context*>(this)->ksymtab_gpl_reloc_section_
- = find_relocation_section(find_ksymtab_gpl_section());
+ const_cast<read_context*>(this)->ksymtab_gpl_reloc_section_ =
+ find_relocation_section(elf_handle(), find_ksymtab_gpl_section());
}
return ksymtab_gpl_reloc_section_;
}
diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc
index ede191014369..b77440206fb0 100644
--- a/src/abg-elf-helpers.cc
+++ b/src/abg-elf-helpers.cc
@@ -357,9 +357,9 @@ find_section(Elf* elf_handle, const std::string& name, Elf64_Word section_type)
///
/// @param symtab the symbol table found.
///
-/// @return true iff the symbol table is found.
-bool
-find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab)
+/// @return the symbol table section
+Elf_Scn*
+find_symbol_table_section(Elf* elf_handle)
{
Elf_Scn* section = 0, *dynsym = 0, *sym_tab = 0;
while ((section = elf_nextscn(elf_handle, section)) != 0)
@@ -378,12 +378,11 @@ find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab)
GElf_Ehdr* elf_header = gelf_getehdr(elf_handle, &eh_mem);
if (elf_header->e_type == ET_REL
|| elf_header->e_type == ET_EXEC)
- symtab = sym_tab ? sym_tab : dynsym;
+ return sym_tab ? sym_tab : dynsym;
else
- symtab = dynsym ? dynsym : sym_tab;
- return true;
+ return dynsym ? dynsym : sym_tab;
}
- return false;
+ return NULL;
}
/// Find the index (in the section headers table) of the symbol table
@@ -402,8 +401,9 @@ find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab)
bool
find_symbol_table_section_index(Elf* elf_handle, size_t& symtab_index)
{
- Elf_Scn* section = 0;
- if (!find_symbol_table_section(elf_handle, section))
+ Elf_Scn* section = find_symbol_table_section(elf_handle);
+
+ if (!section)
return false;
symtab_index = elf_ndxscn(section);
@@ -500,6 +500,17 @@ Elf_Scn*
find_data1_section(Elf* elf_handle)
{return find_section(elf_handle, ".data1", SHT_PROGBITS);}
+/// Return the "Official Procedure descriptors section." This
+/// section is named .opd, and is usually present only on PPC64
+/// ELFv1 binaries.
+///
+/// @param elf_handle the elf handle to consider.
+///
+/// @return the .opd section, if found. Return nil otherwise.
+Elf_Scn*
+find_opd_section(Elf* elf_handle)
+{return find_section(elf_handle, ".opd", SHT_PROGBITS);}
+
/// Return the SHT_GNU_versym, SHT_GNU_verdef and SHT_GNU_verneed
/// sections that are involved in symbol versionning.
///
@@ -548,6 +559,26 @@ get_symbol_versionning_sections(Elf* elf_handle,
return false;
}
+/// Return the __ksymtab section of a linux kernel ELF file (either
+/// a vmlinux binary or a kernel module).
+///
+/// @param elf_handle the elf handle to consider.
+///
+/// @return the __ksymtab section if found, nil otherwise.
+Elf_Scn*
+find_ksymtab_section(Elf* elf_handle)
+{return find_section(elf_handle, "__ksymtab", SHT_PROGBITS);}
+
+/// Return the __ksymtab_gpl section of a linux kernel ELF file (either
+/// a vmlinux binary or a kernel module).
+///
+/// @param elf_handle the elf handle to consider.
+///
+/// @return the __ksymtab section if found, nil otherwise.
+Elf_Scn*
+find_ksymtab_gpl_section(Elf* elf_handle)
+{return find_section(elf_handle, "__ksymtab_gpl", SHT_PROGBITS);}
+
/// Find the __ksymtab_strings section of a Linux kernel binary.
///
/// @param elf_handle the elf handle to use.
@@ -563,6 +594,39 @@ find_ksymtab_strings_section(Elf *elf_handle)
return 0;
}
+/// Return the .rel{a,} section corresponding to a given section.
+///
+/// @param elf_handle the elf handle to consider.
+///
+/// @param target_section the section to search the relocation section for
+///
+/// @return the .rel{a,} section if found, null otherwise.
+Elf_Scn*
+find_relocation_section(Elf* elf_handle, Elf_Scn* target_section)
+{
+ if (target_section)
+ {
+ // the relo section we are searching for has this index as sh_info
+ size_t target_index = elf_ndxscn(target_section);
+
+ // now iterate over all the sections, look for relocation sections and
+ // find the one that points to the section we are searching for
+ Elf_Scn* section = 0;
+ GElf_Shdr header_mem, *header;
+ while ((section = elf_nextscn(elf_handle, section)) != 0)
+ {
+ header = gelf_getshdr(section, &header_mem);
+ if (header == NULL
+ || (header->sh_type != SHT_RELA && header->sh_type != SHT_REL))
+ continue;
+
+ if (header->sh_info == target_index)
+ return section;
+ }
+ }
+ return NULL;
+}
+
/// Get the version definition (from the SHT_GNU_verdef section) of a
/// given symbol represented by a pointer to GElf_Versym.
///
@@ -797,5 +861,52 @@ is_linux_kernel(Elf *elf_handle)
|| is_linux_kernel_module(elf_handle));
}
+/// Get the address at which a given binary is loaded in memory⋅
+///
+/// @param elf_handle the elf handle for the binary to consider.
+///
+/// @param load_address the address where the binary is loaded. This
+/// is set by the function iff it returns true.
+///
+/// @return true if the function could get the binary load address
+/// and assign @p load_address to it.
+bool
+get_binary_load_address(Elf* elf_handle, GElf_Addr& load_address)
+{
+ GElf_Ehdr elf_header;
+ gelf_getehdr(elf_handle, &elf_header);
+ size_t num_segments = elf_header.e_phnum;
+ GElf_Phdr *program_header = NULL;
+ GElf_Addr result;
+ bool found_loaded_segment = false;
+ GElf_Phdr ph_mem;
+
+ for (unsigned i = 0; i < num_segments; ++i)
+ {
+ program_header = gelf_getphdr(elf_handle, i, &ph_mem);
+ if (program_header && program_header->p_type == PT_LOAD)
+ {
+ if (!found_loaded_segment)
+ {
+ result = program_header->p_vaddr;
+ found_loaded_segment = true;
+ }
+
+ if (program_header->p_vaddr < result)
+ // The resulting load address we want is the lowest
+ // load address of all the loaded segments.
+ result = program_header->p_vaddr;
+ }
+ }
+
+ if (found_loaded_segment)
+ {
+ load_address = result;
+ return true;
+ }
+ return false;
+}
+
+
} // end namespace elf_helpers
} // end namespace abigail
diff --git a/src/abg-elf-helpers.h b/src/abg-elf-helpers.h
index 7ddd887de959..8a83bb4f2e95 100644
--- a/src/abg-elf-helpers.h
+++ b/src/abg-elf-helpers.h
@@ -63,8 +63,8 @@ find_section(Elf* elf_handle,
const std::string& name,
Elf64_Word section_type);
-bool
-find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab);
+Elf_Scn*
+find_symbol_table_section(Elf* elf_handle);
bool
find_symbol_table_section_index(Elf* elf_handle, size_t& symtab_index);
@@ -96,15 +96,27 @@ find_data_section(Elf* elf_handle);
Elf_Scn*
find_data1_section(Elf* elf_handle);
+Elf_Scn*
+find_opd_section(Elf* elf_handle);
+
bool
get_symbol_versionning_sections(Elf* elf_handle,
Elf_Scn*& versym_section,
Elf_Scn*& verdef_section,
Elf_Scn*& verneed_section);
+Elf_Scn*
+find_ksymtab_section(Elf* elf_handle);
+
+Elf_Scn*
+find_ksymtab_gpl_section(Elf* elf_handle);
+
Elf_Scn*
find_ksymtab_strings_section(Elf *elf_handle);
+Elf_Scn*
+find_relocation_section(Elf* elf_handle, Elf_Scn* target_section);
+
//
// Helpers for symbol versioning
//
@@ -137,6 +149,12 @@ is_linux_kernel_module(Elf *elf_handle);
bool
is_linux_kernel(Elf *elf_handle);
+//
+// Misc Helpers
+//
+
+bool
+get_binary_load_address(Elf* elf_handle, GElf_Addr& load_address);
} // end namespace elf_helpers
} // end namespace abigail
--
2.26.1.301.g55bc3eb7cb9-goog
next prev parent reply other threads:[~2020-04-20 11:09 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-20 11:08 [PATCH 0/8] Refactor dwarf-reader: split out ELF helpers Matthias Maennich
2020-04-20 11:08 ` [PATCH 1/8] abg-dwarf-reader split: create abg-elf-helpers.{h, cc} and test case Matthias Maennich
2020-04-20 15:35 ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 2/8] abg-elf-helpers: move some elf helpers from abg-dwarf-reader Matthias Maennich
2020-04-20 15:34 ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 3/8] abg-elf-helpers: move some versioning " Matthias Maennich
2020-04-20 15:33 ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 4/8] abg-elf-helpers: move some kernel " Matthias Maennich
2020-04-20 14:32 ` Giuliano Procida
2020-04-20 15:30 ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 5/8] abg-elf-helpers: consolidate the is_linux_kernel* helpers Matthias Maennich
2020-04-20 15:29 ` Giuliano Procida
2020-04-20 11:08 ` Matthias Maennich [this message]
2020-04-20 15:24 ` [PATCH 6/8] abg-dwarf-reader: migrate more ELF helpers to elf-helpers Giuliano Procida
2020-04-21 6:14 ` Matthias Maennich
2020-04-21 11:02 ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 7/8] abg-elf-helpers: migrate more elf helpers (architecture specific helpers) Matthias Maennich
2020-04-20 15:25 ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 8/8] abg-elf-helpers: migrate maybe_adjust_et_rel_sym_addr_to_abs_addr Matthias Maennich
2020-04-21 6:35 ` [PATCH v2 0/8] Refactor dwarf-reader: split out ELF helpers Matthias Maennich
2020-04-21 6:35 ` [PATCH v2 1/8] abg-dwarf-reader split: create abg-elf-helpers.{h, cc} and test case Matthias Maennich
2020-04-22 9:42 ` Dodji Seketeli
2020-04-21 6:35 ` [PATCH v2 2/8] abg-elf-helpers: move some elf helpers from abg-dwarf-reader Matthias Maennich
2020-04-22 9:44 ` Dodji Seketeli
2020-04-21 6:35 ` [PATCH v2 3/8] abg-elf-helpers: move some versioning " Matthias Maennich
2020-04-22 9:46 ` Dodji Seketeli
2020-04-21 6:35 ` [PATCH v2 4/8] abg-elf-helpers: move some kernel " Matthias Maennich
2020-04-22 9:47 ` Dodji Seketeli
2020-04-21 6:35 ` [PATCH v2 5/8] abg-elf-helpers: consolidate the is_linux_kernel* helpers Matthias Maennich
2020-04-22 9:48 ` Dodji Seketeli
2020-04-21 6:35 ` [PATCH v2 6/8] abg-dwarf-reader: migrate more ELF helpers to elf-helpers Matthias Maennich
2020-04-22 9:53 ` Dodji Seketeli
2020-04-21 6:35 ` [PATCH v2 7/8] abg-elf-helpers: migrate more elf helpers (architecture specific helpers) Matthias Maennich
2020-04-22 9:55 ` Dodji Seketeli
2020-04-21 6:35 ` [PATCH v2 8/8] abg-elf-helpers: migrate maybe_adjust_et_rel_sym_addr_to_abs_addr Matthias Maennich
2020-04-22 9:56 ` Dodji Seketeli
2020-04-22 9:57 ` [PATCH v2 0/8] Refactor dwarf-reader: split out ELF helpers Dodji Seketeli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200420110846.218792-7-maennich@google.com \
--to=maennich@google.com \
--cc=dodji@seketeli.org \
--cc=gprocida@google.com \
--cc=kernel-team@android.com \
--cc=libabigail@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).