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
10 changes: 10 additions & 0 deletions .github/workflows/fuzzing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ jobs:
env:
VXS_FUZZ_CORPUS: ${{ runner.temp }}/vxs-fuzz-corpus
run: go run ./helpers/cmd/develop fuzz
- name: Run bounded ThreadSanitizer ownership campaign
shell: bash
env:
VXS_FUZZ_CORPUS: ${{ runner.temp }}/vxs-fuzz-corpus
run: go run ./helpers/cmd/develop fuzz-thread
- name: Run nightly ASan and UBSan stress campaign
if: github.event_name == 'schedule'
shell: bash
Expand Down Expand Up @@ -216,6 +221,11 @@ jobs:
env:
VXS_FUZZ_CORPUS: ${{ runner.temp }}/vxs-fuzz-corpus
run: go run ./helpers/cmd/develop fuzz
- name: Run bounded ThreadSanitizer ownership campaign
shell: bash
env:
VXS_FUZZ_CORPUS: ${{ runner.temp }}/vxs-fuzz-corpus
run: go run ./helpers/cmd/develop fuzz-thread
- name: Run nightly ASan and UBSan stress campaign
if: github.event_name == 'schedule'
shell: bash
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/language-layers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ jobs:
working-directory: Compiler
run: cabal test visual-xsharp-compiler-tests

- name: Test frontend fuzz feedback and mutation policy
shell: pwsh
working-directory: Compiler
run: cabal test fuzz-feedback-tests

- name: Check Haskell package metadata
shell: pwsh
run: |
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ bin/
xide_api/
xide/
.codex/
.claude/
.agents/
.gradle/
.kotlin/
*.sqlite3
node_modules/
dist/
dist-newstyle/
dist-fuzz-coverage/
*.tix
coverage/
*.profraw
*.profdata
Expand Down
7 changes: 7 additions & 0 deletions Compiler/Backend/LLVM/Codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ namespace Visual::XSharp::Backend::LLVM
result->append(*spelling);
result->append(".");
result->append(std::to_string(function.symbol.id));
// LLVM reserves every global name beginning with `llvm.` for
// intrinsics and rejects a module that defines one, but `llvm`
// is an ordinary namespace name in source. `$` cannot occur in
// a source identifier, so the prefixed name is unambiguous and
// cannot collide with another module's symbol.
if (result->starts_with("llvm."))
result->insert(0U, 1U, '$');
return result;
}

Expand Down
36 changes: 35 additions & 1 deletion Compiler/Backend/LLVM/JitSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
#include <utility>
#include <vector>

#ifdef _WIN32
// Only the Windows linking layer below needs these. Other hosts build against
// distribution LLVM releases whose memory manager has no reservation mode.
# include <llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h>
# include <llvm/ExecutionEngine/SectionMemoryManager.h>
#endif

#include "Visual/XSharp/Backend/LLVM.hpp"
#include "Visual/XSharp/Core/Scalar.hpp"

Expand Down Expand Up @@ -262,7 +269,34 @@ namespace Visual::XSharp::Backend::LLVM
return;
}

auto created = llvm::orc::LLJITBuilder().create();
llvm::orc::LLJITBuilder builder;
#ifdef _WIN32
// Win64 unwind tables use image-relative relocations, which
// RuntimeDyld can only apply when no section of an object
// lies below the lowest one it has already seen. The default
// memory manager maps code and data sections separately, so
// the host decides their order and some address layouts
// abort linking with "relocation requires an ordered section
// layout". Reserving one contiguous block per object fixes
// the order: every section is carved from that reservation.
builder.setObjectLinkingLayerCreator(
[](llvm::orc::ExecutionSession &session)
-> llvm::Expected<std::unique_ptr<llvm::orc::ObjectLayer>> {
auto layer
= std::make_unique<llvm::orc::RTDyldObjectLinkingLayer>(
session,
[](const llvm::MemoryBuffer &) {
return std::make_unique<
llvm::SectionMemoryManager>(nullptr, true);
});
// Same COFF symbol-flag handling as LLJIT's default
// linking layer.
layer->setOverrideObjectFlagsWithResponsibilityFlags(true);
layer->setAutoClaimResponsibilityForObjectSymbols(true);
return layer;
});
#endif
auto created = builder.create();
if (!created)
{
initializationError
Expand Down
3 changes: 3 additions & 0 deletions Compiler/Backend/LLVM/Tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ cc_binary(
"CallableInvocationTests.cpp",
"LLVMBackendTests.cpp",
"JitSessionTests.cpp",
"LoopExecutionTests.cpp",
"ReservedSymbolTests.cpp",
"ShortCircuitExecutionTests.cpp",
],
deps = [
"//Compiler/Backend/LLVM:llvm_backend",
Expand Down
18 changes: 18 additions & 0 deletions Compiler/Backend/LLVM/Tests/JitSessionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,21 @@ TEST_CASE(
REQUIRE(after);
REQUIRE(std::get<std::int64_t>(after.value->payload) == 73);
}

TEST_CASE("ORC sessions link unwind metadata regardless of section placement",
"[llvm][orc][layout]")
{
// Win64 objects carry image-relative unwind relocations that are only
// valid when every section of the object lies above its lowest one. The
// host places separately mapped sections at arbitrary addresses, so a
// linker that maps each section on its own fails for some layouts only.
// Many independent sessions sample those layouts; each must link and run.
constexpr int kSessions = 400;
for (int index = 0; index < kSessions; ++index)
{
const auto result
= InvokeConstant(std::int64_t{ index }, Core::Type::int64());
REQUIRE(result);
REQUIRE(std::get<std::int64_t>(result.value->payload) == index);
}
}
Loading
Loading