Fix unaligned_ptr in swiftshader
For something used in three places, this type is probably overkill, but
ah well. Casting an unaligned pointer to uint32_t* is UB, even if you
don't dereference it. So this unaligned_ptr type isn't actually avoiding
UB. Keeping things as void* under the hood, to avoid this.
While I'm here, trim the API surface a bit, so this is a bit easier to
reason about.
Bug: chromium:1394755
Change-Id: I3a198c78051508c6b2ec806ce0ea6b4335cf4ebe
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/72608
Reviewed-by: Shahbaz Youssefi <syoussefi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Shahbaz Youssefi <syoussefi@google.com>
Commit-Queue: Shahbaz Youssefi <syoussefi@google.com>
diff --git a/src/Reactor/ExecutableMemory.hpp b/src/Reactor/ExecutableMemory.hpp
index dbbe32a..2cd5bec 100644
--- a/src/Reactor/ExecutableMemory.hpp
+++ b/src/Reactor/ExecutableMemory.hpp
@@ -41,17 +41,16 @@
void deallocateMemoryPages(void *memory, size_t bytes);
template<typename P>
-P unaligned_read(P *address)
+P unaligned_read(void *address)
{
P value;
memcpy(&value, address, sizeof(P));
return value;
}
-template<typename P, typename V>
-void unaligned_write(P *address, V value)
+template<typename P>
+void unaligned_write(void *address, P value)
{
- static_assert(sizeof(V) == sizeof(P), "value size must match pointee size");
memcpy(address, &value, sizeof(P));
}
@@ -60,33 +59,29 @@
{
public:
explicit unaligned_ref(void *ptr)
- : ptr((P *)ptr)
+ : ptr(ptr)
{}
- template<typename V>
- P operator=(V value)
+ unaligned_ref &operator=(P value)
{
unaligned_write(ptr, value);
- return value;
+ return *this;
}
operator P()
{
- return unaligned_read((P *)ptr);
+ return unaligned_read<P>(ptr);
}
private:
- P *ptr;
+ void *ptr;
};
template<typename P>
class unaligned_ptr
{
- template<typename S>
- friend class unaligned_ptr;
-
public:
- unaligned_ptr(P *ptr)
+ unaligned_ptr(void *ptr)
: ptr(ptr)
{}
@@ -95,10 +90,9 @@
return unaligned_ref<P>(ptr);
}
- template<typename S>
- operator S()
+ explicit operator intptr_t()
{
- return S(ptr);
+ return (intptr_t)ptr;
}
private:
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 0a4e9d2..c0c6b1d 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -518,7 +518,7 @@
}
intptr_t address = (intptr_t)elfHeader + target->sh_offset;
- unaligned_ptr<int32_t> patchSite = (int32_t *)(address + relocation.r_offset);
+ unaligned_ptr<int32_t> patchSite = (void *)(address + relocation.r_offset);
if(CPUID::ARM)
{
@@ -603,8 +603,8 @@
}
intptr_t address = (intptr_t)elfHeader + target->sh_offset;
- unaligned_ptr<int32_t> patchSite32 = (int32_t *)(address + relocation.r_offset);
- unaligned_ptr<int64_t> patchSite64 = (int64_t *)(address + relocation.r_offset);
+ unaligned_ptr<int32_t> patchSite32 = (void *)(address + relocation.r_offset);
+ unaligned_ptr<int64_t> patchSite64 = (void *)(address + relocation.r_offset);
switch(relocation.getType())
{