Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -506,19 +506,29 @@ endif()
# KLEE uclibc support
################################################################################
set(KLEE_UCLIBC_PATH "" CACHE PATH "Path to klee-uclibc root directory")
set(KLEE_UCLIBC_BCA_NAME "klee-uclibc.bca")

set(KLEE_UCLIBC_BCA_32_NAME "klee-uclibc-32.bca")
set(KLEE_UCLIBC_BCA_64_NAME "klee-uclibc-64.bca")

if (NOT KLEE_UCLIBC_PATH STREQUAL "")
# Find the C library bitcode archive
set(KLEE_UCLIBC_C_BCA "${KLEE_UCLIBC_PATH}/lib/libc.a")
if (NOT EXISTS "${KLEE_UCLIBC_C_BCA}")
set(KLEE_UCLIBC_C_32_BCA "${KLEE_UCLIBC_PATH}-32/lib/libc.a")
set(KLEE_UCLIBC_C_64_BCA "${KLEE_UCLIBC_PATH}-64/lib/libc.a")

if (NOT EXISTS "${KLEE_UCLIBC_C_32_BCA}" OR NOT EXISTS "${KLEE_UCLIBC_C_64_BCA}")
message(FATAL_ERROR
"klee-uclibc library not found at \"${KLEE_UCLIBC_C_BCA}\". Set KLEE_UCLIBC_PATH to klee-uclibc root directory or empty string.")
"klee-uclibc library not found at \"${KLEE_UCLIBC_C_32_BCA}\" or \"${KLEE_UCLIBC_C_64_BCA}\". Set KLEE_UCLIBC_PATH to klee-uclibc root directory or empty string.")
endif()
message(STATUS "Found klee-uclibc library: \"${KLEE_UCLIBC_C_BCA}\"")
message(STATUS "Found klee-uclibc library: \"${KLEE_UCLIBC_C_32_BCA}\" and \"${KLEE_UCLIBC_C_64_BCA}\"")
# Copy KLEE_UCLIBC_C_BCA so KLEE can find it where it is expected.
# Create 32 and 64 bit versions
execute_process(COMMAND ${CMAKE_COMMAND} -E copy
"${KLEE_UCLIBC_C_32_BCA}"
"${KLEE_RUNTIME_DIRECTORY}/${KLEE_UCLIBC_BCA_32_NAME}"
)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy
"${KLEE_UCLIBC_C_BCA}"
"${KLEE_RUNTIME_DIRECTORY}/${KLEE_UCLIBC_BCA_NAME}"
"${KLEE_UCLIBC_C_64_BCA}"
"${KLEE_RUNTIME_DIRECTORY}/${KLEE_UCLIBC_BCA_64_NAME}"
)
else()
message(STATUS "Skipping copying of klee-uclibc runtime")
Expand Down
5 changes: 4 additions & 1 deletion include/klee/Config/config.h.cmin
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@
#define RUNTIME_CONFIGURATION "@KLEE_RUNTIME_BUILD_TYPE@"

/* Configure name of KLEE's uClibc library */
#cmakedefine KLEE_UCLIBC_BCA_NAME "@KLEE_UCLIBC_BCA_NAME@"
#cmakedefine KLEE_UCLIBC_BCA_32_NAME "@KLEE_UCLIBC_BCA_32_NAME@"

/* Configure name of KLEE's uClibc library */
#cmakedefine KLEE_UCLIBC_BCA_64_NAME "@KLEE_UCLIBC_BCA_64_NAME@"

/* Configure name of the libCXX bitcode library */
#cmakedefine KLEE_LIBCXX_BC_NAME "@KLEE_LIBCXX_BC_NAME@"
Expand Down
26 changes: 20 additions & 6 deletions lib/Core/Executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,14 +720,29 @@ void Executor::allocateGlobalObjects(ExecutionState &state) {
}

#ifndef WINDOWS
int *errno_addr = getErrnoLocation(state);

llvm::Type *pointerErrnoAddr = llvm::PointerType::get(
llvm::IntegerType::get(m->getContext(), sizeof(*errno_addr) * CHAR_BIT),
adressSpaceNum);
MemoryObject *errnoObj =
addExternalObject(state, (void *)errno_addr,
typeSystemManager->getWrappedType(pointerErrnoAddr),
sizeof *errno_addr, false);
MemoryObject *errnoObj = nullptr;

if (Context::get().getPointerWidth() == 32) {
errnoObj = allocate(state, Expr::createPointer(sizeof(*errno_addr)), false,
true, nullptr, 8);
errnoObj->isFixed = true;

ObjectState *os = bindObjectInState(
state, errnoObj, typeSystemManager->getWrappedType(pointerErrnoAddr),
false);
errno_addr = reinterpret_cast<int *>(errnoObj->address);
} else {
errno_addr = getErrnoLocation(state);
errnoObj =
addExternalObject(state, (void *)errno_addr,
typeSystemManager->getWrappedType(pointerErrnoAddr),
sizeof *errno_addr, false);
}

// Copy values from and to program space explicitly
errnoObj->isUserSpecified = true;
#endif
Expand Down Expand Up @@ -4867,7 +4882,6 @@ void Executor::callExternalFunction(ExecutionState &state, KInstruction *target,
state.addressSpace.copyOutConcretes();
#ifndef WINDOWS
// Update external errno state with local state value
int *errno_addr = getErrnoLocation(state);
IDType idResult;

llvm::Type *pointerErrnoAddr = llvm::PointerType::get(
Expand Down
2 changes: 2 additions & 0 deletions lib/Core/Executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ class Executor : public Interpreter {
RNG theRNG;

private:
int *errno_addr;

using SetOfStates = std::set<ExecutionState *, ExecutionStateIDCompare>;
/* Set of Intrinsic::ID. Plain type is used here to avoid including llvm in
* the header */
Expand Down
3 changes: 2 additions & 1 deletion lib/Core/SpecialFunctionHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,8 @@ void SpecialFunctionHandler::handleErrnoLocation(
"invalid number of arguments to __errno_location/__error");

#ifndef WINDOWS
int *errno_addr = executor.getErrnoLocation(state);
// int *errno_addr = executor.getErrnoLocation(state);
int *errno_addr = executor.errno_addr;
#else
int *errno_addr = nullptr;
#endif
Expand Down
20 changes: 16 additions & 4 deletions scripts/build/p-uclibc.inc
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@ setup_build_variables_uclibc() {

download_uclibc() {
source "${DIR}/common-functions"
git_clone_or_update "${uclibc_url}" "${UCLIBC_PATH}" "${UCLIBC_VERSION}"
git_clone_or_update "${uclibc_url}" "${UCLIBC_PATH}-32" "${UCLIBC_VERSION}"
git_clone_or_update "${uclibc_url}" "${UCLIBC_PATH}-64" "${UCLIBC_VERSION}"
}

build_uclibc() {
cd "${UCLIBC_PATH}" || return 1
pushd "${UCLIBC_PATH}-32" || return 1
./configure --make-llvm-lib --with-cc "${BITCODE_CC}" --with-llvm-config "${LLVM_CONFIG}"
make KLEE_CFLAGS="-m32" || return 1
touch .is_installed
popd &>/dev/null

pushd "${UCLIBC_PATH}-64" || return 1
./configure --make-llvm-lib --with-cc "${BITCODE_CC}" --with-llvm-config "${LLVM_CONFIG}"
make || return 1
touch .is_installed
Expand All @@ -24,7 +31,11 @@ install_uclibc() {
is_installed_uclibc() {
(
setup_build_variables_uclibc
[[ -f "${UCLIBC_PATH}"/.is_installed ]]
[[ -f "${UCLIBC_PATH}-32"/.is_installed ]]
) || return 1
(
setup_build_variables_uclibc
[[ -f "${UCLIBC_PATH}-64"/.is_installed ]]
) || return 1
}

Expand All @@ -40,7 +51,8 @@ get_docker_config_id_uclibc() {
get_build_artifacts_uclibc() {
(
setup_build_variables_uclibc
echo "${UCLIBC_PATH}"
echo "${UCLIBC_PATH}-32"
echo "${UCLIBC_PATH}-64"
)
}

Expand Down
12 changes: 11 additions & 1 deletion tools/klee/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,17 @@ linkWithUclibc(StringRef libDir, std::string opt_suffix,

// Ensure that klee-uclibc exists
SmallString<128> uclibcBCA(libDir);
llvm::sys::path::append(uclibcBCA, KLEE_UCLIBC_BCA_NAME);
// Hack to find out bitness of .bc file

if (opt_suffix.substr(0, 2) == "32") {
llvm::sys::path::append(uclibcBCA, KLEE_UCLIBC_BCA_32_NAME);
} else if (opt_suffix.substr(0, 2) == "64") {
llvm::sys::path::append(uclibcBCA, KLEE_UCLIBC_BCA_64_NAME);
} else {
klee_error("Cannot determine bitness of source file from the name %s",
uclibcBCA.c_str());
}

if (!klee::loadFileAsOneModule(uclibcBCA.c_str(), ctx, libsModules, errorMsg))
klee_error("Cannot find klee-uclibc '%s': %s", uclibcBCA.c_str(),
errorMsg.c_str());
Expand Down