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
8 changes: 4 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v4

- name: install dependencies
run: sudo apt-get update && sudo apt-get install -y llvm-14 clang-14 libc++-14-dev libc++abi-14-dev python3-minimal libgoogle-perftools-dev libboost-container-dev python3-dev libbsd-dev
run: sudo apt-get update && sudo apt-get install -y llvm-18 clang-18 libc++-18-dev libc++abi-18-dev libunwind-18-dev python3-minimal libgoogle-perftools-dev libboost-container-dev python3-dev libbsd-dev

- name: Cache Z3
id: cache-z3
Expand Down Expand Up @@ -51,13 +51,13 @@ jobs:
path: ${{ github.workspace }}/aflpp

- name: configure
run: CC=clang-14 CXX=clang++-14 cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install -DAFLPP_PATH=${{ github.workspace }}/aflpp
run: CC=clang-18 CXX=clang++-18 cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install -DAFLPP_PATH=${{ github.workspace }}/aflpp -DLLVM_DIR=/usr/lib/llvm-18/lib/cmake/llvm

- name: build
run: CC=clang-14 CXX=clang++-14 cmake --build ${{ github.workspace }}/build
run: CC=clang-18 CXX=clang++-18 cmake --build ${{ github.workspace }}/build

- name: install
run: CC=clang-14 CXX=clang++-14 cmake --install ${{ github.workspace }}/build
run: CC=clang-18 CXX=clang++-18 cmake --install ${{ github.workspace }}/build

- name: install lit
run: pip install lit
Expand Down
9 changes: 8 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)

project(symsan VERSION 1.2.2 LANGUAGES C CXX ASM)

find_package(LLVM 14 REQUIRED CONFIG)
find_package(LLVM REQUIRED CONFIG)

# Find Z3 (minimum version 4.8.15 required for string theory APIs)
# Prefer /usr/local over system
Expand Down Expand Up @@ -44,6 +44,13 @@ if (LLVM_FOUND)
message(STATUS "LLVM_VERSION_MAJOR: ${LLVM_VERSION_MAJOR}")
message(STATUS "LLVM_VERSION_MINOR: ${LLVM_VERSION_MINOR}")
message(STATUS "LLVM_VERSION_PATCH: ${LLVM_VERSION_PATCH}")
# SymSan requires LLVM >= 18 (the default on Ubuntu 24.04). Older versions
# predate opaque pointers and the DFSan trampoline removal and are no longer
# supported. (find_package(LLVM 18) can't be used: LLVM's version config
# requires an exact major.minor match.)
if (LLVM_VERSION_MAJOR LESS 18)
message(FATAL_ERROR "SymSan requires LLVM >= 18, found ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}")
endif()
else()
message(FATAL_ERROR "You haven't install LLVM !")
endif()
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ it has more strict dependency on the LLVM version. Right now only LLVM 12 is tes
### Build Requirements

- Linux-amd64 (Tested on Ubuntu 24.04)
- [LLVM 14.0.6](http://llvm.org/docs/index.html): clang, libc++, libc++abi
- [LLVM 18.1.18](http://llvm.org/docs/index.html): clang, libc++, libc++abi

### Compilation

Create a `build` directory and execute the following commands in it:

```shell
$ CC=clang-14 CXX=clang++-14 cmake -DCMAKE_INSTALL_PREFIX=/path/to/install -DCMAKE_BUILD_TYPE=Release /path/to/symsan/source
$ CC=clang-18 CXX=clang++-18 cmake -DCMAKE_INSTALL_PREFIX=/path/to/install -DCMAKE_BUILD_TYPE=Release /path/to/symsan/source
$ make
$ make install
```
Expand Down
4 changes: 4 additions & 0 deletions compiler/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
add_executable(KOClang ko_clang.c)
set_target_properties(KOClang PROPERTIES OUTPUT_NAME "ko-clang")
# Let the driver version-gate the clang flags it forwards.
target_compile_definitions(KOClang PRIVATE
LLVM_VERSION_MAJOR=${LLVM_VERSION_MAJOR}
LLVM_VERSION_MINOR=${LLVM_VERSION_MINOR})

add_custom_command(TARGET KOClang POST_BUILD
COMMAND ln -sf "ko-clang" "ko-clang++")
Expand Down
4 changes: 4 additions & 0 deletions compiler/ko_clang.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,11 @@ static void edit_params(u32 argc, char **argv) {
}

if (!skip_instrumentation) {
// The new pass manager is the default since clang 13 and the flag that
// used to request it was removed in clang 16.
#if LLVM_VERSION_CODE < LLVM_VERSION(16, 0)
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
#endif
// add UCSanPass first, if specified
if (use_ucsan) {
add_ucsan_pass();
Expand Down
23 changes: 10 additions & 13 deletions compiler/ucsan_opt
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ else:
print(f"Cannot find {ucsan_pass_path}, please make sure you have run this script in the right directory(the directory ko-clang installed)")
os._exit(1)

KO_FLAGS = ["KO_CC=clang-14"]
KO_FLAGS = ["KO_CC=clang-18"]
ko_flags = ' '.join(KO_FLAGS)

# Base opt-14 command: load UCSan pass
# Load library twice for LLVM-14:
# -load: registers cl::opt definitions (command-line options)
# -load-pass-plugin: registers the new pass manager plugin
cc = f"opt-14 -load {path_to_install}/lib/symsan/UCSanPass.so" \
f" -load-pass-plugin={path_to_install}/lib/symsan/UCSanPass.so" \
# Base opt command: load the UCSan pass plugin. On LLVM 18 -load-pass-plugin
# alone registers both the new-PM pipeline and the pass's cl::opt options (the
# separate -load needed on LLVM 14 is no longer required).
cc = f"opt-18 -load-pass-plugin={path_to_install}/lib/symsan/UCSanPass.so" \
f" -ucsan-abilist={path_to_install}/lib/symsan/ucsan_abilist.txt"

ko_cc = f"{path_to_install}/bin/ko-clang"
Expand Down Expand Up @@ -66,8 +64,8 @@ if not files:
argparser.print_usage()
os._exit(1)

# Note: With LLVM-14 new pass manager, we don't add -O# flags to opt
# Optimization is controlled via KO_DONT_OPTIMIZE and handled by ko-clang
# Note: with the new pass manager we don't add -O# flags to opt;
# optimization is controlled via KO_DONT_OPTIMIZE and handled by ko-clang
if not args.optimization:
KO_FLAGS.append("KO_DONT_OPTIMIZE=1")

Expand Down Expand Up @@ -98,9 +96,8 @@ if args.taint:
os._exit(1)
# Tell UCSanPass that TaintPass will run after it
cc += f" -ucsan-with-taint=true"
# Load TaintPass library for cl::opt and pass registration
cc += f" -load {taint_pass_path}" \
f" -load-pass-plugin={taint_pass_path}" \
# Load TaintPass plugin (registers its pipeline and cl::opt options)
cc += f" -load-pass-plugin={taint_pass_path}" \
f" -taint-abilist={path_to_install}/lib/symsan/dfsan_abilist.txt" \
f" -taint-with-ucsan=true" \
f" -taint-solve-ub=true"
Expand Down Expand Up @@ -138,7 +135,7 @@ for file in files:
cleanup()
os._exit(1)
tmp_files.append(bc_file)
ret = command(f"llc-14 -filetype=obj --relocation-model=pic -o {obj_file} {bc_file}")
ret = command(f"llc-18 -filetype=obj --relocation-model=pic -o {obj_file} {bc_file}")
if ret != 0:
print(f"Failed to compile {file}, check the error message above")
cleanup()
Expand Down
45 changes: 8 additions & 37 deletions include/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,14 @@
#define LLVM_VERSION(major, minor) ((major)*100 + (minor))
#define LLVM_VERSION_CODE LLVM_VERSION(LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR)

#if LLVM_VERSION_CODE >= LLVM_VERSION(5, 0)
#define LLVM_ATTRIBUTE_LIST AttributeList

#define LLVM_NEW_ALLOCINST(ty, name, insertp) \
(new AllocaInst(ty, getDataLayout().getAllocaAddrSpace(), name, insertp))

#define LLVM_REMOVE_ATTRIBUTE(func, attr, attrbuilder) \
func->removeAttributes(attr, attrbuilder)

#else

#define LLVM_ATTRIBUTE_LIST AttributeSet

#define LLVM_NEW_ALLOCINST(ty, name, insertp) \
(new AllocaInst(ty, name, insertp))

#define LLVM_REMOVE_ATTRIBUTE(func, attr, attrbuilder) \
func->removeAttributes( \
attr, LLVM_ATTRIBUTE_LIST::get(func->getContext(), attr, attrbuilder))

#endif

#if LLVM_VERSION_CODE >= LLVM_VERSION(6, 0)

#define SCL_INSECTION(scl, section, prefix, query, category) \
scl->inSection(section, prefix, query, category)

#define LLVM_ADD_PARAM_ATTR(func, argno, attr) func->addParamAttr(argno, attr)

#else

#define SCL_INSECTION(scl, section, prefix, query, category) \
scl->inSection(prefix, query, category)

#define LLVM_ADD_PARAM_ATTR(func, argno, attr) \
func->addAttribute(argno + 1, attr)

// SymSan targets LLVM 18 (the default on Ubuntu 24.04) as its minimum. These
// headers are only needed by C++ translation units built against LLVM; the
// compiler-driver C sources include this file only for the LLVM_VERSION macros
// above.
#if defined(__cplusplus) && defined(LLVM_VERSION_MAJOR)
#include <optional>
#include "llvm/TargetParser/Triple.h"
#include "llvm/IR/AttributeMask.h"
#endif

#endif
2 changes: 1 addition & 1 deletion instrumentation/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
# fix pass bug: https://github.com/sampsyo/llvm-pass-skeleton/issues/7#issuecomment-401834287
set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-znodelete")
Expand Down
11 changes: 7 additions & 4 deletions instrumentation/LoopOutlinePass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/ADT/SetVector.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/BasicBlock.h"
Expand Down Expand Up @@ -207,7 +208,7 @@ collectGlobals(Function *Out) {
for (Instruction &I : BB)
for (Value *Op : I.operands())
if (auto *gv = dyn_cast<GlobalVariable>(Op->stripPointerCasts()))
if (!gv->getName().startswith("llvm.") && !gv->getName().empty())
if (!(gv->getName()).starts_with("llvm.") && !gv->getName().empty())
gvs.insert(gv);
std::vector<std::pair<std::string, std::string>> out;
for (GlobalVariable *gv : gvs) {
Expand Down Expand Up @@ -240,10 +241,12 @@ static Function *extractTarget(const Target &T, unsigned Idx) {
DT.recalculate(*T.F);

CodeExtractorAnalysisCache CEAC(*T.F);
// NOTE: the trailing Suffix argument is intentionally left at its default;
// LLVM 18 inserted an AllocationBlock parameter before it, so passing it
// positionally is not source-compatible across versions.
CodeExtractor CE(T.Blocks, &DT, /*AggregateArgs=*/false,
/*BFI=*/nullptr, /*BPI=*/nullptr, /*AC=*/nullptr,
/*AllowVarArgs=*/false, /*AllowAlloca=*/false,
/*Suffix=*/"");
/*AllowVarArgs=*/false, /*AllowAlloca=*/false);
if (!CE.isEligible()) {
if (ClVerbose)
errs() << "[loop-outline] skip " << T.F->getName()
Expand Down Expand Up @@ -274,7 +277,7 @@ struct LoopOutlinePass : public PassInfoMixin<LoopOutlinePass> {
// Phase 1 (read-only): gather innermost-loop body regions.
std::vector<Target> Targets;
for (Function &F : M) {
if (F.isDeclaration() || F.getName().startswith("__ucsan_loopbody_"))
if (F.isDeclaration() || (F.getName()).starts_with("__ucsan_loopbody_"))
continue;
DominatorTree DT;
DT.recalculate(F);
Expand Down
Loading
Loading