Skip to content
Open
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
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,10 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__aarch64__");
}

if (getTriple().isVendorLFI()) {
Builder.defineMacro("__LFI__");
}

// Inline assembly supports AArch64 flag outputs.
Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");

Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
DefineStd(Builder, "i386", Opts);
}

if (getTriple().isVendorLFI()) {
Builder.defineMacro("__LFI__");
}

Builder.defineMacro("__SEG_GS");
Builder.defineMacro("__SEG_FS");
Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))");
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ add_clang_library(clangDriver
ToolChains/Hexagon.cpp
ToolChains/HLSL.cpp
ToolChains/Hurd.cpp
ToolChains/LFILinux.cpp
ToolChains/Linux.cpp
ToolChains/MipsLinux.cpp
ToolChains/MinGW.cpp
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "ToolChains/Haiku.h"
#include "ToolChains/Hexagon.h"
#include "ToolChains/Hurd.h"
#include "ToolChains/LFILinux.h"
#include "ToolChains/Lanai.h"
#include "ToolChains/Linux.h"
#include "ToolChains/MSP430.h"
Expand Down Expand Up @@ -6654,6 +6655,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args);
else if (Target.isOHOSFamily())
TC = std::make_unique<toolchains::OHOS>(*this, Target, Args);
else if (Target.getVendor() == llvm::Triple::LFI)
TC = std::make_unique<toolchains::LFILinuxToolChain>(*this, Target, Args);
else
TC = std::make_unique<toolchains::Linux>(*this, Target, Args);
break;
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
else if (MABI.starts_with_insensitive("lp64")) {
if (Triple.isAndroid())
return "rv64imafdcv_zba_zbb_zbs";
if (Triple.isVendorLFI())
return "rv64imafdc_zba_zbb";

return "rv64imafdc";
}
Expand All @@ -345,6 +347,8 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
return "rv64imac";
else if (Triple.isAndroid())
return "rv64imafdcv_zba_zbb_zbs";
else if (Triple.isVendorLFI())
return "rv64imafdc_zba_zbb";
else
return "rv64imafdc";
}
Expand Down
29 changes: 29 additions & 0 deletions clang/lib/Driver/ToolChains/LFILinux.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===-- LFILinux.cpp - LFI ToolChain Implementations ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "LFILinux.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Options.h"

using namespace clang::driver::toolchains;
using namespace llvm::opt;

void LFILinuxToolChain::AddCXXStdlibLibArgs(
const ArgList &Args, ArgStringList &CmdArgs) const {
switch (GetCXXStdlibType(Args)) {
case ToolChain::CST_Libcxx:
CmdArgs.push_back("-lc++");
if (Args.hasArg(options::OPT_fexperimental_library))
CmdArgs.push_back("-lc++experimental");
CmdArgs.push_back("-lc++abi");
break;
case ToolChain::CST_Libstdcxx:
CmdArgs.push_back("-lstdc++");
break;
}
}
38 changes: 38 additions & 0 deletions clang/lib/Driver/ToolChains/LFILinux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===--- LFILinux.h - LFI ToolChain Implementations -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LFI_LINUX_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LFI_LINUX_H

#include "Linux.h"

namespace clang {
namespace driver {
namespace toolchains {

class LLVM_LIBRARY_VISIBILITY LFILinuxToolChain : public Linux {
public:
LFILinuxToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args)
: Linux(D, Triple, Args) {
ExtraOpts.push_back("-z");
ExtraOpts.push_back("separate-code");
ExtraOpts.push_back("-z");
ExtraOpts.push_back("lfi");
}

void
AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
};

} // end namespace toolchains
} // end namespace driver
} // end namespace clang

#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_LFI_LINUX_H
189 changes: 165 additions & 24 deletions clang/tools/driver/cc1as_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include <memory>
#include <optional>
#include <system_error>
#include <sstream>
using namespace clang;
using namespace clang::driver;
using namespace clang::driver::options;
Expand Down Expand Up @@ -539,6 +540,13 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
MCOptions.MCUseDwarfDirectory = MCTargetOptions::EnableDwarfDirectory;
MCOptions.ABIName = Opts.TargetABI;

MAI->setPreserveAsmComments(false);

