translator: Add define to disable pool allocation.
This will help ASan find bugs in the translator when fuzzing, by making
separate allocations instead of using suballocations within the pool.
BUG=swiftshader:86
Change-Id: Ic59f7eef2c7985f7bf545d41be956df478331e2d
Reviewed-on: https://swiftshader-review.googlesource.com/13488
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Corentin Wallez <cwallez@google.com>
diff --git a/src/OpenGL/compiler/BUILD.gn b/src/OpenGL/compiler/BUILD.gn
index 3759f1c..3596e38 100644
--- a/src/OpenGL/compiler/BUILD.gn
+++ b/src/OpenGL/compiler/BUILD.gn
@@ -13,6 +13,7 @@
# limitations under the License.
import("../../swiftshader.gni")
+import("//testing/libfuzzer/fuzzer_test.gni")
# Need a separate config to ensure the warnings are added to the end.
config("swiftshader_opengl_compiler_private_config") {
@@ -37,6 +38,10 @@
}
}
+config("swiftshader_translator_disable_pool_alloc") {
+ defines = [ "SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC" ]
+}
+
swiftshader_source_set("swiftshader_opengl_compiler") {
deps = [
"preprocessor:swiftshader_opengl_preprocessor",
@@ -67,6 +72,10 @@
"util.cpp",
]
+ if (use_fuzzing_engine) {
+ all_dependent_configs = [ ":swiftshader_translator_disable_pool_alloc" ]
+ }
+
if (is_linux || is_mac) {
sources += [ "ossource_posix.cpp" ]
} else if (is_win) {
diff --git a/src/OpenGL/compiler/PoolAlloc.cpp b/src/OpenGL/compiler/PoolAlloc.cpp
index f3d19eb..1235023 100644
--- a/src/OpenGL/compiler/PoolAlloc.cpp
+++ b/src/OpenGL/compiler/PoolAlloc.cpp
@@ -57,27 +57,16 @@
// is documented in PoolAlloc.h.
//
TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
- pageSize(growthIncrement),
- alignment(allocationAlignment),
+ alignment(allocationAlignment)
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ , pageSize(growthIncrement),
freeList(0),
inUseList(0),
numCalls(0),
totalBytes(0)
+#endif
{
//
- // Don't allow page sizes we know are smaller than all common
- // OS page sizes.
- //
- if (pageSize < 4*1024)
- pageSize = 4*1024;
-
- //
- // A large currentPageOffset indicates a new page needs to
- // be obtained to allocate memory.
- //
- currentPageOffset = pageSize;
-
- //
// Adjust alignment to be at least pointer aligned and
// power of 2.
//
@@ -91,6 +80,20 @@
alignment = a;
alignmentMask = a - 1;
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ //
+ // Don't allow page sizes we know are smaller than all common
+ // OS page sizes.
+ //
+ if (pageSize < 4*1024)
+ pageSize = 4*1024;
+
+ //
+ // A large currentPageOffset indicates a new page needs to
+ // be obtained to allocate memory.
+ //
+ currentPageOffset = pageSize;
+
//
// Align header skip
//
@@ -98,10 +101,14 @@
if (headerSkip < sizeof(tHeader)) {
headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
}
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ mStack.push_back({});
+#endif
}
TPoolAllocator::~TPoolAllocator()
{
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
while (inUseList) {
tHeader* next = inUseList->nextPage;
inUseList->~tHeader();
@@ -118,6 +125,14 @@
delete [] reinterpret_cast<char*>(freeList);
freeList = next;
}
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ for (auto& allocs : mStack) {
+ for (auto alloc : allocs) {
+ free(alloc);
+ }
+ }
+ mStack.clear();
+#endif
}
// Support MSVC++ 6.0
@@ -158,14 +173,18 @@
void TPoolAllocator::push()
{
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
tAllocState state = { currentPageOffset, inUseList };
- stack.push_back(state);
+ mStack.push_back(state);
//
// Indicate there is no current page to allocate from.
//
currentPageOffset = pageSize;
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ mStack.push_back({});
+#endif
}
//
@@ -177,11 +196,12 @@
//
void TPoolAllocator::pop()
{
- if (stack.size() < 1)
+ if (mStack.size() < 1)
return;
- tHeader* page = stack.back().page;
- currentPageOffset = stack.back().offset;
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ tHeader* page = mStack.back().page;
+ currentPageOffset = mStack.back().offset;
while (inUseList != page) {
// invoke destructor to free allocation list
@@ -197,7 +217,13 @@
inUseList = nextInUse;
}
- stack.pop_back();
+ mStack.pop_back();
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ for (auto alloc : mStack.back()) {
+ free(alloc);
+ }
+ mStack.pop_back();
+#endif
}
//
@@ -206,12 +232,13 @@
//
void TPoolAllocator::popAll()
{
- while (stack.size() > 0)
+ while (mStack.size() > 0)
pop();
}
void* TPoolAllocator::allocate(size_t numBytes)
{
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
//
// Just keep some interesting statistics.
//
@@ -288,6 +315,14 @@
currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
return initializeAllocation(inUseList, ret, numBytes);
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ void *alloc = malloc(numBytes + alignmentMask);
+ mStack.back().push_back(alloc);
+
+ intptr_t intAlloc = reinterpret_cast<intptr_t>(alloc);
+ intAlloc = (intAlloc + alignmentMask) & ~alignmentMask;
+ return reinterpret_cast<void *>(intAlloc);
+#endif
}
diff --git a/src/OpenGL/compiler/PoolAlloc.h b/src/OpenGL/compiler/PoolAlloc.h
index 1aca1c9..d645a04 100644
--- a/src/OpenGL/compiler/PoolAlloc.h
+++ b/src/OpenGL/compiler/PoolAlloc.h
@@ -160,7 +160,12 @@
// by calling pop(), and to not have to solve memory leak problems.
//
-protected:
+private:
+ size_t alignment; // all returned allocations will be aligned at
+ // this granularity, which will be a power of 2
+ size_t alignmentMask;
+
+#if !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
friend struct tHeader;
struct tHeader {
@@ -203,20 +208,21 @@
}
size_t pageSize; // granularity of allocation from the OS
- size_t alignment; // all returned allocations will be aligned at
- // this granularity, which will be a power of 2
- size_t alignmentMask;
size_t headerSkip; // amount of memory to skip to make room for the
// header (basically, size of header, rounded
// up to make it aligned
size_t currentPageOffset; // next offset in top of inUseList to allocate from
tHeader* freeList; // list of popped memory
tHeader* inUseList; // list of all memory currently being used
- tAllocStack stack; // stack of where to allocate from, to partition pool
+ tAllocStack mStack; // stack of where to allocate from, to partition pool
int numCalls; // just an interesting statistic
size_t totalBytes; // just an interesting statistic
-private:
+
+#else // !defined(SWIFTSHADER_TRANSLATOR_DISABLE_POOL_ALLOC)
+ std::vector<std::vector<void *>> mStack;
+#endif
+
TPoolAllocator& operator=(const TPoolAllocator&); // dont allow assignment operator
TPoolAllocator(const TPoolAllocator&); // dont allow default copy constructor
};