Skip to content

Commit

Permalink
Merge pull request #410 from acj/acj/resolve-symbols-with-bcc
Browse files Browse the repository at this point in the history
Migrate from objdump and grep to library calls
  • Loading branch information
brendangregg committed Apr 18, 2019
2 parents 8816fa4 + fdd02ec commit 48619f4
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ endif()
set(CMAKE_REQUIRED_LIBRARIES bcc)
check_symbol_exists(bcc_prog_load "${LIBBCC_INCLUDE_DIRS}/libbpf.h" HAVE_BCC_PROG_LOAD)
check_symbol_exists(bcc_create_map "${LIBBCC_INCLUDE_DIRS}/libbpf.h" HAVE_BCC_CREATE_MAP)
check_symbol_exists(bcc_elf_foreach_sym "${LIBBCC_INCLUDE_DIRS}/bcc_elf.h" HAVE_BCC_ELF_FOREACH_SYM)

include(CheckTypeSize)
set(CMAKE_EXTRA_INCLUDE_FILES linux/bpf.h)
Expand Down
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ endif(HAVE_BCC_PROG_LOAD)
if(HAVE_BCC_CREATE_MAP)
target_compile_definitions(bpftrace PRIVATE HAVE_BCC_CREATE_MAP)
endif(HAVE_BCC_CREATE_MAP)
if(HAVE_BCC_ELF_FOREACH_SYM)
target_compile_definitions(bpftrace PRIVATE HAVE_BCC_ELF_FOREACH_SYM)
endif(HAVE_BCC_ELF_FOREACH_SYM)
if(HAVE_GET_CURRENT_CGROUP_ID)
target_compile_definitions(bpftrace PRIVATE HAVE_GET_CURRENT_CGROUP_ID)
endif(HAVE_GET_CURRENT_CGROUP_ID)
Expand Down
42 changes: 35 additions & 7 deletions src/bpftrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
#include <fcntl.h>
#include <unistd.h>

#ifdef HAVE_BCC_ELF_FOREACH_SYM
#include <linux/elf.h>

#include "bcc_elf.h"
#endif

#include "bcc_syms.h"
#include "perf_reader.h"

Expand Down Expand Up @@ -1560,25 +1566,47 @@ uint64_t BPFtrace::resolve_cgroupid(const std::string &path)

uint64_t BPFtrace::resolve_uname(const std::string &name, const std::string &path)
{
uint64_t addr = 0;

// TODO: switch from objdump to library call, perhaps bcc_resolve_symname()
#ifdef HAVE_BCC_ELF_FOREACH_SYM
bcc_symbol sym;
int err = bcc_resolve_symname(path.c_str(), name.c_str(), 0, 0, nullptr, &sym);
if (err)
throw std::runtime_error("Could not resolve symbol: " + path + ":" + name);
return sym.offset;
#else
std::string call_str = std::string("objdump -tT ") + path + " | grep -w " + name;
const char *call = call_str.c_str();
auto result = exec_system(call);
addr = read_address_from_output(result);
return read_address_from_output(result);
#endif
}

return addr;
int add_symbol(const char *symname, uint64_t start, uint64_t size, void *payload) {
auto syms = static_cast<std::ostringstream*>(payload);
*syms << std::string(symname) << std::endl;
return 0;
}

std::string BPFtrace::extract_func_symbols_from_path(const std::string &path)
{
// TODO: switch from objdump to library call, perhaps bcc_resolve_symname()
#ifdef HAVE_BCC_ELF_FOREACH_SYM
bcc_symbol_option symbol_option = {
.use_debug_file = 1,
.check_debug_file_crc = 1,
.use_symbol_type = (1 << STT_FUNC) | (1 << STT_GNU_IFUNC)
};

std::ostringstream syms;
int err = bcc_elf_foreach_sym(path.c_str(), add_symbol, &symbol_option, &syms);
if (err)
throw std::runtime_error("Could not list function symbols: " + path);

return syms.str();
#else
std::string call_str = std::string("objdump -tT ") + path +
+ " | " + "grep \"F .text\" | grep -oE '[^[:space:]]+$'";

const char *call = call_str.c_str();
return exec_system(call);
#endif
}

uint64_t BPFtrace::read_address_from_output(std::string output)
Expand Down

0 comments on commit 48619f4

Please sign in to comment.