Expected<sys::fs::TempFile> AsmTemp =
sys::fs::TempFile::create("asm.temp-%%%%%%%.s");
if (!AsmTemp)
return false;

// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
MCInstPrinter *IP = TheTarget->createMCInstPrinter(
Expand All @@ -558,31 +566,52 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
} else {
assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
"Invalid file type!");
if (!FDOS->supportsSeeking()) {
BOS = std::make_unique<buffer_ostream>(*FDOS);
Out = BOS.get();
}

std::unique_ptr<MCCodeEmitter> CE(
TheTarget->createMCCodeEmitter(*MCII, Ctx));
std::unique_ptr<MCAsmBackend> MAB(
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
assert(MAB && "Unable to create asm backend!");

std::unique_ptr<MCObjectWriter> OW =
DwoOS ? MAB->createDwoObjectWriter(*Out, *DwoOS)
: MAB->createObjectWriter(*Out);

Triple T(Opts.Triple);
Str.reset(TheTarget->createMCObjectStreamer(
T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI));
Str.get()->initSections(Opts.NoExecStack, *STI);
if (T.isOSBinFormatMachO() && T.isOSDarwin()) {
Triple *TVT = Opts.DarwinTargetVariantTriple
? &*Opts.DarwinTargetVariantTriple
: nullptr;
Str->emitVersionForTarget(T, VersionTuple(), TVT,
Opts.DarwinTargetVariantSDKVersion);
if (llvm::Triple(Opts.Triple).isVendorLFI()) {
// When compiling .S files, LLVM generates debug info that cannot be
// assembled unless we turn this off here. Encountered when compiling
// sanitizers (asan_interceptors_vfork.S).
Ctx.setGenDwarfForAssembly(false);
MCInstPrinter *IP = TheTarget->createMCInstPrinter(
llvm::Triple(Opts.Triple), Opts.OutputAsmVariant, *MAI, *MCII, *MRI);

std::unique_ptr<MCCodeEmitter> CE;
if (Opts.ShowEncoding)
CE.reset(TheTarget->createMCCodeEmitter(*MCII, Ctx));
std::unique_ptr<MCAsmBackend> MAB(
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));

raw_fd_ostream* Tmp = new raw_fd_ostream(AsmTemp->FD, false);
auto TempOut = std::make_unique<formatted_raw_ostream>(*Tmp);
Str.reset(TheTarget->createAsmStreamer(Ctx, std::move(TempOut), IP,
std::move(CE), std::move(MAB)));
} else {
if (!FDOS->supportsSeeking()) {
BOS = std::make_unique<buffer_ostream>(*FDOS);
Out = BOS.get();
}

std::unique_ptr<MCCodeEmitter> CE(
TheTarget->createMCCodeEmitter(*MCII, Ctx));
std::unique_ptr<MCAsmBackend> MAB(
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
assert(MAB && "Unable to create asm backend!");

std::unique_ptr<MCObjectWriter> OW =
DwoOS ? MAB->createDwoObjectWriter(*Out, *DwoOS)
: MAB->createObjectWriter(*Out);

Triple T(Opts.Triple);
Str.reset(TheTarget->createMCObjectStreamer(
T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI));
Str.get()->initSections(Opts.NoExecStack, *STI);
if (T.isOSBinFormatMachO() && T.isOSDarwin()) {
Triple *TVT = Opts.DarwinTargetVariantTriple
? &*Opts.DarwinTargetVariantTriple
: nullptr;
Str->emitVersionForTarget(T, VersionTuple(), TVT,
Opts.DarwinTargetVariantSDKVersion);
}
}
}

Expand Down Expand Up @@ -622,6 +651,118 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
Failed = Parser->Run(Opts.NoInitialTextSection);
}

