/*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-
#ifndef FOLLY_EXPERIMENTAL_SYMBOLIZER_ELF_H_
-# error This file must be included from Elf.h
+#error This file must be included from Elf.h
#endif
namespace folly {
namespace symbolizer {
template <class Fn>
-const ElfW(Shdr)* ElfFile::iterateSections(Fn fn) const {
- const ElfW(Shdr)* ptr = &at<ElfW(Shdr)>(elfHeader().e_shoff);
+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>
+const ElfShdr* ElfFile::iterateSections(Fn fn) const {
+ const ElfShdr* ptr = &at<ElfShdr>(elfHeader().e_shoff);
for (size_t i = 0; i < elfHeader().e_shnum; i++, ptr++) {
if (fn(*ptr)) {
return ptr;
}
template <class Fn>
-const ElfW(Shdr)* ElfFile::iterateSectionsWithType(uint32_t type, Fn fn)
- const {
+const ElfShdr* ElfFile::iterateSectionsWithType(uint32_t type, Fn fn) const {
return iterateSections(
- [&](const ElfW(Shdr)& sh) {
- return sh.sh_type == type && fn(sh);
- });
+ [&](const ElfShdr& sh) { return sh.sh_type == type && fn(sh); });
}
template <class Fn>
-const char* ElfFile::iterateStrings(const ElfW(Shdr)& stringTable, Fn fn)
- const {
+const char* ElfFile::iterateStrings(const ElfShdr& stringTable, Fn fn) const {
validateStringTable(stringTable);
const char* start = file_ + stringTable.sh_offset;
}
template <class Fn>
-const ElfW(Sym)* ElfFile::iterateSymbols(const ElfW(Shdr)& section, Fn fn)
- const {
- FOLLY_SAFE_CHECK(section.sh_entsize == sizeof(ElfW(Sym)),
- "invalid entry size in symbol table");
+const ElfSym* ElfFile::iterateSymbols(const ElfShdr& section, Fn fn) const {
+ FOLLY_SAFE_CHECK(
+ section.sh_entsize == sizeof(ElfSym),
+ "invalid entry size in symbol table");
- const ElfW(Sym)* sym = &at<ElfW(Sym)>(section.sh_offset);
- const ElfW(Sym)* end = sym + (section.sh_size / section.sh_entsize);
+ const ElfSym* sym = &at<ElfSym>(section.sh_offset);
+ const ElfSym* end = sym + (section.sh_size / section.sh_entsize);
while (sym < end) {
if (fn(*sym)) {
}
template <class Fn>
-const ElfW(Sym)* ElfFile::iterateSymbolsWithType(const ElfW(Shdr)& section,
- uint32_t type, Fn fn) const {
+const ElfSym* ElfFile::iterateSymbolsWithType(
+ const ElfShdr& section,
+ uint32_t type,
+ Fn fn) const {
// N.B. st_info has the same representation on 32- and 64-bit platforms
- return iterateSymbols(section, [&](const ElfW(Sym)& sym) -> bool {
+ return iterateSymbols(section, [&](const ElfSym& sym) -> bool {
return ELF32_ST_TYPE(sym.st_info) == type && fn(sym);
});
}
-} // namespace symbolizer
-} // namespace folly
+template <class Fn>
+const ElfSym* ElfFile::iterateSymbolsWithTypes(
+ const ElfShdr& section,
+ std::initializer_list<uint32_t> types,
+ Fn fn) const {
+ // N.B. st_info has the same representation on 32- and 64-bit platforms
+ return iterateSymbols(section, [&](const ElfSym& sym) -> bool {
+ auto const elfType = ELF32_ST_TYPE(sym.st_info);
+ auto const it = std::find(types.begin(), types.end(), elfType);
+ return it != types.end() && fn(sym);
+ });
+}
+} // namespace symbolizer
+} // namespace folly