Skip to content

Commit

Permalink
Add ElfFile helper for iterating over section entries
Browse files Browse the repository at this point in the history
Summary:
Many ELF sections contain arrays of fixed-size elements. Add a helper function for iterating over these types of sections similar to `ElfFile::iterateSymbols` but which will work for other types.

```
  /**
   * Iterate over entries within a given section.
   *
   * Returns a pointer to the current ("found") entry when fn returned
   * true, or nullptr if fn returned false for all entries.
   */
  template <typename E>
  const E* iterateSectionEntries(
      const ElfShdr& section, std::function<bool(const E&)> fn) const
      noexcept(is_nothrow_invocable_v<E const&>);
```

Update `ElfFile::iterateSymbols()` to call the new method.

Reviewed By: jordalgo

Differential Revision: D38810522

fbshipit-source-id: bf028001f153bdb867c4d8383e486c7c9e18ed95
  • Loading branch information
nslingerland authored and facebook-github-bot committed Aug 20, 2022
1 parent 1bdf5f3 commit a64dbed
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
28 changes: 17 additions & 11 deletions folly/experimental/symbolizer/Elf-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,27 +92,33 @@ const char* ElfFile::iterateStrings(const ElfShdr& stringTable, Fn fn) const
return ptr != end ? ptr : nullptr;
}

template <class Fn>
const ElfSym* ElfFile::iterateSymbols(const ElfShdr& section, Fn fn) const
noexcept(is_nothrow_invocable_v<Fn, ElfSym const&>) {
template <typename E>
const E* ElfFile::iterateSectionEntries(
const ElfShdr& section, std::function<bool(const E&)> fn) const
noexcept(is_nothrow_invocable_v<E const&>) {
FOLLY_SAFE_CHECK(
section.sh_entsize == sizeof(ElfSym),
"invalid entry size in symbol table");
section.sh_entsize == sizeof(E), "invalid entry size in table");

const ElfSym* sym = &at<ElfSym>(section.sh_offset);
const ElfSym* end = sym + (section.sh_size / section.sh_entsize);
const E* ent = &at<E>(section.sh_offset);
const E* end = ent + (section.sh_size / section.sh_entsize);

while (sym < end) {
if (fn(*sym)) {
return sym;
while (ent < end) {
if (fn(*ent)) {
return ent;
}

++sym;
++ent;
}

return nullptr;
}

template <class Fn>
const ElfSym* ElfFile::iterateSymbols(const ElfShdr& section, Fn fn) const
noexcept(is_nothrow_invocable_v<Fn, ElfSym const&>) {
return iterateSectionEntries<ElfSym>(section, fn);
}

template <class Fn>
const ElfSym* ElfFile::iterateSymbolsWithType(
const ElfShdr& section, uint32_t type, Fn fn) const
Expand Down
15 changes: 14 additions & 1 deletion folly/experimental/symbolizer/Elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ using ElfOff = FOLLY_ELF_ELFW(Off);
using ElfPhdr = FOLLY_ELF_ELFW(Phdr);
using ElfShdr = FOLLY_ELF_ELFW(Shdr);
using ElfSym = FOLLY_ELF_ELFW(Sym);
using ElfRel = FOLLY_ELF_ELFW(Rel);
using ElfRela = FOLLY_ELF_ELFW(Rela);

// ElfFileId is supposed to uniquely identify any instance of an ELF binary.
// It does that by using file's inode, dev ID, size and modification time:
Expand Down Expand Up @@ -194,7 +196,7 @@ class ElfFile {
noexcept(is_nothrow_invocable_v<Fn, ElfShdr const&>);

/**
* Iterate over all symbols witin a given section.
* Iterate over all symbols within a given section.
*
* Returns a pointer to the current ("found") symbol when fn returned true,
* or nullptr if fn returned false for all symbols.
Expand All @@ -212,6 +214,17 @@ class ElfFile {
std::initializer_list<uint32_t> types,
Fn fn) const noexcept(is_nothrow_invocable_v<Fn, ElfSym const&>);

/**
* Iterate over entries within a given section.
*
* Returns a pointer to the current ("found") entry when fn returned
* true, or nullptr if fn returned false for all entries.
*/
template <typename E>
const E* iterateSectionEntries(
const ElfShdr& section, std::function<bool(const E&)> fn) const
noexcept(is_nothrow_invocable_v<E const&>);

/**
* Find symbol definition by address.
* Note that this is the file virtual address, so you need to undo
Expand Down

0 comments on commit a64dbed

Please sign in to comment.