mirror of
https://github.com/lifting-bits/remill
synced 2026-06-21 13:56:07 +00:00
Fix GCC compilation (#672)
* Fix compilation with GCC
Fixes a few errors reported by GCC and not Clang
1. "non-trivial designated initializers not supported"
- Fixed by adding array entries that were missing initializers and
reordering
2. "Cannot bind packed field"
- This fixes arrays missing initializers for some entries. This
isn't the greatest fix because instead of using a reference, we
use a pointer, which is basically the same thing, but it is
checked less strictly. I think a real fix would be to remove the
'packed' annotations.
* Add GCC to CI
This commit is contained in:
@@ -24,6 +24,15 @@ jobs:
|
||||
image:
|
||||
- { name: 'ubuntu', tag: '22.04' }
|
||||
llvm: ['15', '16']
|
||||
compiler:
|
||||
- { CC: 'clang', CXX: 'clang++' }
|
||||
- { CC: 'gcc', CXX: 'g++' }
|
||||
exclude:
|
||||
- { llvm: '15', compiler: { CC: 'gcc', CXX: 'g++' } }
|
||||
|
||||
env:
|
||||
CC: ${{ matrix.compiler.CC }}
|
||||
CXX: ${{ matrix.compiler.CXX }}
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
container:
|
||||
@@ -45,7 +54,6 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
sudo apt-get update && sudo apt-get install g++-8
|
||||
./scripts/build.sh --llvm-version ${{ matrix.llvm }}
|
||||
- name: Build with build-presets script
|
||||
shell: bash
|
||||
|
||||
+1
-1
@@ -96,11 +96,11 @@ static const std::string_view kArchNames[] = {
|
||||
[kArchAMD64_AVX512] = "amd64_avx512",
|
||||
[kArchAMD64_SLEIGH] = "amd64_sleigh",
|
||||
[kArchAArch32LittleEndian] = "aarch32",
|
||||
[kArchThumb2LittleEndian] = "thumb2",
|
||||
[kArchAArch64LittleEndian] = "aarch64",
|
||||
[kArchAArch64LittleEndian_SLEIGH] = "aarch64_sleigh",
|
||||
[kArchSparc32] = "sparc32",
|
||||
[kArchSparc64] = "sparc64",
|
||||
[kArchThumb2LittleEndian] = "thumb2",
|
||||
[kArchPPC] = "ppc",
|
||||
};
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ namespace test_runner {
|
||||
|
||||
using MemoryModifier = std::function<void(MemoryHandler &)>;
|
||||
using RegisterValue = std::variant<uint64_t, uint32_t, uint8_t>;
|
||||
using RegisterValueRef = std::variant<std::reference_wrapper<uint64_t>,
|
||||
std::reference_wrapper<uint32_t>,
|
||||
std::reference_wrapper<uint8_t>>;
|
||||
using RegisterValueRef = std::variant<uint64_t *,
|
||||
uint32_t *,
|
||||
uint8_t *>;
|
||||
|
||||
struct RegisterCondition {
|
||||
std::string register_name;
|
||||
@@ -63,14 +63,14 @@ class TestOutputSpec {
|
||||
RegisterAccessorMap reg_to_accessor;
|
||||
|
||||
template <typename T>
|
||||
T &GetRegister(S &state, const std::string ®_name) const {
|
||||
T *GetRegister(S &state, const std::string ®_name) const {
|
||||
auto accessor = reg_to_accessor.find(reg_name);
|
||||
if (accessor == reg_to_accessor.end()) {
|
||||
throw std::runtime_error(std::string("Unknown reg: ") + reg_name);
|
||||
}
|
||||
auto wrapper = accessor->second(state);
|
||||
if (auto underlying = std::get_if<std::reference_wrapper<T>>(&wrapper)) {
|
||||
return underlying->get();
|
||||
if (auto underlying = std::get_if<T *>(&wrapper)) {
|
||||
return *underlying;
|
||||
}
|
||||
throw std::runtime_error(
|
||||
std::string("Reg value " + reg_name + " has incorrect type"));
|
||||
@@ -78,13 +78,13 @@ class TestOutputSpec {
|
||||
|
||||
template <typename T>
|
||||
void ApplyCondition(S &state, const std::string ®_name, T value) const {
|
||||
auto ® = this->GetRegister<T>(state, reg_name);
|
||||
reg = value;
|
||||
auto *reg = this->GetRegister<T>(state, reg_name);
|
||||
*reg = value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void CheckCondition(S &state, const std::string ®_name, T value) const {
|
||||
auto actual = this->GetRegister<T>(state, reg_name);
|
||||
auto actual = *(this->GetRegister<T>(state, reg_name));
|
||||
LOG(INFO) << "Reg: " << reg_name << " Actual: " << std::hex
|
||||
<< static_cast<uint64_t>(actual) << " Expected: " << std::hex
|
||||
<< static_cast<uint64_t>(value);
|
||||
|
||||
+28
-28
@@ -35,115 +35,115 @@ const static std::unordered_map<
|
||||
reg_to_accessor = {
|
||||
{"pc",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.pc.qword);
|
||||
return &st.pc.qword;
|
||||
}},
|
||||
{"r0",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r0.qword);
|
||||
return &st.gpr.r0.qword;
|
||||
}},
|
||||
{"r1",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r1.qword);
|
||||
return &st.gpr.r1.qword;
|
||||
}},
|
||||
{"r2",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r2.qword);
|
||||
return &st.gpr.r2.qword;
|
||||
}},
|
||||
{"r3",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r3.qword);
|
||||
return &st.gpr.r3.qword;
|
||||
}},
|
||||
{"r4",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r4.qword);
|
||||
return &st.gpr.r4.qword;
|
||||
}},
|
||||
{"r5",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r5.qword);
|
||||
return &st.gpr.r5.qword;
|
||||
}},
|
||||
{"r6",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r6.qword);
|
||||
return &st.gpr.r6.qword;
|
||||
}},
|
||||
{"r7",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r7.qword);
|
||||
return &st.gpr.r7.qword;
|
||||
}},
|
||||
{"r8",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r8.qword);
|
||||
return &st.gpr.r8.qword;
|
||||
}},
|
||||
{"r9",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return (st.gpr.r9.qword);
|
||||
return &st.gpr.r9.qword;
|
||||
}},
|
||||
{"r10",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.gpr.r10.qword;
|
||||
return &st.gpr.r10.qword;
|
||||
}},
|
||||
{"r11",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.gpr.r11.qword;
|
||||
return &st.gpr.r11.qword;
|
||||
}},
|
||||
{"r12",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.gpr.r12.qword;
|
||||
return &st.gpr.r12.qword;
|
||||
}},
|
||||
{"cr",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.iar.cr.qword;
|
||||
return &st.iar.cr.qword;
|
||||
}},
|
||||
{"cr0",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.cr_flags.cr0;
|
||||
return &st.cr_flags.cr0;
|
||||
}},
|
||||
{"cr1",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.cr_flags.cr1;
|
||||
return &st.cr_flags.cr1;
|
||||
}},
|
||||
{"cr2",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.cr_flags.cr2;
|
||||
return &st.cr_flags.cr2;
|
||||
}},
|
||||
{"cr3",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.cr_flags.cr3;
|
||||
return &st.cr_flags.cr3;
|
||||
}},
|
||||
{"cr4",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.cr_flags.cr4;
|
||||
return &st.cr_flags.cr4;
|
||||
}},
|
||||
{"cr5",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.cr_flags.cr5;
|
||||
return &st.cr_flags.cr5;
|
||||
}},
|
||||
{"cr6",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.cr_flags.cr6;
|
||||
return &st.cr_flags.cr6;
|
||||
}},
|
||||
{"cr7",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.cr_flags.cr7;
|
||||
return &st.cr_flags.cr7;
|
||||
}},
|
||||
{"lr",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.iar.lr.qword;
|
||||
return &st.iar.lr.qword;
|
||||
}},
|
||||
{"ctr",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.iar.ctr.qword;
|
||||
return &st.iar.ctr.qword;
|
||||
}},
|
||||
{"xer",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.iar.xer.qword;
|
||||
return &st.iar.xer.qword;
|
||||
}},
|
||||
{"xer_so",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.xer_flags.so;
|
||||
return &st.xer_flags.so;
|
||||
}},
|
||||
{"xer_ov",
|
||||
[](PPCState &st) -> test_runner::RegisterValueRef {
|
||||
return st.xer_flags.ov;
|
||||
return &st.xer_flags.ov;
|
||||
}},
|
||||
};
|
||||
|
||||
|
||||
@@ -53,18 +53,18 @@ const static std::unordered_map<
|
||||
reg_to_accessor = {
|
||||
{"r15",
|
||||
[](AArch32State &st) -> test_runner::RegisterValueRef {
|
||||
return st.gpr.r15.dword;
|
||||
return &st.gpr.r15.dword;
|
||||
}},
|
||||
{"sp",
|
||||
[](AArch32State &st) -> test_runner::RegisterValueRef {
|
||||
return st.gpr.r13.dword;
|
||||
return &st.gpr.r13.dword;
|
||||
}},
|
||||
{"r1",
|
||||
[](AArch32State &st) -> test_runner::RegisterValueRef {
|
||||
return st.gpr.r1.dword;
|
||||
return &st.gpr.r1.dword;
|
||||
}},
|
||||
{"z", [](AArch32State &st) -> test_runner::RegisterValueRef {
|
||||
return st.sr.z;
|
||||
return &st.sr.z;
|
||||
}}};
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ class TestOutputSpec {
|
||||
T value,
|
||||
std::function<test_runner::RegisterValueRef(AArch32State &)> accessor,
|
||||
AArch32State &state) const {
|
||||
std::get<std::reference_wrapper<T>>(accessor(state)).get() = value;
|
||||
*(std::get<T *>(accessor(state))) = value;
|
||||
}
|
||||
|
||||
void ApplyCondition(AArch32State &state, std::string reg,
|
||||
@@ -137,7 +137,7 @@ class TestOutputSpec {
|
||||
T value,
|
||||
std::function<test_runner::RegisterValueRef(AArch32State &)> accessor,
|
||||
AArch32State &state) const {
|
||||
auto sval = std::get<std::reference_wrapper<T>>(accessor(state)).get();
|
||||
T sval = *(std::get<T *>(accessor(state)));
|
||||
LOG(INFO) << "state value: " << sval;
|
||||
CHECK_EQ(sval, value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user