Skip to content

Commit 5f7d744

Browse files
authored
Update LLVM backend to work with version 12 (#1358)
This may also work with later versions, but I did not test them
1 parent 9f7d1ba commit 5f7d744

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

lib/bap_llvm/llvm_disasm.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
#include <llvm/Support/FormattedStream.h>
88
#include <llvm/Support/TargetRegistry.h>
99
#include <llvm/Support/CommandLine.h>
10+
#if LLVM_VERSION_MAJOR >= 12
11+
#include <llvm/Support/Process.h>
12+
#include <llvm/Support/StringSaver.h>
13+
#endif
1014
#include <llvm-c/Target.h>
1115

1216
#if LLVM_VERSION_MAJOR >= 10
@@ -627,8 +631,27 @@ struct create_llvm_disassembler : disasm_factory {
627631

628632
}
629633

634+
static void parse_environment_options(const char *prog_name, const char *env_var) {
635+
#if LLVM_VERSION_MAJOR >= 12
636+
llvm::Optional<std::string> env_value = llvm::sys::Process::GetEnv(llvm::StringRef(env_var));
637+
if (!env_value)
638+
return;
639+
640+
llvm::SmallVector<const char *, 20> new_argv;
641+
llvm::BumpPtrAllocator alloc;
642+
llvm::StringSaver saver(alloc);
643+
new_argv.push_back(saver.save(prog_name).data());
644+
645+
llvm::cl::TokenizeGNUCommandLine(*env_value, saver, new_argv);
646+
int new_argc = static_cast<int>(new_argv.size());
647+
llvm::cl::ParseCommandLineOptions(new_argc, &new_argv[0], llvm::StringRef(""));
648+
#else
649+
llvm::cl::ParseEnvironmentOptions(prog_name, env_var);
650+
#endif
651+
}
652+
630653
int disasm_llvm_init() {
631-
llvm::cl::ParseEnvironmentOptions("bap", "BAP_LLVM_OPTIONS");
654+
parse_environment_options("bap", "BAP_LLVM_OPTIONS");
632655
bap::initialize_llvm();
633656
auto f = std::make_shared<bap::create_llvm_disassembler>();
634657
return bap::register_disassembler("llvm", f);

lib/bap_llvm/llvm_elf_loader.hpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ using namespace llvm::object;
1919

2020
template <typename T>
2121
bool has_addresses(const ELFObjectFile<T> &obj) {
22+
#if LLVM_VERSION_MAJOR >= 12
23+
auto hdr = &obj.getELFFile().getHeader();
24+
#else
2225
auto hdr = obj.getELFFile()->getHeader();
26+
#endif
2327
return (hdr->e_type == ELF::ET_EXEC ||
2428
hdr->e_type == ELF::ET_DYN ||
2529
hdr->e_type == ELF::ET_CORE);
@@ -28,7 +32,11 @@ bool has_addresses(const ELFObjectFile<T> &obj) {
2832

2933
template <typename T>
3034
bool is_executable(const ELFObjectFile<T> &obj) {
35+
#if LLVM_VERSION_MAJOR >= 12
36+
auto hdr = &obj.getELFFile().getHeader();
37+
#else
3138
auto hdr = obj.getELFFile()->getHeader();
39+
#endif
3240
return (hdr->e_type == ELF::ET_EXEC ||
3341
hdr->e_type == ELF::ET_DYN);
3442
}
@@ -42,7 +50,11 @@ bool is_executable(const ELFObjectFile<T> &obj) {
4250
template <typename T>
4351
uint64_t base_address(const ELFObjectFile<T> &obj) {
4452
uint64_t base = 0L;
53+
#if LLVM_VERSION_MAJOR >= 12
54+
auto elf = obj.getELFFile();
55+
#else
4556
auto elf = *obj.getELFFile();
57+
#endif
4658
auto segs = prim::elf_program_headers(elf);
4759
auto code = segs.end();
4860

@@ -58,7 +70,12 @@ uint64_t base_address(const ELFObjectFile<T> &obj) {
5870
template <typename T>
5971
uint64_t minimal_progbits_offset(const ELFObjectFile<T> &obj) {
6072
auto smallest = std::numeric_limits<uint64_t>::max();
61-
for (auto sec : prim::elf_sections(*obj.getELFFile())) {
73+
#if LLVM_VERSION_MAJOR >= 12
74+
auto &elf_file = obj.getELFFile();
75+
#else
76+
auto &elf_file = *obj.getELFFile();
77+
#endif
78+
for (auto sec : prim::elf_sections(elf_file)) {
6279
if (sec.sh_type == ELF::SHT_PROGBITS && sec.sh_offset < smallest) {
6380
smallest = sec.sh_offset;
6481
}
@@ -68,7 +85,11 @@ uint64_t minimal_progbits_offset(const ELFObjectFile<T> &obj) {
6885

6986
template <typename T>
7087
void emit_entry_point(const ELFObjectFile<T> &obj, ogre_doc &s) {
88+
#if LLVM_VERSION_MAJOR >= 12
89+
auto hdr = &obj.getELFFile().getHeader();
90+
#else
7191
auto hdr = obj.getELFFile()->getHeader();
92+
#endif
7293
s.entry("llvm:entry-point") << hdr->e_entry;
7394
}
7495

@@ -80,7 +101,11 @@ std::string name_of_index(std::size_t i) {
80101

81102
template <typename T>
82103
void emit_program_headers(const ELFObjectFile<T> &obj, ogre_doc &s) {
104+
#if LLVM_VERSION_MAJOR >= 12
105+
auto hdrs = prim::elf_program_headers(obj.getELFFile());
106+
#else
83107
auto hdrs = prim::elf_program_headers(*obj.getELFFile());
108+
#endif
84109
for (auto it = hdrs.begin(); it != hdrs.end(); ++it) {
85110
bool ld = (it->p_type == ELF::PT_LOAD);
86111
bool r = static_cast<bool>(it->p_flags & ELF::PF_R);
@@ -162,7 +187,14 @@ bool is_external(uint64_t addr, uint64_t offset, uint64_t size) {
162187

163188
template <typename T>
164189
void emit_symbol_entry(const ELFObjectFile<T> &obj, const SymbolRef &sym, ogre_doc &s) {
190+
#if LLVM_VERSION_MAJOR >= 12
191+
auto sym_elf_or_error = obj.getSymbol(sym.getRawDataRefImpl());
192+
if (!sym_elf_or_error)
193+
return;
194+
auto sym_elf = *sym_elf_or_error;
195+
#else
165196
auto sym_elf = obj.getSymbol(sym.getRawDataRefImpl());
197+
#endif
166198
auto name = prim::symbol_name(sym);
167199
auto addr = prim::symbol_address(sym);
168200
auto off = symbol_file_offset(obj, sym);
@@ -188,7 +220,11 @@ void emit_symbol_entries(const ELFObjectFile<T> &obj, symbol_iterator begin, sym
188220

189221
template <typename T>
190222
void emit_symbol_entries(const ELFObjectFile<T> &obj, ogre_doc &s) {
223+
#if LLVM_VERSION_MAJOR >= 12
224+
auto elf = &obj.getELFFile();
225+
#else
191226
auto elf = obj.getELFFile();
227+
#endif
192228
emit_symbol_entries(obj, obj.symbol_begin(), obj.symbol_end(), s);
193229
auto secs = prim::elf_sections(*elf);
194230
emit_symbol_entries(obj, obj.dynamic_symbol_begin(), obj.dynamic_symbol_end(), s);

0 commit comments

Comments
 (0)