Merge pull request #237 from compnerd/riscv
add support for RISC-V
diff --git a/src/elf.cc b/src/elf.cc
index 9e8c4b4..eb0e263 100644
--- a/src/elf.cc
+++ b/src/elf.cc
@@ -777,60 +777,70 @@
}
}
-static void ElfMachineToCapstone(Elf64_Half e_machine, cs_arch* arch,
+static bool ElfMachineToCapstone(Elf64_Half e_machine, cs_arch* arch,
cs_mode* mode) {
switch (e_machine) {
case EM_386:
*arch = CS_ARCH_X86;
*mode = CS_MODE_32;
- break;
+ return true;
case EM_X86_64:
*arch = CS_ARCH_X86;
*mode = CS_MODE_64;
- break;
+ return true;
// These aren't tested, but we include them on the off-chance
// that it will work.
case EM_ARM:
*arch = CS_ARCH_ARM;
*mode = CS_MODE_LITTLE_ENDIAN;
- break;
+ return true;
case EM_AARCH64:
*arch = CS_ARCH_ARM64;
*mode = CS_MODE_ARM;
- break;
+ return true;
case EM_MIPS:
*arch = CS_ARCH_MIPS;
- break;
+ return true;
case EM_PPC:
*arch = CS_ARCH_PPC;
*mode = CS_MODE_32;
- break;
+ return true;
case EM_PPC64:
*arch = CS_ARCH_PPC;
*mode = CS_MODE_64;
- break;
+ return true;
case EM_SPARC:
*arch = CS_ARCH_SPARC;
*mode = CS_MODE_BIG_ENDIAN;
- break;
+ return true;
case EM_SPARCV9:
*arch = CS_ARCH_SPARC;
*mode = CS_MODE_V9;
- break;
+ return true;
+
default:
- THROWF("Unknown ELF machine value: $0'", e_machine);
+ if (verbose_level > 1) {
+ printf(
+ "Unable to map to capstone target, disassembly will be "
+ "unavailable");
+ }
+ return false;
}
}
-static void ReadElfArchMode(const InputFile& file, cs_arch* arch, cs_mode* mode) {
+static bool ReadElfArchMode(const InputFile& file, cs_arch* arch, cs_mode* mode) {
+ bool capstone_available = true;
ForEachElf(file, nullptr,
- [=](const ElfFile& elf, string_view /*filename*/,
- uint32_t /*index_base*/) {
+ [&capstone_available, arch, mode](const ElfFile& elf,
+ string_view /*filename*/,
+ uint32_t /*index_base*/) {
// Last .o file wins? (For .a files)? It's kind of arbitrary,
// but a single .a file shouldn't have multiple archs in it.
- ElfMachineToCapstone(elf.header().e_machine, arch, mode);
+ capstone_available &=
+ ElfMachineToCapstone(elf.header().e_machine, arch, mode);
});
+ return capstone_available;
}
static void ReadELFSymbols(const InputFile& file, RangeSink* sink,
@@ -838,7 +848,7 @@
bool is_object = IsObjectFile(file.data());
DisassemblyInfo info;
DisassemblyInfo* infop = &info;
- ReadElfArchMode(file, &info.arch, &info.mode);
+ bool capstone_available = ReadElfArchMode(file, &info.arch, &info.mode);
ForEachElf(
file, sink,
@@ -882,7 +892,7 @@
string_view name = strtab_section.ReadString(sym.st_name);
uint64_t full_addr =
ToVMAddr(sym.st_value, index_base + sym.st_shndx, is_object);
- if (sink && !disassemble) {
+ if (sink && !(capstone_available && disassemble)) {
sink->AddVMRangeAllowAlias(
"elf_symbols", full_addr, sym.st_size,
ItaniumDemangle(name, sink->data_source()));
@@ -891,7 +901,8 @@
table->insert(
std::make_pair(name, std::make_pair(full_addr, sym.st_size)));
}
- if (disassemble && ELF64_ST_TYPE(sym.st_info) == STT_FUNC) {
+ if (capstone_available && disassemble &&
+ ELF64_ST_TYPE(sym.st_info) == STT_FUNC) {
if (verbose_level > 1) {
printf("Disassembling function: %s\n", name.data());
}
@@ -1374,8 +1385,7 @@
info->start_address = vmaddr;
}
- ReadElfArchMode(file_data(), &info->arch, &info->mode);
- return true;
+ return ReadElfArchMode(file_data(), &info->arch, &info->mode);
}
};