Add dummy key methods for UBSan RTTI.
Chromium UBSan builds require RTTI, for which GCC/Clang requires each
class' first non-inline virtual method (the "key method") to have a known
definition so that its address can be used as a unique type identifier:
https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html
libEGL and libGLESv2 each use objects who's full definition only exists
within one or the other. Methods for which the definition is unknown can
still be called if they are virtual, because the compiler/linker only needs
to know the vtable entry offset. But because of the GCC/Clang requirement
of having the first non-inline virtual method be fully defined, we need to
add dummy virtual methods and their definitions.
Bug swiftshader:31
Change-Id: Ib146cac811388086b29dbb099266c43795d6ed31
Reviewed-on: https://swiftshader-review.googlesource.com/8708
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/Main/FrameBuffer.hpp b/src/Main/FrameBuffer.hpp
index c3afc3d..77a00f6 100644
--- a/src/Main/FrameBuffer.hpp
+++ b/src/Main/FrameBuffer.hpp
@@ -36,6 +36,8 @@
class FrameBuffer
{
+ virtual void typeinfo(); // Dummy key method (https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)
+
public:
FrameBuffer(int width, int height, bool fullscreen, bool topLeftOrigin);
@@ -103,6 +105,8 @@
static bool topLeftOrigin;
};
+
+ inline void FrameBuffer::typeinfo() {}
}
#endif // sw_FrameBuffer_hpp
diff --git a/src/OpenGL/common/Image.hpp b/src/OpenGL/common/Image.hpp
index 5a4e289..9e99852 100644
--- a/src/OpenGL/common/Image.hpp
+++ b/src/OpenGL/common/Image.hpp
@@ -48,6 +48,8 @@
class Image : public sw::Surface, public gl::Object
{
+ virtual void typeinfo(); // Dummy key method (https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)
+
public:
// 2D texture image
Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
@@ -192,6 +194,8 @@
void loadD32FS8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer);
};
+inline void Image::typeinfo() {}
+
#ifdef __ANDROID__
inline GLenum GLPixelFormatFromAndroid(int halFormat)
diff --git a/src/OpenGL/libEGL/BUILD.gn b/src/OpenGL/libEGL/BUILD.gn
index 03af0f5..6442bca 100644
--- a/src/OpenGL/libEGL/BUILD.gn
+++ b/src/OpenGL/libEGL/BUILD.gn
@@ -57,11 +57,6 @@
if (is_debug) {
sources += [ "../common/debug.cpp" ]
- } else if (is_linux) {
- sources += [
- "../../Renderer/Surface.cpp",
- "../common/Image.cpp",
- ]
}
if (is_mac) {
diff --git a/src/OpenGL/libEGL/Display.h b/src/OpenGL/libEGL/Display.h
index 93ab2cb..dfa0737 100644
--- a/src/OpenGL/libEGL/Display.h
+++ b/src/OpenGL/libEGL/Display.h
@@ -37,6 +37,8 @@
class Display
{
+ virtual void typeinfo(); // Dummy key method (https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)
+
public:
static Display *get(EGLDisplay dpy);
@@ -97,6 +99,8 @@
gl::NameSpace<Image> mSharedImageNameSpace;
};
+
+ inline void Display::typeinfo() {}
}
#endif // INCLUDE_DISPLAY_H_
diff --git a/src/OpenGL/libEGL/EGLSurface.h b/src/OpenGL/libEGL/EGLSurface.h
index f086823..0129f3d 100644
--- a/src/OpenGL/libEGL/EGLSurface.h
+++ b/src/OpenGL/libEGL/EGLSurface.h
@@ -33,6 +33,8 @@
class Surface : public gl::Object
{
+ virtual void typeinfo(); // Dummy key method (https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)
+
public:
virtual bool initialize();
virtual void swap() = 0;
@@ -96,6 +98,8 @@
EGLint swapInterval;
};
+inline void Surface::typeinfo() {}
+
class WindowSurface : public Surface
{
public:
diff --git a/src/Renderer/Surface.hpp b/src/Renderer/Surface.hpp
index 5a5fe10..f99e108 100644
--- a/src/Renderer/Surface.hpp
+++ b/src/Renderer/Surface.hpp
@@ -250,6 +250,8 @@
bool dirty;
};
+ virtual void typeinfo(); // Dummy key method (https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)
+
public:
Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice);
Surface(Resource *texture, int width, int height, int depth, Format format, bool lockable, bool renderTarget, int pitchP = 0);
@@ -475,6 +477,8 @@
namespace sw
{
+ inline void Surface::typeinfo() {}
+
void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal)
{
return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client);