Commit dc61925c by John Porto

Subzero. ARM32. Nonsfi.

Adds nonsfi support to the ARM32 backend. BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4076 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1665263003 .
parent e54e530e
...@@ -447,7 +447,6 @@ check-xtest: $(OBJDIR)/pnacl-sz make_symlink runtime ...@@ -447,7 +447,6 @@ check-xtest: $(OBJDIR)/pnacl-sz make_symlink runtime
-i x8664,native,sse4.1,test_vector_ops \ -i x8664,native,sse4.1,test_vector_ops \
-i x8664,sandbox,sse4.1,Om1 \ -i x8664,sandbox,sse4.1,Om1 \
-i arm32,neon \ -i arm32,neon \
-e arm32,nonsfi \
-e arm32,neon,test_vector_ops \ -e arm32,neon,test_vector_ops \
-e arm32,neon,test_select -e arm32,neon,test_select
PNACL_BIN_PATH=$(PNACL_BIN_PATH) \ PNACL_BIN_PATH=$(PNACL_BIN_PATH) \
......
...@@ -76,15 +76,17 @@ entry: ...@@ -76,15 +76,17 @@ entry:
define i32 @_Z4castIdbET0_T_(double %a) { define i32 @_Z4castIdbET0_T_(double %a) {
entry: entry:
; %tobool = fcmp une double %a, 0.000000e+00 ; %tobool = fcmp une double %a, 0.000000e+00
%tobool = fptoui double %a to i1 %tobool = fptoui double %a to i32
%tobool.ret_ext = zext i1 %tobool to i32 %tobool.i1 = trunc i32 %tobool to i1
%tobool.ret_ext = zext i1 %tobool.i1 to i32
ret i32 %tobool.ret_ext ret i32 %tobool.ret_ext
} }
define i32 @_Z4castIfbET0_T_(float %a) { define i32 @_Z4castIfbET0_T_(float %a) {
entry: entry:
; %tobool = fcmp une float %a, 0.000000e+00 ; %tobool = fcmp une float %a, 0.000000e+00
%tobool = fptoui float %a to i1 %tobool = fptoui float %a to i32
%tobool.ret_ext = zext i1 %tobool to i32 %tobool.i1 = trunc i32 %tobool to i1
%tobool.ret_ext = zext i1 %tobool.i1 to i32
ret i32 %tobool.ret_ext ret i32 %tobool.ret_ext
} }
...@@ -23,6 +23,7 @@ def Translate(ll_files, extra_args, obj, verbose): ...@@ -23,6 +23,7 @@ def Translate(ll_files, extra_args, obj, verbose):
'-O2', '-O2',
'-filetype=obj', '-filetype=obj',
'-bitcode-format=llvm', '-bitcode-format=llvm',
'-arm-enable-dwarf-eh=1',
'-o', obj '-o', obj
] + extra_args, echo=verbose) ] + extra_args, echo=verbose)
shellcmd(['le32-nacl-objcopy', shellcmd(['le32-nacl-objcopy',
......
...@@ -177,6 +177,7 @@ def main(): ...@@ -177,6 +177,7 @@ def main():
obj_sz]) obj_sz])
objs.append(obj_sz) objs.append(obj_sz)
shellcmd(['{bin}/pnacl-llc'.format(bin=bindir), shellcmd(['{bin}/pnacl-llc'.format(bin=bindir),
'-arm-enable-dwarf-eh=1',
'-mtriple=' + triple, '-mtriple=' + triple,
'-externalize', '-externalize',
'-filetype=obj', '-filetype=obj',
...@@ -237,7 +238,7 @@ def main(): ...@@ -237,7 +238,7 @@ def main():
compiler = '{bin}/{prefix}{cc}'.format( compiler = '{bin}/{prefix}{cc}'.format(
bin=bindir, prefix='pnacl-', bin=bindir, prefix='pnacl-',
cc='clang' if pure_c else 'clang++') cc='clang' if pure_c else 'clang++')
shellcmd([compiler, shellcmd([compiler] + target_params + [
args.driver, args.driver,
'-O2', '-O2',
'-o', bitcode_nonfinal, '-o', bitcode_nonfinal,
...@@ -253,6 +254,7 @@ def main(): ...@@ -253,6 +254,7 @@ def main():
'-disable-opt', '-disable-opt',
bitcode_nonfinal, '-S', '-o', bitcode]) bitcode_nonfinal, '-S', '-o', bitcode])
shellcmd(['{bin}/pnacl-llc'.format(bin=bindir), shellcmd(['{bin}/pnacl-llc'.format(bin=bindir),
'-arm-enable-dwarf-eh=1',
'-mtriple=' + triple, '-mtriple=' + triple,
'-externalize', '-externalize',
'-filetype=obj', '-filetype=obj',
......
...@@ -42,6 +42,13 @@ def RunNativePrefix(toolchain_root, target, run_cmd): ...@@ -42,6 +42,13 @@ def RunNativePrefix(toolchain_root, target, run_cmd):
prefix = arch_map[target] prefix = arch_map[target]
return (prefix + ' ' + run_cmd) if prefix else run_cmd return (prefix + ' ' + run_cmd) if prefix else run_cmd
def NonsfiLoaderArch(target):
"""Returns the arch for the nonsfi_loader"""
arch_map = { 'arm32' : 'arm',
'x8632' : 'x86-32',
}
return arch_map[target]
def main(): def main():
"""Framework for cross test generation and execution. """Framework for cross test generation and execution.
...@@ -176,8 +183,11 @@ def main(): ...@@ -176,8 +183,11 @@ def main():
if sb == 'sandbox': if sb == 'sandbox':
run_cmd = '{root}/run.py -q '.format(root=root) + run_cmd run_cmd = '{root}/run.py -q '.format(root=root) + run_cmd
elif sb == 'nonsfi': elif sb == 'nonsfi':
run_cmd = ('{root}/scons-out/opt-linux-x86-32/obj/src/nonsfi/' + run_cmd = (
'loader/nonsfi_loader ').format(root=root) + run_cmd '{root}/scons-out/opt-linux-{arch}/obj/src/nonsfi/' +
'loader/nonsfi_loader ').format(
root=root, arch=NonsfiLoaderArch(target)) + run_cmd
run_cmd = RunNativePrefix(args.toolchain_root, target, run_cmd)
else: else:
run_cmd = RunNativePrefix(args.toolchain_root, target, run_cmd) run_cmd = RunNativePrefix(args.toolchain_root, target, run_cmd)
if args.lit: if args.lit:
......
...@@ -63,3 +63,4 @@ double __Sz_sitofp_i64_f64(int64_t Value) { return (double)Value; } ...@@ -63,3 +63,4 @@ double __Sz_sitofp_i64_f64(int64_t Value) { return (double)Value; }
// memset - call @llvm.memset.p0i8.i32 // memset - call @llvm.memset.p0i8.i32
// unsandboxed_irt: // unsandboxed_irt:
// __nacl_read_tp // __nacl_read_tp
// __aeabi_read_tp [arm32 only]
...@@ -14,3 +14,6 @@ ...@@ -14,3 +14,6 @@
.text .text
.p2alignl 4,0xE7FEDEF0 .p2alignl 4,0xE7FEDEF0
.globl __nacl_read_tp
__nacl_read_tp:
b __aeabi_read_tp
...@@ -143,6 +143,12 @@ llvm::StringRef Assembler::getBufferView() const { ...@@ -143,6 +143,12 @@ llvm::StringRef Assembler::getBufferView() const {
Buffer.size()); Buffer.size());
} }
void Assembler::bindRelocOffset(RelocOffset *Offset) {
if (!getPreliminary()) {
Offset->setOffset(Buffer.getPosition());
}
}
void Assembler::emitIASBytes(GlobalContext *Ctx) const { void Assembler::emitIASBytes(GlobalContext *Ctx) const {
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
intptr_t EndPosition = Buffer.size(); intptr_t EndPosition = Buffer.size();
......
...@@ -311,6 +311,8 @@ public: ...@@ -311,6 +311,8 @@ public:
return Buffer.createTextFixup(Text, BytesUsed); return Buffer.createTextFixup(Text, BytesUsed);
} }
void bindRelocOffset(RelocOffset *Offset);
void setNeedsTextFixup() { Buffer.setNeedsTextFixup(); } void setNeedsTextFixup() { Buffer.setNeedsTextFixup(); }
void resetNeedsTextFixup() { Buffer.resetNeedsTextFixup(); } void resetNeedsTextFixup() { Buffer.resetNeedsTextFixup(); }
......
...@@ -609,12 +609,13 @@ size_t MoveRelocatableFixup::emit(GlobalContext *Ctx, ...@@ -609,12 +609,13 @@ size_t MoveRelocatableFixup::emit(GlobalContext *Ctx,
return InstARM32::InstSize; return InstARM32::InstSize;
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
IValueT Inst = Asm.load<IValueT>(position()); IValueT Inst = Asm.load<IValueT>(position());
const bool IsMovw = kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ||
kind() == llvm::ELF::R_ARM_MOVW_PREL_NC;
Str << "\t" Str << "\t"
"mov" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "w" : "t") << "\t" "mov" << (IsMovw ? "w" : "t") << "\t"
<< RegARM32::getRegName(RegNumT::fixme((Inst >> kRdShift) & 0xF)) << RegARM32::getRegName(RegNumT::fixme((Inst >> kRdShift) & 0xF))
<< ", #:" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "lower" : "upper") << ", #:" << (IsMovw ? "lower" : "upper") << "16:" << symbol(Ctx, &Asm)
<< "16:" << symbol(Ctx, &Asm) << "\t@ .word " << "\t@ .word " << llvm::format_hex_no_prefix(Inst, 8) << "\n";
<< llvm::format_hex_no_prefix(Inst, 8) << "\n";
return InstARM32::InstSize; return InstARM32::InstSize;
} }
...@@ -625,8 +626,7 @@ void MoveRelocatableFixup::emitOffset(Assembler *Asm) const { ...@@ -625,8 +626,7 @@ void MoveRelocatableFixup::emitOffset(Assembler *Asm) const {
const IValueT Inst = Asm->load<IValueT>(position()); const IValueT Inst = Asm->load<IValueT>(position());
constexpr IValueT Imm16Mask = 0x000F0FFF; constexpr IValueT Imm16Mask = 0x000F0FFF;
const IValueT Imm16 = const IValueT Imm16 = offset() & 0xffff;
offset() >> (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? 0 : 16) & 0xffff;
Asm->store(position(), Asm->store(position(),
(Inst & ~Imm16Mask) | ((Imm16 >> 12) << 16) | (Imm16 & 0xfff)); (Inst & ~Imm16Mask) | ((Imm16 >> 12) << 16) | (Imm16 & 0xfff));
} }
...@@ -635,8 +635,10 @@ MoveRelocatableFixup *AssemblerARM32::createMoveFixup(bool IsMovW, ...@@ -635,8 +635,10 @@ MoveRelocatableFixup *AssemblerARM32::createMoveFixup(bool IsMovW,
const Constant *Value) { const Constant *Value) {
MoveRelocatableFixup *F = MoveRelocatableFixup *F =
new (allocate<MoveRelocatableFixup>()) MoveRelocatableFixup(); new (allocate<MoveRelocatableFixup>()) MoveRelocatableFixup();
F->set_kind(IsMovW ? llvm::ELF::R_ARM_MOVW_ABS_NC F->set_kind(IsMovW ? (IsNonsfi ? llvm::ELF::R_ARM_MOVW_PREL_NC
: llvm::ELF::R_ARM_MOVT_ABS); : llvm::ELF::R_ARM_MOVW_ABS_NC)
: (IsNonsfi ? llvm::ELF::R_ARM_MOVT_PREL
: llvm::ELF::R_ARM_MOVT_ABS));
F->set_value(Value); F->set_value(Value);
Buffer.installFixup(F); Buffer.installFixup(F);
return F; return F;
......
...@@ -95,8 +95,8 @@ public: ...@@ -95,8 +95,8 @@ public:
const RegNumT FrameOrStackReg; const RegNumT FrameOrStackReg;
}; };
explicit AssemblerARM32(bool use_far_branches = false) explicit AssemblerARM32(bool IsNonsfi, bool use_far_branches = false)
: Assembler(Asm_ARM32) { : Assembler(Asm_ARM32), IsNonsfi(IsNonsfi) {
// TODO(kschimpf): Add mode if needed when branches are handled. // TODO(kschimpf): Add mode if needed when branches are handled.
(void)use_far_branches; (void)use_far_branches;
} }
...@@ -551,6 +551,8 @@ public: ...@@ -551,6 +551,8 @@ public:
private: private:
ENABLE_MAKE_UNIQUE; ENABLE_MAKE_UNIQUE;
const bool IsNonsfi;
// A vector of pool-allocated x86 labels for CFG nodes. // A vector of pool-allocated x86 labels for CFG nodes.
using LabelVector = std::vector<Label *>; using LabelVector = std::vector<Label *>;
LabelVector CfgNodeLabels; LabelVector CfgNodeLabels;
......
...@@ -167,7 +167,6 @@ public: ...@@ -167,7 +167,6 @@ public:
Label *getOrCreateCfgNodeLabel(SizeT Number); Label *getOrCreateCfgNodeLabel(SizeT Number);
Label *getOrCreateLocalLabel(SizeT Number); Label *getOrCreateLocalLabel(SizeT Number);
void bindLocalLabel(SizeT Number); void bindLocalLabel(SizeT Number);
void bindRelocOffset(RelocOffset *Offset);
bool fixupIsPCRel(FixupKind Kind) const override { bool fixupIsPCRel(FixupKind Kind) const override {
// Currently assuming this is the only PC-rel relocation type used. // Currently assuming this is the only PC-rel relocation type used.
......
...@@ -106,13 +106,6 @@ void AssemblerX86Base<TraitsType>::bindLocalLabel(SizeT Number) { ...@@ -106,13 +106,6 @@ void AssemblerX86Base<TraitsType>::bindLocalLabel(SizeT Number) {
} }
template <typename TraitsType> template <typename TraitsType>
void AssemblerX86Base<TraitsType>::bindRelocOffset(RelocOffset *Offset) {
if (!getPreliminary()) {
Offset->setOffset(Buffer.getPosition());
}
}
template <typename TraitsType>
void AssemblerX86Base<TraitsType>::call(GPRRegister reg) { void AssemblerX86Base<TraitsType>::call(GPRRegister reg) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer); AssemblerBuffer::EnsureCapacity ensured(&Buffer);
emitRexB(RexTypeIrrelevant, reg); emitRexB(RexTypeIrrelevant, reg);
......
...@@ -157,6 +157,19 @@ public: ...@@ -157,6 +157,19 @@ public:
} }
/// @} /// @}
/// \name Manage the Globals used by this function.
/// @{
std::unique_ptr<VariableDeclarationList> getGlobalInits() {
return std::move(GlobalInits);
}
void addGlobal(VariableDeclaration *Global) {
if (GlobalInits == nullptr) {
GlobalInits.reset(new VariableDeclarationList);
}
GlobalInits->push_back(Global);
}
/// @}
/// \name Miscellaneous accessors. /// \name Miscellaneous accessors.
/// @{ /// @{
TargetLowering *getTarget() const { return Target.get(); } TargetLowering *getTarget() const { return Target.get(); }
...@@ -166,9 +179,6 @@ public: ...@@ -166,9 +179,6 @@ public:
return llvm::dyn_cast<T>(TargetAssembler.get()); return llvm::dyn_cast<T>(TargetAssembler.get());
} }
Assembler *releaseAssembler() { return TargetAssembler.release(); } Assembler *releaseAssembler() { return TargetAssembler.release(); }
std::unique_ptr<VariableDeclarationList> getGlobalInits() {
return std::move(GlobalInits);
}
bool hasComputedFrame() const; bool hasComputedFrame() const;
bool getFocusedTiming() const { return FocusedTiming; } bool getFocusedTiming() const { return FocusedTiming; }
void setFocusedTiming() { FocusedTiming = true; } void setFocusedTiming() { FocusedTiming = true; }
......
...@@ -22,9 +22,9 @@ ...@@ -22,9 +22,9 @@
#include "IceGlobalInits.h" #include "IceGlobalInits.h"
#include "IceInst.h" #include "IceInst.h"
#include "IceOperand.h" #include "IceOperand.h"
#include "llvm/Support/MathExtras.h"
using namespace llvm::ELF; #include "llvm/Support/ELF.h"
#include "llvm/Support/MathExtras.h"
namespace Ice { namespace Ice {
...@@ -419,11 +419,13 @@ void ELFObjectWriter::writeDataOfType(SectionType ST, ...@@ -419,11 +419,13 @@ void ELFObjectWriter::writeDataOfType(SectionType ST,
Section->appendZeros(Str, Init->getNumBytes()); Section->appendZeros(Str, Init->getNumBytes());
break; break;
case VariableDeclaration::Initializer::RelocInitializerKind: { case VariableDeclaration::Initializer::RelocInitializerKind: {
const auto Reloc = const auto *Reloc =
llvm::cast<VariableDeclaration::RelocInitializer>(Init.get()); llvm::cast<VariableDeclaration::RelocInitializer>(Init.get());
AssemblerFixup NewFixup; AssemblerFixup NewFixup;
NewFixup.set_position(Section->getCurrentSize()); NewFixup.set_position(Section->getCurrentSize());
NewFixup.set_kind(RelocationKind); NewFixup.set_kind(Reloc->hasFixup() ? Reloc->getFixup()
: RelocationKind);
assert(NewFixup.kind() != llvm::ELF::R_ARM_NONE);
constexpr bool SuppressMangling = true; constexpr bool SuppressMangling = true;
NewFixup.set_value(Ctx.getConstantSym( NewFixup.set_value(Ctx.getConstantSym(
Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx), Reloc->getOffset(), Reloc->getDeclaration()->mangleName(&Ctx),
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define SUBZERO_SRC_ICEGLOBALINITS_H #define SUBZERO_SRC_ICEGLOBALINITS_H
#include "IceDefs.h" #include "IceDefs.h"
#include "IceFixups.h"
#include "IceGlobalContext.h" #include "IceGlobalContext.h"
#include "IceIntrinsics.h" #include "IceIntrinsics.h"
#include "IceOperand.h" #include "IceOperand.h"
...@@ -321,7 +322,16 @@ public: ...@@ -321,7 +322,16 @@ public:
static std::unique_ptr<RelocInitializer> static std::unique_ptr<RelocInitializer>
create(const GlobalDeclaration *Declaration, create(const GlobalDeclaration *Declaration,
const RelocOffsetArray &OffsetExpr) { const RelocOffsetArray &OffsetExpr) {
return makeUnique<RelocInitializer>(Declaration, OffsetExpr); constexpr bool NoFixup = false;
return makeUnique<RelocInitializer>(Declaration, OffsetExpr, NoFixup);
}
static std::unique_ptr<RelocInitializer>
create(const GlobalDeclaration *Declaration,
const RelocOffsetArray &OffsetExpr, FixupKind Fixup) {
constexpr bool HasFixup = true;
return makeUnique<RelocInitializer>(Declaration, OffsetExpr, HasFixup,
Fixup);
} }
RelocOffsetT getOffset() const { RelocOffsetT getOffset() const {
...@@ -332,6 +342,12 @@ public: ...@@ -332,6 +342,12 @@ public:
return Offset; return Offset;
} }
bool hasFixup() const { return HasFixup; }
FixupKind getFixup() const {
assert(HasFixup);
return Fixup;
}
const GlobalDeclaration *getDeclaration() const { return Declaration; } const GlobalDeclaration *getDeclaration() const { return Declaration; }
SizeT getNumBytes() const final { return RelocAddrSize; } SizeT getNumBytes() const final { return RelocAddrSize; }
void dump(GlobalContext *Ctx, Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
...@@ -344,14 +360,17 @@ public: ...@@ -344,14 +360,17 @@ public:
ENABLE_MAKE_UNIQUE; ENABLE_MAKE_UNIQUE;
RelocInitializer(const GlobalDeclaration *Declaration, RelocInitializer(const GlobalDeclaration *Declaration,
const RelocOffsetArray &OffsetExpr) const RelocOffsetArray &OffsetExpr, bool HasFixup,
FixupKind Fixup = 0)
: Initializer(RelocInitializerKind), : Initializer(RelocInitializerKind),
Declaration(Declaration), // The global declaration used in the reloc. Declaration(Declaration), // The global declaration used in the reloc.
OffsetExpr(OffsetExpr) {} OffsetExpr(OffsetExpr), HasFixup(HasFixup), Fixup(Fixup) {}
const GlobalDeclaration *Declaration; const GlobalDeclaration *Declaration;
/// The offset to add to the relocation. /// The offset to add to the relocation.
const RelocOffsetArray OffsetExpr; const RelocOffsetArray OffsetExpr;
const bool HasFixup = false;
const FixupKind Fixup = 0;
}; };
/// Models the list of initializers. /// Models the list of initializers.
......
...@@ -354,7 +354,8 @@ OperandARM32FlexFpImm::OperandARM32FlexFpImm(Cfg * /*Func*/, Type Ty, ...@@ -354,7 +354,8 @@ OperandARM32FlexFpImm::OperandARM32FlexFpImm(Cfg * /*Func*/, Type Ty,
uint32_t ModifiedImm) uint32_t ModifiedImm)
: OperandARM32Flex(kFlexFpImm, Ty), ModifiedImm(ModifiedImm) {} : OperandARM32Flex(kFlexFpImm, Ty), ModifiedImm(ModifiedImm) {}
bool OperandARM32FlexFpImm::canHoldImm(Operand *C, uint32_t *ModifiedImm) { bool OperandARM32FlexFpImm::canHoldImm(const Operand *C,
uint32_t *ModifiedImm) {
switch (C->getType()) { switch (C->getType()) {
default: default:
llvm::report_fatal_error("Unhandled fp constant type."); llvm::report_fatal_error("Unhandled fp constant type.");
...@@ -369,7 +370,7 @@ bool OperandARM32FlexFpImm::canHoldImm(Operand *C, uint32_t *ModifiedImm) { ...@@ -369,7 +370,7 @@ bool OperandARM32FlexFpImm::canHoldImm(Operand *C, uint32_t *ModifiedImm) {
static constexpr uint32_t AllowedBits = a | B | bbbbb | cdefgh; static constexpr uint32_t AllowedBits = a | B | bbbbb | cdefgh;
static_assert(AllowedBits == 0xFFF80000u, static_assert(AllowedBits == 0xFFF80000u,
"Invalid mask for f32 modified immediates."); "Invalid mask for f32 modified immediates.");
const float F32 = llvm::cast<ConstantFloat>(C)->getValue(); const float F32 = llvm::cast<const ConstantFloat>(C)->getValue();
const uint32_t I32 = Utils::bitCopy<uint32_t>(F32); const uint32_t I32 = Utils::bitCopy<uint32_t>(F32);
if (I32 & ~AllowedBits) { if (I32 & ~AllowedBits) {
// constant has disallowed bits. // constant has disallowed bits.
...@@ -398,7 +399,7 @@ bool OperandARM32FlexFpImm::canHoldImm(Operand *C, uint32_t *ModifiedImm) { ...@@ -398,7 +399,7 @@ bool OperandARM32FlexFpImm::canHoldImm(Operand *C, uint32_t *ModifiedImm) {
static constexpr uint32_t AllowedBits = a | B | bbbbbbbb | cdefgh; static constexpr uint32_t AllowedBits = a | B | bbbbbbbb | cdefgh;
static_assert(AllowedBits == 0xFFFF0000u, static_assert(AllowedBits == 0xFFFF0000u,
"Invalid mask for f64 modified immediates."); "Invalid mask for f64 modified immediates.");
const double F64 = llvm::cast<ConstantDouble>(C)->getValue(); const double F64 = llvm::cast<const ConstantDouble>(C)->getValue();
const uint64_t I64 = Utils::bitCopy<uint64_t>(F64); const uint64_t I64 = Utils::bitCopy<uint64_t>(F64);
if (I64 & 0xFFFFFFFFu) { if (I64 & 0xFFFFFFFFu) {
// constant has disallowed bits. // constant has disallowed bits.
...@@ -1725,6 +1726,9 @@ void InstARM32Label::emit(const Cfg *Func) const { ...@@ -1725,6 +1726,9 @@ void InstARM32Label::emit(const Cfg *Func) const {
void InstARM32Label::emitIAS(const Cfg *Func) const { void InstARM32Label::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); auto *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
Asm->bindLocalLabel(Func, this, Number); Asm->bindLocalLabel(Func, this, Number);
if (OffsetReloc != nullptr) {
Asm->bindRelocOffset(OffsetReloc);
}
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); emitUsingTextFixup(Func);
} }
...@@ -1867,6 +1871,9 @@ template <> void InstARM32Movw::emit(const Cfg *Func) const { ...@@ -1867,6 +1871,9 @@ template <> void InstARM32Movw::emit(const Cfg *Func) const {
if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) { if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src0)) {
Str << "#:lower16:"; Str << "#:lower16:";
CR->emitWithoutPrefix(Func->getTarget()); CR->emitWithoutPrefix(Func->getTarget());
if (Func->getContext()->getFlags().getUseNonsfi()) {
Str << " - .";
}
} else { } else {
Src0->emit(Func); Src0->emit(Func);
} }
...@@ -1893,6 +1900,9 @@ template <> void InstARM32Movt::emit(const Cfg *Func) const { ...@@ -1893,6 +1900,9 @@ template <> void InstARM32Movt::emit(const Cfg *Func) const {
if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) { if (auto *CR = llvm::dyn_cast<ConstantRelocatable>(Src1)) {
Str << "#:upper16:"; Str << "#:upper16:";
CR->emitWithoutPrefix(Func->getTarget()); CR->emitWithoutPrefix(Func->getTarget());
if (Func->getContext()->getFlags().getUseNonsfi()) {
Str << " - .";
}
} else { } else {
Src1->emit(Func); Src1->emit(Func);
} }
......
...@@ -265,7 +265,7 @@ public: ...@@ -265,7 +265,7 @@ public:
return Operand->getKind() == static_cast<OperandKind>(kFlexFpImm); return Operand->getKind() == static_cast<OperandKind>(kFlexFpImm);
} }
static bool canHoldImm(Operand *C, uint32_t *ModifiedImm); static bool canHoldImm(const Operand *C, uint32_t *ModifiedImm);
uint32_t getModifiedImm() const { return ModifiedImm; } uint32_t getModifiedImm() const { return ModifiedImm; }
...@@ -973,10 +973,13 @@ public: ...@@ -973,10 +973,13 @@ public:
void emit(const Cfg *Func) const override; void emit(const Cfg *Func) const override;
void emitIAS(const Cfg *Func) const override; void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override; void dump(const Cfg *Func) const override;
void setRelocOffset(RelocOffset *Value) { OffsetReloc = Value; }
private: private:
InstARM32Label(Cfg *Func, TargetARM32 *Target); InstARM32Label(Cfg *Func, TargetARM32 *Target);
RelocOffset *OffsetReloc = nullptr;
SizeT Number; // used for unique label generation. SizeT Number; // used for unique label generation.
}; };
......
...@@ -556,6 +556,10 @@ void ConstantRelocatable::emitWithoutPrefix(const TargetLowering *Target, ...@@ -556,6 +556,10 @@ void ConstantRelocatable::emitWithoutPrefix(const TargetLowering *Target,
void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const { void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
if (!EmitString.empty()) {
Str << EmitString;
return;
}
Str << "@"; Str << "@";
if (Func && !SuppressMangling) { if (Func && !SuppressMangling) {
Str << Func->getContext()->mangleName(Name); Str << Func->getContext()->mangleName(Name);
......
...@@ -843,6 +843,10 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var, ...@@ -843,6 +843,10 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var,
llvm::cast<VariableDeclaration::RelocInitializer>(Init.get()); llvm::cast<VariableDeclaration::RelocInitializer>(Init.get());
Str << "\t" << getEmit32Directive() << "\t"; Str << "\t" << getEmit32Directive() << "\t";
Str << Reloc->getDeclaration()->mangleName(Ctx); Str << Reloc->getDeclaration()->mangleName(Ctx);
if (Reloc->hasFixup()) {
// TODO(jpp): this is ARM32 specific.
Str << "(GOTOFF)";
}
if (RelocOffsetT Offset = Reloc->getOffset()) { if (RelocOffsetT Offset = Reloc->getOffset()) {
if (Offset >= 0 || (Offset == INT32_MIN)) if (Offset >= 0 || (Offset == INT32_MIN))
Str << " + " << Offset; Str << " + " << Offset;
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallBitVector.h"
#include <unordered_set>
namespace Ice { namespace Ice {
namespace ARM32 { namespace ARM32 {
...@@ -64,7 +66,8 @@ public: ...@@ -64,7 +66,8 @@ public:
} }
std::unique_ptr<::Ice::Assembler> createAssembler() const override { std::unique_ptr<::Ice::Assembler> createAssembler() const override {
return makeUnique<ARM32::AssemblerARM32>(); const bool IsNonsfi = SandboxingType == ST_Nonsfi;
return makeUnique<ARM32::AssemblerARM32>(IsNonsfi);
} }
void initNodeForLowering(CfgNode *Node) override { void initNodeForLowering(CfgNode *Node) override {
...@@ -856,6 +859,48 @@ protected: ...@@ -856,6 +859,48 @@ protected:
void postLowerLegalization(); void postLowerLegalization();
/// Manages the GotPtr variable, which is used for Nonsfi sandboxing.
/// @{
void createGotPtr();
void insertGotPtrInitPlaceholder();
VariableDeclaration *createGotRelocation(RelocOffset *AddPcReloc);
void materializeGotAddr(CfgNode *Node);
Variable *GotPtr = nullptr;
// TODO(jpp): use CfgLocalAllocator.
/// @}
/// Manages the Gotoff relocations created during the function lowering. A
/// single Gotoff relocation is created for each global variable used by the
/// function being lowered.
/// @{
// TODO(jpp): if the same global G is used in different functions, then this
// method will emit one G(gotoff) relocation per function.
IceString createGotoffRelocation(const ConstantRelocatable *CR);
std::unordered_set<IceString> KnownGotoffs;
/// @}
/// Loads the constant relocatable Name to Register. Then invoke Finish to
/// finish the relocatable lowering. Finish **must** use PC in its first
/// emitted instruction, or the relocatable in Register will contain the wrong
/// value.
//
// Lowered sequence:
//
// Movw:
// movw Register, #:lower16:Name - (End - Movw) - 8 .
// Movt:
// movt Register, #:upper16:Name - (End - Movt) - 8 .
// PC = fake-def
// End:
// Finish(PC)
//
// The -8 in movw/movt above is to account for the PC value that the first
// instruction emitted by Finish(PC) will read.
void loadNamedConstantRelocatablePIC(const IceString &Name,
Variable *Register,
std::function<void(Variable *PC)> Finish,
bool SuppressMangling = true);
/// Sandboxer defines methods for ensuring that "dangerous" operations are /// Sandboxer defines methods for ensuring that "dangerous" operations are
/// masked during sandboxed code emission. For regular, non-sandboxed code /// masked during sandboxed code emission. For regular, non-sandboxed code
/// emission, its methods are simple pass-through methods. /// emission, its methods are simple pass-through methods.
......
; RUN: %p2i -i %s --filetype=obj --assemble --disassemble --args -O2 -nonsfi=1 \ ; RUN: %p2i -i %s --target=x8632 --filetype=obj --assemble --disassemble \
; RUN: --ffunction-sections \ ; RUN: --args -O2 -nonsfi=1 --ffunction-sections \
; RUN: | FileCheck --check-prefix=NONSFI %s ; RUN: | FileCheck --check-prefix=NONSFI %s
; RUN: %p2i -i %s --filetype=obj --assemble --disassemble --args -O2 -nonsfi=0 \ ; RUN: %p2i -i %s --target=x8632 --filetype=obj --assemble --disassemble \
; RUN: --ffunction-sections \ ; RUN: --args -O2 -nonsfi=0 --ffunction-sections \
; RUN: | FileCheck --check-prefix=DEFAULT %s ; RUN: | FileCheck --check-prefix=DEFAULT %s
; RUN: %p2i -i %s --target=arm32 --filetype=obj --assemble --disassemble \
; RUN: --args -O2 -nonsfi=1 --ffunction-sections \
; RUN: | FileCheck --check-prefix=ARM32-NONSFI %s
@G1 = internal global [4 x i8] zeroinitializer, align 4 @G1 = internal global [4 x i8] zeroinitializer, align 4
@G2 = internal global [4 x i8] zeroinitializer, align 4 @G2 = internal global [4 x i8] zeroinitializer, align 4
...@@ -20,6 +24,13 @@ entry: ...@@ -20,6 +24,13 @@ entry:
; NONSFI: call {{.*}} R_386_PC32 {{.*}}testLoadBasic ; NONSFI: call {{.*}} R_386_PC32 {{.*}}testLoadBasic
; DEFAULT-LABEL: testCallRegular ; DEFAULT-LABEL: testCallRegular
; ARM32-NONSFI-LABEL: testCallRegular
; ARM32-NONSFI: movw [[REG:r[0-9]+]], {{.*}} R_ARM_MOVW_PREL_NC GOTOFF{{.*}}testLoadBasic
; ARM32-NONSFI-NEXT: movt [[REG:r[0-9]+]], {{.*}} R_ARM_MOVT_PREL GOTOFF{{.*}}testLoadBasic
; ARM32-NONSFI-NEXT: ldr [[GOTOFF:r[0-9]+]], [pc, [[REG]]]
; ARM32-NONSFI-NEXT: add [[CT:r[0-9]+]], {{.*}}, [[CT]]
; ARM32-NONSFI: blx [[CT]]
define internal double @testCallBuiltin(double %val) { define internal double @testCallBuiltin(double %val) {
entry: entry:
%result = frem double %val, %val %result = frem double %val, %val
...@@ -30,6 +41,13 @@ entry: ...@@ -30,6 +41,13 @@ entry:
; NONSFI: call {{.*}} R_386_PC32 fmod ; NONSFI: call {{.*}} R_386_PC32 fmod
; DEFAULT-LABEL: testCallBuiltin ; DEFAULT-LABEL: testCallBuiltin
; ARM32-NONSFI-LABEL: testCallBuiltin
; ARM32-NONSFI: movw [[REG:r[0-9]+]], {{.*}} R_ARM_MOVW_PREL_NC GOTOFF{{.*}}fmod
; ARM32-NONSFI-NEXT: movt [[REG:r[0-9]+]], {{.*}} R_ARM_MOVT_PREL GOTOFF{{.*}}fmod
; ARM32-NONSFI-NEXT: ldr [[GOTOFF:r[0-9]+]], [pc, [[REG]]]
; ARM32-NONSFI-NEXT: add [[CT:r[0-9]+]], {{.*}}, [[CT]]
; ARM32-NONSFI: blx [[CT]]
define internal i32 @testLoadBasic() { define internal i32 @testLoadBasic() {
entry: entry:
%a = bitcast [4 x i8]* @G1 to i32* %a = bitcast [4 x i8]* @G1 to i32*
...@@ -41,6 +59,14 @@ entry: ...@@ -41,6 +59,14 @@ entry:
; NONSFI: mov {{.*}} R_386_GOTOFF {{G1|.bss}} ; NONSFI: mov {{.*}} R_386_GOTOFF {{G1|.bss}}
; DEFAULT-LABEL: testLoadBasic ; DEFAULT-LABEL: testLoadBasic
; ARM32 PIC load.
; ARM32-NONSFI-LABEL: testLoadBasic
; ARM32-NONSFI: movw {{.*}} R_ARM_MOVW_PREL_NC _GLOBAL_OFFSET_TABLE_
; ARM32-NONSFI-NEXT: movt {{.*}} R_ARM_MOVT_PREL _GLOBAL_OFFSET_TABLE_
; ARM32-NONSFI: movw [[REG:r[0-9]+]], {{.*}} R_ARM_MOVW_PREL_NC {{.*}}G1
; ARM32-NONSFI-NEXT: movt [[REG]], {{.*}} R_ARM_MOVT_PREL {{.*}}G1
; ARM32-NONSFI-NEXT: ldr r{{[0-9]+}}, [pc, [[REG]]]
define internal i32 @testLoadFixedOffset() { define internal i32 @testLoadFixedOffset() {
entry: entry:
%a = ptrtoint [4 x i8]* @G1 to i32 %a = ptrtoint [4 x i8]* @G1 to i32
...@@ -54,6 +80,15 @@ entry: ...@@ -54,6 +80,15 @@ entry:
; NONSFI: mov {{.*}}+0x4] {{.*}} R_386_GOTOFF {{G1|.bss}} ; NONSFI: mov {{.*}}+0x4] {{.*}} R_386_GOTOFF {{G1|.bss}}
; DEFAULT-LABEL: testLoadFixedOffset ; DEFAULT-LABEL: testLoadFixedOffset
; ARM32-NONSFI-LABEL: testLoadFixedOffset
; ARM32-NONSFI: movw [[GOT:r[0-9]+]], {{.*}} R_ARM_MOVW_PREL_NC _GLOBAL_OFFSET_TABLE_
; ARM32-NONSFI-NEXT: movt [[GOT]], {{.*}} R_ARM_MOVT_PREL _GLOBAL_OFFSET_TABLE_
; ARM32-NONSFI: movw [[REG:r[0-9]+]], {{.*}} R_ARM_MOVW_PREL_NC {{.*}}G1
; ARM32-NONSFI-NEXT: movt [[REG]], {{.*}} R_ARM_MOVT_PREL {{.*}}G1
; ARM32-NONSFI-NEXT: ldr [[ADDR:r[0-9]+]], [pc, [[REG]]]
; ARM32-NONSFI-NEXT: add [[G1BASE:r[0-9]+]], [[GOT]], [[ADDR]]
; ARM32-NONSFI-NEXT: add {{.*}}, [[G1BASE]], #4
define internal i32 @testLoadIndexed(i32 %idx) { define internal i32 @testLoadIndexed(i32 %idx) {
entry: entry:
%a = ptrtoint [4 x i8]* @G1 to i32 %a = ptrtoint [4 x i8]* @G1 to i32
...@@ -70,6 +105,15 @@ entry: ...@@ -70,6 +105,15 @@ entry:
; NONSFI: mov {{.*}}*4+0xc] {{.*}} R_386_GOTOFF {{G1|.bss}} ; NONSFI: mov {{.*}}*4+0xc] {{.*}} R_386_GOTOFF {{G1|.bss}}
; DEFAULT-LABEL: testLoadIndexed ; DEFAULT-LABEL: testLoadIndexed
; ARM32-NONSFI-LABEL: testLoadIndexed
; ARM32-NONSFI: movw [[GOT:r[0-9]+]], {{.*}} R_ARM_MOVW_PREL_NC _GLOBAL_OFFSET_TABLE_
; ARM32-NONSFI-NEXT: movt [[GOT]], {{.*}} R_ARM_MOVT_PREL _GLOBAL_OFFSET_TABLE_
; ARM32-NONSFI: movw [[REG:r[0-9]+]], {{.*}} R_ARM_MOVW_PREL_NC {{.*}}G1
; ARM32-NONSFI-NEXT: movt [[REG]], {{.*}} R_ARM_MOVT_PREL {{.*}}G1
; ARM32-NONSFI-NEXT: ldr [[ADDR:r[0-9]+]], [pc, [[REG]]]
; ARM32-NONSFI-NEXT: add [[G1BASE:r[0-9]+]], [[GOT]], [[ADDR]]
; ARaM32-NONSFI-NEXT: add {{.*}}, [[G1BASE]]
define internal i32 @testLoadIndexedBase(i32 %base, i32 %idx) { define internal i32 @testLoadIndexedBase(i32 %base, i32 %idx) {
entry: entry:
%a = ptrtoint [4 x i8]* @G1 to i32 %a = ptrtoint [4 x i8]* @G1 to i32
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment