Commit fbc0b24a authored by Mirek Klimos's avatar Mirek Klimos Committed by Facebook Github Bot

folly::ElfFile - add support to iterate over program headers

Summary: Adding iterateProgramHeaders, similar to iterateSections, just iterates over program headers instead of section headers. I want this to get the size of the first PT_LOAD header.

Differential Revision: D5602575

fbshipit-source-id: f73989cade20214f884571c1099761ecaa4841f7
parent 520148aa
...@@ -21,6 +21,18 @@ ...@@ -21,6 +21,18 @@
namespace folly { namespace folly {
namespace symbolizer { namespace symbolizer {
template <class Fn>
const ElfPhdr* ElfFile::iterateProgramHeaders(Fn fn) const {
const ElfPhdr* ptr = &at<ElfPhdr>(elfHeader().e_phoff);
for (size_t i = 0; i < elfHeader().e_phnum; i++, ptr++) {
if (fn(*ptr)) {
return ptr;
}
}
return nullptr;
}
template <class Fn> template <class Fn>
const ElfShdr* ElfFile::iterateSections(Fn fn) const { const ElfShdr* ElfFile::iterateSections(Fn fn) const {
const ElfShdr* ptr = &at<ElfShdr>(elfHeader().e_shoff); const ElfShdr* ptr = &at<ElfShdr>(elfHeader().e_shoff);
......
...@@ -263,24 +263,18 @@ bool ElfFile::init(const char** msg) { ...@@ -263,24 +263,18 @@ bool ElfFile::init(const char** msg) {
} }
} }
const ElfPhdr* programHeader = &at<ElfPhdr>(elfHeader.e_phoff);
bool foundBase = false;
for (size_t i = 0; i < elfHeader.e_phnum; programHeader++, i++) {
// Program headers are sorted by load address, so the first PT_LOAD // Program headers are sorted by load address, so the first PT_LOAD
// header gives us the base address. // header gives us the base address.
if (programHeader->p_type == PT_LOAD) { const ElfPhdr* programHeader =
baseAddress_ = programHeader->p_vaddr; iterateProgramHeaders([](auto& h) { return h.p_type == PT_LOAD; });
foundBase = true;
break;
}
}
if (!foundBase) { if (!programHeader) {
if (msg) { if (msg) {
*msg = "could not find base address"; *msg = "could not find base address";
} }
return false; return false;
} }
baseAddress_ = programHeader->p_vaddr;
return true; return true;
} }
......
...@@ -122,6 +122,14 @@ class ElfFile { ...@@ -122,6 +122,14 @@ class ElfFile {
template <class Fn> template <class Fn>
const char* iterateStrings(const ElfShdr& stringTable, Fn fn) const; const char* iterateStrings(const ElfShdr& stringTable, Fn fn) const;
/**
* Iterate over program headers as long as fn(section) returns false.
* Returns a pointer to the current ("found") section when fn returned
* true, or nullptr if fn returned false for all sections.
*/
template <class Fn>
const ElfPhdr* iterateProgramHeaders(Fn fn) const;
/** /**
* Iterate over all sections for as long as fn(section) returns false. * Iterate over all sections for as long as fn(section) returns false.
* Returns a pointer to the current ("found") section when fn returned * Returns a pointer to the current ("found") section when fn returned
......
...@@ -52,6 +52,13 @@ TEST_F(ElfTest, PointerValue) { ...@@ -52,6 +52,13 @@ TEST_F(ElfTest, PointerValue) {
EXPECT_STREQ(kStringValue, str); EXPECT_STREQ(kStringValue, str);
} }
TEST_F(ElfTest, iterateProgramHeaders) {
auto phdr = elfFile_.iterateProgramHeaders(
[](auto& h) { return h.p_type == PT_LOAD; });
EXPECT_NE(nullptr, phdr);
EXPECT_GE(phdr->p_filesz, 0);
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment