forked from OSchip/llvm-project
[interception] Check for export table's size before referring to its elements.
This fix a bug, when calling InternalGetProcAddress() for an executable that doesn't export any symbol. So the table is empty. If we don't check for this condition, the program fails with Error 0xc0000142. Also, I add a regression test for Windows. Differential Revision: https://reviews.llvm.org/D28502 llvm-svn: 292747
This commit is contained in:
parent
15fbf682a1
commit
4e12600c90
|
@ -878,6 +878,8 @@ uptr InternalGetProcAddress(void *module, const char *func_name) {
|
|||
|
||||
IMAGE_DATA_DIRECTORY *export_directory =
|
||||
&headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||
if (export_directory->Size == 0)
|
||||
return 0;
|
||||
RVAPtr<IMAGE_EXPORT_DIRECTORY> exports(module,
|
||||
export_directory->VirtualAddress);
|
||||
RVAPtr<DWORD> functions(module, exports->AddressOfFunctions);
|
||||
|
|
|
@ -1,5 +1,30 @@
|
|||
set(INTERCEPTION_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
|
||||
set(INTERCEPTION_TESTSUITES)
|
||||
set(INTERCEPTION_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
foreach(arch ${SANITIZER_COMMON_SUPPORTED_ARCH})
|
||||
set(INTERCEPTION_TEST_TARGET_ARCH ${arch})
|
||||
set(CONFIG_NAME ${arch}-${OS_NAME})
|
||||
|
||||
get_test_cc_for_arch(${arch} INTERCEPTION_TEST_TARGET_CC
|
||||
INTERCEPTION_TEST_TARGET_CFLAGS)
|
||||
|
||||
string(TOUPPER ${arch} ARCH_UPPER_CASE)
|
||||
set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
|
||||
set(INTERCEPTION_TEST_TARGET_LIB RTInterception.test.${arch})
|
||||
|
||||
get_property(INTERCEPTION_TEST_TARGET_LIB_DIR TARGET
|
||||
${INTERCEPTION_TEST_TARGET_LIB} PROPERTY ARCHIVE_OUTPUT_DIRECTORY)
|
||||
|
||||
configure_lit_site_cfg(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg
|
||||
)
|
||||
|
||||
list(APPEND INTERCEPTION_TESTSUITES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
|
||||
list(APPEND INTERCEPTION_TEST_DEPS RTInterception.test.${arch})
|
||||
endforeach()
|
||||
|
||||
# Unit tests. There are currently no unit tests capable to running on Apple or
|
||||
# Android targets.
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// RUN: %clang_cl %s %inter_lib -o %t
|
||||
// RUN: %run %t 2>&1 | FileCheck %s
|
||||
// CHECK: OK
|
||||
|
||||
#include "interception/interception.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
// We try to get a pointer to a function from an executable that doesn't export
|
||||
// any symbol (empty export table).
|
||||
int main() {
|
||||
__sanitizer::uptr FunPtr = __interception::InternalGetProcAddress(
|
||||
(void *)GetModuleHandleA(0), "exampleFun");
|
||||
if (FunPtr == 0)
|
||||
printf("OK");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
def getRoot(config):
|
||||
if not config.parent:
|
||||
return config
|
||||
return getRoot(config.parent)
|
||||
|
||||
root = getRoot(config)
|
||||
|
||||
if root.host_os not in ['Windows']:
|
||||
config.unsupported = True
|
|
@ -0,0 +1,28 @@
|
|||
# -*- Python -*-
|
||||
|
||||
# Setup source root.
|
||||
config.test_source_root = os.path.join(os.path.dirname(__file__), "TestCases")
|
||||
|
||||
# Setup config name.
|
||||
config.name = "Interception"
|
||||
|
||||
# Add library sustitutions.
|
||||
if config.host_os == 'Windows':
|
||||
libpath = os.path.join(config.target_lib_dir, config.target_lib + ".lib")
|
||||
config.substitutions.append( ("%inter_lib", libpath))
|
||||
else:
|
||||
libpath = os.path.join(config.target_lib_dir, "lib" + config.target_lib + ".a")
|
||||
config.substitutions.append( ("%inter_lib", libpath))
|
||||
|
||||
# Add clang substitutions.
|
||||
config.substitutions.append( ("%clang ", " ".join([config.clang,
|
||||
config.target_cflags, "-I"+config.sources_dir, ""]) ))
|
||||
|
||||
# Configure clang_cl for Windows.
|
||||
if config.host_os == 'Windows':
|
||||
clang_cl_invocation = config.clang.replace("clang.exe","clang-cl.exe")
|
||||
config.substitutions.append( ("%clang_cl ", " ".join([clang_cl_invocation,
|
||||
config.target_cflags, "/I"+config.sources_dir, ""]) ))
|
||||
|
||||
# Files to be considered for tests.
|
||||
config.suffixes = ['.c', '.cc', '.cpp']
|
|
@ -0,0 +1,15 @@
|
|||
@LIT_SITE_CFG_IN_HEADER@
|
||||
|
||||
# Tool-specific config options.
|
||||
config.target_cflags = "@INTERCEPTION_TEST_TARGET_CFLAGS@"
|
||||
config.clang = "@INTERCEPTION_TEST_TARGET_CC@"
|
||||
config.target_arch = "@INTERCEPTION_TEST_TARGET_ARCH@"
|
||||
config.target_lib = "@INTERCEPTION_TEST_TARGET_LIB@"
|
||||
config.target_lib_dir = "@INTERCEPTION_TEST_TARGET_LIB_DIR@"
|
||||
config.sources_dir = os.path.join("@COMPILER_RT_SOURCE_DIR@", "lib")
|
||||
|
||||
# Load common config for all compiler-rt lit tests.
|
||||
lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
|
||||
|
||||
# Load tool-specific config that would do the real work.
|
||||
lit_config.load_config(config, "@INTERCEPTION_LIT_SOURCE_DIR@/lit.cfg")
|
Loading…
Reference in New Issue