aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/Core
diff options
context:
space:
mode:
authorLukáš Zaoral <lzaoral@redhat.com>2022-01-22 15:30:03 +0100
committerCristian Cadar <c.cadar@imperial.ac.uk>2022-03-09 20:45:11 +0100
commitec81fd165883cf0d033e7822c39c6b6c33f57d77 (patch)
tree29e82316ca78ea27b361b280792bf92a5d5fe08c /lib/Core
parent69190130d38bfc9b5d67add843f2c542dc843470 (diff)
downloadklee-ec81fd165883cf0d033e7822c39c6b6c33f57d77.tar.gz
Core/Executor: Fix unaligned write of fp80 arguments
... in Executor::callExternalFunction. Fixes the following error reported in Feature/VarArg{Alignment,LongDouble}.c tests: lib/Expr/Expr.cpp:366:5: runtime error: store to misaligned address 0x7ffc011d3528 for type 'long double', which requires 16 byte alignment
Diffstat (limited to 'lib/Core')
-rw-r--r--lib/Core/Executor.cpp4
-rw-r--r--lib/Core/ExternalDispatcher.cpp5
2 files changed, 9 insertions, 0 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index c50e4520..85413a42 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -3881,6 +3881,10 @@ void Executor::callExternalFunction(ExecutionState &state,
} else {
ref<Expr> arg = toUnique(state, *ai);
if (ConstantExpr *ce = dyn_cast<ConstantExpr>(arg)) {
+ // fp80 must be aligned to 16 according to the System V AMD 64 ABI
+ if (ce->getWidth() == Expr::Fl80 && wordIndex & 0x01)
+ wordIndex++;
+
// XXX kick toMemory functions from here
ce->toMemory(&args[wordIndex]);
wordIndex += (ce->getWidth()+63)/64;
diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp
index e43a8a83..aadb340d 100644
--- a/lib/Core/ExternalDispatcher.cpp
+++ b/lib/Core/ExternalDispatcher.cpp
@@ -302,6 +302,11 @@ Function *ExternalDispatcherImpl::createDispatcher(Function *target,
// functions.
auto argTy =
(i < FTy->getNumParams() ? FTy->getParamType(i) : (*ai)->getType());
+
+ // fp80 must be aligned to 16 according to the System V AMD 64 ABI
+ if (argTy->isX86_FP80Ty() && idx & 0x01)
+ idx++;
+
auto argI64p =
Builder.CreateGEP(argI64s->getType()->getPointerElementType(), argI64s,
ConstantInt::get(Type::getInt32Ty(ctx), idx));