const auto& triple = llvm::Triple(Opts.Triple);
if (triple.isVendorLFI()) {
Expected<sys::fs::TempFile> RewriteTemp =
sys::fs::TempFile::create("rewrite.temp-%%%%%%%.s");
if (!RewriteTemp) {
consumeError(AsmTemp->discard());
return false;
}

const char* LFIRewriter = std::getenv("LFIREWRITER");
const char* LFIFlags = "";
if (triple.isVendorLFIStores())
LFIFlags = "--sandbox=stores";
const char* LFIDebug = std::getenv("LFIDEBUG");

if (!LFIRewriter)
LFIRewriter = "lfi-rewrite";

auto Prog = sys::findProgramByName(std::string(LFIRewriter));
if (!Prog) {
errs() << "Could not find " << LFIRewriter;
consumeError(RewriteTemp->discard());
consumeError(AsmTemp->discard());
return Failed;
}

std::stringstream SS;
SS << Prog.get() << " " << LFIFlags << " " << "-a " << triple.getArchName().str() << " " << AsmTemp->TmpName << " -o " << RewriteTemp->TmpName << "\n";
if (LFIDebug)
errs() << SS.str();
std::string Cmd = SS.str();

SmallVector<StringRef, 3> Args = {
"/bin/sh", "-c", Cmd,
};

int RC = sys::ExecuteAndWait(Args[0], Args);
if (RC < -1) {
printf("lfi: exited abnormally\n");
} else if (RC < 0) {
printf("lfi: unable to invoke\n");
} else if (RC > 0) {
printf("lfi: returned non-zero\n");
}

auto EBuf = MemoryBuffer::getFileAsStream(RewriteTemp->TmpName);
if (!EBuf) {
consumeError(RewriteTemp->discard());
consumeError(AsmTemp->discard());
return Failed;
}
auto *Buf = EBuf->get();
std::string Str(Buf->getBufferStart(), Buf->getBufferEnd());

std::unique_ptr<MemoryBuffer> MBuf;
MBuf = MemoryBuffer::getMemBuffer(Str, RewriteTemp->TmpName);
SourceMgr SrcMgr;
SrcMgr.AddNewSourceBuffer(std::move(MBuf), SMLoc());

std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(triple.getTriple()));
if (!MRI) {
errs() << "Unable to create target register info!";
abort();
}

std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());

std::string OutputString;
raw_string_ostream NewOut(OutputString);
auto FOut = std::make_unique<formatted_raw_ostream>(NewOut);

MCContext *NewCtx = new MCContext(triple, MAI.get(), MRI.get(), STI.get(), &SrcMgr, Ctx.getTargetOptions());
TheTarget->createMCObjectFileInfo(*NewCtx, Ctx.getObjectFileInfo()->isPositionIndependent());
NewCtx->setObjectFileInfo(Ctx.getObjectFileInfo());

std::unique_ptr<MCStreamer> MCStr;

NewCtx->setUseNamesOnTempLabels(false);

MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *NewCtx);
MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions);
MCStr.reset(TheTarget->createMCObjectStreamer(
triple, *NewCtx, std::unique_ptr<MCAsmBackend>(MAB),
MAB->createObjectWriter(*Out), std::unique_ptr<MCCodeEmitter>(CE),
*STI));
MCStr.get()->initSections(Opts.NoExecStack, *STI);

std::unique_ptr<MCAsmParser> Parser(
createMCAsmParser(SrcMgr, *NewCtx, *MCStr, *MAI));

std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
assert(MII && "Failed to create instruction info");
std::unique_ptr<MCTargetAsmParser> NewTAP(TheTarget->createMCAsmParser(
TAP->getSTI(), *Parser, *MII, MCOptions));
if (!NewTAP)
report_fatal_error("External rewriting not supported by this streamer because"
" we don't have an asm parser for this target\n");
if (!triple.isAArch64()) {
NewTAP->setAvailableFeatures(TAP->getAvailableFeatures());
}

Parser->setTargetParser(*NewTAP);

if (Parser->Run(/*NoInitialTextSection*/ false, /*NoFinalize*/ false))
Failed = true;

consumeError(RewriteTemp->discard());
}
consumeError(AsmTemp->discard());

return Failed;

return Failed;
}

Expand Down
2 changes: 1 addition & 1 deletion libunwind/src/DwarfInstructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
// __unw_step_stage2 is not used for cross unwinding, so we use
// __aarch64__ rather than LIBUNWIND_TARGET_AARCH64 to make sure we are
// building for AArch64 natively.
#if defined(__aarch64__)
#if defined(__aarch64__) && !defined(__LFI__)
if (stage2 && cieInfo.mteTaggedFrame) {
pint_t sp = registers.getSP();
pint_t p = sp;
Expand Down
Loading