Rename function vars for global clang-tidy checks (#179)
This commit is contained in:
Родитель
d32a1ba6d5
Коммит
39ab0f053f
|
@ -3,9 +3,9 @@ Language: Cpp
|
|||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: None
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
|
@ -27,7 +27,7 @@ BinPackParameters: true
|
|||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
|
@ -105,7 +105,7 @@ PenaltyExcessCharacter: 1000000
|
|||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortIncludes: CaseInsensitive
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
|
|
|
@ -29,8 +29,8 @@ ARMArgumentRaiser::ARMArgumentRaiser(ARMModuleRaiser &mr)
|
|||
|
||||
ARMArgumentRaiser::~ARMArgumentRaiser() {}
|
||||
|
||||
void ARMArgumentRaiser::init(MachineFunction *mf, Function *rf) {
|
||||
ARMRaiserBase::init(mf, rf);
|
||||
void ARMArgumentRaiser::init(MachineFunction *NewMF, Function *NewRF) {
|
||||
ARMRaiserBase::init(NewMF, NewRF);
|
||||
MFI = &MF->getFrameInfo();
|
||||
TII = MF->getSubtarget<ARMSubtarget>().getInstrInfo();
|
||||
}
|
||||
|
|
|
@ -29,23 +29,23 @@ class ARMArgumentRaiser : public ARMRaiserBase {
|
|||
public:
|
||||
static char ID;
|
||||
|
||||
ARMArgumentRaiser(ARMModuleRaiser &mr);
|
||||
ARMArgumentRaiser(ARMModuleRaiser &MR);
|
||||
~ARMArgumentRaiser() override;
|
||||
void init(MachineFunction *mf = nullptr, Function *rf = nullptr) override;
|
||||
void init(MachineFunction *MF = nullptr, Function *RF = nullptr) override;
|
||||
bool raiseArgs();
|
||||
bool runOnMachineFunction(MachineFunction &mf) override;
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
|
||||
private:
|
||||
/// Change all return relative register operands to stack 0.
|
||||
void updateReturnRegister(MachineFunction &mf);
|
||||
void updateReturnRegister(MachineFunction &MF);
|
||||
/// Change all function arguments of registers into stack elements with
|
||||
/// same indexes of arguments.
|
||||
void updateParameterRegister(unsigned reg, MachineBasicBlock &mbb);
|
||||
void updateParameterRegister(unsigned Reg, MachineBasicBlock &MBB);
|
||||
/// Change rest of function arguments on stack frame into stack elements.
|
||||
void updateParameterFrame(MachineFunction &mf);
|
||||
void updateParameterFrame(MachineFunction &MF);
|
||||
/// Using newly created stack elements replace relative operands in
|
||||
/// MachineInstr.
|
||||
void updateParameterInstr(MachineFunction &mf);
|
||||
void updateParameterInstr(MachineFunction &MF);
|
||||
/// Move arguments which are passed by ARM registers(R0 - R3) from function
|
||||
/// arg.x to corresponding registers in entry block.
|
||||
void moveArgumentToRegister(unsigned Reg, MachineBasicBlock &PMBB);
|
||||
|
|
|
@ -28,9 +28,9 @@ namespace mctoll {
|
|||
class ARMInstructionSplitting : public ARMRaiserBase {
|
||||
public:
|
||||
static char ID;
|
||||
ARMInstructionSplitting(ARMModuleRaiser &mr);
|
||||
ARMInstructionSplitting(ARMModuleRaiser &MR);
|
||||
~ARMInstructionSplitting() override;
|
||||
void init(MachineFunction *mf = nullptr, Function *rf = nullptr) override;
|
||||
void init(MachineFunction *MF = nullptr, Function *RF = nullptr) override;
|
||||
bool split();
|
||||
bool runOnMachineFunction(MachineFunction &mf) override;
|
||||
|
||||
|
@ -44,21 +44,21 @@ private:
|
|||
MachineInstr *splitLDRSTRPreImm(MachineBasicBlock &MBB, MachineInstr &MI);
|
||||
MachineInstr *splitLDRSTRImm(MachineBasicBlock &MBB, MachineInstr &MI);
|
||||
MachineInstr *splitCommon(MachineBasicBlock &MBB, MachineInstr &MI,
|
||||
unsigned newOpc);
|
||||
unsigned NewOpc);
|
||||
MachineInstr *splitS(MachineBasicBlock &MBB, MachineInstr &MI,
|
||||
unsigned newOpc, int idx);
|
||||
unsigned NewOpc, int Idx);
|
||||
MachineInstr *splitC(MachineBasicBlock &MBB, MachineInstr &MI,
|
||||
unsigned newOpc, int idx);
|
||||
unsigned NewOpc, int Idx);
|
||||
MachineInstr *splitCS(MachineBasicBlock &MBB, MachineInstr &MI,
|
||||
unsigned newOpc, int idx);
|
||||
unsigned NewOpc, int Idx);
|
||||
/// True if the ARM instruction performs Shift_C().
|
||||
bool isShift_C(unsigned Opcode);
|
||||
bool isShift_C(unsigned Opcode); // NOLINT(readability-identifier-naming)
|
||||
/// No matter what pattern of Load/Store is, change the Opcode to xxxi12.
|
||||
unsigned getLoadStoreOpcode(unsigned Opcode);
|
||||
/// If the MI is load/store which needs wback, it will return true.
|
||||
bool isLDRSTRPre(unsigned Opcode);
|
||||
MachineInstrBuilder &addOperand(MachineInstrBuilder &mib, MachineOperand &mo,
|
||||
bool isDef = false);
|
||||
MachineInstrBuilder &addOperand(MachineInstrBuilder &MIB, MachineOperand &MO,
|
||||
bool IsDef = false);
|
||||
|
||||
MachineRegisterInfo *MRI;
|
||||
const ARMBaseInstrInfo *TII;
|
||||
|
|
|
@ -321,12 +321,12 @@ const Value *ARMMIRevising::getGlobalValueByOffset(int64_t MCInstOffset,
|
|||
|
||||
auto SymOrErr = Symbol->getValue();
|
||||
if (!SymOrErr)
|
||||
report_error(SymOrErr.takeError(), "Can not find the symbol!");
|
||||
reportError(SymOrErr.takeError(), "Can not find the symbol!");
|
||||
|
||||
uint64_t SymVirtAddr = *SymOrErr;
|
||||
auto SecOrErr = Symbol->getSection();
|
||||
if (!SecOrErr)
|
||||
report_error(SecOrErr.takeError(),
|
||||
reportError(SecOrErr.takeError(),
|
||||
"Can not find the section which is the symbol in!");
|
||||
|
||||
section_iterator SecIter = *SecOrErr;
|
||||
|
@ -340,7 +340,7 @@ const Value *ARMMIRevising::getGlobalValueByOffset(int64_t MCInstOffset,
|
|||
} else {
|
||||
auto StrOrErr = SecIter->getContents();
|
||||
if (!StrOrErr)
|
||||
report_error(StrOrErr.takeError(),
|
||||
reportError(StrOrErr.takeError(),
|
||||
"Failed to get the content of section!");
|
||||
StringRef SecData = *StrOrErr;
|
||||
// Currently, Symbol->getValue() is virtual address.
|
||||
|
|
|
@ -36,34 +36,34 @@ bool ARMMachineInstructionRaiser::raiseMachineFunction() {
|
|||
ARMModuleRaiser &rmr = const_cast<ARMModuleRaiser &>(*amr);
|
||||
|
||||
ARMMIRevising mir(rmr);
|
||||
mir.init(&MF, raisedFunction);
|
||||
mir.setMCInstRaiser(mcInstRaiser);
|
||||
mir.init(&MF, RaisedFunction);
|
||||
mir.setMCInstRaiser(InstRaiser);
|
||||
mir.revise();
|
||||
|
||||
ARMEliminatePrologEpilog epe(rmr);
|
||||
epe.init(&MF, raisedFunction);
|
||||
epe.init(&MF, RaisedFunction);
|
||||
epe.eliminate();
|
||||
|
||||
ARMCreateJumpTable cjt(rmr);
|
||||
cjt.init(&MF, raisedFunction);
|
||||
cjt.setMCInstRaiser(mcInstRaiser);
|
||||
cjt.init(&MF, RaisedFunction);
|
||||
cjt.setMCInstRaiser(InstRaiser);
|
||||
cjt.create();
|
||||
cjt.getJTlist(jtList);
|
||||
|
||||
ARMArgumentRaiser ar(rmr);
|
||||
ar.init(&MF, raisedFunction);
|
||||
ar.init(&MF, RaisedFunction);
|
||||
ar.raiseArgs();
|
||||
|
||||
ARMFrameBuilder fb(rmr);
|
||||
fb.init(&MF, raisedFunction);
|
||||
fb.init(&MF, RaisedFunction);
|
||||
fb.build();
|
||||
|
||||
ARMInstructionSplitting ispl(rmr);
|
||||
ispl.init(&MF, raisedFunction);
|
||||
ispl.init(&MF, RaisedFunction);
|
||||
ispl.split();
|
||||
|
||||
ARMSelectionDAGISel sdis(rmr);
|
||||
sdis.init(&MF, raisedFunction);
|
||||
sdis.init(&MF, RaisedFunction);
|
||||
sdis.setjtList(jtList);
|
||||
sdis.doSelection();
|
||||
|
||||
|
@ -98,14 +98,14 @@ Value *ARMMachineInstructionRaiser::getRegOrArgValue(unsigned PReg, int MBBNo) {
|
|||
|
||||
FunctionType *ARMMachineInstructionRaiser::getRaisedFunctionPrototype() {
|
||||
ARMFunctionPrototype AFP;
|
||||
raisedFunction = AFP.discover(MF);
|
||||
RaisedFunction = AFP.discover(MF);
|
||||
|
||||
Function *ori = const_cast<Function *>(&MF.getFunction());
|
||||
// Insert the map of raised function to tempFunctionPointer.
|
||||
const_cast<ModuleRaiser *>(MR)->insertPlaceholderRaisedFunctionMap(
|
||||
raisedFunction, ori);
|
||||
RaisedFunction, ori);
|
||||
|
||||
return raisedFunction->getFunctionType();
|
||||
return RaisedFunction->getFunctionType();
|
||||
}
|
||||
|
||||
// Create a new MachineFunctionRaiser object and add it to the list of
|
||||
|
|
|
@ -26,18 +26,21 @@ namespace mctoll {
|
|||
class ARMRaiserBase : public FunctionPass {
|
||||
protected:
|
||||
ARMRaiserBase() = delete;
|
||||
ARMRaiserBase(char &PassID, ARMModuleRaiser &mr)
|
||||
: FunctionPass(PassID), MR(&mr) {
|
||||
ARMRaiserBase(char &PassID, ARMModuleRaiser &ArmMR)
|
||||
: FunctionPass(PassID), MR(&ArmMR) {
|
||||
M = MR->getModule();
|
||||
}
|
||||
~ARMRaiserBase() override {}
|
||||
virtual void init(MachineFunction *mf = nullptr, Function *rf = nullptr) {
|
||||
if (mf)
|
||||
MF = mf;
|
||||
if (rf)
|
||||
RF = rf;
|
||||
|
||||
virtual void init(MachineFunction *NewMF = nullptr, Function *NewRF = nullptr) {
|
||||
if (NewMF)
|
||||
MF = NewMF;
|
||||
if (NewRF)
|
||||
RF = NewRF;
|
||||
}
|
||||
virtual bool runOnMachineFunction(MachineFunction &mf) { return false; }
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &CurrMF) { return false; }
|
||||
|
||||
bool runOnFunction(Function &Func) override {
|
||||
RF = &Func;
|
||||
MF = MR->getMachineFunction(&Func);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
namespace llvm {
|
||||
namespace mctoll {
|
||||
|
||||
/// This is a extention of SelectionDAG. It contains additional information
|
||||
/// This is a extension of SelectionDAG. It contains additional information
|
||||
/// of DAG which is used by llvm-mctoll.
|
||||
class DAGRaisingInfo {
|
||||
public:
|
||||
|
|
|
@ -699,7 +699,7 @@ void IREmitter::emitSpecialNode(SDNode *Node) {
|
|||
// variadic function prototype.
|
||||
bool IsSyscall = false;
|
||||
if (CallFunc == nullptr) {
|
||||
// According MI to get BL instruction address.
|
||||
// According to MI to get BL instruction address.
|
||||
// uint64_t callAddr = DAGInfo->NPMap[Node]->InstAddr;
|
||||
uint64_t CallAddr = MR->getTextSectionAddress() +
|
||||
getMCInstIndex(*(DAGInfo->NPMap[Node]->MI));
|
||||
|
|
|
@ -304,7 +304,7 @@ static void printTLSDirectory(const COFFObjectFile *Obj) {
|
|||
|
||||
const data_directory *DataDir = Obj->getDataDirectory(COFF::TLS_TABLE);
|
||||
if (!DataDir)
|
||||
report_error("missing data dir for TLS table", Obj->getFileName());
|
||||
reportError("missing data dir for TLS table", Obj->getFileName());
|
||||
|
||||
uintptr_t IntPtr = 0;
|
||||
if (DataDir->RelativeVirtualAddress == 0)
|
||||
|
@ -334,7 +334,7 @@ static void printLoadConfiguration(const COFFObjectFile *Obj) {
|
|||
const data_directory *DataDir =
|
||||
Obj->getDataDirectory(COFF::LOAD_CONFIG_TABLE);
|
||||
if (!DataDir)
|
||||
report_error("missing data dir for TLS table", Obj->getFileName());
|
||||
reportError("missing data dir for TLS table", Obj->getFileName());
|
||||
|
||||
uintptr_t IntPtr = 0;
|
||||
if (DataDir->RelativeVirtualAddress == 0)
|
||||
|
@ -675,11 +675,11 @@ void mctoll::printCOFFSymbolTable(const COFFObjectFile *coff) {
|
|||
for (unsigned SI = 0, SE = coff->getNumberOfSymbols(); SI != SE; ++SI) {
|
||||
auto Symbol = coff->getSymbol(SI);
|
||||
if (!Symbol)
|
||||
report_error(Symbol.takeError(), coff->getFileName());
|
||||
reportError(Symbol.takeError(), coff->getFileName());
|
||||
|
||||
auto NameOrErr = coff->getSymbolName(*Symbol);
|
||||
if (!NameOrErr)
|
||||
report_error(NameOrErr.takeError(), coff->getFileName());
|
||||
reportError(NameOrErr.takeError(), coff->getFileName());
|
||||
StringRef Name = *NameOrErr;
|
||||
|
||||
outs() << "[" << format("%2d", SI) << "]"
|
||||
|
|
|
@ -120,19 +120,19 @@ struct SymbolSorter {
|
|||
bool operator()(const SymbolRef &A, const SymbolRef &B) {
|
||||
Expected<SymbolRef::Type> ATypeOrErr = A.getType();
|
||||
if (!ATypeOrErr)
|
||||
report_error(ATypeOrErr.takeError(), A.getObject()->getFileName());
|
||||
reportError(ATypeOrErr.takeError(), A.getObject()->getFileName());
|
||||
|
||||
SymbolRef::Type AType = *ATypeOrErr;
|
||||
Expected<SymbolRef::Type> BTypeOrErr = B.getType();
|
||||
if (!BTypeOrErr)
|
||||
report_error(BTypeOrErr.takeError(), B.getObject()->getFileName());
|
||||
reportError(BTypeOrErr.takeError(), B.getObject()->getFileName());
|
||||
SymbolRef::Type BType = *BTypeOrErr;
|
||||
auto ASymOrErr = A.getValue();
|
||||
if (!ASymOrErr)
|
||||
report_error(ASymOrErr.takeError(), A.getObject()->getFileName());
|
||||
reportError(ASymOrErr.takeError(), A.getObject()->getFileName());
|
||||
auto BSymOrErr = B.getValue();
|
||||
if (!BSymOrErr)
|
||||
report_error(BSymOrErr.takeError(), B.getObject()->getFileName());
|
||||
reportError(BSymOrErr.takeError(), B.getObject()->getFileName());
|
||||
uint64_t AAddr = (AType != SymbolRef::ST_Function) ? 0 : *ASymOrErr;
|
||||
uint64_t BAddr = (BType != SymbolRef::ST_Function) ? 0 : *BSymOrErr;
|
||||
return AAddr < BAddr;
|
||||
|
@ -268,7 +268,7 @@ static void CreateSymbolAddressMap(MachOObjectFile *O,
|
|||
ST == SymbolRef::ST_Other) {
|
||||
auto SymOrErr = Symbol.getValue();
|
||||
if (!SymOrErr)
|
||||
report_error(SymOrErr.takeError(), Symbol.getObject()->getFileName());
|
||||
reportError(SymOrErr.takeError(), Symbol.getObject()->getFileName());
|
||||
uint64_t Address = *SymOrErr;
|
||||
StringRef SymName = unwrapOrError(Symbol.getName(), FileName);
|
||||
if (!SymName.startswith(".objc"))
|
||||
|
@ -852,7 +852,7 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
|
|||
outs() << ":\n";
|
||||
}
|
||||
}
|
||||
// To use the report_error() form with an ArchiveName and FileName set
|
||||
// To use the reportError() form with an ArchiveName and FileName set
|
||||
// these up based on what is passed for Name and ArchiveMemberName.
|
||||
StringRef ArchiveName;
|
||||
StringRef FileName;
|
||||
|
@ -869,7 +869,7 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
|
|||
// the error message.
|
||||
if (Disassemble || FilterSections.size() != 0)
|
||||
if (Error Err = MachOOF->checkSymbolTable())
|
||||
report_error(std::move(Err), ArchiveName, FileName, ArchitectureName);
|
||||
reportError(std::move(Err), ArchiveName, FileName, ArchitectureName);
|
||||
|
||||
if (Disassemble) {
|
||||
if (MachOOF->getHeader().filetype == MachO::MH_KEXT_BUNDLE &&
|
||||
|
@ -904,7 +904,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(Filename);
|
||||
if (!BinaryOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(BinaryOrErr.takeError()))
|
||||
report_error(std::move(E), Filename);
|
||||
reportError(std::move(E), Filename);
|
||||
else
|
||||
outs() << Filename << ": is not an object file\n";
|
||||
return;
|
||||
|
@ -919,7 +919,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
|
||||
if (!ChildOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(std::move(E), Filename, C);
|
||||
reportError(std::move(E), Filename, C);
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
|
||||
|
@ -929,7 +929,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
}
|
||||
}
|
||||
if (Err)
|
||||
report_error(std::move(Err), Filename);
|
||||
reportError(std::move(Err), Filename);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -956,7 +956,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
ProcessMachO(Filename, MachOOF, "", ArchitectureName);
|
||||
} else if (auto E = isNotObjectErrorInvalidFileType(
|
||||
ObjOrErr.takeError())) {
|
||||
report_error(std::move(E), Filename, StringRef(),
|
||||
reportError(std::move(E), Filename, StringRef(),
|
||||
ArchitectureName);
|
||||
continue;
|
||||
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
|
||||
|
@ -972,7 +972,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
if (!ChildOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(
|
||||
ChildOrErr.takeError()))
|
||||
report_error(std::move(E), Filename, C, ArchitectureName);
|
||||
reportError(std::move(E), Filename, C, ArchitectureName);
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O =
|
||||
|
@ -980,7 +980,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
|
||||
}
|
||||
if (Err)
|
||||
report_error(std::move(Err), Filename);
|
||||
reportError(std::move(Err), Filename);
|
||||
} else {
|
||||
consumeError(AOrErr.takeError());
|
||||
error("Mach-O universal file: " + Filename + " for " +
|
||||
|
@ -1014,7 +1014,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
ProcessMachO(Filename, MachOOF);
|
||||
} else if (auto E = isNotObjectErrorInvalidFileType(
|
||||
ObjOrErr.takeError())) {
|
||||
report_error(std::move(E), Filename);
|
||||
reportError(std::move(E), Filename);
|
||||
continue;
|
||||
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
|
||||
I->getAsArchive()) {
|
||||
|
@ -1025,7 +1025,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
if (!ChildOrErr) {
|
||||
if (auto E =
|
||||
isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(std::move(E), Filename, C);
|
||||
reportError(std::move(E), Filename, C);
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O =
|
||||
|
@ -1033,7 +1033,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
ProcessMachO(Filename, O, O->getFileName());
|
||||
}
|
||||
if (Err)
|
||||
report_error(std::move(Err), Filename);
|
||||
reportError(std::move(Err), Filename);
|
||||
} else {
|
||||
consumeError(AOrErr.takeError());
|
||||
error("Mach-O universal file: " + Filename + " for architecture " +
|
||||
|
@ -1060,7 +1060,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
ProcessMachO(Filename, MachOOF, "", ArchitectureName);
|
||||
} else if (auto E =
|
||||
isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
|
||||
report_error(std::move(E), Filename, StringRef(), ArchitectureName);
|
||||
reportError(std::move(E), Filename, StringRef(), ArchitectureName);
|
||||
|
||||
continue;
|
||||
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
|
||||
|
@ -1076,7 +1076,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
if (!ChildOrErr) {
|
||||
if (auto E =
|
||||
isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(std::move(E), Filename, C, ArchitectureName);
|
||||
reportError(std::move(E), Filename, C, ArchitectureName);
|
||||
continue;
|
||||
}
|
||||
if (MachOObjectFile *O =
|
||||
|
@ -1087,7 +1087,7 @@ void mctoll::parseInputMachO(StringRef Filename) {
|
|||
}
|
||||
}
|
||||
if (Err)
|
||||
report_error(std::move(Err), Filename);
|
||||
reportError(std::move(Err), Filename);
|
||||
} else {
|
||||
consumeError(AOrErr.takeError());
|
||||
error("Mach-O universal file: " + Filename + " for architecture " +
|
||||
|
@ -1313,7 +1313,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
|
|||
op_info->Value -= Pc + Offset + Size;
|
||||
Expected<StringRef> SymName = Symbol.getName();
|
||||
if (!SymName)
|
||||
report_error(SymName.takeError(), info->O->getFileName());
|
||||
reportError(SymName.takeError(), info->O->getFileName());
|
||||
const char *name = SymName->data();
|
||||
unsigned Type = info->O->getAnyRelocationType(RE);
|
||||
if (Type == MachO::X86_64_RELOC_SUBTRACTOR) {
|
||||
|
@ -1330,7 +1330,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
|
|||
Symbol = *RelocSymNext;
|
||||
Expected<StringRef> SymNameNext = Symbol.getName();
|
||||
if (!SymNameNext)
|
||||
report_error(SymNameNext.takeError(), info->O->getFileName());
|
||||
reportError(SymNameNext.takeError(), info->O->getFileName());
|
||||
name = SymNameNext->data();
|
||||
}
|
||||
}
|
||||
|
@ -1402,7 +1402,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
|
|||
if (isExtern) {
|
||||
Expected<StringRef> SymName = Symbol.getName();
|
||||
if (!SymName)
|
||||
report_error(SymName.takeError(), info->O->getFileName());
|
||||
reportError(SymName.takeError(), info->O->getFileName());
|
||||
const char *name = SymName->data();
|
||||
op_info->AddSymbol.Present = 1;
|
||||
op_info->AddSymbol.Name = name;
|
||||
|
@ -1521,7 +1521,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,
|
|||
return 0;
|
||||
Expected<StringRef> SymName = Reloc->getSymbol()->getName();
|
||||
if (!SymName)
|
||||
report_error(SymName.takeError(), info->O->getFileName());
|
||||
reportError(SymName.takeError(), info->O->getFileName());
|
||||
const char *name = SymName->data();
|
||||
op_info->AddSymbol.Present = 1;
|
||||
op_info->AddSymbol.Name = name;
|
||||
|
@ -1682,7 +1682,7 @@ static const char *GuessIndirectSymbol(uint64_t ReferenceValue,
|
|||
SymbolRef Symbol = *Sym;
|
||||
Expected<StringRef> SymName = Symbol.getName();
|
||||
if (!SymName)
|
||||
report_error(SymName.takeError(), info->O->getFileName());
|
||||
reportError(SymName.takeError(), info->O->getFileName());
|
||||
const char *name = SymName->data();
|
||||
return name;
|
||||
}
|
||||
|
@ -1914,11 +1914,11 @@ static const char *get_symbol_64(uint32_t sect_offset, SectionRef S,
|
|||
if (reloc_found && isExtern) {
|
||||
auto SymOrErr = Symbol.getValue();
|
||||
if (!SymOrErr)
|
||||
report_error(SymOrErr.takeError(), Symbol.getObject()->getFileName());
|
||||
reportError(SymOrErr.takeError(), Symbol.getObject()->getFileName());
|
||||
n_value = *SymOrErr;
|
||||
Expected<StringRef> NameOrError = Symbol.getName();
|
||||
if (!NameOrError)
|
||||
report_error(NameOrError.takeError(), info->O->getFileName());
|
||||
reportError(NameOrError.takeError(), info->O->getFileName());
|
||||
StringRef Name = *NameOrError;
|
||||
if (!Name.empty()) {
|
||||
SymbolName = Name.data();
|
||||
|
@ -3294,7 +3294,7 @@ static const char *GuessLiteralPointer(uint64_t ReferenceValue,
|
|||
if (Type == MachO::X86_64_RELOC_SIGNED) {
|
||||
auto SymOrErr = Symbol.getValue();
|
||||
if (!SymOrErr)
|
||||
report_error(SymOrErr.takeError(),
|
||||
reportError(SymOrErr.takeError(),
|
||||
Symbol.getObject()->getFileName());
|
||||
ReferenceValue = *SymOrErr;
|
||||
}
|
||||
|
@ -3763,18 +3763,18 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
|
|||
for (const SymbolRef &Symbol : MachOOF->symbols()) {
|
||||
Expected<SymbolRef::Type> STOrErr = Symbol.getType();
|
||||
if (!STOrErr)
|
||||
report_error(STOrErr.takeError(), MachOOF->getFileName());
|
||||
reportError(STOrErr.takeError(), MachOOF->getFileName());
|
||||
SymbolRef::Type ST = *STOrErr;
|
||||
if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data ||
|
||||
ST == SymbolRef::ST_Other) {
|
||||
auto SymOrErr = Symbol.getValue();
|
||||
if (!SymOrErr)
|
||||
report_error(SymOrErr.takeError(), Symbol.getObject()->getFileName());
|
||||
reportError(SymOrErr.takeError(), Symbol.getObject()->getFileName());
|
||||
|
||||
uint64_t Address = *SymOrErr;
|
||||
Expected<StringRef> SymNameOrErr = Symbol.getName();
|
||||
if (!SymNameOrErr)
|
||||
report_error(SymNameOrErr.takeError(), MachOOF->getFileName());
|
||||
reportError(SymNameOrErr.takeError(), MachOOF->getFileName());
|
||||
StringRef SymName = *SymNameOrErr;
|
||||
AddrMap[Address] = SymName;
|
||||
if (!DisSymName.empty() && DisSymName == SymName)
|
||||
|
@ -3828,12 +3828,12 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
|
|||
for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
|
||||
Expected<StringRef> SymNameOrErr = Symbols[SymIdx].getName();
|
||||
if (!SymNameOrErr)
|
||||
report_error(SymNameOrErr.takeError(), MachOOF->getFileName());
|
||||
reportError(SymNameOrErr.takeError(), MachOOF->getFileName());
|
||||
StringRef SymName = *SymNameOrErr;
|
||||
|
||||
Expected<SymbolRef::Type> STOrErr = Symbols[SymIdx].getType();
|
||||
if (!STOrErr)
|
||||
report_error(STOrErr.takeError(), MachOOF->getFileName());
|
||||
reportError(STOrErr.takeError(), MachOOF->getFileName());
|
||||
SymbolRef::Type ST = *STOrErr;
|
||||
if (ST != SymbolRef::ST_Function && ST != SymbolRef::ST_Data)
|
||||
continue;
|
||||
|
@ -3873,7 +3873,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
|
|||
uint64_t SectSize = Sections[SectIdx].getSize();
|
||||
auto SymOrErr = Symbols[SymIdx].getValue();
|
||||
if (!SymOrErr)
|
||||
report_error(SymOrErr.takeError(),
|
||||
reportError(SymOrErr.takeError(),
|
||||
Symbols[SymIdx].getObject()->getFileName());
|
||||
uint64_t Start = *SymOrErr;
|
||||
uint64_t SectionAddress = Sections[SectIdx].getAddress();
|
||||
|
@ -3893,14 +3893,14 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
|
|||
while (Symbols.size() > NextSymIdx) {
|
||||
Expected<SymbolRef::Type> STOrErr = Symbols[NextSymIdx].getType();
|
||||
if (!STOrErr)
|
||||
report_error(STOrErr.takeError(), MachOOF->getFileName());
|
||||
reportError(STOrErr.takeError(), MachOOF->getFileName());
|
||||
SymbolRef::Type NextSymType = *STOrErr;
|
||||
if (NextSymType == SymbolRef::ST_Function) {
|
||||
containsNextSym =
|
||||
Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]);
|
||||
auto SymOrErr = Symbols[NextSymIdx].getValue();
|
||||
if (!SymOrErr)
|
||||
report_error(SymOrErr.takeError(),
|
||||
reportError(SymOrErr.takeError(),
|
||||
Symbols[NextSymIdx].getObject()->getFileName());
|
||||
|
||||
NextSym = *SymOrErr;
|
||||
|
@ -6120,7 +6120,7 @@ static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue,
|
|||
(*info->bindtable)[Address] = name;
|
||||
}
|
||||
if (Err)
|
||||
report_error(std::move(Err), info->O->getFileName());
|
||||
reportError(std::move(Err), info->O->getFileName());
|
||||
}
|
||||
auto name = info->bindtable->lookup(ReferenceValue);
|
||||
return !name.empty() ? name.data() : nullptr;
|
||||
|
|
|
@ -23,12 +23,12 @@ using namespace llvm::mctoll;
|
|||
|
||||
FunctionFilter::~FunctionFilter() {
|
||||
if (!ExcludedFunctionVector.empty())
|
||||
for (auto FIE : ExcludedFunctionVector)
|
||||
for (auto *FIE : ExcludedFunctionVector)
|
||||
if (FIE != nullptr)
|
||||
delete FIE;
|
||||
|
||||
if (!IncludedFunctionVector.empty())
|
||||
for (auto FII : IncludedFunctionVector)
|
||||
for (auto *FII : IncludedFunctionVector)
|
||||
if (FII != nullptr)
|
||||
delete FII;
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ FunctionFilter::findFuncInfoBySymbol(StringRef &Sym,
|
|||
else
|
||||
assert(false && "Unsupported filter type specified");
|
||||
|
||||
for (auto F : FunctionVec) {
|
||||
for (auto *F : FunctionVec) {
|
||||
if (F->getSymName() == Sym)
|
||||
return F;
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ Function *FunctionFilter::findFunctionByIndex(uint64_t StartIndex,
|
|||
|
||||
assert(FuncVec != nullptr && "Unexpected null function vector");
|
||||
|
||||
for (auto F : *FuncVec) {
|
||||
for (auto *F : *FuncVec) {
|
||||
if (F->StartIdx == StartIndex)
|
||||
return F->Func;
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ void FunctionFilter::eraseFunctionBySymbol(StringRef &Sym,
|
|||
for (FunctionFilter::FuncInfoVector::iterator I = FuncVec->begin(),
|
||||
E = FuncVec->end();
|
||||
I != E; ++I) {
|
||||
auto EM = *I;
|
||||
auto *EM = *I;
|
||||
if (EM != nullptr && EM->getSymName() == Sym) {
|
||||
FuncVec->erase(I);
|
||||
delete EM;
|
||||
|
@ -268,9 +268,9 @@ bool FunctionFilter::readFilterFunctionConfigFile(
|
|||
if (FunctionFilterFilename.size() == 0)
|
||||
return false;
|
||||
|
||||
std::ifstream f;
|
||||
f.open(FunctionFilterFilename);
|
||||
if (!f.is_open()) {
|
||||
std::ifstream F;
|
||||
F.open(FunctionFilterFilename);
|
||||
if (!F.is_open()) {
|
||||
dbgs() << "Warning: Can not read the configuration file of filter "
|
||||
"function set!!!";
|
||||
return false;
|
||||
|
@ -278,8 +278,8 @@ bool FunctionFilter::readFilterFunctionConfigFile(
|
|||
|
||||
FunctionFilter::FilterType FFType = FunctionFilter::FILTER_NONE;
|
||||
char Buf[512];
|
||||
while (!f.eof()) {
|
||||
f.getline(Buf, 512);
|
||||
while (!F.eof()) {
|
||||
F.getline(Buf, 512);
|
||||
StringRef RawLine(Buf);
|
||||
StringRef Line = RawLine.trim();
|
||||
// Ignore comment line
|
||||
|
@ -327,7 +327,7 @@ bool FunctionFilter::readFilterFunctionConfigFile(
|
|||
}
|
||||
}
|
||||
// Close function filter configuration file
|
||||
f.close();
|
||||
F.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -336,7 +336,7 @@ bool FunctionFilter::isFilterSetEmpty(FilterType FT) {
|
|||
FuncInfoVector FunctionSet;
|
||||
if (FT == FILTER_INCLUDE)
|
||||
return IncludedFunctionVector.empty();
|
||||
else if (FT == FILTER_EXCLUDE)
|
||||
if (FT == FILTER_EXCLUDE)
|
||||
return ExcludedFunctionVector.empty();
|
||||
|
||||
llvm_unreachable_internal("Unexpected function filter type specified");
|
||||
|
|
|
@ -54,13 +54,13 @@ public:
|
|||
clang::QualType RetTy = FuncDecl->getDeclaredReturnType();
|
||||
Entry.ReturnType =
|
||||
getUnqualifiedTypeString(RetTy, FuncDecl->getASTContext());
|
||||
for (auto Param : FuncDecl->parameters()) {
|
||||
for (auto *Param : FuncDecl->parameters()) {
|
||||
clang::QualType ParamTy = Param->getOriginalType();
|
||||
std::string ParamTyStr =
|
||||
getUnqualifiedTypeString(ParamTy, FuncDecl->getASTContext());
|
||||
Entry.Arguments.push_back(ParamTyStr);
|
||||
}
|
||||
Entry.isVariadic = FuncDecl->isVariadic();
|
||||
Entry.IsVariadic = FuncDecl->isVariadic();
|
||||
// TODO: Raising binaries compiled from C++ sources is not yet supported. C
|
||||
// does not support function overloading. So, for now, trivially check for
|
||||
// function name to detect duplicate function prototype specification. Need
|
||||
|
@ -188,26 +188,26 @@ Function *IncludedFileInfo::CreateFunction(StringRef &CFuncName,
|
|||
if (Func != nullptr)
|
||||
return Func;
|
||||
|
||||
auto iter = IncludedFileInfo::ExternalFunctions.find(CFuncName.str());
|
||||
if (iter == IncludedFileInfo::ExternalFunctions.end()) {
|
||||
auto Iter = IncludedFileInfo::ExternalFunctions.find(CFuncName.str());
|
||||
if (Iter == IncludedFileInfo::ExternalFunctions.end()) {
|
||||
errs() << "Unknown prototype for function : " << CFuncName.data() << "\n";
|
||||
errs() << "Use -I </full/path/to/file>, where /full/path/to/file declares "
|
||||
"its prototype\n";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const IncludedFileInfo::FunctionRetAndArgs &retAndArgs = iter->second;
|
||||
const IncludedFileInfo::FunctionRetAndArgs &RetAndArgs = Iter->second;
|
||||
Type *RetType =
|
||||
MR.getFunctionFilter()->getPrimitiveDataType(retAndArgs.ReturnType);
|
||||
MR.getFunctionFilter()->getPrimitiveDataType(RetAndArgs.ReturnType);
|
||||
std::vector<Type *> ArgVec;
|
||||
for (StringRef arg : retAndArgs.Arguments) {
|
||||
Type *argType = MR.getFunctionFilter()->getPrimitiveDataType(arg);
|
||||
for (StringRef Arg : RetAndArgs.Arguments) {
|
||||
Type *argType = MR.getFunctionFilter()->getPrimitiveDataType(Arg);
|
||||
ArgVec.push_back(argType);
|
||||
}
|
||||
|
||||
ArrayRef<Type *> Args(ArgVec);
|
||||
if (llvm::FunctionType *FuncType =
|
||||
FunctionType::get(RetType, Args, retAndArgs.isVariadic)) {
|
||||
FunctionType::get(RetType, Args, RetAndArgs.IsVariadic)) {
|
||||
FunctionCallee FunCallee = M->getOrInsertFunction(CFuncName, FuncType);
|
||||
assert(isa<Function>(FunCallee.getCallee()) && "Expect Function");
|
||||
Func = reinterpret_cast<Function *>(FunCallee.getCallee());
|
||||
|
@ -265,7 +265,7 @@ bool IncludedFileInfo::getExternalFunctionPrototype(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool IncludedFileInfo::IsExternalVariable(std::string Name) {
|
||||
bool IncludedFileInfo::isExternalVariable(std::string Name) {
|
||||
// If there is a suffix like stdout@@GLIBC_2.2.5, remove it to check
|
||||
// if the symbol is defined in a user-passed header file
|
||||
auto NameEnd = Name.find("@@");
|
||||
|
|
|
@ -26,11 +26,11 @@ class IncludedFileInfo {
|
|||
~IncludedFileInfo(){};
|
||||
|
||||
public:
|
||||
typedef struct FunctionRetAndArgs_t {
|
||||
struct FunctionRetAndArgs {
|
||||
std::string ReturnType;
|
||||
std::vector<std::string> Arguments;
|
||||
bool isVariadic;
|
||||
} FunctionRetAndArgs;
|
||||
bool IsVariadic;
|
||||
};
|
||||
|
||||
static Function *CreateFunction(StringRef &CFuncName, ModuleRaiser &MR);
|
||||
|
||||
|
@ -43,7 +43,7 @@ public:
|
|||
std::string &Target,
|
||||
std::string &SysRoot);
|
||||
|
||||
static bool IsExternalVariable(std::string Name);
|
||||
static bool isExternalVariable(std::string Name);
|
||||
};
|
||||
|
||||
} // end namespace mctoll
|
||||
|
|
|
@ -43,4 +43,4 @@ public:
|
|||
} // end namespace mctoll
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_TOOLS_LLVM_MCTOLL_MCINSTRAISER_H
|
||||
#endif // LLVM_TOOLS_LLVM_MCTOLL_MCINSTORDATA_H
|
||||
|
|
|
@ -27,40 +27,40 @@ void MCInstRaiser::buildCFG(MachineFunction &MF, const MCInstrAnalysis *MIA,
|
|||
// create a new MBB
|
||||
// set current instruction index as entry of current MBB
|
||||
// b) add raised MachineInstr to current MBB.
|
||||
auto targetIndicesEnd = targetIndices.end();
|
||||
uint64_t curMBBEntryInstIndex;
|
||||
auto TargetIndicesEnd = TargetIndices.end();
|
||||
uint64_t CurMBBEntryInstIndex;
|
||||
|
||||
for (auto mcInstorDataIter = mcInstMap.begin();
|
||||
mcInstorDataIter != mcInstMap.end(); mcInstorDataIter++) {
|
||||
uint64_t mcInstIndex = mcInstorDataIter->first;
|
||||
MCInstOrData mcInstorData = mcInstorDataIter->second;
|
||||
for (auto MCInstorDataIter = InstMap.begin();
|
||||
MCInstorDataIter != InstMap.end(); MCInstorDataIter++) {
|
||||
uint64_t MCInstIndex = MCInstorDataIter->first;
|
||||
MCInstOrData MCInstorData = MCInstorDataIter->second;
|
||||
|
||||
// If the current mcInst is a target of some instruction,
|
||||
// i) record the target of previous instruction and fall-through as
|
||||
// needed.
|
||||
// ii) start a new MachineBasicBlock
|
||||
if (targetIndices.find(mcInstIndex) != targetIndicesEnd) {
|
||||
if (TargetIndices.find(MCInstIndex) != TargetIndicesEnd) {
|
||||
// Create a map of curMBBEntryInstIndex to the current
|
||||
// MachineBasicBlock for use later to create control flow edges
|
||||
// - except when creating the first MBB.
|
||||
if (MF.size()) {
|
||||
// Find the target MCInst indices of the previous MCInst
|
||||
uint64_t prevMCInstIndex = std::prev(mcInstorDataIter)->first;
|
||||
MCInstOrData prevTextSecBytes = std::prev(mcInstorDataIter)->second;
|
||||
std::vector<uint64_t> prevMCInstTargets;
|
||||
uint64_t PrevMCInstIndex = std::prev(MCInstorDataIter)->first;
|
||||
MCInstOrData PrevTextSecBytes = std::prev(MCInstorDataIter)->second;
|
||||
std::vector<uint64_t> PrevMCInstTargets;
|
||||
|
||||
// If handling a mcInst
|
||||
if (mcInstorData.isMCInst()) {
|
||||
MCInst mcInst = mcInstorData.getMCInst();
|
||||
if (MCInstorData.isMCInst()) {
|
||||
MCInst MCInstr = MCInstorData.getMCInst();
|
||||
// If this instruction is preceeded by mcInst
|
||||
if (prevTextSecBytes.isMCInst()) {
|
||||
MCInst prevMCInst = prevTextSecBytes.getMCInst();
|
||||
if (PrevTextSecBytes.isMCInst()) {
|
||||
MCInst PrevMCInst = PrevTextSecBytes.getMCInst();
|
||||
// If previous MCInst is a branch
|
||||
if (MIA->isBranch(prevMCInst)) {
|
||||
if (MIA->isBranch(PrevMCInst)) {
|
||||
uint64_t Target;
|
||||
// Get its target
|
||||
if (MIA->evaluateBranch(prevMCInst, prevMCInstIndex,
|
||||
(mcInstIndex - prevMCInstIndex),
|
||||
if (MIA->evaluateBranch(PrevMCInst, PrevMCInstIndex,
|
||||
(MCInstIndex - PrevMCInstIndex),
|
||||
Target)) {
|
||||
// Record its target if it is within the function start
|
||||
// and function end. Branch instructions with such
|
||||
|
@ -69,13 +69,13 @@ void MCInstRaiser::buildCFG(MachineFunction &MF, const MCInstrAnalysis *MIA,
|
|||
// TODO: How to handle any branches out of these bounds?
|
||||
// Does such a situation exist?
|
||||
if ((Target >= FuncStart) && (Target < FuncEnd)) {
|
||||
prevMCInstTargets.push_back(Target);
|
||||
PrevMCInstTargets.push_back(Target);
|
||||
// If previous instruction is a conditional branch, the
|
||||
// next instruction is also a target
|
||||
if (MIA->isConditionalBranch(prevMCInst)) {
|
||||
if ((mcInstIndex >= FuncStart) &&
|
||||
(mcInstIndex <= FuncEnd)) {
|
||||
prevMCInstTargets.push_back(mcInstIndex);
|
||||
if (MIA->isConditionalBranch(PrevMCInst)) {
|
||||
if ((MCInstIndex >= FuncStart) &&
|
||||
(MCInstIndex <= FuncEnd)) {
|
||||
PrevMCInstTargets.push_back(MCInstIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,36 +83,36 @@ void MCInstRaiser::buildCFG(MachineFunction &MF, const MCInstrAnalysis *MIA,
|
|||
}
|
||||
// Previous MCInst is not a branch. So, current instruction is a
|
||||
// target
|
||||
else if ((mcInstIndex >= FuncStart) && (mcInstIndex <= FuncEnd))
|
||||
prevMCInstTargets.push_back(mcInstIndex);
|
||||
else if ((MCInstIndex >= FuncStart) && (MCInstIndex <= FuncEnd))
|
||||
PrevMCInstTargets.push_back(MCInstIndex);
|
||||
|
||||
// Add to MBB -> targets map
|
||||
MBBNumToMCInstTargetsMap.insert(
|
||||
std::make_pair(MF.back().getNumber(), prevMCInstTargets));
|
||||
mcInstToMBBNum.insert(
|
||||
std::make_pair(curMBBEntryInstIndex, MF.back().getNumber()));
|
||||
std::make_pair(MF.back().getNumber(), PrevMCInstTargets));
|
||||
InstToMBBNum.insert(
|
||||
std::make_pair(CurMBBEntryInstIndex, MF.back().getNumber()));
|
||||
} else {
|
||||
// This is preceded by data. Note that this mcInst is a target.
|
||||
// So need to start a new basic block
|
||||
// Add to MBB -> targets map
|
||||
MBBNumToMCInstTargetsMap.insert(
|
||||
std::make_pair(MF.back().getNumber(), prevMCInstTargets));
|
||||
mcInstToMBBNum.insert(
|
||||
std::make_pair(curMBBEntryInstIndex, MF.back().getNumber()));
|
||||
std::make_pair(MF.back().getNumber(), PrevMCInstTargets));
|
||||
InstToMBBNum.insert(
|
||||
std::make_pair(CurMBBEntryInstIndex, MF.back().getNumber()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the new MBB to MachineFunction
|
||||
if (mcInstorData.isMCInst()) {
|
||||
if (MCInstorData.isMCInst()) {
|
||||
MF.push_back(MF.CreateMachineBasicBlock());
|
||||
curMBBEntryInstIndex = mcInstIndex;
|
||||
CurMBBEntryInstIndex = MCInstIndex;
|
||||
}
|
||||
}
|
||||
if (mcInstorData.isMCInst()) {
|
||||
if (MCInstorData.isMCInst()) {
|
||||
// Add raised MachineInstr to current MBB.
|
||||
MF.back().push_back(
|
||||
RaiseMCInst(*MII, MF, mcInstorData.getMCInst(), mcInstIndex));
|
||||
RaiseMCInst(*MII, MF, MCInstorData.getMCInst(), MCInstIndex));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,8 +121,8 @@ void MCInstRaiser::buildCFG(MachineFunction &MF, const MCInstrAnalysis *MIA,
|
|||
// If the terminating instruction of last MBB is a branch instruction,
|
||||
// ensure appropriate control flow edges are added.
|
||||
std::vector<uint64_t> termMCInstTargets;
|
||||
auto mcIDMapIter = mcInstMap.rbegin();
|
||||
if (mcIDMapIter != mcInstMap.rend()) {
|
||||
auto mcIDMapIter = InstMap.rbegin();
|
||||
if (mcIDMapIter != InstMap.rend()) {
|
||||
uint64_t termMCInstIndex = mcIDMapIter->first;
|
||||
auto termMCInst = mcIDMapIter->second.getMCInst();
|
||||
// The following code handles a situation where the text section ends with
|
||||
|
@ -156,33 +156,33 @@ void MCInstRaiser::buildCFG(MachineFunction &MF, const MCInstrAnalysis *MIA,
|
|||
}
|
||||
MBBNumToMCInstTargetsMap.insert(
|
||||
std::make_pair(MF.back().getNumber(), termMCInstTargets));
|
||||
mcInstToMBBNum.insert(
|
||||
std::make_pair(curMBBEntryInstIndex, MF.back().getNumber()));
|
||||
InstToMBBNum.insert(
|
||||
std::make_pair(CurMBBEntryInstIndex, MF.back().getNumber()));
|
||||
}
|
||||
|
||||
// Walk all MachineBasicBlocks in MF to add control flow edges
|
||||
unsigned mbbCount = MF.getNumBlockIDs();
|
||||
for (unsigned mbbIndex = 0; mbbIndex < mbbCount; mbbIndex++) {
|
||||
unsigned MBBCount = MF.getNumBlockIDs();
|
||||
for (unsigned MBBIndex = 0; MBBIndex < MBBCount; MBBIndex++) {
|
||||
// Get the MBB
|
||||
MachineBasicBlock *currentMBB = MF.getBlockNumbered(mbbIndex);
|
||||
std::map<uint64_t, std::vector<uint64_t>>::iterator iter =
|
||||
MBBNumToMCInstTargetsMap.find(mbbIndex);
|
||||
assert(iter != MBBNumToMCInstTargetsMap.end());
|
||||
std::vector<uint64_t> targetMCInstIndices = iter->second;
|
||||
for (auto mbbMCInstTgt : targetMCInstIndices) {
|
||||
std::map<uint64_t, uint64_t>::iterator tgtIter =
|
||||
mcInstToMBBNum.find(mbbMCInstTgt);
|
||||
MachineBasicBlock *CurrentMBB = MF.getBlockNumbered(MBBIndex);
|
||||
std::map<uint64_t, std::vector<uint64_t>>::iterator Iter =
|
||||
MBBNumToMCInstTargetsMap.find(MBBIndex);
|
||||
assert(Iter != MBBNumToMCInstTargetsMap.end());
|
||||
std::vector<uint64_t> TargetMCInstIndices = Iter->second;
|
||||
for (auto MBBMCInstTgt : TargetMCInstIndices) {
|
||||
std::map<uint64_t, uint64_t>::iterator TgtIter =
|
||||
InstToMBBNum.find(MBBMCInstTgt);
|
||||
// If the target is not found, it could be outside the function
|
||||
// being constructed.
|
||||
// TODO: Need to keep track of all such targets and link them in
|
||||
// a later global pass over all MachineFunctions of the module.
|
||||
if (tgtIter == mcInstToMBBNum.end()) {
|
||||
if (TgtIter == InstToMBBNum.end()) {
|
||||
outs() << "**** Warning : Index ";
|
||||
outs().write_hex(mbbMCInstTgt);
|
||||
outs().write_hex(MBBMCInstTgt);
|
||||
outs() << " not found\n";
|
||||
} else if (!MF.getBlockNumbered(mbbIndex)->isReturnBlock()) {
|
||||
MachineBasicBlock *succ = MF.getBlockNumbered(tgtIter->second);
|
||||
currentMBB->addSuccessorWithoutProb(succ);
|
||||
} else if (!MF.getBlockNumbered(MBBIndex)->isReturnBlock()) {
|
||||
MachineBasicBlock *Succ = MF.getBlockNumbered(TgtIter->second);
|
||||
CurrentMBB->addSuccessorWithoutProb(Succ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,48 +193,48 @@ void MCInstRaiser::buildCFG(MachineFunction &MF, const MCInstrAnalysis *MIA,
|
|||
LLVM_DEBUG(MF.dump());
|
||||
}
|
||||
|
||||
static inline int64_t raiseSignedImm(int64_t val, const DataLayout &dl) {
|
||||
if (dl.getPointerSize() == 4)
|
||||
return static_cast<int32_t>(val);
|
||||
static inline int64_t raiseSignedImm(int64_t Val, const DataLayout &DL) {
|
||||
if (DL.getPointerSize() == 4)
|
||||
return static_cast<int32_t>(Val);
|
||||
|
||||
return val;
|
||||
return Val;
|
||||
}
|
||||
|
||||
MachineInstr *MCInstRaiser::RaiseMCInst(const MCInstrInfo &mcInstrInfo,
|
||||
MachineFunction &machineFunction,
|
||||
MCInst mcInst, uint64_t mcInstIndex) {
|
||||
MachineInstr *MCInstRaiser::RaiseMCInst(const MCInstrInfo &InstrInfo,
|
||||
MachineFunction &MF,
|
||||
MCInst Inst, uint64_t InstIndex) {
|
||||
// Construct MachineInstr that is the raised abstraction of MCInstr
|
||||
const MCInstrDesc &mcInstrDesc = mcInstrInfo.get(mcInst.getOpcode());
|
||||
DebugLoc *debugLoc = new DebugLoc();
|
||||
MachineInstrBuilder builder =
|
||||
BuildMI(machineFunction, *debugLoc, mcInstrDesc);
|
||||
const MCInstrDesc &InstrDesc = InstrInfo.get(Inst.getOpcode());
|
||||
DebugLoc *DL = new DebugLoc();
|
||||
MachineInstrBuilder Builder =
|
||||
BuildMI(MF, *DL, InstrDesc);
|
||||
|
||||
// Get the number of declared MachineOperands for this
|
||||
// MachineInstruction and add them to the MachineInstr being
|
||||
// constructed. Any implicitDefs or implicitDefs would already have
|
||||
// been added while MachineInstr is created during the construction
|
||||
// of builder object above.
|
||||
const unsigned int defCount = mcInstrDesc.getNumDefs();
|
||||
const unsigned int numOperands = mcInstrDesc.getNumOperands();
|
||||
for (unsigned int indx = 0; indx < numOperands; indx++) {
|
||||
const unsigned int DefCount = InstrDesc.getNumDefs();
|
||||
const unsigned int NumOperands = InstrDesc.getNumOperands();
|
||||
for (unsigned int Indx = 0; Indx < NumOperands; Indx++) {
|
||||
// Raise operand
|
||||
MCOperand mcOperand = mcInst.getOperand(indx);
|
||||
if (mcOperand.isImm()) {
|
||||
builder.addImm(
|
||||
raiseSignedImm(mcOperand.getImm(), machineFunction.getDataLayout()));
|
||||
} else if (mcOperand.isReg()) {
|
||||
MCOperand Operand = Inst.getOperand(Indx);
|
||||
if (Operand.isImm()) {
|
||||
Builder.addImm(
|
||||
raiseSignedImm(Operand.getImm(), MF.getDataLayout()));
|
||||
} else if (Operand.isReg()) {
|
||||
// The first defCount operands are defines (i.e., out operands).
|
||||
if (indx < defCount)
|
||||
builder.addDef(mcOperand.getReg());
|
||||
if (Indx < DefCount)
|
||||
Builder.addDef(Operand.getReg());
|
||||
else
|
||||
builder.addUse(mcOperand.getReg());
|
||||
Builder.addUse(Operand.getReg());
|
||||
} else {
|
||||
outs() << "**** Unhandled Operand : ";
|
||||
LLVM_DEBUG(mcOperand.dump());
|
||||
LLVM_DEBUG(Operand.dump());
|
||||
}
|
||||
}
|
||||
|
||||
LLVMContext &C = machineFunction.getFunction().getContext();
|
||||
LLVMContext &C = MF.getFunction().getContext();
|
||||
// Creation of MDNode representing Metadata with mcInstIndex may be done
|
||||
// using the following couple of lines of code. But I just wanted to spell
|
||||
// it out for better understanding.
|
||||
|
@ -248,57 +248,57 @@ MachineInstr *MCInstRaiser::RaiseMCInst(const MCInstrInfo &mcInstrInfo,
|
|||
|
||||
// Create arbitrary precision
|
||||
// integer
|
||||
llvm::APInt ArbPrecInt(64, mcInstIndex, false);
|
||||
llvm::APInt ArbPrecInt(64, InstIndex, false);
|
||||
// Create ConstantAsMetadata
|
||||
ConstantAsMetadata *CMD =
|
||||
ConstantAsMetadata::get(ConstantInt::get(C, ArbPrecInt));
|
||||
MDNode *N = MDNode::get(C, CMD);
|
||||
builder.addMetadata(N);
|
||||
return builder.getInstr();
|
||||
Builder.addMetadata(N);
|
||||
return Builder.getInstr();
|
||||
}
|
||||
|
||||
void MCInstRaiser::dump() const {
|
||||
for (auto in : mcInstMap) {
|
||||
uint64_t mcInstIndex = in.first;
|
||||
MCInstOrData mcInstorData = in.second;
|
||||
LLVM_DEBUG(dbgs() << "0x" << format("%016" PRIx64, mcInstIndex) << ": ");
|
||||
LLVM_DEBUG(mcInstorData.dump());
|
||||
for (auto In : InstMap) {
|
||||
uint64_t InstIndex = In.first;
|
||||
MCInstOrData InstorData = In.second;
|
||||
LLVM_DEBUG(dbgs() << "0x" << format("%016" PRIx64, InstIndex) << ": ");
|
||||
LLVM_DEBUG(InstorData.dump());
|
||||
}
|
||||
}
|
||||
|
||||
bool MCInstRaiser::adjustFuncEnd(uint64_t n) {
|
||||
bool MCInstRaiser::adjustFuncEnd(uint64_t N) {
|
||||
// NOTE: At present it appears that we only need it to increase the function
|
||||
// end index.
|
||||
if (FuncEnd > n)
|
||||
if (FuncEnd > N)
|
||||
return false;
|
||||
|
||||
FuncEnd = n;
|
||||
FuncEnd = N;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MCInstRaiser::addMCInstOrData(uint64_t index, MCInstOrData mcInst) {
|
||||
void MCInstRaiser::addMCInstOrData(uint64_t Index, MCInstOrData Inst) {
|
||||
// Set dataInCode flag as appropriate
|
||||
if (mcInst.isData() && !dataInCode)
|
||||
dataInCode = true;
|
||||
if (Inst.isData() && !DataInCode)
|
||||
DataInCode = true;
|
||||
|
||||
mcInstMap.insert(std::make_pair(index, mcInst));
|
||||
InstMap.insert(std::make_pair(Index, Inst));
|
||||
}
|
||||
|
||||
int64_t MCInstRaiser::getMBBNumberOfMCInstOffset(uint64_t Offset,
|
||||
MachineFunction &MF) const {
|
||||
if ((Offset < FuncStart) || (Offset > FuncEnd))
|
||||
return -1;
|
||||
auto iter = mcInstToMBBNum.find(Offset);
|
||||
if (iter != mcInstToMBBNum.end())
|
||||
return (*iter).second;
|
||||
auto Iter = InstToMBBNum.find(Offset);
|
||||
if (Iter != InstToMBBNum.end())
|
||||
return (*Iter).second;
|
||||
|
||||
// MBBNo not found. Check to see if the Offset corresponds to a non-leading
|
||||
// instruction of any of the blocks. Such a situation may occur when this
|
||||
// function is called before noops are deleted.
|
||||
for (auto N : mcInstToMBBNum) {
|
||||
for (auto N : InstToMBBNum) {
|
||||
uint64_t CurMBBStartOffset = N.first;
|
||||
uint64_t CurMBBNo = N.second;
|
||||
auto CurMBB = MF.getBlockNumbered(CurMBBNo);
|
||||
auto *CurMBB = MF.getBlockNumbered(CurMBBNo);
|
||||
unsigned CurMBBSizeinBytes = 0;
|
||||
for (const MachineInstr &I : CurMBB->instrs()) {
|
||||
CurMBBSizeinBytes += getMCInstSize(getMCInstIndex(I));
|
||||
|
@ -312,18 +312,18 @@ int64_t MCInstRaiser::getMBBNumberOfMCInstOffset(uint64_t Offset,
|
|||
}
|
||||
|
||||
int64_t MCInstRaiser::getMCInstOffsetOfMBBNumber(uint64_t MBBNum) const {
|
||||
auto iter =
|
||||
std::find_if(mcInstToMBBNum.begin(), mcInstToMBBNum.end(),
|
||||
[MBBNum](auto &&item) { return item.second == MBBNum; });
|
||||
auto Iter =
|
||||
std::find_if(InstToMBBNum.begin(), InstToMBBNum.end(),
|
||||
[MBBNum](auto &&Item) { return Item.second == MBBNum; });
|
||||
|
||||
if (iter != mcInstToMBBNum.end())
|
||||
return iter->first;
|
||||
if (Iter != InstToMBBNum.end())
|
||||
return Iter->first;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t MCInstRaiser::getMCInstSize(uint64_t Offset) const {
|
||||
const_mcinst_iter Iter = mcInstMap.find(Offset);
|
||||
const_mcinst_iter End = mcInstMap.end();
|
||||
const_mcinst_iter Iter = InstMap.find(Offset);
|
||||
const_mcinst_iter End = InstMap.end();
|
||||
assert(Iter != End && "Attempt to find MCInst at non-existent offset");
|
||||
|
||||
if (Iter.operator++() != End) {
|
||||
|
|
|
@ -27,25 +27,25 @@ public:
|
|||
using const_mcinst_iter = std::map<uint64_t, MCInstOrData>::const_iterator;
|
||||
|
||||
MCInstRaiser(uint64_t Start, uint64_t End)
|
||||
: FuncStart(Start), FuncEnd(End), dataInCode(false){};
|
||||
: FuncStart(Start), FuncEnd(End), DataInCode(false){};
|
||||
|
||||
void addTarget(uint64_t targetIndex) {
|
||||
void addTarget(uint64_t TargetIndex) {
|
||||
// Add targetIndex only if it falls within the function start and end
|
||||
if (!((targetIndex >= FuncStart) && (targetIndex <= FuncEnd)))
|
||||
if (!((TargetIndex >= FuncStart) && (TargetIndex <= FuncEnd)))
|
||||
return;
|
||||
targetIndices.insert(targetIndex);
|
||||
TargetIndices.insert(TargetIndex);
|
||||
}
|
||||
|
||||
void addMCInstOrData(uint64_t index, MCInstOrData mcInst);
|
||||
void addMCInstOrData(uint64_t Index, MCInstOrData MCInst);
|
||||
|
||||
void buildCFG(MachineFunction &MF, const MCInstrAnalysis *mia,
|
||||
const MCInstrInfo *mii);
|
||||
void buildCFG(MachineFunction &MF, const MCInstrAnalysis *MIA,
|
||||
const MCInstrInfo *MII);
|
||||
|
||||
std::set<uint64_t> getTargetIndices() const { return targetIndices; }
|
||||
std::set<uint64_t> getTargetIndices() const { return TargetIndices; }
|
||||
uint64_t getFuncStart() const { return FuncStart; }
|
||||
uint64_t getFuncEnd() const { return FuncEnd; }
|
||||
// Change the value of function end to a new value greater than current value
|
||||
bool adjustFuncEnd(uint64_t n);
|
||||
bool adjustFuncEnd(uint64_t N);
|
||||
// Is Index in range of this function?
|
||||
bool isMCInstInRange(uint64_t Index) {
|
||||
return ((Index >= FuncStart) && (Index <= FuncEnd));
|
||||
|
@ -53,8 +53,8 @@ public:
|
|||
// Dump routine
|
||||
void dump() const;
|
||||
// Data in Code
|
||||
void setDataInCode(bool v) { dataInCode = v; }
|
||||
bool hasDataInCode() { return dataInCode; }
|
||||
void setDataInCode(bool V) { DataInCode = V; }
|
||||
bool hasDataInCode() { return DataInCode; }
|
||||
|
||||
// Get the MBB number that corresponds to MCInst at Offset.
|
||||
// MBB has the raised MachineInstr corresponding to MCInst at
|
||||
|
@ -72,11 +72,11 @@ public:
|
|||
// Returns the iterator pointing to MCInstOrData at Offset in
|
||||
// input instruction stream.
|
||||
const_mcinst_iter getMCInstAt(uint64_t Offset) const {
|
||||
return mcInstMap.find(Offset);
|
||||
return InstMap.find(Offset);
|
||||
}
|
||||
|
||||
const_mcinst_iter const_mcinstr_begin() const { return mcInstMap.begin(); }
|
||||
const_mcinst_iter const_mcinstr_end() const { return mcInstMap.end(); }
|
||||
const_mcinst_iter const_mcinstr_begin() const { return InstMap.begin(); }
|
||||
const_mcinst_iter const_mcinstr_end() const { return InstMap.end(); }
|
||||
|
||||
// Get the size of instruction
|
||||
uint64_t getMCInstSize(uint64_t Offset) const;
|
||||
|
@ -88,19 +88,19 @@ private:
|
|||
// targets. Separate data structures are used instead of aggregating the
|
||||
// target information to minimize the amount of memory allocated
|
||||
// per instruction - given the ratio of control flow instructions is
|
||||
// not high, in general. However it is important to populate the target
|
||||
// not high, in general. However, it is important to populate the target
|
||||
// information during binary parse time AND is not duplicated.
|
||||
// A sequential list of source MCInsts or 32-bit data with corresponding index
|
||||
// Iteration over std::map contents is in non-descending order of keys. So,
|
||||
// the order in the map is guaranteed to be the order of instructions in the
|
||||
// insertion order i.e., code stream order.
|
||||
std::map<uint64_t, MCInstOrData> mcInstMap;
|
||||
std::map<uint64_t, MCInstOrData> InstMap;
|
||||
// All targets recorded in a set to avoid duplicate entries
|
||||
std::set<uint64_t> targetIndices;
|
||||
std::set<uint64_t> TargetIndices;
|
||||
// A map of MCInst index, mci, to MachineBasicBlock number, mbbnum. The first
|
||||
// instruction of MachineBasicBlock number mbbnum is the MachineInstr
|
||||
// representation of the MCinst at the index, mci
|
||||
std::map<uint64_t, uint64_t> mcInstToMBBNum;
|
||||
std::map<uint64_t, uint64_t> InstToMBBNum;
|
||||
|
||||
std::map<uint64_t, std::vector<uint64_t>> MBBNumToMCInstTargetsMap;
|
||||
MachineInstr *RaiseMCInst(const MCInstrInfo &, MachineFunction &, MCInst,
|
||||
|
@ -111,7 +111,7 @@ private:
|
|||
// Flag to indicate that the mcInstVector includes data (or uint32_ sized
|
||||
// quantities that the disassembler was unable to recognize as instructions
|
||||
// and are considered data
|
||||
bool dataInCode;
|
||||
bool DataInCode;
|
||||
};
|
||||
|
||||
} // end namespace mctoll
|
||||
|
|
|
@ -14,8 +14,8 @@ using namespace llvm::mctoll;
|
|||
bool MachineFunctionRaiser::runRaiserPasses() {
|
||||
bool Success = false;
|
||||
// Raise MCInst to MachineInstr and Build CFG
|
||||
if (machineInstRaiser != nullptr)
|
||||
Success = machineInstRaiser->raise();
|
||||
if (MachineInstRaiser != nullptr)
|
||||
Success = MachineInstRaiser->raise();
|
||||
|
||||
cleanupRaisedFunction();
|
||||
return Success;
|
||||
|
@ -34,13 +34,13 @@ void MachineFunctionRaiser::cleanupRaisedFunction() {
|
|||
}
|
||||
|
||||
MachineInstructionRaiser *MachineFunctionRaiser::getMachineInstrRaiser() {
|
||||
return machineInstRaiser;
|
||||
return MachineInstRaiser;
|
||||
}
|
||||
|
||||
Function *MachineFunctionRaiser::getRaisedFunction() {
|
||||
return machineInstRaiser->getRaisedFunction();
|
||||
return MachineInstRaiser->getRaisedFunction();
|
||||
}
|
||||
|
||||
void MachineFunctionRaiser::setRaisedFunction(Function *F) {
|
||||
return machineInstRaiser->setRaisedFunction(F);
|
||||
return MachineInstRaiser->setRaisedFunction(F);
|
||||
}
|
||||
|
|
|
@ -29,31 +29,31 @@ using IndexedData32 = std::pair<uint64_t, uint32_t>;
|
|||
|
||||
class MachineFunctionRaiser {
|
||||
public:
|
||||
MachineFunctionRaiser(Module &M, MachineFunction &MF, const ModuleRaiser *MR,
|
||||
MachineFunctionRaiser(Module &TheM, MachineFunction &TheMF, const ModuleRaiser *TheMR,
|
||||
uint64_t Start, uint64_t End)
|
||||
: MF(MF), M(M), machineInstRaiser(nullptr), MR(MR) {
|
||||
: MF(TheMF), M(TheM), MachineInstRaiser(nullptr), MR(TheMR) {
|
||||
|
||||
mcInstRaiser = new MCInstRaiser(Start, End);
|
||||
InstRaiser = new MCInstRaiser(Start, End);
|
||||
|
||||
// The new MachineFunction is not in SSA form, yet
|
||||
MF.getProperties().reset(MachineFunctionProperties::Property::IsSSA);
|
||||
};
|
||||
|
||||
virtual ~MachineFunctionRaiser() { delete mcInstRaiser; }
|
||||
virtual ~MachineFunctionRaiser() { delete InstRaiser; }
|
||||
|
||||
bool runRaiserPasses();
|
||||
|
||||
MachineFunction &getMachineFunction() const { return MF; }
|
||||
|
||||
// Getters
|
||||
MCInstRaiser *getMCInstRaiser() { return mcInstRaiser; }
|
||||
MCInstRaiser *getMCInstRaiser() { return InstRaiser; }
|
||||
|
||||
Module &getModule() { return M; }
|
||||
|
||||
MachineInstructionRaiser *getMachineInstrRaiser();
|
||||
|
||||
void setMachineInstrRaiser(MachineInstructionRaiser *MIR) {
|
||||
machineInstRaiser = MIR;
|
||||
MachineInstRaiser = MIR;
|
||||
}
|
||||
|
||||
Function *getRaisedFunction();
|
||||
|
@ -69,13 +69,13 @@ private:
|
|||
Module &M;
|
||||
|
||||
// Data members built and used by this class
|
||||
MCInstRaiser *mcInstRaiser;
|
||||
MachineInstructionRaiser *machineInstRaiser;
|
||||
MCInstRaiser *InstRaiser;
|
||||
MachineInstructionRaiser *MachineInstRaiser;
|
||||
// A vector of data blobs found in the instruction stream
|
||||
// of this function. A data blob is a sequence of data bytes.
|
||||
// Multiple such data blobs may be found while disassembling
|
||||
// the instruction stream of a function symbol.
|
||||
std::vector<IndexedData32> dataBlobVector;
|
||||
std::vector<IndexedData32> DataBlobVector;
|
||||
const ModuleRaiser *MR;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace mctoll {
|
|||
// transfer (i.e., branch) instructions during a post-processing
|
||||
// phase.
|
||||
|
||||
typedef struct ControlTransferInfo_t {
|
||||
struct ControlTransferInfo {
|
||||
BasicBlock *CandidateBlock;
|
||||
// This is the MachineInstr that needs to be raised
|
||||
const MachineInstr *CandidateMachineInstr;
|
||||
|
@ -39,14 +39,14 @@ typedef struct ControlTransferInfo_t {
|
|||
std::vector<Value *> RegValues;
|
||||
// Flag to indicate that CandidateMachineInstr has been raised
|
||||
bool Raised;
|
||||
} ControlTransferInfo;
|
||||
};
|
||||
|
||||
class MachineInstructionRaiser {
|
||||
public:
|
||||
MachineInstructionRaiser() = delete;
|
||||
MachineInstructionRaiser(MachineFunction &machFunc, const ModuleRaiser *mr,
|
||||
MCInstRaiser *mcir = nullptr)
|
||||
: MF(machFunc), raisedFunction(nullptr), mcInstRaiser(mcir), MR(mr) {}
|
||||
MachineInstructionRaiser(MachineFunction &TheMF, const ModuleRaiser *TheMR,
|
||||
MCInstRaiser *TheMCIR = nullptr)
|
||||
: MF(TheMF), RaisedFunction(nullptr), InstRaiser(TheMCIR), MR(TheMR) {}
|
||||
virtual ~MachineInstructionRaiser(){};
|
||||
|
||||
virtual bool raise() { return true; };
|
||||
|
@ -56,9 +56,9 @@ public:
|
|||
virtual bool buildFuncArgTypeVector(const std::set<MCPhysReg> &,
|
||||
std::vector<Type *> &) = 0;
|
||||
|
||||
Function *getRaisedFunction() { return raisedFunction; }
|
||||
void setRaisedFunction(Function *F) { raisedFunction = F; }
|
||||
MCInstRaiser *getMCInstRaiser() { return mcInstRaiser; }
|
||||
Function *getRaisedFunction() { return RaisedFunction; }
|
||||
void setRaisedFunction(Function *F) { RaisedFunction = F; }
|
||||
MCInstRaiser *getMCInstRaiser() { return InstRaiser; }
|
||||
MachineFunction &getMF() { return MF; };
|
||||
const ModuleRaiser *getModuleRaiser() { return MR; }
|
||||
|
||||
|
@ -71,8 +71,8 @@ protected:
|
|||
// This is the Function object that holds the raised abstraction of MF.
|
||||
// Note that the function associated with MF should not be referenced or
|
||||
// updated. It was created just to enable the creation of MF.
|
||||
Function *raisedFunction;
|
||||
MCInstRaiser *mcInstRaiser;
|
||||
Function *RaisedFunction;
|
||||
MCInstRaiser *InstRaiser;
|
||||
const ModuleRaiser *MR;
|
||||
|
||||
// A vector of information to be used for raising of control transfer
|
||||
|
|
|
@ -45,13 +45,13 @@ void mctoll::error(Error E) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
[[noreturn]] void mctoll::report_error(StringRef File, Twine Message) {
|
||||
[[noreturn]] void mctoll::reportError(StringRef File, Twine Message) {
|
||||
WithColor::error(errs(), ToolName)
|
||||
<< "'" << File << "': " << Message << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
[[noreturn]] void mctoll::report_error(Error E, StringRef File) {
|
||||
[[noreturn]] void mctoll::reportError(Error E, StringRef File) {
|
||||
assert(E);
|
||||
std::string Buf;
|
||||
raw_string_ostream OS(Buf);
|
||||
|
@ -61,7 +61,7 @@ void mctoll::error(Error E) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
[[noreturn]] void mctoll::report_error(Error E, StringRef ArchiveName,
|
||||
[[noreturn]] void mctoll::reportError(Error E, StringRef ArchiveName,
|
||||
StringRef FileName,
|
||||
StringRef ArchitectureName) {
|
||||
assert(E);
|
||||
|
@ -80,7 +80,7 @@ void mctoll::error(Error E) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
[[noreturn]] void mctoll::report_error(Error E, StringRef ArchiveName,
|
||||
[[noreturn]] void mctoll::reportError(Error E, StringRef ArchiveName,
|
||||
const object::Archive::Child &C,
|
||||
StringRef ArchitectureName) {
|
||||
Expected<StringRef> NameOrErr = C.getName();
|
||||
|
@ -89,41 +89,41 @@ void mctoll::error(Error E) {
|
|||
// archive instead of "???" as the name.
|
||||
if (!NameOrErr) {
|
||||
consumeError(NameOrErr.takeError());
|
||||
report_error(std::move(E), ArchiveName, "???", ArchitectureName);
|
||||
reportError(std::move(E), ArchiveName, "???", ArchitectureName);
|
||||
} else
|
||||
report_error(std::move(E), ArchiveName, NameOrErr.get(), ArchitectureName);
|
||||
reportError(std::move(E), ArchiveName, NameOrErr.get(), ArchitectureName);
|
||||
}
|
||||
|
||||
// raiser registry context
|
||||
static SmallVector<ModuleRaiser *, 4> ModuleRaiserRegistry;
|
||||
|
||||
bool mctoll::isSupportedArch(Triple::ArchType arch) {
|
||||
for (auto m : ModuleRaiserRegistry)
|
||||
if (m->getArchType() == arch)
|
||||
bool mctoll::isSupportedArch(Triple::ArchType Arch) {
|
||||
for (auto *M : ModuleRaiserRegistry)
|
||||
if (M->getArchType() == Arch)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ModuleRaiser *mctoll::getModuleRaiser(const TargetMachine *tm) {
|
||||
ModuleRaiser *mr = nullptr;
|
||||
auto arch = tm->getTargetTriple().getArch();
|
||||
for (auto m : ModuleRaiserRegistry)
|
||||
if (m->getArchType() == arch) {
|
||||
mr = m;
|
||||
ModuleRaiser *mctoll::getModuleRaiser(const TargetMachine *TM) {
|
||||
ModuleRaiser *MR = nullptr;
|
||||
auto Arch = TM->getTargetTriple().getArch();
|
||||
for (auto *M : ModuleRaiserRegistry)
|
||||
if (M->getArchType() == Arch) {
|
||||
MR = M;
|
||||
break;
|
||||
}
|
||||
assert(nullptr != mr && "This arch has not yet supported for raising!\n");
|
||||
return mr;
|
||||
assert(nullptr != MR && "This arch has not yet supported for raising!\n");
|
||||
return MR;
|
||||
}
|
||||
|
||||
void mctoll::registerModuleRaiser(ModuleRaiser *m) {
|
||||
ModuleRaiserRegistry.push_back(m);
|
||||
void mctoll::registerModuleRaiser(ModuleRaiser *M) {
|
||||
ModuleRaiserRegistry.push_back(M);
|
||||
}
|
||||
|
||||
Function *ModuleRaiser::getRaisedFunctionAt(uint64_t Index) const {
|
||||
int64_t TextSecAddr = getTextSectionAddress();
|
||||
for (auto MFR : mfRaiserVector)
|
||||
for (auto *MFR : mfRaiserVector)
|
||||
if ((MFR->getMCInstRaiser()->getFuncStart() + TextSecAddr) == Index)
|
||||
return MFR->getRaisedFunction();
|
||||
|
||||
|
@ -167,7 +167,7 @@ Function *ModuleRaiser::getCalledFunctionUsingTextReloc(uint64_t Loc,
|
|||
if (TextReloc != nullptr) {
|
||||
Expected<StringRef> Sym = TextReloc->getSymbol()->getName();
|
||||
assert(Sym && "Failed to find call target symbol");
|
||||
for (auto MFR : mfRaiserVector) {
|
||||
for (auto *MFR : mfRaiserVector) {
|
||||
Function *F = MFR->getRaisedFunction();
|
||||
assert(F && "Unexpected null function pointer encountered");
|
||||
if (Sym->equals(F->getName()))
|
||||
|
@ -180,7 +180,7 @@ Function *ModuleRaiser::getCalledFunctionUsingTextReloc(uint64_t Loc,
|
|||
bool ModuleRaiser::runMachineFunctionPasses() {
|
||||
bool Success = true;
|
||||
|
||||
for (auto MFR : mfRaiserVector) {
|
||||
for (auto *MFR : mfRaiserVector) {
|
||||
LLVM_DEBUG(dbgs() << "Function: "
|
||||
<< MFR->getMachineFunction().getName().data() << "\n");
|
||||
LLVM_DEBUG(dbgs() << "Parsed MCInst List\n");
|
||||
|
@ -188,7 +188,7 @@ bool ModuleRaiser::runMachineFunctionPasses() {
|
|||
}
|
||||
|
||||
// For each of the functions, run passes to set up for instruction raising.
|
||||
for (auto MFR : mfRaiserVector) {
|
||||
for (auto *MFR : mfRaiserVector) {
|
||||
// 1. Build CFG
|
||||
MCInstRaiser *MCIR = MFR->getMCInstRaiser();
|
||||
// Populates the MachineFunction with CFG.
|
||||
|
@ -205,7 +205,7 @@ bool ModuleRaiser::runMachineFunctionPasses() {
|
|||
const int IterCount = 2;
|
||||
for (int i = 0; i < IterCount; i++) {
|
||||
AllPrototypesConstructed = true;
|
||||
for (auto MFR : mfRaiserVector) {
|
||||
for (auto *MFR : mfRaiserVector) {
|
||||
LLVM_DEBUG(dbgs() << "Build Prototype for : "
|
||||
<< MFR->getMachineFunction().getName().data() << "\n");
|
||||
Function *RF = MFR->getRaisedFunction();
|
||||
|
@ -224,7 +224,7 @@ bool ModuleRaiser::runMachineFunctionPasses() {
|
|||
}
|
||||
assert(AllPrototypesConstructed && "Failed to construct all prototypes");
|
||||
// Run instruction raiser passes.
|
||||
for (auto MFR : mfRaiserVector)
|
||||
for (auto *MFR : mfRaiserVector)
|
||||
Success |= MFR->runRaiserPasses();
|
||||
|
||||
return Success;
|
||||
|
@ -259,13 +259,13 @@ bool ModuleRaiser::collectTextSectionRelocs(const SectionRef &TextSec) {
|
|||
// If the corresponding relocated section is TextSec, CandRelocSection
|
||||
// is the section with relocation information for TextSec.
|
||||
if (RelocatedSecIter->getIndex() == (uint64_t)TextSectionIndex) {
|
||||
for (const RelocationRef &reloc : CandRelocSection.relocations())
|
||||
TextRelocs.push_back(reloc);
|
||||
for (const RelocationRef &Reloc : CandRelocSection.relocations())
|
||||
TextRelocs.push_back(Reloc);
|
||||
|
||||
// Sort the relocations
|
||||
std::sort(TextRelocs.begin(), TextRelocs.end(),
|
||||
[](const RelocationRef &a, const RelocationRef &b) -> bool {
|
||||
return a.getOffset() < b.getOffset();
|
||||
[](const RelocationRef &A, const RelocationRef &B) -> bool {
|
||||
return A.getOffset() < B.getOffset();
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ bool ModuleRaiser::changeRaisedFunctionReturnType(Function *TargetFunc,
|
|||
|
||||
// Get the MachineFunction of TargetFunc
|
||||
MachineFunctionRaiser *TargetFuncMFRaiser = nullptr;
|
||||
for (auto MIR : mfRaiserVector) {
|
||||
for (auto *MIR : mfRaiserVector) {
|
||||
if (MIR->getRaisedFunction() == TargetFunc) {
|
||||
TargetFuncMFRaiser = MIR;
|
||||
break;
|
||||
|
@ -377,7 +377,7 @@ bool ModuleRaiser::changeRaisedFunctionReturnType(Function *TargetFunc,
|
|||
LLVMContext &Ctx(TargetFunc->getContext());
|
||||
Function *TgtFuncCallerFunc = TgtFuncCall->getParent()->getParent();
|
||||
for (BasicBlock &BB : *TgtFuncCallerFunc) {
|
||||
if (auto RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
|
||||
if (auto *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
|
||||
Value *NewRetVal = (NewRetTy->isVoidTy()) ? nullptr : TgtFuncCall;
|
||||
// If NewRetTy is void, NewRetVal is void else it is OrigCall
|
||||
// create and insert a new return instruction returning NewRetVal
|
||||
|
|
|
@ -168,22 +168,22 @@ protected:
|
|||
bool InfoSet;
|
||||
};
|
||||
|
||||
bool isSupportedArch(Triple::ArchType arch);
|
||||
ModuleRaiser *getModuleRaiser(const TargetMachine *tm);
|
||||
void registerModuleRaiser(ModuleRaiser *m);
|
||||
bool isSupportedArch(Triple::ArchType Arch);
|
||||
ModuleRaiser *getModuleRaiser(const TargetMachine *TM);
|
||||
void registerModuleRaiser(ModuleRaiser *M);
|
||||
|
||||
// error functions used from main and from raisers libs
|
||||
extern StringRef ToolName;
|
||||
|
||||
void error(std::error_code ec);
|
||||
void error(std::error_code EC);
|
||||
void error(Error E);
|
||||
[[noreturn]] void error(Twine Message);
|
||||
[[noreturn]] void report_error(StringRef File, Twine Message);
|
||||
[[noreturn]] void report_error(Error E, StringRef File);
|
||||
[[noreturn]] void report_error(Error E, StringRef FileName,
|
||||
[[noreturn]] void reportError(StringRef File, Twine Message);
|
||||
[[noreturn]] void reportError(Error E, StringRef File);
|
||||
[[noreturn]] void reportError(Error E, StringRef FileName,
|
||||
StringRef ArchiveName,
|
||||
StringRef ArchitectureName = StringRef());
|
||||
[[noreturn]] void report_error(Error E, StringRef ArchiveName,
|
||||
[[noreturn]] void reportError(Error E, StringRef ArchiveName,
|
||||
const object::Archive::Child &C,
|
||||
StringRef ArchitectureName = StringRef());
|
||||
|
||||
|
@ -191,7 +191,7 @@ template <typename T, typename... Ts>
|
|||
T unwrapOrError(Expected<T> EO, Ts &&...Args) {
|
||||
if (EO)
|
||||
return std::move(*EO);
|
||||
report_error(EO.takeError(), std::forward<Ts>(Args)...);
|
||||
reportError(EO.takeError(), std::forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
} // end namespace mctoll
|
||||
|
|
|
@ -29,30 +29,30 @@ Function *RuntimeFunction::getOrCreateSecOffsetCalcFunction(Module &M) {
|
|||
Type *Int64Ty = Type::getInt64Ty(Ctx);
|
||||
Value *Zero64BitValue = ConstantInt::get(Int64Ty, 0, false /* isSigned */);
|
||||
|
||||
SmallVector<Type *, 4> argTypes = {
|
||||
SmallVector<Type *, 4> ArgTypes = {
|
||||
Int64Ty /* RODAddr */,
|
||||
Int64Ty /* SecStAddr */,
|
||||
Int64Ty /*SecSize */,
|
||||
Int64Ty /* Runtime ROData GV */,
|
||||
};
|
||||
ArrayRef<Type *> argTypeVector(argTypes);
|
||||
ArrayRef<Type *> ArgTypeVector(ArgTypes);
|
||||
|
||||
FunctionType *FuncType =
|
||||
FunctionType::get(Int64Ty, argTypeVector, false /* isVarArg*/);
|
||||
FunctionType::get(Int64Ty, ArgTypeVector, false /* isVarArg*/);
|
||||
|
||||
// Create function
|
||||
Func =
|
||||
Function::Create(FuncType, GlobalValue::ExternalLinkage, FuncName, M);
|
||||
Func->setCallingConv(CallingConv::C);
|
||||
|
||||
Function::arg_iterator args = Func->arg_begin();
|
||||
Value *InAddr = args++;
|
||||
Function::arg_iterator Args = Func->arg_begin();
|
||||
Value *InAddr = Args++;
|
||||
InAddr->setName("InAddr");
|
||||
Value *SecBeg = args++;
|
||||
Value *SecBeg = Args++;
|
||||
SecBeg->setName("SecBeg");
|
||||
Value *SecSz = args++;
|
||||
Value *SecSz = Args++;
|
||||
SecSz->setName("SecSz");
|
||||
Value *RTGV = args++;
|
||||
Value *RTGV = Args++;
|
||||
RTGV->setName("RTGV");
|
||||
|
||||
// Create the entry basic block
|
||||
|
|
|
@ -92,27 +92,27 @@ static inline uint8_t getInstructionBitPrecision(uint64_t TSFlags) {
|
|||
// Instructions using prefix to indicate precision
|
||||
if ((TSFlags & llvm::X86II::OpPrefixMask) == llvm::X86II::XS) {
|
||||
return 32;
|
||||
} else if ((TSFlags & llvm::X86II::OpPrefixMask) == llvm::X86II::XD) {
|
||||
}
|
||||
if ((TSFlags & llvm::X86II::OpPrefixMask) == llvm::X86II::XD) {
|
||||
return 64;
|
||||
} else {
|
||||
// Instructions operating on packed values
|
||||
auto Domain = (TSFlags >> llvm::X86II::SSEDomainShift) & 3;
|
||||
// X64BaseInfo.h does not define enums. X86InstrFormats.td specified
|
||||
// GenericDomain = 0 (non-SSE instruction)
|
||||
// SSEPackedSingle = 1
|
||||
// SSEPackedSouble = 2
|
||||
// SSEPackedInt = 3
|
||||
switch (Domain) {
|
||||
case 1:
|
||||
case 3:
|
||||
return 32;
|
||||
case 2:
|
||||
return 64;
|
||||
case 0:
|
||||
return 0;
|
||||
default:
|
||||
llvm_unreachable("Unknown precision in instruction encoding");
|
||||
}
|
||||
}
|
||||
// Instructions operating on packed values
|
||||
auto Domain = (TSFlags >> llvm::X86II::SSEDomainShift) & 3;
|
||||
// X64BaseInfo.h does not define enums. X86InstrFormats.td specified
|
||||
// GenericDomain = 0 (non-SSE instruction)
|
||||
// SSEPackedSingle = 1
|
||||
// SSEPackedSouble = 2
|
||||
// SSEPackedInt = 3
|
||||
switch (Domain) {
|
||||
case 1:
|
||||
case 3:
|
||||
return 32;
|
||||
case 2:
|
||||
return 64;
|
||||
case 0:
|
||||
return 0;
|
||||
default:
|
||||
llvm_unreachable("Unknown precision in instruction encoding");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -179,8 +179,8 @@ FunctionType *X86MachineInstructionRaiser::getRaisedFunctionPrototype() {
|
|||
// Raise the jumptable
|
||||
raiseMachineJumpTable();
|
||||
|
||||
if (raisedFunction != nullptr)
|
||||
return raisedFunction->getFunctionType();
|
||||
if (RaisedFunction != nullptr)
|
||||
return RaisedFunction->getFunctionType();
|
||||
|
||||
// Cleanup NOOP instructions from all MachineBasicBlocks
|
||||
deleteNOOPInstrMF();
|
||||
|
@ -492,21 +492,21 @@ FunctionType *X86MachineInstructionRaiser::getRaisedFunctionPrototype() {
|
|||
FunctionType::get(returnType, argTypeVector, false /* isVarArg*/);
|
||||
|
||||
// 4. Create the real Function now that we have discovered the arguments.
|
||||
raisedFunction =
|
||||
RaisedFunction =
|
||||
Function::Create(FT, GlobalValue::ExternalLinkage, functionName, module);
|
||||
|
||||
// Set global linkage
|
||||
raisedFunction->setLinkage(GlobalValue::ExternalLinkage);
|
||||
RaisedFunction->setLinkage(GlobalValue::ExternalLinkage);
|
||||
// Set C calling convention
|
||||
raisedFunction->setCallingConv(CallingConv::C);
|
||||
RaisedFunction->setCallingConv(CallingConv::C);
|
||||
// Set the function to be in the same linkage unit
|
||||
raisedFunction->setDSOLocal(true);
|
||||
RaisedFunction->setDSOLocal(true);
|
||||
// TODO : Set other function attributes as needed.
|
||||
// Add argument names to the function.
|
||||
// Note: Call to arg_begin() calls Function::BuildLazyArguments()
|
||||
// to build the arguments.
|
||||
Function::arg_iterator ArgIt = raisedFunction->arg_begin();
|
||||
unsigned numFuncArgs = raisedFunction->arg_size();
|
||||
Function::arg_iterator ArgIt = RaisedFunction->arg_begin();
|
||||
unsigned numFuncArgs = RaisedFunction->arg_size();
|
||||
StringRef prefix("arg");
|
||||
// Set the name.
|
||||
for (unsigned i = 0; i < numFuncArgs; ++i, ++ArgIt)
|
||||
|
@ -514,9 +514,9 @@ FunctionType *X86MachineInstructionRaiser::getRaisedFunctionPrototype() {
|
|||
|
||||
// Insert the map of raised function to tempFunctionPointer.
|
||||
const_cast<ModuleRaiser *>(MR)->insertPlaceholderRaisedFunctionMap(
|
||||
raisedFunction, tempFunctionPtr);
|
||||
RaisedFunction, tempFunctionPtr);
|
||||
|
||||
return raisedFunction->getFunctionType();
|
||||
return RaisedFunction->getFunctionType();
|
||||
}
|
||||
|
||||
// Discover and return the type of return register (viz., RAX or its
|
||||
|
@ -539,7 +539,7 @@ Type *X86MachineInstructionRaiser::getReachingReturnType(
|
|||
SmallVector<MachineBasicBlock *, 8> WorkList;
|
||||
Type *ReturnTypeOnPath = nullptr;
|
||||
|
||||
for (auto P : MBB.predecessors()) {
|
||||
for (auto *P : MBB.predecessors()) {
|
||||
WorkList.insert(WorkList.begin(), P);
|
||||
}
|
||||
|
||||
|
@ -562,7 +562,7 @@ Type *X86MachineInstructionRaiser::getReachingReturnType(
|
|||
break;
|
||||
}
|
||||
// Continue traversal
|
||||
for (auto Pred : PredMBB->predecessors()) {
|
||||
for (auto *Pred : PredMBB->predecessors()) {
|
||||
if (!BlockVisited[Pred->getNumber()])
|
||||
WorkList.insert(WorkList.begin(), Pred);
|
||||
}
|
||||
|
@ -625,11 +625,11 @@ X86MachineInstructionRaiser::getReturnTypeFromMBB(const MachineBasicBlock &MBB,
|
|||
if (I->isReturn())
|
||||
continue;
|
||||
|
||||
// No need to inspect padding instructions. ld uses nop and lld uses int3
|
||||
// for alignment padding in text section.
|
||||
// No need to inspect padding instructions. ld uses nop and lld uses int3 for
|
||||
// alignment padding in text section.
|
||||
auto Opcode = I->getOpcode();
|
||||
if (isNoop(Opcode) || (Opcode == X86::INT3))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
unsigned DefReg = X86::NoRegister;
|
||||
const TargetRegisterInfo *TRI = MF.getRegInfo().getTargetRegisterInfo();
|
||||
|
|
|
@ -119,17 +119,17 @@ bool X86MachineInstructionRaiser::raiseMachineJumpTable() {
|
|||
// mov instruction of the kind mov offset(, IndxReg, Scale), Reg
|
||||
else {
|
||||
// Get index of memory reference in the instruction.
|
||||
int memoryRefOpIndex = getMemoryRefOpIndex(JmpTblBaseCalcMI);
|
||||
int MemoryRefOpIndex = getMemoryRefOpIndex(JmpTblBaseCalcMI);
|
||||
if ((InstKind == InstructionKind::MOV_FROM_MEM) ||
|
||||
(InstKind == InstructionKind::BRANCH_MEM_OP)) {
|
||||
assert((memoryRefOpIndex >= 0) && "Unexpected memory operand index");
|
||||
X86AddressMode memRef =
|
||||
llvm::getAddressFromInstr(&JmpTblBaseCalcMI, memoryRefOpIndex);
|
||||
if (memRef.Base.Reg == X86::NoRegister) {
|
||||
unsigned memReadTargetByteSz = getInstructionMemOpSize(Opcode);
|
||||
assert(memReadTargetByteSz > 0 &&
|
||||
assert((MemoryRefOpIndex >= 0) && "Unexpected memory operand index");
|
||||
X86AddressMode MemRef =
|
||||
llvm::getAddressFromInstr(&JmpTblBaseCalcMI, MemoryRefOpIndex);
|
||||
if (MemRef.Base.Reg == X86::NoRegister) {
|
||||
unsigned MemReadTargetByteSz = getInstructionMemOpSize(Opcode);
|
||||
assert(MemReadTargetByteSz > 0 &&
|
||||
"Incorrect memory access size of instruction");
|
||||
int JmpTblBaseAddress = memRef.Disp;
|
||||
int JmpTblBaseAddress = MemRef.Disp;
|
||||
if (JmpTblBaseAddress > 0) {
|
||||
// This value should be an absolute offset into a rodata section.
|
||||
// Get the contents of the section with JmpTblBase
|
||||
|
@ -169,13 +169,13 @@ bool X86MachineInstructionRaiser::raiseMachineJumpTable() {
|
|||
size_t CurReadByteOffset = JmpTblBaseOffset;
|
||||
|
||||
while (CurReadByteOffset < DataSize) {
|
||||
ArrayRef<uint8_t> v(memReadTargetByteSz);
|
||||
ArrayRef<uint8_t> v(MemReadTargetByteSz);
|
||||
|
||||
if (CurReadByteOffset + memReadTargetByteSz > DataSize)
|
||||
if (CurReadByteOffset + MemReadTargetByteSz > DataSize)
|
||||
break;
|
||||
|
||||
Error EC = SectionContent.readBytes(CurReadByteOffset,
|
||||
memReadTargetByteSz, v);
|
||||
MemReadTargetByteSz, v);
|
||||
// Eat the error; the section does not have jumptable data
|
||||
if (EC) {
|
||||
handleAllErrors(std::move(EC),
|
||||
|
@ -198,7 +198,7 @@ bool X86MachineInstructionRaiser::raiseMachineJumpTable() {
|
|||
// stop looking for table entries.
|
||||
break;
|
||||
}
|
||||
CurReadByteOffset += memReadTargetByteSz;
|
||||
CurReadByteOffset += MemReadTargetByteSz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,10 +237,10 @@ bool X86MachineInstructionRaiser::raiseMachineJumpTable() {
|
|||
// NOTE: This check is not needed for branch with memory operand.
|
||||
unsigned SR = find64BitSuperReg(JmpTblBaseReg);
|
||||
|
||||
for (MachineBasicBlock::const_instr_iterator instIter =
|
||||
for (MachineBasicBlock::const_instr_iterator InstIter =
|
||||
JmpTblBaseCalcMI.getNextNode()->getIterator();
|
||||
instIter != JmpTblBaseCalcMBB.end(); ++instIter) {
|
||||
for (auto O : instIter->defs()) {
|
||||
InstIter != JmpTblBaseCalcMBB.end(); ++InstIter) {
|
||||
for (auto O : InstIter->defs()) {
|
||||
if (O.isReg()) {
|
||||
if (find64BitSuperReg(O.getReg()) == SR) {
|
||||
BuildJumpTable = false;
|
||||
|
@ -276,7 +276,7 @@ bool X86MachineInstructionRaiser::raiseMachineJumpTable() {
|
|||
SwitchMBB->erase(BranchInstr);
|
||||
|
||||
// Set default basic block in jump table info
|
||||
for (auto Pred : SwitchMBB->predecessors()) {
|
||||
for (auto *Pred : SwitchMBB->predecessors()) {
|
||||
if (Pred != &JmpTblBaseCalcMBB) {
|
||||
JmpTblInfo.df_MBB = Pred;
|
||||
break;
|
||||
|
@ -299,7 +299,7 @@ bool X86MachineInstructionRaiser::raiseMachineJumpTable() {
|
|||
// the assert to and continue if the assumption is correct.
|
||||
SwitchMBB = *(JmpTblBaseCalcMBB.pred_begin());
|
||||
// Set default basic block in jump table info
|
||||
for (auto Succ : SwitchMBB->successors()) {
|
||||
for (auto *Succ : SwitchMBB->successors()) {
|
||||
if (Succ != &JmpTblBaseCalcMBB) {
|
||||
JmpTblInfo.df_MBB = Succ;
|
||||
break;
|
||||
|
@ -345,7 +345,7 @@ bool X86MachineInstructionRaiser::raiseMachineJumpTable() {
|
|||
// Find the appropriate jump opcode based on the size of switch value
|
||||
BuildMI(SwitchMBB, DebugLoc(), TII->get(X86::JMP64r))
|
||||
.addJumpTableIndex(JmpTblInfo.jtIdx);
|
||||
jtList.push_back(JmpTblInfo);
|
||||
JTList.push_back(JmpTblInfo);
|
||||
|
||||
// Add jump table targets as successors of SwitchMBB.
|
||||
for (MachineBasicBlock *NewSucc : JmpTgtMBBvec) {
|
||||
|
@ -357,9 +357,9 @@ bool X86MachineInstructionRaiser::raiseMachineJumpTable() {
|
|||
}
|
||||
|
||||
// Delete MBBs
|
||||
for (auto MBB : MBBsToBeErased) {
|
||||
for (auto *MBB : MBBsToBeErased) {
|
||||
// Remove MBB from the successors of all the predecessors of MBB
|
||||
for (auto Pred : MBB->predecessors())
|
||||
for (auto *Pred : MBB->predecessors())
|
||||
Pred->removeSuccessor(MBB);
|
||||
MBB->eraseFromParent();
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ bool X86MachineInstructionRaiser::raiseMachineJumpTable() {
|
|||
// MachineBasicBlock with a jmp to jump-table.
|
||||
Value *
|
||||
X86MachineInstructionRaiser::getSwitchCompareValue(MachineBasicBlock &MBB) {
|
||||
Value *switchOnVal = nullptr;
|
||||
Value *SwitchOnVal = nullptr;
|
||||
// Walk the basic block backwards to find the most recent
|
||||
// instruction that implicitly defines eflags.
|
||||
bool EflagsModifierFound = false;
|
||||
|
@ -381,8 +381,8 @@ X86MachineInstructionRaiser::getSwitchCompareValue(MachineBasicBlock &MBB) {
|
|||
for (auto LastInstIter = MBB.instr_rend();
|
||||
((CurInstrIter != LastInstIter) && (!EflagsModifierFound));
|
||||
++CurInstrIter) {
|
||||
MachineInstr &curInst = *CurInstrIter;
|
||||
if (curInst.getDesc().hasImplicitDefOfPhysReg(X86::EFLAGS)) {
|
||||
MachineInstr &CurInst = *CurInstrIter;
|
||||
if (CurInst.getDesc().hasImplicitDefOfPhysReg(X86::EFLAGS)) {
|
||||
EflagsModifierFound = true;
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ X86MachineInstructionRaiser::getSwitchCompareValue(MachineBasicBlock &MBB) {
|
|||
"Unexpected number of operands of sub instruction found while "
|
||||
"detecting switch compare value");
|
||||
|
||||
unsigned int cmpSrcReg = X86::NoRegister;
|
||||
unsigned int CmpSrcReg = X86::NoRegister;
|
||||
|
||||
if (CurInstrIter->getNumExplicitDefs() == 1) {
|
||||
const unsigned DestOpIndex = 0, UseOp1Index = 1, UseOp2Index = 2;
|
||||
|
@ -417,7 +417,7 @@ X86MachineInstructionRaiser::getSwitchCompareValue(MachineBasicBlock &MBB) {
|
|||
assert(SrcOp.isReg() && ImmOp.isImm() &&
|
||||
"Unexpected types of operands of sub instruction found while "
|
||||
"detecting switch compare value");
|
||||
cmpSrcReg = SrcOp.getReg();
|
||||
CmpSrcReg = SrcOp.getReg();
|
||||
} else if (CurInstrIter->getNumExplicitDefs() == 0) {
|
||||
const unsigned UseOp1Index = 0, UseOp2Index = 1;
|
||||
const MachineOperand &SrcOp = CurInstrIter->getOperand(UseOp1Index);
|
||||
|
@ -425,49 +425,49 @@ X86MachineInstructionRaiser::getSwitchCompareValue(MachineBasicBlock &MBB) {
|
|||
assert(SrcOp.isReg() && ImmOp.isImm() &&
|
||||
"Unexpected types of operands of sub instruction found while "
|
||||
"detecting switch compare value");
|
||||
cmpSrcReg = SrcOp.getReg();
|
||||
CmpSrcReg = SrcOp.getReg();
|
||||
} else {
|
||||
assert(false && "Unexpected number of defs in compare instruction found "
|
||||
"while determining switch compare value");
|
||||
}
|
||||
|
||||
assert(Register::isPhysicalRegister(cmpSrcReg) &&
|
||||
assert(Register::isPhysicalRegister(CmpSrcReg) &&
|
||||
"Unable to detect compare source register");
|
||||
Value *CmpVal = getRegOrArgValue(cmpSrcReg, MBB.getNumber());
|
||||
Value *CmpVal = getRegOrArgValue(CmpSrcReg, MBB.getNumber());
|
||||
Instruction *CmpInst = dyn_cast<Instruction>(CmpVal);
|
||||
assert((CmpInst != nullptr) &&
|
||||
"Expect instruction while finding switch compare value");
|
||||
switchOnVal = CmpInst->getOperand(0);
|
||||
SwitchOnVal = CmpInst->getOperand(0);
|
||||
// If switchOnval is a cast value, it is most likely cast to match the
|
||||
// source of the compare instruction. Get to the value prior to casting.
|
||||
CastInst *castInst = dyn_cast<CastInst>(switchOnVal);
|
||||
while (castInst) {
|
||||
switchOnVal = castInst->getOperand(0);
|
||||
castInst = dyn_cast<CastInst>(switchOnVal);
|
||||
CastInst *CastInstr = dyn_cast<CastInst>(SwitchOnVal);
|
||||
while (CastInstr) {
|
||||
SwitchOnVal = CastInstr->getOperand(0);
|
||||
CastInstr = dyn_cast<CastInst>(SwitchOnVal);
|
||||
}
|
||||
} else if (instrNameStartsWith(*CurInstrIter, "XOR32")) {
|
||||
CurInstrIter--;
|
||||
const unsigned UseOp1Index = 1;
|
||||
const MachineOperand &SrcOp = CurInstrIter->getOperand(UseOp1Index);
|
||||
unsigned int cmpSrcReg = X86::NoRegister;
|
||||
cmpSrcReg = SrcOp.getReg();
|
||||
Value *CmpVal = getRegOrArgValue(cmpSrcReg, MBB.getNumber());
|
||||
unsigned int CmpSrcReg = X86::NoRegister;
|
||||
CmpSrcReg = SrcOp.getReg();
|
||||
Value *CmpVal = getRegOrArgValue(CmpSrcReg, MBB.getNumber());
|
||||
Instruction *CmpInst = dyn_cast<Instruction>(CmpVal);
|
||||
assert((CmpInst != nullptr) &&
|
||||
"Expect instruction while finding switch compare value");
|
||||
switchOnVal = CmpInst->getOperand(0);
|
||||
SwitchOnVal = CmpInst->getOperand(0);
|
||||
// If switchOnval is a cast value, it is most likely cast to match the
|
||||
// source of the compare instruction. Get to the value prior to casting.
|
||||
CastInst *castInst = dyn_cast<CastInst>(switchOnVal);
|
||||
while (castInst) {
|
||||
switchOnVal = castInst->getOperand(0);
|
||||
castInst = dyn_cast<CastInst>(switchOnVal);
|
||||
CastInst *CastInstr = dyn_cast<CastInst>(SwitchOnVal);
|
||||
while (CastInstr) {
|
||||
SwitchOnVal = CastInstr->getOperand(0);
|
||||
CastInstr = dyn_cast<CastInst>(SwitchOnVal);
|
||||
}
|
||||
} else
|
||||
assert(false && "Unhandled EFLAGS modifying instruction found while "
|
||||
"detecting switch compare value");
|
||||
|
||||
return switchOnVal;
|
||||
return SwitchOnVal;
|
||||
}
|
||||
|
||||
#undef DEBUG_TYPE
|
||||
|
|
|
@ -2393,7 +2393,7 @@ bool X86MachineInstructionRaiser::raiseLoadIntToFloatRegInstr(
|
|||
CastInst::getCastOpcode(LdInst, true, FloatTy, true), LdInst, FloatTy);
|
||||
RaisedBB->getInstList().push_back(CInst);
|
||||
// Push value to top of FPU register stack
|
||||
FPURegisterStackPush(CInst);
|
||||
pushFPURegisterStack(CInst);
|
||||
} break;
|
||||
case X86::LD_F32m:
|
||||
case X86::LD_F64m: {
|
||||
|
@ -2403,7 +2403,7 @@ bool X86MachineInstructionRaiser::raiseLoadIntToFloatRegInstr(
|
|||
CastInst::getCastOpcode(LdInst, true, FloatTy, true), LdInst, FloatTy);
|
||||
RaisedBB->getInstList().push_back(CInst);
|
||||
// Push value to top of FPU register stack
|
||||
FPURegisterStackPush(CInst);
|
||||
pushFPURegisterStack(CInst);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -2493,7 +2493,7 @@ bool X86MachineInstructionRaiser::raiseStoreIntToFloatRegInstr(
|
|||
} break;
|
||||
case X86::ST_FP32m:
|
||||
case X86::ST_FP64m: {
|
||||
Value *ST0Val = FPURegisterStackTop();
|
||||
Value *ST0Val = topFPURegisterStack();
|
||||
Type *SrcTy = ST0Val->getType();
|
||||
// The value in ST0 is converted to single-precision or double precision
|
||||
// floating-point format. So, cast the memRefValue to the PointerType of
|
||||
|
@ -2511,7 +2511,7 @@ bool X86MachineInstructionRaiser::raiseStoreIntToFloatRegInstr(
|
|||
new StoreInst(ST0Val, MemRefValue, RaisedBB);
|
||||
|
||||
// Pop value to top of FPU register stack
|
||||
FPURegisterStackPop();
|
||||
popFPURegisterStack();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -4483,7 +4483,7 @@ bool X86MachineInstructionRaiser::raiseIndirectBranchMachineInstr(
|
|||
const MachineJumpTableInfo *MJT = MF.getJumpTableInfo();
|
||||
|
||||
// Get the case value
|
||||
MachineBasicBlock *cdMBB = jtList[jtIndex].conditionMBB;
|
||||
MachineBasicBlock *cdMBB = JTList[jtIndex].conditionMBB;
|
||||
Value *cdi = getSwitchCompareValue(*cdMBB);
|
||||
assert(cdi != nullptr && "Failed to get switch compare value.");
|
||||
Type *caseValTy = cdi->getType();
|
||||
|
@ -4498,7 +4498,7 @@ bool X86MachineInstructionRaiser::raiseIndirectBranchMachineInstr(
|
|||
|
||||
// Create the Switch Instruction
|
||||
unsigned int numCases = JTCases.size();
|
||||
auto intr_df = mbbToBBMap.find(jtList[jtIndex].df_MBB->getNumber());
|
||||
auto intr_df = mbbToBBMap.find(JTList[jtIndex].df_MBB->getNumber());
|
||||
|
||||
BasicBlock *df_bb = intr_df->second;
|
||||
SwitchInst *Inst = SwitchInst::Create(cdi, df_bb, numCases);
|
||||
|
@ -4905,7 +4905,7 @@ bool X86MachineInstructionRaiser::raiseGenericMachineInstr(
|
|||
// Raise a return instruction.
|
||||
bool X86MachineInstructionRaiser::raiseReturnMachineInstr(
|
||||
const MachineInstr &MI) {
|
||||
Type *RetType = raisedFunction->getReturnType();
|
||||
Type *RetType = RaisedFunction->getReturnType();
|
||||
Value *RetValue = nullptr;
|
||||
|
||||
// Get the BasicBlock corresponding to MachineBasicBlock of MI.
|
||||
|
@ -4973,12 +4973,12 @@ bool X86MachineInstructionRaiser::raiseReturnMachineInstr(
|
|||
// Make sure that the return type of raisedFunction is void. Else change it to
|
||||
// void type as reaching definition computation is more accurate than that
|
||||
// deduced earlier just looking at the per-basic block definitions.
|
||||
Type *RaisedFuncReturnTy = raisedFunction->getReturnType();
|
||||
Type *RaisedFuncReturnTy = RaisedFunction->getReturnType();
|
||||
if (RetValue == nullptr) {
|
||||
if (!RaisedFuncReturnTy->isVoidTy()) {
|
||||
ModuleRaiser *NonConstMR = const_cast<ModuleRaiser *>(MR);
|
||||
NonConstMR->changeRaisedFunctionReturnType(
|
||||
raisedFunction, Type::getVoidTy(MF.getFunction().getContext()));
|
||||
RaisedFunction, Type::getVoidTy(MF.getFunction().getContext()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4987,7 +4987,7 @@ bool X86MachineInstructionRaiser::raiseReturnMachineInstr(
|
|||
|
||||
bool X86MachineInstructionRaiser::raiseBranchMachineInstrs() {
|
||||
LLVM_DEBUG(outs() << "CFG : Before Raising Terminator Instructions\n");
|
||||
LLVM_DEBUG(raisedFunction->dump());
|
||||
LLVM_DEBUG(RaisedFunction->dump());
|
||||
|
||||
// Raise branch instructions with control transfer records
|
||||
bool success = true;
|
||||
|
@ -5056,7 +5056,7 @@ bool X86MachineInstructionRaiser::raiseBranchMachineInstrs() {
|
|||
}
|
||||
}
|
||||
LLVM_DEBUG(outs() << "CFG : After Raising Terminator Instructions\n");
|
||||
LLVM_DEBUG(raisedFunction->dump());
|
||||
LLVM_DEBUG(RaisedFunction->dump());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -5075,7 +5075,7 @@ bool X86MachineInstructionRaiser::raiseFPURegisterOpInstr(
|
|||
case X86::ADD_FPrST0:
|
||||
case X86::MUL_FPrST0:
|
||||
case X86::DIV_FPrST0: {
|
||||
Value *St0Val = FPURegisterStackGetValueAt(0);
|
||||
Value *St0Val = getFPURegisterStackValueAt(0);
|
||||
assert((St0Val != nullptr) && "Failed to get ST(0) value");
|
||||
Type *St0ValTy = St0Val->getType();
|
||||
assert(St0ValTy->isFloatingPointTy() &&
|
||||
|
@ -5089,7 +5089,7 @@ bool X86MachineInstructionRaiser::raiseFPURegisterOpInstr(
|
|||
int8_t FPRegIndex = StRegOp.getReg() - X86::ST0;
|
||||
assert((FPRegIndex >= 0) && (FPRegIndex < FPUSTACK_SZ) &&
|
||||
"Unexpected FPU register stack index computed");
|
||||
Value *StVal = FPURegisterStackGetValueAt(FPRegIndex);
|
||||
Value *StVal = getFPURegisterStackValueAt(FPRegIndex);
|
||||
assert((StVal != nullptr) && "Failed to get value of FPU register");
|
||||
if (StVal->getType() != St0ValTy) {
|
||||
CastInst *CInst = CastInst::Create(
|
||||
|
@ -5109,9 +5109,9 @@ bool X86MachineInstructionRaiser::raiseFPURegisterOpInstr(
|
|||
}
|
||||
RaisedBB->getInstList().push_back(FPRegOpInstr);
|
||||
// Update the FP register FPRegIndex with FPRegOpInstr
|
||||
FPURegisterStackSetValueAt(FPRegIndex, FPRegOpInstr);
|
||||
setFPURegisterStackValueAt(FPRegIndex, FPRegOpInstr);
|
||||
// Pop FPU register stack
|
||||
FPURegisterStackPop();
|
||||
popFPURegisterStack();
|
||||
} break;
|
||||
default: {
|
||||
assert(false && "Unhandled FPU instruction");
|
||||
|
@ -5408,7 +5408,7 @@ bool X86MachineInstructionRaiser::raiseCallMachineInstr(
|
|||
else {
|
||||
RetInstr = ReturnInst::Create(Ctx, callInst);
|
||||
ModuleRaiser *NonConstMR = const_cast<ModuleRaiser *>(MR);
|
||||
NonConstMR->changeRaisedFunctionReturnType(raisedFunction,
|
||||
NonConstMR->changeRaisedFunctionReturnType(RaisedFunction,
|
||||
callInst->getType());
|
||||
}
|
||||
RaisedBB->getInstList().push_back(RetInstr);
|
||||
|
@ -5671,7 +5671,7 @@ bool X86MachineInstructionRaiser::raise() {
|
|||
if (Success) {
|
||||
// Delete empty basic blocks with no predecessors
|
||||
SmallVector<BasicBlock *, 4> UnConnectedBEmptyBs;
|
||||
for (BasicBlock &BB : *raisedFunction) {
|
||||
for (BasicBlock &BB : *RaisedFunction) {
|
||||
if (BB.hasNPredecessors(0) && BB.size() == 0)
|
||||
UnConnectedBEmptyBs.push_back(&BB);
|
||||
}
|
||||
|
@ -5681,7 +5681,7 @@ bool X86MachineInstructionRaiser::raise() {
|
|||
// Unify all exit nodes of the raised function
|
||||
legacy::PassManager PM;
|
||||
PM.add(createUnifyFunctionExitNodesPass());
|
||||
PM.run(*(raisedFunction->getParent()));
|
||||
PM.run(*(RaisedFunction->getParent()));
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
// Return type of the floating point physical register
|
||||
Type *getPhysSSERegType(unsigned int PhysReg, uint8_t BitPrecision);
|
||||
|
||||
bool insertAllocaInEntryBlock(Instruction *alloca, int StackOffset,
|
||||
bool insertAllocaInEntryBlock(Instruction *Alloca, int StackOffset,
|
||||
int MFIndex);
|
||||
BasicBlock *getRaisedBasicBlock(const MachineBasicBlock *);
|
||||
bool recordDefsToPromote(unsigned PhysReg, unsigned MBBNo, Value *Alloca);
|
||||
|
@ -71,7 +71,7 @@ public:
|
|||
int MBBNo, Instruction *Alloca);
|
||||
int getArgumentNumber(unsigned PReg) override;
|
||||
auto getRegisterInfo() const { return x86RegisterInfo; }
|
||||
bool instrNameStartsWith(const MachineInstr &MI, StringRef name) const;
|
||||
bool instrNameStartsWith(const MachineInstr &MI, StringRef Name) const;
|
||||
X86RaisedValueTracker *getRaisedValues() { return raisedValues; }
|
||||
|
||||
private:
|
||||
|
@ -176,14 +176,14 @@ private:
|
|||
// Raise Machine Jumptable
|
||||
bool raiseMachineJumpTable();
|
||||
|
||||
Value *getSwitchCompareValue(MachineBasicBlock &mbb);
|
||||
Value *getSwitchCompareValue(MachineBasicBlock &MBB);
|
||||
|
||||
// FPU Stack access functions
|
||||
void FPURegisterStackPush(Value *);
|
||||
void FPURegisterStackPop();
|
||||
Value *FPURegisterStackGetValueAt(int8_t);
|
||||
void FPURegisterStackSetValueAt(int8_t, Value *);
|
||||
Value *FPURegisterStackTop();
|
||||
void pushFPURegisterStack(Value *Val);
|
||||
void popFPURegisterStack();
|
||||
Value *getFPURegisterStackValueAt(int8_t);
|
||||
void setFPURegisterStackValueAt(int8_t, Value *);
|
||||
Value *topFPURegisterStack();
|
||||
|
||||
int getMemoryRefOpIndex(const MachineInstr &);
|
||||
Value *getGlobalVariableValueAt(const MachineInstr &, uint64_t);
|
||||
|
@ -192,7 +192,7 @@ private:
|
|||
Value *getMemoryAddressExprValue(const MachineInstr &);
|
||||
Value *createPCRelativeAccesssValue(const MachineInstr &);
|
||||
|
||||
bool changePhysRegToVirtReg(MachineInstr &);
|
||||
bool changePhysRegToVirtReg(MachineInstr &MI);
|
||||
|
||||
Value *getPhysRegValue(const MachineInstr &, unsigned);
|
||||
|
||||
|
@ -201,7 +201,7 @@ private:
|
|||
Type *getReturnTypeFromMBB(const MachineBasicBlock &MBB, bool &HasCall);
|
||||
Function *getTargetFunctionAtPLTOffset(const MachineInstr &, uint64_t);
|
||||
Value *getStackAllocatedValue(const MachineInstr &, X86AddressMode &, bool);
|
||||
Value *getRegOperandValue(const MachineInstr &mi, unsigned OperandIndex);
|
||||
Value *getRegOperandValue(const MachineInstr &MI, unsigned OperandIndex);
|
||||
|
||||
bool handleUnpromotedReachingDefs();
|
||||
bool handleUnterminatedBlocks();
|
||||
|
@ -222,7 +222,7 @@ private:
|
|||
bool isPopFromStack(const MachineInstr &MI) const;
|
||||
bool isEffectiveAddrValue(Value *Val);
|
||||
|
||||
std::vector<JumpTableInfo> jtList;
|
||||
std::vector<JumpTableInfo> JTList;
|
||||
};
|
||||
|
||||
} // end namespace mctoll
|
||||
|
|
|
@ -157,8 +157,8 @@ Value *X86MachineInstructionRaiser::getMemoryRefValue(const MachineInstr &MI) {
|
|||
// If this is neither a stack reference nor a pc-relative access, get the
|
||||
// associated memory address expression value.
|
||||
if (MemoryRefValue == nullptr) {
|
||||
Value *memrefValue = getMemoryAddressExprValue(MI);
|
||||
MemoryRefValue = memrefValue;
|
||||
Value *MemRefValue = getMemoryAddressExprValue(MI);
|
||||
MemoryRefValue = MemRefValue;
|
||||
}
|
||||
} else {
|
||||
// TODO : Memory references with BaseType FrameIndexBase
|
||||
|
@ -199,7 +199,7 @@ Value *X86MachineInstructionRaiser::loadMemoryRefValue(
|
|||
if (IsPCRelMemRef) {
|
||||
// If it is a PC-relative global variable with an initializer, it is memory
|
||||
// content and should not be loaded from.
|
||||
if (auto GV = dyn_cast<GlobalVariable>(MemRefValue))
|
||||
if (auto *GV = dyn_cast<GlobalVariable>(MemRefValue))
|
||||
LoadFromMemrefValue = !(GV->hasInitializer());
|
||||
// If it is not a PC-relative constant expression accessed using
|
||||
// GetElementPtrInst, it is memory content and should not be loaded from.
|
||||
|
@ -238,12 +238,11 @@ Value *X86MachineInstructionRaiser::loadMemoryRefValue(
|
|||
RaisedBB->getInstList().push_back(LdInst);
|
||||
|
||||
return LdInst;
|
||||
} else {
|
||||
// memRefValue already represents the global value loaded from
|
||||
// PC-relative memory location. It is incorrect to generate an
|
||||
// additional load of this value. It should be directly used.
|
||||
return MemRefValue;
|
||||
}
|
||||
// memRefValue already represents the global value loaded from
|
||||
// PC-relative memory location. It is incorrect to generate an
|
||||
// additional load of this value. It should be directly used.
|
||||
return MemRefValue;
|
||||
}
|
||||
|
||||
// Delete noop instructions
|
||||
|
@ -259,21 +258,21 @@ bool X86MachineInstructionRaiser::deleteNOOPInstrMI(
|
|||
}
|
||||
|
||||
bool X86MachineInstructionRaiser::deleteNOOPInstrMF() {
|
||||
bool modified = false;
|
||||
bool Modified = false;
|
||||
for (MachineBasicBlock &MBB : MF) {
|
||||
// MBBI may be invalidated by the raising operation.
|
||||
MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
|
||||
while (MBBI != E) {
|
||||
MachineBasicBlock::iterator NMBBI = std::next(MBBI);
|
||||
modified |= deleteNOOPInstrMI(MBB, MBBI);
|
||||
Modified |= deleteNOOPInstrMI(MBB, MBBI);
|
||||
MBBI = NMBBI;
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
return Modified;
|
||||
}
|
||||
|
||||
bool X86MachineInstructionRaiser::unlinkEmptyMBBs() {
|
||||
bool modified = false;
|
||||
bool Modified = false;
|
||||
std::set<unsigned> EmptyMBBNos;
|
||||
// Collect empty basic block numbers
|
||||
for (MachineBasicBlock &MBB : MF) {
|
||||
|
@ -287,22 +286,22 @@ bool X86MachineInstructionRaiser::unlinkEmptyMBBs() {
|
|||
// Transfer all successors of DelMBB as successors of each of the
|
||||
// predecessors of DelMBB.
|
||||
if (DelMBB->pred_size() > 0) {
|
||||
for (auto DelMBBPred : DelMBB->predecessors()) {
|
||||
for (auto *DelMBBPred : DelMBB->predecessors()) {
|
||||
DelMBBPred->transferSuccessors(DelMBB);
|
||||
}
|
||||
} else {
|
||||
// If DelMBB does not have any predecessors, successors of DelMBB would
|
||||
// not be deleted since transferAllSuccessors will not be called. So, we
|
||||
// need to explicitly delete all successors of DelMBB.
|
||||
for (auto DelMBBSucc : DelMBB->successors()) {
|
||||
for (auto *DelMBBSucc : DelMBB->successors()) {
|
||||
DelMBB->removeSuccessor(DelMBBSucc);
|
||||
}
|
||||
}
|
||||
// Do not delete DelMBB
|
||||
}
|
||||
modified = true;
|
||||
Modified = true;
|
||||
}
|
||||
return modified;
|
||||
return Modified;
|
||||
}
|
||||
|
||||
// Return the Type of the physical register.
|
||||
|
@ -385,7 +384,8 @@ Type *X86MachineInstructionRaiser::getPhysRegOperandType(const MachineInstr &MI,
|
|||
assert(RegSzInBits > 0 && "Non-zero register size expected");
|
||||
if (isGPReg(PReg)) {
|
||||
return Type::getIntNTy(Ctx, RegSzInBits);
|
||||
} else if (isSSE2Reg(PReg)) {
|
||||
}
|
||||
if (isSSE2Reg(PReg)) {
|
||||
return getRaisedValues()->getSSEInstructionType(MI, RegSzInBits, Ctx);
|
||||
}
|
||||
llvm_unreachable("Unhandled register type encountered");
|
||||
|
@ -462,7 +462,7 @@ const MachineInstr *X86MachineInstructionRaiser::getPhysRegDefiningInstInBlock(
|
|||
for (auto MO : MI.operands()) {
|
||||
// Consider only the register operand
|
||||
if (MO.isReg() && MO.isDef()) {
|
||||
unsigned MOReg = MO.getReg();
|
||||
Register MOReg = MO.getReg();
|
||||
// If it is a physical register other than EFLAGS
|
||||
if (MOReg != X86::EFLAGS && Register::isPhysicalRegister(MOReg)) {
|
||||
if (SuperReg == find64BitSuperReg(MOReg))
|
||||
|
@ -477,8 +477,8 @@ const MachineInstr *X86MachineInstructionRaiser::getPhysRegDefiningInstInBlock(
|
|||
}
|
||||
|
||||
// FPU Access functions
|
||||
void X86MachineInstructionRaiser::FPURegisterStackPush(Value *val) {
|
||||
assert(val->getType()->isFloatingPointTy() &&
|
||||
void X86MachineInstructionRaiser::pushFPURegisterStack(Value *Val) {
|
||||
assert(Val->getType()->isFloatingPointTy() &&
|
||||
"Attempt to push non-FP type value on FPU register stack");
|
||||
assert((FPUStack.TOP < FPUSTACK_SZ) && (FPUStack.TOP >= 0) &&
|
||||
"Incorrect initial FPU Register Stack top in push");
|
||||
|
@ -487,11 +487,11 @@ void X86MachineInstructionRaiser::FPURegisterStackPush(Value *val) {
|
|||
|
||||
assert((PushIndex < FPUSTACK_SZ) && (PushIndex >= 0) &&
|
||||
"Incorrect FPU Register Stack index computed in push");
|
||||
FPUStack.Regs[PushIndex] = val;
|
||||
FPUStack.Regs[PushIndex] = Val;
|
||||
FPUStack.TOP = PushIndex;
|
||||
}
|
||||
|
||||
void X86MachineInstructionRaiser::FPURegisterStackPop() {
|
||||
void X86MachineInstructionRaiser::popFPURegisterStack() {
|
||||
assert((FPUStack.TOP < FPUSTACK_SZ) && (FPUStack.TOP >= 0) &&
|
||||
"Incorrect initial FPU Register Stack top in pop");
|
||||
|
||||
|
@ -506,11 +506,11 @@ void X86MachineInstructionRaiser::FPURegisterStackPop() {
|
|||
}
|
||||
|
||||
// Get value at index
|
||||
Value *X86MachineInstructionRaiser::FPURegisterStackGetValueAt(int8_t index) {
|
||||
Value *X86MachineInstructionRaiser::getFPURegisterStackValueAt(int8_t Index) {
|
||||
assert((FPUStack.TOP < FPUSTACK_SZ) && (FPUStack.TOP >= 0) &&
|
||||
"Incorrect initial FPU Register Stack top in FPU register access");
|
||||
|
||||
int8_t AccessIndex = (FPUSTACK_SZ + FPUStack.TOP + index) % FPUSTACK_SZ;
|
||||
int8_t AccessIndex = (FPUSTACK_SZ + FPUStack.TOP + Index) % FPUSTACK_SZ;
|
||||
|
||||
assert((AccessIndex < FPUSTACK_SZ) && (AccessIndex >= 0) &&
|
||||
"Incorrect FPU Register Stack index computed in FPU register access");
|
||||
|
@ -519,23 +519,23 @@ Value *X86MachineInstructionRaiser::FPURegisterStackGetValueAt(int8_t index) {
|
|||
}
|
||||
|
||||
// Set value at index to val
|
||||
void X86MachineInstructionRaiser::FPURegisterStackSetValueAt(int8_t index,
|
||||
Value *val) {
|
||||
assert(val->getType()->isFloatingPointTy() &&
|
||||
void X86MachineInstructionRaiser::setFPURegisterStackValueAt(int8_t Index,
|
||||
Value *Val) {
|
||||
assert(Val->getType()->isFloatingPointTy() &&
|
||||
"Attempt to insert non-FP type value in FPU register stack");
|
||||
assert((FPUStack.TOP < FPUSTACK_SZ) && (FPUStack.TOP >= 0) &&
|
||||
"Incorrect initial FPU Register Stack top in FPU register access");
|
||||
|
||||
int8_t AccessIndex = (FPUSTACK_SZ + FPUStack.TOP + index) % FPUSTACK_SZ;
|
||||
int8_t AccessIndex = (FPUSTACK_SZ + FPUStack.TOP + Index) % FPUSTACK_SZ;
|
||||
|
||||
assert((AccessIndex < FPUSTACK_SZ) && (AccessIndex >= 0) &&
|
||||
"Incorrect FPU Register Stack index computed in FPU register access");
|
||||
|
||||
FPUStack.Regs[AccessIndex] = val;
|
||||
FPUStack.Regs[AccessIndex] = Val;
|
||||
}
|
||||
|
||||
Value *X86MachineInstructionRaiser::FPURegisterStackTop() {
|
||||
return FPURegisterStackGetValueAt(0);
|
||||
Value *X86MachineInstructionRaiser::topFPURegisterStack() {
|
||||
return getFPURegisterStackValueAt(0);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
|
@ -692,7 +692,7 @@ Value *X86MachineInstructionRaiser::createPCRelativeAccesssValue(
|
|||
auto SymbOrErr = Elf64LEObjFile->getSymbol(SymbImpl);
|
||||
assert(SymbOrErr && "PC-relative access: Dynamic symbol not found");
|
||||
// get symbol size
|
||||
auto Symb = SymbOrErr.get();
|
||||
auto *Symb = SymbOrErr.get();
|
||||
uint64_t SymbSize = Symb->st_size;
|
||||
GlobalValue::LinkageTypes Lnkg;
|
||||
switch (Symb->getBinding()) {
|
||||
|
@ -757,7 +757,7 @@ Value *X86MachineInstructionRaiser::createPCRelativeAccesssValue(
|
|||
}
|
||||
|
||||
Constant *GlobalInit;
|
||||
if (IncludedFileInfo::IsExternalVariable(Symname->str())) {
|
||||
if (IncludedFileInfo::isExternalVariable(Symname->str())) {
|
||||
GlobalInit = nullptr;
|
||||
Lnkg = GlobalValue::ExternalLinkage;
|
||||
} else {
|
||||
|
@ -766,7 +766,7 @@ Value *X86MachineInstructionRaiser::createPCRelativeAccesssValue(
|
|||
: nullptr;
|
||||
}
|
||||
|
||||
auto GlobalVal = new GlobalVariable(*(MR->getModule()), GlobalValTy,
|
||||
auto *GlobalVal = new GlobalVariable(*(MR->getModule()), GlobalValTy,
|
||||
false /* isConstant */, Lnkg,
|
||||
GlobalInit, Symname->data());
|
||||
// Don't use symbSize as it was modified.
|
||||
|
@ -804,12 +804,12 @@ Value *X86MachineInstructionRaiser::createPCRelativeAccesssValue(
|
|||
// which is most likely global.
|
||||
|
||||
llvm::LLVMContext &Ctx(MF.getFunction().getContext());
|
||||
DataRefImpl symbImpl = TextReloc->getSymbol()->getRawDataRefImpl();
|
||||
DataRefImpl SymbImpl = TextReloc->getSymbol()->getRawDataRefImpl();
|
||||
// get symbol
|
||||
auto SymbOrErr = Elf64LEObjFile->getSymbol(symbImpl);
|
||||
auto SymbOrErr = Elf64LEObjFile->getSymbol(SymbImpl);
|
||||
assert(SymbOrErr && "PC-relative access: Relocation symbol not found");
|
||||
// get symbol size
|
||||
auto Symb = SymbOrErr.get();
|
||||
auto *Symb = SymbOrErr.get();
|
||||
uint64_t SymSize = Symb->st_size;
|
||||
GlobalValue::LinkageTypes Lnkg;
|
||||
switch (Symb->getBinding()) {
|
||||
|
@ -878,14 +878,14 @@ Value *X86MachineInstructionRaiser::createPCRelativeAccesssValue(
|
|||
}
|
||||
|
||||
Constant *GlobalInit;
|
||||
if (IncludedFileInfo::IsExternalVariable(Symname->str())) {
|
||||
if (IncludedFileInfo::isExternalVariable(Symname->str())) {
|
||||
GlobalInit = nullptr;
|
||||
Lnkg = GlobalValue::ExternalLinkage;
|
||||
} else {
|
||||
GlobalInit = ConstantInt::get(GlobalValTy, SymInitVal);
|
||||
}
|
||||
|
||||
auto GlobalVal = new GlobalVariable(*(MR->getModule()), GlobalValTy,
|
||||
auto *GlobalVal = new GlobalVariable(*(MR->getModule()), GlobalValTy,
|
||||
false /* isConstant */, Lnkg,
|
||||
GlobalInit, Symname->data());
|
||||
// Don't use symSize as it was modified.
|
||||
|
@ -939,9 +939,8 @@ StoreInst *X86MachineInstructionRaiser::promotePhysregToStackSlot(
|
|||
StackLocTy = Type::getIntNTy(Ctxt, StackLocSzInBits);
|
||||
} else if (ReachingValue->getType()->isFloatingPointTy() ||
|
||||
ReachingValue->getType()->isVectorTy()) {
|
||||
assert(
|
||||
StackLocSzInBits == 128 &&
|
||||
"Expected FP types and vectors to be stored in 128 bit stack location");
|
||||
assert(StackLocSzInBits == 128 &&
|
||||
"Expected FP types and vectors to be stored in 128 bit stack location");
|
||||
StackLocTy = VectorType::get(Type::getInt32Ty(Ctxt), 4, false);
|
||||
} else {
|
||||
llvm_unreachable("Unhandled type");
|
||||
|
@ -987,19 +986,19 @@ StoreInst *X86MachineInstructionRaiser::promotePhysregToStackSlot(
|
|||
return StInst;
|
||||
|
||||
MachineDominatorTree MDT(MF);
|
||||
auto DefiningMBB = MF.getBlockNumbered(DefiningMBBNo);
|
||||
auto *DefiningMBB = MF.getBlockNumbered(DefiningMBBNo);
|
||||
// Construct instructions that use ReachingValue and are in a basic block
|
||||
// other than DefiningMBB.
|
||||
for (auto U : ReachingValue->users()) {
|
||||
if (auto I = dyn_cast<Instruction>(U)) {
|
||||
for (auto *U : ReachingValue->users()) {
|
||||
if (auto *I = dyn_cast<Instruction>(U)) {
|
||||
if (I->getParent() == ReachingBB)
|
||||
continue;
|
||||
|
||||
// find MBB number from which the instruction was raised
|
||||
auto InstMBBNo =
|
||||
std::find_if(std::begin(mbbToBBMap), std::end(mbbToBBMap),
|
||||
[&](const std::pair<unsigned int, BasicBlock *> &pair) {
|
||||
return pair.second == I->getParent();
|
||||
[&](const std::pair<unsigned int, BasicBlock *> &Pair) {
|
||||
return Pair.second == I->getParent();
|
||||
});
|
||||
|
||||
// Only replace I with LdInst, if StInst dominates I
|
||||
|
@ -1012,7 +1011,7 @@ StoreInst *X86MachineInstructionRaiser::promotePhysregToStackSlot(
|
|||
|
||||
// Replace all uses of ReachingValue with that loaded from stack location at
|
||||
// which ReachingValue is stored.
|
||||
for (auto I : UsageInstList) {
|
||||
for (auto *I : UsageInstList) {
|
||||
LoadInst *LdFromStkSlot = new LoadInst(
|
||||
Alloca->getType()->getPointerElementType(), Alloca, "ld-stk-prom", I);
|
||||
I->replaceUsesOfWith(ReachingValue, LdFromStkSlot);
|
||||
|
@ -1034,7 +1033,7 @@ static bool isStackLocation(Value *Val) {
|
|||
int NumUseOps = BinaryOp->getNumOperands();
|
||||
assert((NumUseOps == 2) && "Unexpected operands of binary operands");
|
||||
for (int i = 0; i < NumUseOps; i++) {
|
||||
auto Op = BinaryOp->getOperand(i);
|
||||
auto *Op = BinaryOp->getOperand(i);
|
||||
if (isa<CastInst>(Op)) {
|
||||
CastInst *P = dyn_cast<CastInst>(Op);
|
||||
V = P->getOperand(0);
|
||||
|
@ -1072,9 +1071,9 @@ bool X86MachineInstructionRaiser::handleUnpromotedReachingDefs() {
|
|||
|
||||
// Check for unterminated basic blocks.
|
||||
bool X86MachineInstructionRaiser::handleUnterminatedBlocks() {
|
||||
auto raisedFunction = getRaisedFunction();
|
||||
LLVMContext &Ctx(raisedFunction->getContext());
|
||||
for (auto &BB : *raisedFunction) {
|
||||
auto *RaisedFunction = getRaisedFunction();
|
||||
LLVMContext &Ctx(RaisedFunction->getContext());
|
||||
for (auto &BB : *RaisedFunction) {
|
||||
if (!BB.empty() && (BB.getTerminator() == nullptr)) {
|
||||
// If the last instruction of a basic block is a call instruction
|
||||
// convert it into a tail call and insert an unreachable instruction
|
||||
|
@ -1109,11 +1108,11 @@ bool X86MachineInstructionRaiser::createFunctionStackFrame() {
|
|||
// If there are stack objects allocated
|
||||
if (ShadowStackIndexedByOffset.size() > 1) {
|
||||
MachineFrameInfo &MFrameInfo = MF.getFrameInfo();
|
||||
const DataLayout &dataLayout = MR->getModule()->getDataLayout();
|
||||
unsigned allocaAddrSpace = dataLayout.getAllocaAddrSpace();
|
||||
const DataLayout &DL = MR->getModule()->getDataLayout();
|
||||
unsigned AllocaAddrSpace = DL.getAllocaAddrSpace();
|
||||
|
||||
std::map<int64_t, int>::iterator StackOffsetToIndexMapIter;
|
||||
LLVMContext &llvmContext(MF.getFunction().getContext());
|
||||
LLVMContext &Context(MF.getFunction().getContext());
|
||||
StackOffsetToIndexMapIter = ShadowStackIndexedByOffset.begin();
|
||||
// The first non-spill alloca in StackOffsetToIndexMapIter map record
|
||||
// represents the alloca corresponding to the top-of-stack offset. Get stack
|
||||
|
@ -1140,27 +1139,27 @@ bool X86MachineInstructionRaiser::createFunctionStackFrame() {
|
|||
MFrameInfo.getObjectAllocation(StackTopObjIndex));
|
||||
Type *TOSAllocaOrigType = TOSAlloca->getType();
|
||||
auto TOSSzInBytes =
|
||||
TOSAlloca->getAllocationSizeInBits(dataLayout).getValue() / 8;
|
||||
TOSAlloca->getAllocationSizeInBits(DL).getValue() / 8;
|
||||
// Get stack bottom offset and index
|
||||
int64_t StackBottomOffset = ShadowStackIndexedByOffset.rbegin()->first;
|
||||
int StackBottomObjIndex = ShadowStackIndexedByOffset.rbegin()->second;
|
||||
const AllocaInst *BOSAlloca =
|
||||
MFrameInfo.getObjectAllocation(StackBottomObjIndex);
|
||||
auto BOSSzInBytes =
|
||||
BOSAlloca->getAllocationSizeInBits(dataLayout).getValue() / 8;
|
||||
BOSAlloca->getAllocationSizeInBits(DL).getValue() / 8;
|
||||
// Get stack frame size. Note that stack grows down on x86-64. Need to
|
||||
// ensure that stack frame size includes the size of the bottom most
|
||||
// object as well.
|
||||
int StackFrameSize = StackBottomOffset - StackTopOffset + BOSSzInBytes;
|
||||
assert(StackFrameSize > 0 && "Unexpected stack frame size");
|
||||
Value *StackFreameSizeVal =
|
||||
ConstantInt::get(llvmContext, APInt(32, StackFrameSize));
|
||||
ConstantInt::get(Context, APInt(32, StackFrameSize));
|
||||
// Construct new alloca corresponding to TOS offset with size
|
||||
// StackFrameSize bytes and insert it before TOSAlloca (which will be
|
||||
// replaced later by the cast of this alloca).
|
||||
Type *ByteTy = Type::getInt8Ty(llvmContext);
|
||||
Type *ByteTy = Type::getInt8Ty(Context);
|
||||
AllocaInst *StackFrameAlloca =
|
||||
new AllocaInst(ByteTy, allocaAddrSpace, StackFreameSizeVal, Align(),
|
||||
new AllocaInst(ByteTy, AllocaAddrSpace, StackFreameSizeVal, Align(),
|
||||
"stktop_" + std::to_string(TOSSzInBytes), TOSAlloca);
|
||||
// Cast the StackFrameAlloca instruction to the type of TOSAlloca
|
||||
Instruction *CastStackFrameAlloca =
|
||||
|
@ -1192,7 +1191,7 @@ bool X86MachineInstructionRaiser::createFunctionStackFrame() {
|
|||
ReplaceInstWithInst(dyn_cast<Instruction>(TOSAlloca), CastStackFrameAlloca);
|
||||
// Cast StackFrameAlloca as int and insert it before StackObjAlloca,
|
||||
// which will be replaced later
|
||||
Type *Int64Ty = Type::getInt64Ty(llvmContext);
|
||||
Type *Int64Ty = Type::getInt64Ty(Context);
|
||||
Instruction *StackFrameAllocaAddr = CastInst::Create(
|
||||
CastInst::getCastOpcode(StackFrameAlloca, false, Int64Ty, false),
|
||||
StackFrameAlloca, Int64Ty, "tos", CastStackFrameAlloca->getNextNode());
|
||||
|
@ -1263,7 +1262,7 @@ bool X86MachineInstructionRaiser::createFunctionStackFrame() {
|
|||
|
||||
Value *X86MachineInstructionRaiser::getStackAllocatedValue(
|
||||
const MachineInstr &MI, X86AddressMode &MemRef, bool IsStackPointerAdjust) {
|
||||
unsigned int stackFrameIndex;
|
||||
unsigned int StackFrameIndex;
|
||||
|
||||
assert((MemRef.BaseType == X86AddressMode::RegBase) &&
|
||||
"Register type operand expected for stack allocated value lookup");
|
||||
|
@ -1272,40 +1271,39 @@ Value *X86MachineInstructionRaiser::getStackAllocatedValue(
|
|||
"Stack or base pointer expected for stack allocated value lookup");
|
||||
Value *CurSPVal = getRegOrArgValue(PReg, MI.getParent()->getNumber());
|
||||
Type *MemOpTy = nullptr;
|
||||
LLVMContext &llvmContext(MF.getFunction().getContext());
|
||||
const DataLayout &dataLayout = MR->getModule()->getDataLayout();
|
||||
unsigned allocaAddrSpace = dataLayout.getAllocaAddrSpace();
|
||||
unsigned stackObjectSize = getInstructionMemOpSize(MI.getOpcode());
|
||||
if (IsStackPointerAdjust && (stackObjectSize == 0)) {
|
||||
stackObjectSize = 8;
|
||||
LLVMContext &Context(MF.getFunction().getContext());
|
||||
const DataLayout &DL = MR->getModule()->getDataLayout();
|
||||
unsigned AllocaAddrSpace = DL.getAllocaAddrSpace();
|
||||
unsigned StackObjectSize = getInstructionMemOpSize(MI.getOpcode());
|
||||
if (IsStackPointerAdjust && (StackObjectSize == 0)) {
|
||||
StackObjectSize = 8;
|
||||
}
|
||||
InstructionKind InstrKind = getInstructionKind(MI.getOpcode());
|
||||
bool SSE2MemOp = ((InstrKind == InstructionKind::SSE_MOV_FROM_MEM) ||
|
||||
(InstrKind == InstructionKind::SSE_MOV_TO_MEM));
|
||||
if (SSE2MemOp) {
|
||||
auto SSERegSzInBits = stackObjectSize * 8;
|
||||
MemOpTy = getRaisedValues()->getSSEInstructionType(MI, SSERegSzInBits,
|
||||
llvmContext);
|
||||
auto SSERegSzInBits = StackObjectSize * 8;
|
||||
MemOpTy = getRaisedValues()->getSSEInstructionType(MI, SSERegSzInBits, Context);
|
||||
} else {
|
||||
switch (stackObjectSize) {
|
||||
switch (StackObjectSize) {
|
||||
case 8:
|
||||
MemOpTy = Type::getInt64Ty(llvmContext);
|
||||
MemOpTy = Type::getInt64Ty(Context);
|
||||
break;
|
||||
case 4:
|
||||
MemOpTy = Type::getInt32Ty(llvmContext);
|
||||
MemOpTy = Type::getInt32Ty(Context);
|
||||
break;
|
||||
case 2:
|
||||
MemOpTy = Type::getInt16Ty(llvmContext);
|
||||
MemOpTy = Type::getInt16Ty(Context);
|
||||
break;
|
||||
case 1:
|
||||
MemOpTy = Type::getInt8Ty(llvmContext);
|
||||
MemOpTy = Type::getInt8Ty(Context);
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected access size of memory ref instruction");
|
||||
}
|
||||
}
|
||||
|
||||
assert(stackObjectSize != 0 && MemOpTy != nullptr &&
|
||||
assert(StackObjectSize != 0 && MemOpTy != nullptr &&
|
||||
"Unknown type of operand in memory referencing instruction");
|
||||
BasicBlock *RaisedBB = getRaisedBasicBlock(MI.getParent());
|
||||
|
||||
|
@ -1364,10 +1362,10 @@ Value *X86MachineInstructionRaiser::getStackAllocatedValue(
|
|||
// If this is a stack pinter adjustment, find the corresponding adjustment
|
||||
// slot and return it. There is no need for a new slot to be created.
|
||||
if (IsStackPointerAdjust) {
|
||||
auto SSIter = ShadowStackIndexedByOffset.find(-MIStackOffset);
|
||||
if (SSIter != ShadowStackIndexedByOffset.end())
|
||||
auto Iter = ShadowStackIndexedByOffset.find(-MIStackOffset);
|
||||
if (Iter != ShadowStackIndexedByOffset.end())
|
||||
return const_cast<AllocaInst *>(
|
||||
MFrameInfo.getObjectAllocation(SSIter->second));
|
||||
MFrameInfo.getObjectAllocation(Iter->second));
|
||||
}
|
||||
|
||||
// Find if there exists a stack slot that includes the offset MIStackSlot
|
||||
|
@ -1384,7 +1382,7 @@ Value *X86MachineInstructionRaiser::getStackAllocatedValue(
|
|||
assert(Stride > 0 && "Unexpected stack slot stride");
|
||||
// Convert pointer to int with size of the source binary ISA pointer
|
||||
Type *PtrCastIntTy =
|
||||
Type::getIntNTy(llvmContext, dataLayout.getPointerSizeInBits());
|
||||
Type::getIntNTy(Context, DL.getPointerSizeInBits());
|
||||
|
||||
PtrToIntInst *AllocaAsInt =
|
||||
new PtrToIntInst(StackSlotAllocaInst, PtrCastIntTy, "", RaisedBB);
|
||||
|
@ -1401,26 +1399,26 @@ Value *X86MachineInstructionRaiser::getStackAllocatedValue(
|
|||
std::string SPStr = (MIStackOffset < 0) ? BaseName + "N." : BaseName + "P.";
|
||||
auto ByteAlign = Align();
|
||||
// Create alloca instruction to allocate stack slot
|
||||
AllocaInst *alloca =
|
||||
new AllocaInst(MemOpTy, allocaAddrSpace, 0, ByteAlign,
|
||||
AllocaInst *Alloca =
|
||||
new AllocaInst(MemOpTy, AllocaAddrSpace, 0, ByteAlign,
|
||||
SPStr + std::to_string(std::abs(MIStackOffset)));
|
||||
|
||||
// Create a stack slot associated with the alloca instruction
|
||||
stackFrameIndex = MF.getFrameInfo().CreateStackObject(
|
||||
stackObjectSize, ByteAlign, false /* isSpillSlot */, alloca);
|
||||
StackFrameIndex = MF.getFrameInfo().CreateStackObject(
|
||||
StackObjectSize, ByteAlign, false /* isSpillSlot */, Alloca);
|
||||
|
||||
// Set MIStackOffset as the offset for stack frame object created.
|
||||
MF.getFrameInfo().setObjectOffset(stackFrameIndex, MIStackOffset);
|
||||
MF.getFrameInfo().setObjectOffset(StackFrameIndex, MIStackOffset);
|
||||
|
||||
// Add the alloca instruction to entry block
|
||||
insertAllocaInEntryBlock(alloca, MIStackOffset, stackFrameIndex);
|
||||
insertAllocaInEntryBlock(Alloca, MIStackOffset, StackFrameIndex);
|
||||
|
||||
return alloca;
|
||||
return Alloca;
|
||||
}
|
||||
|
||||
// Return the Function * referenced by the PLT entry at offset
|
||||
Function *X86MachineInstructionRaiser::getTargetFunctionAtPLTOffset(
|
||||
const MachineInstr &mi, uint64_t pltEntOff) {
|
||||
const MachineInstr &MI, uint64_t PltEntOff) {
|
||||
Function *CalledFunc = nullptr;
|
||||
const ELF64LEObjectFile *Elf64LEObjFile =
|
||||
dyn_cast<ELF64LEObjectFile>(MR->getObjectFile());
|
||||
|
@ -1432,7 +1430,7 @@ Function *X86MachineInstructionRaiser::getTargetFunctionAtPLTOffset(
|
|||
for (section_iterator SecIter : Elf64LEObjFile->sections()) {
|
||||
uint64_t SecStart = SecIter->getAddress();
|
||||
uint64_t SecEnd = SecStart + SecIter->getSize();
|
||||
if ((SecStart <= pltEntOff) && (SecEnd > pltEntOff)) {
|
||||
if ((SecStart <= PltEntOff) && (SecEnd > PltEntOff)) {
|
||||
StringRef SecName;
|
||||
if (auto NameOrErr = SecIter->getName())
|
||||
SecName = *NameOrErr;
|
||||
|
@ -1448,10 +1446,10 @@ Function *X86MachineInstructionRaiser::getTargetFunctionAtPLTOffset(
|
|||
SecData.size());
|
||||
// Disassemble the first instruction at the offset
|
||||
MCInst Inst;
|
||||
uint64_t jmpInstSz;
|
||||
uint64_t jmpInstOff = pltEntOff;
|
||||
uint64_t JmpInstSz;
|
||||
uint64_t JmpInstOff = PltEntOff;
|
||||
bool Success = MR->getMCDisassembler()->getInstruction(
|
||||
Inst, jmpInstSz, Bytes.slice(jmpInstOff - SecStart), pltEntOff,
|
||||
Inst, JmpInstSz, Bytes.slice(JmpInstOff - SecStart), PltEntOff,
|
||||
nulls());
|
||||
assert(Success && "Failed to disassemble instruction in PLT");
|
||||
unsigned int Opcode = Inst.getOpcode();
|
||||
|
@ -1459,9 +1457,9 @@ Function *X86MachineInstructionRaiser::getTargetFunctionAtPLTOffset(
|
|||
// instructions used for Indirect Branch Tracking - get to the next
|
||||
// instruction that is expected to be the jump to target.
|
||||
if ((Opcode == X86::ENDBR32) || (Opcode == X86::ENDBR64)) {
|
||||
jmpInstOff += jmpInstSz;
|
||||
JmpInstOff += JmpInstSz;
|
||||
Success = MR->getMCDisassembler()->getInstruction(
|
||||
Inst, jmpInstSz, Bytes.slice(jmpInstOff - SecStart), jmpInstOff,
|
||||
Inst, JmpInstSz, Bytes.slice(JmpInstOff - SecStart), JmpInstOff,
|
||||
nulls());
|
||||
assert(Success && "Failed to disassemble instruction in PLT");
|
||||
Opcode = Inst.getOpcode();
|
||||
|
@ -1533,7 +1531,7 @@ Function *X86MachineInstructionRaiser::getTargetFunctionAtPLTOffset(
|
|||
// a) offset of jmp instruction + size of the instruction
|
||||
// (representing pc-related addressing) b) jmp target offset in the
|
||||
// instruction
|
||||
uint64_t GotPltRelocOffset = jmpInstOff + jmpInstSz + PCOffset;
|
||||
uint64_t GotPltRelocOffset = JmpInstOff + JmpInstSz + PCOffset;
|
||||
const RelocationRef *GotPltReloc =
|
||||
MR->getDynRelocAtOffset(GotPltRelocOffset);
|
||||
assert(GotPltReloc != nullptr &&
|
||||
|
@ -1586,7 +1584,7 @@ Value *X86MachineInstructionRaiser::getOrCreateGlobalRODataValueAtOffset(
|
|||
dyn_cast<ELF64LEObjectFile>(MR->getObjectFile());
|
||||
assert(Elf64LEObjFile != nullptr &&
|
||||
"Only 64-bit ELF binaries supported at present.");
|
||||
LLVMContext &llvmContext(MF.getFunction().getContext());
|
||||
LLVMContext &Context(MF.getFunction().getContext());
|
||||
// Check if this is an address in .rodata
|
||||
for (section_iterator SecIter : Elf64LEObjFile->sections()) {
|
||||
uint64_t SecStart = SecIter->getAddress();
|
||||
|
@ -1617,8 +1615,8 @@ Value *X86MachineInstructionRaiser::getOrCreateGlobalRODataValueAtOffset(
|
|||
MR->getObjectFile()->getFileName());
|
||||
unsigned DataSize = SecIter->getSize();
|
||||
auto DataStr = makeArrayRef(SecData.bytes_begin(), DataSize);
|
||||
Constant *StrConstant = ConstantDataArray::get(llvmContext, DataStr);
|
||||
auto GlobalStrConstVal = new GlobalVariable(
|
||||
Constant *StrConstant = ConstantDataArray::get(Context, DataStr);
|
||||
auto *GlobalStrConstVal = new GlobalVariable(
|
||||
*(MR->getModule()), StrConstant->getType(), true /* isConstant */,
|
||||
GlobalValue::PrivateLinkage, StrConstant, RODataSecValueName);
|
||||
GlobalStrConstVal->setAlignment(MaybeAlign(SecIter->getAlignment()));
|
||||
|
@ -1632,9 +1630,9 @@ Value *X86MachineInstructionRaiser::getOrCreateGlobalRODataValueAtOffset(
|
|||
unsigned DataOffset = (Offset - SecStart);
|
||||
// Construct index array for a GEP instruction that accesses
|
||||
// byte array
|
||||
Value *Zero32Value = ConstantInt::get(Type::getInt32Ty(llvmContext), 0);
|
||||
Value *Zero32Value = ConstantInt::get(Type::getInt32Ty(Context), 0);
|
||||
Value *DataOffsetIndex =
|
||||
ConstantInt::get(Type::getInt32Ty(llvmContext), DataOffset);
|
||||
ConstantInt::get(Type::getInt32Ty(Context), DataOffset);
|
||||
Constant *GetElem = ConstantExpr::getInBoundsGetElementPtr(
|
||||
RODataSecValue->getType()->getPointerElementType(), RODataSecValue,
|
||||
{Zero32Value, DataOffsetIndex});
|
||||
|
@ -1684,7 +1682,7 @@ X86MachineInstructionRaiser::getGlobalVariableValueAt(const MachineInstr &MI,
|
|||
auto SymSize = Symbol.getSize();
|
||||
|
||||
if (!SymAddr)
|
||||
report_error(SymAddr.takeError(),
|
||||
reportError(SymAddr.takeError(),
|
||||
"Failed to lookup symbol for global address");
|
||||
uint64_t SymAddrVal = SymAddr.get();
|
||||
// We have established that Offset is not negative above. So, OK to
|
||||
|
@ -1717,7 +1715,7 @@ X86MachineInstructionRaiser::getGlobalVariableValueAt(const MachineInstr &MI,
|
|||
// variable.
|
||||
Expected<StringRef> GlobalDataSymName = GlobalSymRef.getName();
|
||||
if (!GlobalDataSymName)
|
||||
report_error(GlobalDataSymName.takeError(),
|
||||
reportError(GlobalDataSymName.takeError(),
|
||||
"Failed to find global symbol name.");
|
||||
// Find if a global value associated with symbol name is already
|
||||
// created
|
||||
|
@ -1759,7 +1757,7 @@ X86MachineInstructionRaiser::getGlobalVariableValueAt(const MachineInstr &MI,
|
|||
// get symbol
|
||||
auto SymbOrErr = Elf64LEObjFile->getSymbol(SymbImpl);
|
||||
assert(SymbOrErr && "Global symbol not found");
|
||||
auto Symb = SymbOrErr.get();
|
||||
auto *Symb = SymbOrErr.get();
|
||||
// get symbol size
|
||||
uint64_t SymbSize = Symb->st_size;
|
||||
// If symbol size is less than symbol section size, set alignment to
|
||||
|
@ -1802,7 +1800,7 @@ X86MachineInstructionRaiser::getGlobalVariableValueAt(const MachineInstr &MI,
|
|||
// In executable and shared object files, st_value holds a virtual
|
||||
// address.
|
||||
SmallVector<Constant *, 32> ConstantVec;
|
||||
bool isBSSSymbol = false;
|
||||
bool IsBSSSymbol = false;
|
||||
for (section_iterator SecIter : Elf64LEObjFile->sections()) {
|
||||
uint64_t SecStart = SecIter->getAddress();
|
||||
uint64_t SecEnd = SecStart + SecIter->getSize();
|
||||
|
@ -1811,12 +1809,12 @@ X86MachineInstructionRaiser::getGlobalVariableValueAt(const MachineInstr &MI,
|
|||
// Else, symVal is already initialized to 0.
|
||||
if (SecIter->isBSS()) {
|
||||
Lnkg = GlobalValue::CommonLinkage;
|
||||
isBSSSymbol = true;
|
||||
IsBSSSymbol = true;
|
||||
} else {
|
||||
StringRef SecData = unwrapOrError(
|
||||
SecIter->getContents(), MR->getObjectFile()->getFileName());
|
||||
unsigned Index = SymVirtualAddr - SecStart;
|
||||
const char *beg =
|
||||
const char *Beg =
|
||||
reinterpret_cast<const char *>(SecData.bytes_begin() + Index);
|
||||
|
||||
// Symbol size should at least be the same as memory access size
|
||||
|
@ -1826,7 +1824,7 @@ X86MachineInstructionRaiser::getGlobalVariableValueAt(const MachineInstr &MI,
|
|||
"Inconsistent values of memory access size and symbol size");
|
||||
// Read MemAccesssSize number of bytes and check if they represent
|
||||
// addresses in .rodata.
|
||||
StringRef SymbolBytes(beg, SymbSize);
|
||||
StringRef SymbolBytes(Beg, SymbSize);
|
||||
unsigned BytesRead = 0;
|
||||
// Symbol represents addresses into .rodata section.
|
||||
bool SymHasRODataAddrs = false;
|
||||
|
@ -1874,8 +1872,8 @@ X86MachineInstructionRaiser::getGlobalVariableValueAt(const MachineInstr &MI,
|
|||
|
||||
// Check for consistency of the types of symbol data.
|
||||
if (ConstantVec.size()) {
|
||||
auto Ty = ConstantVec[0]->getType();
|
||||
for (auto V : ConstantVec) {
|
||||
auto *Ty = ConstantVec[0]->getType();
|
||||
for (auto *V : ConstantVec) {
|
||||
assert((V->getType() == Ty) &&
|
||||
"Inconsistent types in constant array of global variable.");
|
||||
}
|
||||
|
@ -1897,7 +1895,7 @@ X86MachineInstructionRaiser::getGlobalVariableValueAt(const MachineInstr &MI,
|
|||
} else {
|
||||
// This is an aggregate array whose size is symbSize bytes,
|
||||
// initialized by BSS.
|
||||
assert(isBSSSymbol && "Unexpected non-BSS symbol encountered");
|
||||
assert(IsBSSSymbol && "Unexpected non-BSS symbol encountered");
|
||||
Type *ByteType = Type::getInt8Ty(Ctx);
|
||||
Type *GlobalArrValTy = ArrayType::get(ByteType, SymbSize);
|
||||
GlobalInit = ConstantAggregateZero::get(GlobalArrValTy);
|
||||
|
@ -1940,14 +1938,14 @@ X86MachineInstructionRaiser::getGlobalVariableValueAt(const MachineInstr &MI,
|
|||
|
||||
// Declare external global variables as external and don't initalize
|
||||
// them
|
||||
if (IncludedFileInfo::IsExternalVariable(
|
||||
if (IncludedFileInfo::isExternalVariable(
|
||||
GlobalDataSymNameIndexStrRef.str())) {
|
||||
Lnkg = GlobalValue::ExternalLinkage;
|
||||
GlobalInit = nullptr;
|
||||
}
|
||||
|
||||
// Now, create the global variable for the symbol at given Offset.
|
||||
auto GlobalVal = new GlobalVariable(
|
||||
auto *GlobalVal = new GlobalVariable(
|
||||
*(MR->getModule()), GlobalValTy, false /* isConstant */, Lnkg,
|
||||
GlobalInit, GlobalDataSymNameIndexStrRef);
|
||||
GlobalVal->setAlignment(MaybeAlign(GlobDataSymAlignment));
|
||||
|
@ -2157,7 +2155,7 @@ X86MachineInstructionRaiser::getMemoryAddressExprValue(const MachineInstr &MI) {
|
|||
// Construct index array for a GEP instruction that accesses
|
||||
// byte array
|
||||
std::vector<Value *> ByteAccessGEPIdxArr;
|
||||
for (auto IdxIter = GlobGEP->idx_begin();
|
||||
for (auto *IdxIter = GlobGEP->idx_begin();
|
||||
IdxIter != GlobGEP->idx_end(); IdxIter++) {
|
||||
Value *IdxVal = IdxIter->get();
|
||||
// Special case for index value of 0
|
||||
|
@ -2272,31 +2270,31 @@ Value *X86MachineInstructionRaiser::getRegOrArgValue(unsigned PReg, int MBBNo) {
|
|||
|
||||
// Just return the value associated with PReg, if one exists.
|
||||
if (PRegValue == nullptr) {
|
||||
int pos = getArgumentNumber(PReg);
|
||||
int Pos = getArgumentNumber(PReg);
|
||||
|
||||
// If PReg is an argument register, get its value from function
|
||||
// argument list.
|
||||
if (pos > 0) {
|
||||
if (Pos > 0) {
|
||||
// Get the value only if the function has an argument at
|
||||
// pos.
|
||||
if (pos <= (int)raisedFunction->arg_size()) {
|
||||
bool isRegFloatingPointType = isSSE2Reg(PReg);
|
||||
int actualPos = 0; // SSE regs and int regs are scrambled
|
||||
if (Pos <= (int)RaisedFunction->arg_size()) {
|
||||
bool IsRegFloatingPointType = isSSE2Reg(PReg);
|
||||
int ActualPos = 0; // SSE regs and int regs are scrambled
|
||||
int i = 0;
|
||||
|
||||
while (actualPos < (int)raisedFunction->arg_size() && i < pos) {
|
||||
bool isArgFloatingPointType =
|
||||
raisedFunction->getArg(i)->getType()->isFloatingPointTy();
|
||||
while (ActualPos < (int)RaisedFunction->arg_size() && i < Pos) {
|
||||
bool IsArgFloatingPointType =
|
||||
RaisedFunction->getArg(i)->getType()->isFloatingPointTy();
|
||||
|
||||
if (isArgFloatingPointType == isRegFloatingPointType) {
|
||||
if (IsArgFloatingPointType == IsRegFloatingPointType) {
|
||||
i++;
|
||||
}
|
||||
actualPos++;
|
||||
ActualPos++;
|
||||
}
|
||||
|
||||
Function::arg_iterator argIter =
|
||||
raisedFunction->arg_begin() + actualPos - 1;
|
||||
PRegValue = argIter;
|
||||
Function::arg_iterator ArgIter =
|
||||
RaisedFunction->arg_begin() + ActualPos - 1;
|
||||
PRegValue = ArgIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2355,12 +2353,12 @@ Value *X86MachineInstructionRaiser::getPhysRegValue(const MachineInstr &MI,
|
|||
"Expect physical register to get SSA value");
|
||||
unsigned SrcOpSize = getPhysRegSizeInBits(PReg);
|
||||
Value *SrcOpValue = getRegOrArgValue(PReg, MI.getParent()->getNumber());
|
||||
const DataLayout &dataLayout = MR->getModule()->getDataLayout();
|
||||
const DataLayout &DL = MR->getModule()->getDataLayout();
|
||||
|
||||
if (SrcOpValue) {
|
||||
// Generate the appropriate cast instruction if the sizes of the current
|
||||
// source value and that of the source register do not match.
|
||||
uint64_t SrcValueSize = dataLayout.getTypeSizeInBits(SrcOpValue->getType());
|
||||
uint64_t SrcValueSize = DL.getTypeSizeInBits(SrcOpValue->getType());
|
||||
if (SrcOpSize != SrcValueSize) {
|
||||
// Get the BasicBlock corresponding to MachineBasicBlock of MI.
|
||||
BasicBlock *RaisedBB = getRaisedBasicBlock(MI.getParent());
|
||||
|
@ -2381,19 +2379,19 @@ Value *X86MachineInstructionRaiser::getPhysRegValue(const MachineInstr &MI,
|
|||
}
|
||||
|
||||
// Find the index of the first memory reference operand.
|
||||
int X86MachineInstructionRaiser::getMemoryRefOpIndex(const MachineInstr &mi) {
|
||||
const MCInstrDesc &Desc = mi.getDesc();
|
||||
int memOperandNo = X86II::getMemoryOperandNo(Desc.TSFlags);
|
||||
if (memOperandNo >= 0)
|
||||
memOperandNo += X86II::getOperandBias(Desc);
|
||||
return memOperandNo;
|
||||
int X86MachineInstructionRaiser::getMemoryRefOpIndex(const MachineInstr &MI) {
|
||||
const MCInstrDesc &Desc = MI.getDesc();
|
||||
int MemOperandNo = X86II::getMemoryOperandNo(Desc.TSFlags);
|
||||
if (MemOperandNo >= 0)
|
||||
MemOperandNo += X86II::getOperandBias(Desc);
|
||||
return MemOperandNo;
|
||||
}
|
||||
|
||||
// Insert a newly created alloca instruction representing stack location at
|
||||
// offset StackOffset and with MachineFrame index MFIndex. It is assumed that
|
||||
// MachineFrameInfo of Machine function already has the stack slot created for
|
||||
// offset StackOffset at MFIndex
|
||||
bool X86MachineInstructionRaiser::insertAllocaInEntryBlock(Instruction *alloca,
|
||||
bool X86MachineInstructionRaiser::insertAllocaInEntryBlock(Instruction *Alloca,
|
||||
int StackOffset,
|
||||
int MFIndex) {
|
||||
// Avoid using BasicBlock InstrList iterators so that the tool can use LLVM
|
||||
|
@ -2418,7 +2416,7 @@ bool X86MachineInstructionRaiser::insertAllocaInEntryBlock(Instruction *alloca,
|
|||
// If this insertion point is at the beginning of the map, insert the alloca
|
||||
// instruction at the beginning of the block.
|
||||
if (InsertAtIter == ShadowStackIndexedByOffset.begin()) {
|
||||
InstList.push_front(alloca);
|
||||
InstList.push_front(Alloca);
|
||||
} else {
|
||||
// Insert alloca after the alloca instruction corresponding to the prior
|
||||
// stack slot.
|
||||
|
@ -2426,7 +2424,7 @@ bool X86MachineInstructionRaiser::insertAllocaInEntryBlock(Instruction *alloca,
|
|||
InsertAtIter--;
|
||||
AllocaInst *Inst = const_cast<AllocaInst *>(
|
||||
MFInfo.getObjectAllocation(InsertAtIter->second));
|
||||
InstList.insertAfter(Inst->getIterator(), alloca);
|
||||
InstList.insertAfter(Inst->getIterator(), Alloca);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2517,8 +2515,8 @@ bool X86MachineInstructionRaiser::recordMachineInstrInfo(
|
|||
}
|
||||
|
||||
bool X86MachineInstructionRaiser::instrNameStartsWith(const MachineInstr &MI,
|
||||
StringRef name) const {
|
||||
return x86InstrInfo->getName(MI.getOpcode()).startswith(name);
|
||||
StringRef Name) const {
|
||||
return x86InstrInfo->getName(MI.getOpcode()).startswith(Name);
|
||||
}
|
||||
|
||||
#undef DEBUG_TYPE
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "X86RaisedValueTracker.h"
|
||||
#include "InstMetadata.h"
|
||||
#include "RuntimeFunction.h"
|
||||
#include "X86RaisedValueTracker.h"
|
||||
#include "X86RegisterUtils.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include <X86InstrBuilder.h>
|
||||
|
@ -27,14 +27,14 @@ using namespace llvm::mctoll::X86RegisterUtils;
|
|||
|
||||
X86RaisedValueTracker::X86RaisedValueTracker(
|
||||
X86MachineInstructionRaiser *MIRaiser)
|
||||
: x86MIRaiser(MIRaiser) {
|
||||
: X86MIRaiser(MIRaiser) {
|
||||
|
||||
// Initialize entries for function register arguments in physToValueMap
|
||||
// Only first 6 arguments are passed as registers
|
||||
unsigned GPRegArgCount = X86RegisterUtils::GPR64ArgRegs64Bit.size();
|
||||
unsigned SSERegArgCount = X86RegisterUtils::SSEArgRegs64Bit.size();
|
||||
MachineFunction &MF = x86MIRaiser->getMF();
|
||||
Function *CurFunction = x86MIRaiser->getRaisedFunction();
|
||||
MachineFunction &MF = X86MIRaiser->getMF();
|
||||
Function *CurFunction = X86MIRaiser->getRaisedFunction();
|
||||
|
||||
unsigned GPArgNum = 0;
|
||||
unsigned SSEArgNum = 0;
|
||||
|
@ -59,42 +59,42 @@ X86RaisedValueTracker::X86RaisedValueTracker(
|
|||
}
|
||||
|
||||
unsigned ArgTySzInBits = ArgTy->getPrimitiveSizeInBits();
|
||||
physRegDefsInMBB[ArgReg][0] = std::make_pair(ArgTySzInBits, nullptr);
|
||||
PhysRegDefsInMBB[ArgReg][0] = std::make_pair(ArgTySzInBits, nullptr);
|
||||
}
|
||||
// Walk all blocks to initialize physRegDefsInMBB based on register defs.
|
||||
for (MachineBasicBlock &MBB : MF) {
|
||||
int MBBNo = MBB.getNumber();
|
||||
// Walk MachineInsts of the MachineBasicBlock
|
||||
for (MachineBasicBlock::iterator mbbIter = MBB.instr_begin(),
|
||||
mbbEnd = MBB.instr_end();
|
||||
mbbIter != mbbEnd; mbbIter++) {
|
||||
MachineInstr &MI = *mbbIter;
|
||||
for (MachineBasicBlock::iterator MBBIter = MBB.instr_begin(),
|
||||
MBBEnd = MBB.instr_end();
|
||||
MBBIter != MBBEnd; MBBIter++) {
|
||||
MachineInstr &MI = *MBBIter;
|
||||
// Look at all defs - explicit and implicit.
|
||||
unsigned NumDefs = MI.getNumDefs();
|
||||
|
||||
for (unsigned i = 0, e = MI.getNumOperands(); NumDefs && i != e; ++i) {
|
||||
for (unsigned i = 0, E = MI.getNumOperands(); NumDefs && i != E; ++i) {
|
||||
MachineOperand &MO = MI.getOperand(i);
|
||||
if (!MO.isReg() || !MO.isDef())
|
||||
continue;
|
||||
|
||||
unsigned int PhysReg = MO.getReg();
|
||||
Register PhysReg = MO.getReg();
|
||||
// EFLAGS bits are modeled as 1-bit registers. So, nothing to do if
|
||||
// Physreg is EFLAGS
|
||||
if ((PhysReg == X86::EFLAGS) || (PhysReg == X86::FPSW) ||
|
||||
(PhysReg == X86::FPCW))
|
||||
continue;
|
||||
|
||||
unsigned int SuperReg = x86MIRaiser->find64BitSuperReg(PhysReg);
|
||||
unsigned int SuperReg = X86MIRaiser->find64BitSuperReg(PhysReg);
|
||||
// No value assigned yet for the definition of SuperReg in CurMBBNo.
|
||||
// The value will be updated as the block is raised.
|
||||
if (isSSE2Instruction(MI.getOpcode())) {
|
||||
uint8_t InstrBitPrecision =
|
||||
getInstructionBitPrecision(MI.getDesc().TSFlags);
|
||||
physRegDefsInMBB[SuperReg][MBBNo] =
|
||||
PhysRegDefsInMBB[SuperReg][MBBNo] =
|
||||
std::make_pair(InstrBitPrecision, nullptr);
|
||||
} else {
|
||||
uint8_t PhysRegSzInBits = getPhysRegSizeInBits(PhysReg);
|
||||
physRegDefsInMBB[SuperReg][MBBNo] =
|
||||
PhysRegDefsInMBB[SuperReg][MBBNo] =
|
||||
std::make_pair(PhysRegSzInBits, nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -111,20 +111,20 @@ bool X86RaisedValueTracker::setPhysRegSSAValue(unsigned int PhysReg, int MBBNo,
|
|||
assert((PhysReg != X86::NoRegister) &&
|
||||
"Attempt to set value of an invalid register");
|
||||
// Always convert PhysReg to the 64-bit version.
|
||||
unsigned int SuperReg = x86MIRaiser->find64BitSuperReg(PhysReg);
|
||||
unsigned int SuperReg = X86MIRaiser->find64BitSuperReg(PhysReg);
|
||||
|
||||
if (!Val->hasName() && PhysReg < X86::NUM_TARGET_REGS)
|
||||
Val->setName(x86MIRaiser->getRegisterInfo()->getName(PhysReg));
|
||||
physRegDefsInMBB[SuperReg][MBBNo].second = Val;
|
||||
Val->setName(X86MIRaiser->getRegisterInfo()->getName(PhysReg));
|
||||
PhysRegDefsInMBB[SuperReg][MBBNo].second = Val;
|
||||
if (Val->getType()->isFloatingPointTy()) {
|
||||
auto BitPrecision = Val->getType()->getPrimitiveSizeInBits();
|
||||
physRegDefsInMBB[SuperReg][MBBNo].first = BitPrecision;
|
||||
PhysRegDefsInMBB[SuperReg][MBBNo].first = BitPrecision;
|
||||
} else {
|
||||
physRegDefsInMBB[SuperReg][MBBNo].first =
|
||||
PhysRegDefsInMBB[SuperReg][MBBNo].first =
|
||||
X86RegisterUtils::getPhysRegSizeInBits(PhysReg);
|
||||
}
|
||||
|
||||
assert((physRegDefsInMBB[SuperReg][MBBNo].first != 0) &&
|
||||
assert((PhysRegDefsInMBB[SuperReg][MBBNo].first != 0) &&
|
||||
"Found incorrect size of physical register");
|
||||
return true;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ X86RaisedValueTracker::getGlobalReachingDefs(unsigned int PhysReg, int MBBNo,
|
|||
// Recursively walk the predecessors of current block to get
|
||||
// the reaching definition for PhysReg.
|
||||
|
||||
MachineFunction &MF = x86MIRaiser->getMF();
|
||||
MachineFunction &MF = X86MIRaiser->getMF();
|
||||
MachineBasicBlock *CurMBB = MF.getBlockNumbered(MBBNo);
|
||||
// Look for the most recent definition of SuperReg in current block.
|
||||
const std::pair<int, Value *> LocalDef =
|
||||
|
@ -155,7 +155,7 @@ X86RaisedValueTracker::getGlobalReachingDefs(unsigned int PhysReg, int MBBNo,
|
|||
// For each of the predecessors find if SuperReg has a definition in its
|
||||
// reach tree.
|
||||
bool RDFound = true;
|
||||
for (auto P : CurMBB->predecessors()) {
|
||||
for (auto *P : CurMBB->predecessors()) {
|
||||
// Initialize a bit vector tracking visited bacic blocks.
|
||||
BitVector BlockVisited(MF.getNumBlockIDs(), false);
|
||||
SmallVector<MachineBasicBlock *, 8> WorkList;
|
||||
|
@ -165,8 +165,8 @@ X86RaisedValueTracker::getGlobalReachingDefs(unsigned int PhysReg, int MBBNo,
|
|||
// Visit an unvisited predecessor P
|
||||
if (BlockVisited[P->getNumber()])
|
||||
continue;
|
||||
else
|
||||
WorkList.push_back(P);
|
||||
|
||||
WorkList.push_back(P);
|
||||
|
||||
// New path being traversed. Set RDFound to be false
|
||||
RDFound = false;
|
||||
|
@ -186,10 +186,10 @@ X86RaisedValueTracker::getGlobalReachingDefs(unsigned int PhysReg, int MBBNo,
|
|||
RDFound = true;
|
||||
} else {
|
||||
// Reach info not found, continue walking the predecessors of CurBB.
|
||||
for (auto P : PredMBB->predecessors()) {
|
||||
for (auto *Pred : PredMBB->predecessors()) {
|
||||
// push_back the block which was not visited.
|
||||
if (!BlockVisited[P->getNumber()])
|
||||
WorkList.push_back(P);
|
||||
if (!BlockVisited[Pred->getNumber()])
|
||||
WorkList.push_back(Pred);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,55 +222,55 @@ std::pair<int, Value *>
|
|||
X86RaisedValueTracker::getInBlockRegOrArgDefVal(unsigned int PhysReg,
|
||||
int MBBNo) {
|
||||
// Always convert PhysReg to the 64-bit version.
|
||||
unsigned int SuperReg = x86MIRaiser->find64BitSuperReg(PhysReg);
|
||||
unsigned int SuperReg = X86MIRaiser->find64BitSuperReg(PhysReg);
|
||||
|
||||
Value *DefValue = nullptr;
|
||||
int DefMBBNo = INVALID_MBB;
|
||||
// TODO : Support outside of GPRs need to be implemented.
|
||||
// Find the per-block definitions SuperReg
|
||||
PhysRegMBBValueDefMap::iterator PhysRegBBValDefIter =
|
||||
physRegDefsInMBB.find(SuperReg);
|
||||
PhysRegDefsInMBB.find(SuperReg);
|
||||
// If per-block definition map exists
|
||||
if (PhysRegBBValDefIter != physRegDefsInMBB.end()) {
|
||||
if (PhysRegBBValDefIter != PhysRegDefsInMBB.end()) {
|
||||
// Find if there is a definition in MBB with number MBBNo
|
||||
MBBNoToValueMap mbbToValMap = PhysRegBBValDefIter->second;
|
||||
MBBNoToValueMap::iterator mbbToValMapIter = mbbToValMap.find(MBBNo);
|
||||
if (mbbToValMapIter != mbbToValMap.end()) {
|
||||
assert((mbbToValMapIter->second.first != 0) &&
|
||||
MBBNoToValueMap MBBToValMap = PhysRegBBValDefIter->second;
|
||||
MBBNoToValueMap::iterator MBBToValMapIter = MBBToValMap.find(MBBNo);
|
||||
if (MBBToValMapIter != MBBToValMap.end()) {
|
||||
assert((MBBToValMapIter->second.first != 0) &&
|
||||
"Found incorrect size of physical register");
|
||||
DefMBBNo = mbbToValMapIter->first;
|
||||
DefValue = mbbToValMapIter->second.second;
|
||||
DefMBBNo = MBBToValMapIter->first;
|
||||
DefValue = MBBToValMapIter->second.second;
|
||||
}
|
||||
}
|
||||
// If MBBNo is entry and ReachingDef was not found, check to see
|
||||
// if this is an argument value.
|
||||
if ((DefValue == nullptr) && (MBBNo == 0)) {
|
||||
int pos = x86MIRaiser->getArgumentNumber(PhysReg);
|
||||
int Pos = X86MIRaiser->getArgumentNumber(PhysReg);
|
||||
|
||||
// If PReg is an argument register, get its value from function
|
||||
// argument list.
|
||||
if (pos > 0) {
|
||||
Function *RaisedFunction = x86MIRaiser->getRaisedFunction();
|
||||
if (Pos > 0) {
|
||||
Function *RaisedFunction = X86MIRaiser->getRaisedFunction();
|
||||
|
||||
int actualPos = pos;
|
||||
int ActualPos = Pos;
|
||||
if (isSSE2Reg(PhysReg)) {
|
||||
// sse2 args are always after general purpose args
|
||||
// increment actualpos for every general purpose register encountered
|
||||
for (auto iter = RaisedFunction->arg_begin();
|
||||
iter != RaisedFunction->arg_end(); iter++) {
|
||||
if (!iter->getType()->isFloatingPointTy()) {
|
||||
actualPos++;
|
||||
for (auto *Iter = RaisedFunction->arg_begin();
|
||||
Iter != RaisedFunction->arg_end(); Iter++) {
|
||||
if (!Iter->getType()->isFloatingPointTy()) {
|
||||
ActualPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the value only if the function has an argument at
|
||||
// pos.
|
||||
if (actualPos <= (int)(RaisedFunction->arg_size())) {
|
||||
Function::arg_iterator argIter =
|
||||
RaisedFunction->arg_begin() + actualPos - 1;
|
||||
if (ActualPos <= (int)(RaisedFunction->arg_size())) {
|
||||
Function::arg_iterator ArgIter =
|
||||
RaisedFunction->arg_begin() + ActualPos - 1;
|
||||
DefMBBNo = 0;
|
||||
DefValue = argIter;
|
||||
DefValue = ArgIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -287,21 +287,21 @@ X86RaisedValueTracker::getInBlockRegOrArgDefVal(unsigned int PhysReg,
|
|||
unsigned X86RaisedValueTracker::getInBlockPhysRegSize(unsigned int PhysReg,
|
||||
int MBBNo) {
|
||||
// Always convert PhysReg to the 64-bit version.
|
||||
unsigned int SuperReg = x86MIRaiser->find64BitSuperReg(PhysReg);
|
||||
unsigned int SuperReg = X86MIRaiser->find64BitSuperReg(PhysReg);
|
||||
|
||||
// TODO : Support outside of GPRs need to be implemented.
|
||||
// Find the per-block definitions SuperReg
|
||||
PhysRegMBBValueDefMap::iterator PhysRegBBValDefIter =
|
||||
physRegDefsInMBB.find(SuperReg);
|
||||
PhysRegDefsInMBB.find(SuperReg);
|
||||
// If per-block definition map exists
|
||||
if (PhysRegBBValDefIter != physRegDefsInMBB.end()) {
|
||||
if (PhysRegBBValDefIter != PhysRegDefsInMBB.end()) {
|
||||
// Find if there is a definition in MBB with number MBBNo
|
||||
MBBNoToValueMap mbbToValMap = PhysRegBBValDefIter->second;
|
||||
MBBNoToValueMap::iterator mbbToValMapIter = mbbToValMap.find(MBBNo);
|
||||
if (mbbToValMapIter != mbbToValMap.end()) {
|
||||
assert((mbbToValMapIter->second.first != 0) &&
|
||||
MBBNoToValueMap MBBToValMap = PhysRegBBValDefIter->second;
|
||||
MBBNoToValueMap::iterator MBBToValMapIter = MBBToValMap.find(MBBNo);
|
||||
if (MBBToValMapIter != MBBToValMap.end()) {
|
||||
assert((MBBToValMapIter->second.first != 0) &&
|
||||
"Found incorrect size of physical register");
|
||||
return mbbToValMapIter->second.first;
|
||||
return MBBToValMapIter->second.first;
|
||||
}
|
||||
}
|
||||
// MachineBasicBlock with MBBNo does not define SuperReg.
|
||||
|
@ -321,12 +321,12 @@ unsigned X86RaisedValueTracker::getInBlockPhysRegSize(unsigned int PhysReg,
|
|||
|
||||
Value *X86RaisedValueTracker::getReachingDef(unsigned int PhysReg, int MBBNo,
|
||||
bool AllPreds, bool AnySubReg) {
|
||||
MachineFunction &MF = x86MIRaiser->getMF();
|
||||
MachineFunction &MF = X86MIRaiser->getMF();
|
||||
LLVMContext &Ctxt(MF.getFunction().getContext());
|
||||
Value *RetValue = nullptr;
|
||||
|
||||
std::vector<std::pair<int, Value *>> ReachingDefs;
|
||||
const ModuleRaiser *MR = x86MIRaiser->getModuleRaiser();
|
||||
const ModuleRaiser *MR = X86MIRaiser->getModuleRaiser();
|
||||
ReachingDefs = getGlobalReachingDefs(PhysReg, MBBNo, AllPreds);
|
||||
int RDVecSz = ReachingDefs.size();
|
||||
// If there are more than one distinct incoming reaching defs
|
||||
|
@ -340,7 +340,7 @@ Value *X86RaisedValueTracker::getReachingDef(unsigned int PhysReg, int MBBNo,
|
|||
|
||||
// 1. Allocate stack slot
|
||||
const DataLayout &DL = MR->getModule()->getDataLayout();
|
||||
unsigned allocaAddrSpace = DL.getAllocaAddrSpace();
|
||||
unsigned AllocaAddrSpace = DL.getAllocaAddrSpace();
|
||||
|
||||
// Get the super-type of all reaching definition values
|
||||
Type *AllocTy = nullptr;
|
||||
|
@ -381,8 +381,8 @@ Value *X86RaisedValueTracker::getReachingDef(unsigned int PhysReg, int MBBNo,
|
|||
AllocTy = Type::getInt64Ty(Ctxt);
|
||||
}
|
||||
|
||||
Align typeAlign(DL.getPrefTypeAlignment(AllocTy));
|
||||
auto typeSize =
|
||||
Align TypeAlign(DL.getPrefTypeAlignment(AllocTy));
|
||||
auto TypeSize =
|
||||
isEflagBit(PhysReg) ? 1 : AllocTy->getPrimitiveSizeInBits() / 8;
|
||||
|
||||
const TargetRegisterInfo *TRI = MF.getRegInfo().getTargetRegisterInfo();
|
||||
|
@ -394,12 +394,12 @@ Value *X86RaisedValueTracker::getReachingDef(unsigned int PhysReg, int MBBNo,
|
|||
}
|
||||
|
||||
// Create alloca instruction to allocate stack slot
|
||||
AllocaInst *Alloca = new AllocaInst(AllocTy, allocaAddrSpace, 0, typeAlign,
|
||||
AllocaInst *Alloca = new AllocaInst(AllocTy, AllocaAddrSpace, 0, TypeAlign,
|
||||
PhysRegName + "-SKT-LOC");
|
||||
|
||||
// Create a stack slot associated with the alloca instruction of size 8
|
||||
unsigned int StackFrameIndex = MF.getFrameInfo().CreateStackObject(
|
||||
typeSize, typeAlign, true /* isSpillSlot */, Alloca);
|
||||
TypeSize, TypeAlign, true /* isSpillSlot */, Alloca);
|
||||
|
||||
// Compute size of new stack object.
|
||||
const MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
|
@ -421,7 +421,7 @@ Value *X86RaisedValueTracker::getReachingDef(unsigned int PhysReg, int MBBNo,
|
|||
MF.getFrameInfo().setObjectOffset(StackFrameIndex, Offset);
|
||||
|
||||
// Add the alloca instruction to entry block
|
||||
x86MIRaiser->insertAllocaInEntryBlock(Alloca, Offset, StackFrameIndex);
|
||||
X86MIRaiser->insertAllocaInEntryBlock(Alloca, Offset, StackFrameIndex);
|
||||
|
||||
// If PhysReg is defined in MBBNo, store the defined value in the
|
||||
// newly created stack slot.
|
||||
|
@ -429,7 +429,7 @@ Value *X86RaisedValueTracker::getReachingDef(unsigned int PhysReg, int MBBNo,
|
|||
getInBlockRegOrArgDefVal(PhysReg, MBBNo);
|
||||
Value *DefValue = MBBNoRDPair.second;
|
||||
if (DefValue != nullptr) {
|
||||
BasicBlock &RaisedBB = x86MIRaiser->getRaisedFunction()->getEntryBlock();
|
||||
BasicBlock &RaisedBB = X86MIRaiser->getRaisedFunction()->getEntryBlock();
|
||||
new StoreInst(DefValue, Alloca, &RaisedBB);
|
||||
}
|
||||
// The store instruction simply stores value defined on stack. No defines
|
||||
|
@ -444,13 +444,13 @@ Value *X86RaisedValueTracker::getReachingDef(unsigned int PhysReg, int MBBNo,
|
|||
// This is an incoming edge from a block that is not yet
|
||||
// raised. Record this in the set of incomplete promotions that will
|
||||
// be handled after all blocks are raised.
|
||||
x86MIRaiser->recordDefsToPromote(PhysReg, MBBVal.first, Alloca);
|
||||
X86MIRaiser->recordDefsToPromote(PhysReg, MBBVal.first, Alloca);
|
||||
} else {
|
||||
Instruction *I = dyn_cast<Instruction>(MBBVal.second);
|
||||
if (!hasRODataAccess(Alloca) && (I != nullptr)) {
|
||||
Alloca->copyMetadata(*I);
|
||||
}
|
||||
StoreInst *StInst = x86MIRaiser->promotePhysregToStackSlot(
|
||||
StoreInst *StInst = X86MIRaiser->promotePhysregToStackSlot(
|
||||
PhysReg, MBBVal.second, MBBVal.first, Alloca);
|
||||
assert(StInst != nullptr &&
|
||||
"Failed to promote reaching definition to stack slot");
|
||||
|
@ -462,7 +462,7 @@ Value *X86RaisedValueTracker::getReachingDef(unsigned int PhysReg, int MBBNo,
|
|||
LdReachingVal =
|
||||
setInstMetadataRODataContent(dyn_cast<LoadInst>(LdReachingVal));
|
||||
// Insert load instruction
|
||||
x86MIRaiser->getRaisedBasicBlock(MF.getBlockNumbered(MBBNo))
|
||||
X86MIRaiser->getRaisedBasicBlock(MF.getBlockNumbered(MBBNo))
|
||||
->getInstList()
|
||||
.push_back(LdReachingVal);
|
||||
if (!AnySubReg) {
|
||||
|
@ -471,14 +471,14 @@ Value *X86RaisedValueTracker::getReachingDef(unsigned int PhysReg, int MBBNo,
|
|||
// liveness discovery.
|
||||
Type *RegType = (isEflagBit(PhysReg))
|
||||
? Type::getInt1Ty(Ctxt)
|
||||
: x86MIRaiser->getPhysRegType(PhysReg);
|
||||
: X86MIRaiser->getPhysRegType(PhysReg);
|
||||
Type *LdReachingValType = LdReachingVal->getType();
|
||||
assert((LdReachingValType->isIntegerTy() ||
|
||||
LdReachingValType->isFloatingPointTy() ||
|
||||
LdReachingValType->isVectorTy()) &&
|
||||
"Unhandled type mismatch of reaching register definition");
|
||||
if (RegType != LdReachingValType) {
|
||||
auto BB = x86MIRaiser->getRaisedBasicBlock(MF.getBlockNumbered(MBBNo));
|
||||
auto *BB = X86MIRaiser->getRaisedBasicBlock(MF.getBlockNumbered(MBBNo));
|
||||
if (isSSE2Reg(PhysReg)) {
|
||||
assert(LdReachingValType->getPrimitiveSizeInBits() == 128 &&
|
||||
"Expected FP/vector types to be stored in 128 bit stack slot");
|
||||
|
@ -514,11 +514,11 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
"Unknown EFLAGS bit specified");
|
||||
|
||||
int MBBNo = MI.getParent()->getNumber();
|
||||
MachineFunction &MF = x86MIRaiser->getMF();
|
||||
MachineFunction &MF = X86MIRaiser->getMF();
|
||||
LLVMContext &Ctx = MF.getFunction().getContext();
|
||||
|
||||
BasicBlock *RaisedBB =
|
||||
x86MIRaiser->getRaisedBasicBlock(MF.getBlockNumbered(MBBNo));
|
||||
X86MIRaiser->getRaisedBasicBlock(MF.getBlockNumbered(MBBNo));
|
||||
|
||||
unsigned int ResTyNumBits =
|
||||
TestResultVal->getType()->getPrimitiveSizeInBits();
|
||||
|
@ -531,16 +531,16 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
X86RegisterUtils::getEflagName(FlagBit));
|
||||
|
||||
RaisedBB->getInstList().push_back(ZFTest);
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second = ZFTest;
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second = ZFTest;
|
||||
} break;
|
||||
case X86RegisterUtils::EFLAGS::SF: {
|
||||
Value *ZeroVal = ConstantInt::get(Ctx, APInt(ResTyNumBits, 0));
|
||||
// Set SF - test if TestVal is signed
|
||||
auto ShiftVal = ConstantInt::get(Ctx, APInt(ResTyNumBits, 1));
|
||||
auto HighBitSetVal =
|
||||
auto *ShiftVal = ConstantInt::get(Ctx, APInt(ResTyNumBits, 1));
|
||||
auto *HighBitSetVal =
|
||||
ConstantInt::get(Ctx, APInt(ResTyNumBits, ResTyNumBits - 1));
|
||||
// Compute 1 << (ResTyNumBits - 1)
|
||||
auto ShiftLeft = ConstantExpr::getShl(ShiftVal, HighBitSetVal, true, true);
|
||||
auto *ShiftLeft = ConstantExpr::getShl(ShiftVal, HighBitSetVal, true, true);
|
||||
|
||||
// Create the instruction
|
||||
// and SubInst, ShiftLeft
|
||||
|
@ -553,28 +553,28 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
new ICmpInst(CmpInst::Predicate::ICMP_NE, AndInst, ZeroVal,
|
||||
X86RegisterUtils::getEflagName(FlagBit));
|
||||
RaisedBB->getInstList().push_back(SFTest);
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second = SFTest;
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second = SFTest;
|
||||
} break;
|
||||
case X86RegisterUtils::EFLAGS::OF: {
|
||||
auto IntrinsicOF = Intrinsic::not_intrinsic;
|
||||
Value *TestArg[2];
|
||||
Module *M = x86MIRaiser->getModuleRaiser()->getModule();
|
||||
Module *M = X86MIRaiser->getModuleRaiser()->getModule();
|
||||
|
||||
// If TestVal is a cast value, it is most likely cast to match the
|
||||
// source of the compare instruction. Get to the value prior to casting.
|
||||
CastInst *castInst = dyn_cast<CastInst>(TestResultVal);
|
||||
while (castInst) {
|
||||
TestResultVal = castInst->getOperand(0);
|
||||
castInst = dyn_cast<CastInst>(TestResultVal);
|
||||
CastInst *CastInstr = dyn_cast<CastInst>(TestResultVal);
|
||||
while (CastInstr) {
|
||||
TestResultVal = CastInstr->getOperand(0);
|
||||
CastInstr = dyn_cast<CastInst>(TestResultVal);
|
||||
}
|
||||
|
||||
Instruction *TestInst = dyn_cast<Instruction>(TestResultVal);
|
||||
assert((TestInst != nullptr) && "Expect test producing instruction while "
|
||||
"testing and setting of EFLAGS");
|
||||
|
||||
if ((x86MIRaiser->instrNameStartsWith(MI, "SUB")) ||
|
||||
(x86MIRaiser->instrNameStartsWith(MI, "CMP")) ||
|
||||
(x86MIRaiser->instrNameStartsWith(MI, "SBB"))) {
|
||||
if ((X86MIRaiser->instrNameStartsWith(MI, "SUB")) ||
|
||||
(X86MIRaiser->instrNameStartsWith(MI, "CMP")) ||
|
||||
(X86MIRaiser->instrNameStartsWith(MI, "SBB"))) {
|
||||
IntrinsicOF = Intrinsic::ssub_with_overflow;
|
||||
TestArg[0] = TestInst->getOperand(0);
|
||||
TestArg[1] = TestInst->getOperand(1);
|
||||
|
@ -591,9 +591,9 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
ValueOF, ArrayRef<Value *>(TestArg));
|
||||
RaisedBB->getInstList().push_back(GetOF);
|
||||
// Extract OF and set it
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second =
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second =
|
||||
ExtractValueInst::Create(GetOF, 1, "OF", RaisedBB);
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "ADD")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "ADD")) {
|
||||
IntrinsicOF = Intrinsic::sadd_with_overflow;
|
||||
TestArg[0] = TestInst->getOperand(0);
|
||||
TestArg[1] = TestInst->getOperand(1);
|
||||
|
@ -610,9 +610,9 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
ValueOF, ArrayRef<Value *>(TestArg));
|
||||
RaisedBB->getInstList().push_back(GetOF);
|
||||
// Extract OF and set it
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second =
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second =
|
||||
ExtractValueInst::Create(GetOF, 1, "OF", RaisedBB);
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "ROL")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "ROL")) {
|
||||
// OF flag is defined only for 1-bit rotates i.e., ROLr*1).
|
||||
// It is undefined in all other cases. OF flag is set to the exclusive OR
|
||||
// of CF after rotate and the most-significant bit of the result.
|
||||
|
@ -654,9 +654,9 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
// Generate XOR ResultCF, MSBIsSet to compute OF
|
||||
Instruction *ResultOF =
|
||||
BinaryOperator::CreateXor(ResultCF, MSBIsSet, "OF", RaisedBB);
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second = ResultOF;
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second = ResultOF;
|
||||
}
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "ROR")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "ROR")) {
|
||||
// OF flag is defined only for 1-bit rotates i.e., RORr*1).
|
||||
// It is undefined in all other cases. OF flag is set to the exclusive OR
|
||||
// of the two most-significant bits of the result.
|
||||
|
@ -704,11 +704,11 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
// Generate XOR MSBIsSet, PreMSBIsSet to compute OF
|
||||
Instruction *ResultOF =
|
||||
BinaryOperator::CreateXor(MSBIsSet, PreMSBIsSet, "OF", RaisedBB);
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second = ResultOF;
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second = ResultOF;
|
||||
}
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "TEST")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "TEST")) {
|
||||
// Set CF to 0 and make type to i1
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second =
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second =
|
||||
ConstantInt::get(Type::getInt1Ty(Ctx), 0);
|
||||
} else {
|
||||
LLVM_DEBUG(MI.dump());
|
||||
|
@ -718,7 +718,7 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
case X86RegisterUtils::EFLAGS::PF: {
|
||||
// PF is set if least-significant byte of the result contains an even number
|
||||
// of 1 bits; else the flag is cleared.
|
||||
Module *M = x86MIRaiser->getModuleRaiser()->getModule();
|
||||
Module *M = X86MIRaiser->getModuleRaiser()->getModule();
|
||||
|
||||
Value *SrcVal = TestResultVal;
|
||||
|
||||
|
@ -750,21 +750,21 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
Instruction *PFTest = new ICmpInst(CmpInst::Predicate::ICMP_EQ,
|
||||
ParityEvenBit, ZeroValue, "PF");
|
||||
RaisedBB->getInstList().push_back(PFTest);
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second = PFTest;
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second = PFTest;
|
||||
} break;
|
||||
case X86RegisterUtils::EFLAGS::CF: {
|
||||
Module *M = x86MIRaiser->getModuleRaiser()->getModule();
|
||||
Module *M = X86MIRaiser->getModuleRaiser()->getModule();
|
||||
Value *NewCF = nullptr;
|
||||
|
||||
// If TestVal is a cast value, it is most likely cast to match the
|
||||
// source of the compare instruction. Get to the value prior to casting.
|
||||
CastInst *castInst = dyn_cast<CastInst>(TestResultVal);
|
||||
while (castInst) {
|
||||
TestResultVal = castInst->getOperand(0);
|
||||
castInst = dyn_cast<CastInst>(TestResultVal);
|
||||
CastInst *CastInstr = dyn_cast<CastInst>(TestResultVal);
|
||||
while (CastInstr) {
|
||||
TestResultVal = CastInstr->getOperand(0);
|
||||
CastInstr = dyn_cast<CastInst>(TestResultVal);
|
||||
}
|
||||
|
||||
if (x86MIRaiser->instrNameStartsWith(MI, "NEG")) {
|
||||
if (X86MIRaiser->instrNameStartsWith(MI, "NEG")) {
|
||||
// Set CF to 0 if source operand is 0 else to 1
|
||||
Instruction *TestInst = dyn_cast<Instruction>(TestResultVal);
|
||||
assert((TestInst != nullptr) && "Expect test producing instruction while "
|
||||
|
@ -790,9 +790,9 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
X86RegisterUtils::getEflagName(FlagBit));
|
||||
RaisedBB->getInstList().push_back(CmpInst);
|
||||
NewCF = CmpInst;
|
||||
} else if ((x86MIRaiser->instrNameStartsWith(MI, "SUB")) ||
|
||||
(x86MIRaiser->instrNameStartsWith(MI, "CMP")) ||
|
||||
(x86MIRaiser->instrNameStartsWith(MI, "SBB"))) {
|
||||
} else if ((X86MIRaiser->instrNameStartsWith(MI, "SUB")) ||
|
||||
(X86MIRaiser->instrNameStartsWith(MI, "CMP")) ||
|
||||
(X86MIRaiser->instrNameStartsWith(MI, "SBB"))) {
|
||||
Value *TestArg[2];
|
||||
Instruction *TestInst = dyn_cast<Instruction>(TestResultVal);
|
||||
assert((TestInst != nullptr) && "Expect test producing instruction while "
|
||||
|
@ -812,7 +812,7 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
RaisedBB->getInstList().push_back(GetCF);
|
||||
// Extract flag-bit
|
||||
NewCF = ExtractValueInst::Create(GetCF, 1, "CF", RaisedBB);
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "ADD")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "ADD")) {
|
||||
Value *TestArg[2];
|
||||
Instruction *TestInst = dyn_cast<Instruction>(TestResultVal);
|
||||
assert((TestInst != nullptr) && "Expect test producing instruction while "
|
||||
|
@ -832,7 +832,7 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
RaisedBB->getInstList().push_back(GetCF);
|
||||
// Extract flag-bit
|
||||
NewCF = ExtractValueInst::Create(GetCF, 1, "CF", RaisedBB);
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "SHRD")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "SHRD")) {
|
||||
// TestInst should have been a call to intrinsic llvm.fshr.*
|
||||
CallInst *IntrinsicCall = dyn_cast<CallInst>(TestResultVal);
|
||||
assert((IntrinsicCall != nullptr) &&
|
||||
|
@ -872,11 +872,11 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
|
||||
RaisedBB->getInstList().push_back(NewCFInst);
|
||||
|
||||
Value *OldCF = physRegDefsInMBB[FlagBit][MBBNo].second;
|
||||
Value *OldCF = PhysRegDefsInMBB[FlagBit][MBBNo].second;
|
||||
if (OldCF == nullptr) {
|
||||
// if CF is undefined, assume CF = 0
|
||||
LLVMContext &Ctx(MF.getFunction().getContext());
|
||||
OldCF = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
|
||||
LLVMContext &FuncCtx(MF.getFunction().getContext());
|
||||
OldCF = ConstantInt::get(Type::getInt1Ty(FuncCtx), 0);
|
||||
}
|
||||
|
||||
// Select the value of CF based on Count value being > 0
|
||||
|
@ -885,13 +885,13 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
RaisedBB->getInstList().push_back(SelectCF);
|
||||
|
||||
NewCF = SelectCF;
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "SHL") ||
|
||||
x86MIRaiser->instrNameStartsWith(MI, "SHR") ||
|
||||
x86MIRaiser->instrNameStartsWith(MI, "SAR")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "SHL") ||
|
||||
X86MIRaiser->instrNameStartsWith(MI, "SHR") ||
|
||||
X86MIRaiser->instrNameStartsWith(MI, "SAR")) {
|
||||
Value *DstArgVal = nullptr;
|
||||
Value *CountArgVal = nullptr;
|
||||
// If this is a funnel shift
|
||||
if (x86MIRaiser->instrNameStartsWith(MI, "SHLD")) {
|
||||
if (X86MIRaiser->instrNameStartsWith(MI, "SHLD")) {
|
||||
// TestInst should have been a call to intrinsic llvm.fshl.*
|
||||
CallInst *IntrinsicCall = dyn_cast<CallInst>(TestResultVal);
|
||||
assert((IntrinsicCall != nullptr) &&
|
||||
|
@ -952,11 +952,11 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
|
||||
RaisedBB->getInstList().push_back(NewCFInst);
|
||||
|
||||
Value *OldCF = physRegDefsInMBB[FlagBit][MBBNo].second;
|
||||
Value *OldCF = PhysRegDefsInMBB[FlagBit][MBBNo].second;
|
||||
if (OldCF == nullptr) {
|
||||
// if CF is undefined, assume CF = 0
|
||||
LLVMContext &Ctx(MF.getFunction().getContext());
|
||||
OldCF = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
|
||||
LLVMContext &FuncCtx(MF.getFunction().getContext());
|
||||
OldCF = ConstantInt::get(Type::getInt1Ty(FuncCtx), 0);
|
||||
}
|
||||
// Select the value of CF based on Count value being > 0
|
||||
Instruction *SelectCF =
|
||||
|
@ -964,7 +964,7 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
RaisedBB->getInstList().push_back(SelectCF);
|
||||
|
||||
NewCF = SelectCF;
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "ROL")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "ROL")) {
|
||||
// CF flag receives a copy of the bit that was shifted from one end to
|
||||
// the other. Find the least-significant bit, which is the bit shifted
|
||||
// from the most-significant location.
|
||||
|
@ -980,7 +980,7 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
// Insert compare instruction
|
||||
RaisedBB->getInstList().push_back(ResultCF);
|
||||
NewCF = ResultCF;
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "ROR")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "ROR")) {
|
||||
// CF flag receives a copy of the bit that was shifted from one end to
|
||||
// the other. Find the most-significant bit, which is the bit shifted
|
||||
// from the least-significant location.
|
||||
|
@ -1006,7 +1006,7 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
BitSetResult, ZeroValue, "MSB-SET");
|
||||
RaisedBB->getInstList().push_back(dyn_cast<Instruction>(MSBIsSet));
|
||||
NewCF = MSBIsSet;
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "IMUL")) {
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "IMUL")) {
|
||||
// TestInst should have been mul instruction
|
||||
BinaryOperator *TestInst = dyn_cast<BinaryOperator>(TestResultVal);
|
||||
assert((TestInst != nullptr) && (TestInst->getNumOperands() == 2) &&
|
||||
|
@ -1027,12 +1027,12 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
ValueOF, ArrayRef<Value *>(TestArg));
|
||||
RaisedBB->getInstList().push_back(GetOF);
|
||||
// Extract OF and set both OF and CF to the same value
|
||||
auto NewOF = ExtractValueInst::Create(GetOF, 1, "OF", RaisedBB);
|
||||
physRegDefsInMBB[EFLAGS::OF][MBBNo].second = NewOF;
|
||||
auto *NewOF = ExtractValueInst::Create(GetOF, 1, "OF", RaisedBB);
|
||||
PhysRegDefsInMBB[EFLAGS::OF][MBBNo].second = NewOF;
|
||||
NewCF = NewOF;
|
||||
// Set OF to the same value of CF
|
||||
physRegDefsInMBB[EFLAGS::OF][MBBNo].second = NewCF;
|
||||
} else if (x86MIRaiser->instrNameStartsWith(MI, "TEST")) {
|
||||
PhysRegDefsInMBB[EFLAGS::OF][MBBNo].second = NewCF;
|
||||
} else if (X86MIRaiser->instrNameStartsWith(MI, "TEST")) {
|
||||
// Set CF to 0 and make type to i1
|
||||
NewCF = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
|
||||
} else {
|
||||
|
@ -1042,7 +1042,7 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
}
|
||||
// Update CF.
|
||||
assert((NewCF != nullptr) && "Value to update CF not found");
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second = NewCF;
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second = NewCF;
|
||||
} break;
|
||||
|
||||
// TODO: Add code to test for other flags
|
||||
|
@ -1050,7 +1050,7 @@ bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
|
|||
assert(false && "Unhandled EFLAGS bit specified");
|
||||
}
|
||||
// EFLAGS bit size is 1
|
||||
physRegDefsInMBB[FlagBit][MBBNo].first = 1;
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].first = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1061,9 +1061,9 @@ bool X86RaisedValueTracker::setEflagValue(unsigned int FlagBit, int MBBNo,
|
|||
(FlagBit < X86RegisterUtils::EFLAGS::UNDEFINED) &&
|
||||
"Unknown EFLAGS bit specified");
|
||||
Val->setName(X86RegisterUtils::getEflagName(FlagBit));
|
||||
physRegDefsInMBB[FlagBit][MBBNo].second = Val;
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].second = Val;
|
||||
// EFLAGS bit size is 1
|
||||
physRegDefsInMBB[FlagBit][MBBNo].first = 1;
|
||||
PhysRegDefsInMBB[FlagBit][MBBNo].first = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1073,7 +1073,7 @@ bool X86RaisedValueTracker::setEflagBoolean(unsigned int FlagBit, int MBBNo,
|
|||
assert((FlagBit >= X86RegisterUtils::EFLAGS::CF) &&
|
||||
(FlagBit < X86RegisterUtils::EFLAGS::UNDEFINED) &&
|
||||
"Unknown EFLAGS bit specified");
|
||||
LLVMContext &Ctx = x86MIRaiser->getMF().getFunction().getContext();
|
||||
LLVMContext &Ctx = X86MIRaiser->getMF().getFunction().getContext();
|
||||
Value *Val = Set ? ConstantInt::getTrue(Ctx) : ConstantInt::getFalse(Ctx);
|
||||
setEflagValue(FlagBit, MBBNo, Val);
|
||||
return true;
|
||||
|
@ -1142,9 +1142,9 @@ X86RaisedValueTracker::reinterpretSSERegValue(Value *SrcVal, Type *DstTy,
|
|||
DstTy->getContext(), SrcVal->getType()->getPrimitiveSizeInBits());
|
||||
Type *DstIntTy =
|
||||
Type::getIntNTy(DstTy->getContext(), DstTy->getPrimitiveSizeInBits());
|
||||
auto IntCastInst = new BitCastInst(SrcVal, SrcIntTy);
|
||||
auto *IntCastInst = new BitCastInst(SrcVal, SrcIntTy);
|
||||
INSERT_INSTRUCTION(IntCastInst);
|
||||
auto CastInst = CastInst::Create(
|
||||
auto *CastInst = CastInst::Create(
|
||||
CastInst::getCastOpcode(IntCastInst, false, DstIntTy, false),
|
||||
IntCastInst, DstIntTy);
|
||||
INSERT_INSTRUCTION(CastInst);
|
||||
|
@ -1156,10 +1156,10 @@ X86RaisedValueTracker::reinterpretSSERegValue(Value *SrcVal, Type *DstTy,
|
|||
SrcVal->getType()->getPrimitiveSizeInBits() /
|
||||
DstTy->getPrimitiveSizeInBits(),
|
||||
false);
|
||||
auto SrcVec = new BitCastInst(SrcVal, SrcTyVec);
|
||||
auto *SrcVec = new BitCastInst(SrcVal, SrcTyVec);
|
||||
INSERT_INSTRUCTION(SrcVec);
|
||||
|
||||
auto Zero = ConstantInt::get(Type::getInt64Ty(DstTy->getContext()), 0);
|
||||
auto *Zero = ConstantInt::get(Type::getInt64Ty(DstTy->getContext()), 0);
|
||||
Result = ExtractElementInst::Create(SrcVec, Zero);
|
||||
} else if (SrcVal->getType()->getPrimitiveSizeInBits() <
|
||||
DstTy->getPrimitiveSizeInBits()) {
|
||||
|
@ -1175,8 +1175,8 @@ X86RaisedValueTracker::reinterpretSSERegValue(Value *SrcVal, Type *DstTy,
|
|||
SrcVec = ConstantInt::get(SrcTyVec, 0);
|
||||
}
|
||||
|
||||
auto Zero = ConstantInt::get(Type::getInt64Ty(DstTy->getContext()), 0);
|
||||
auto InsertElem = InsertElementInst::Create(SrcVec, SrcVal, Zero);
|
||||
auto *Zero = ConstantInt::get(Type::getInt64Ty(DstTy->getContext()), 0);
|
||||
auto *InsertElem = InsertElementInst::Create(SrcVec, SrcVal, Zero);
|
||||
INSERT_INSTRUCTION(InsertElem);
|
||||
|
||||
Result = new BitCastInst(InsertElem, DstTy);
|
||||
|
@ -1256,19 +1256,19 @@ bool X86RaisedValueTracker::setInstMetadataRODataIndex(Value *SrcValue,
|
|||
// String denoting rodata index metadata.
|
||||
// std::string RODataMDKindStr(RODATA_INDEX_MD_STR);
|
||||
// Check if SrcValue is an index into rodata
|
||||
if (auto RODataIndex = dyn_cast<ConstantExpr>(SrcValue)) {
|
||||
if (auto *RODataIndex = dyn_cast<ConstantExpr>(SrcValue)) {
|
||||
std::string OpcodeName(RODataIndex->getOpcodeName());
|
||||
if (OpcodeName.compare("getelementptr") == 0) {
|
||||
if (RODataIndex->getOperand(0)->getName().startswith("rodata_")) {
|
||||
assert(!hasRODataAccess(Inst) && "ROData annotation already exists");
|
||||
// Add metadata to indicate that this instruction uses rodata index.
|
||||
auto ROMD = ValueAsMetadata::get(SrcValue);
|
||||
auto *ROMD = ValueAsMetadata::get(SrcValue);
|
||||
Inst->setMetadata(
|
||||
RODATA_INDEX_MD_STR,
|
||||
MDNode::get(Inst->getContext(), ArrayRef<Metadata *>{ROMD}));
|
||||
}
|
||||
}
|
||||
} else if (auto InstUsingROData = dyn_cast<Instruction>(SrcValue)) {
|
||||
} else if (auto *InstUsingROData = dyn_cast<Instruction>(SrcValue)) {
|
||||
if (hasRODataAccess(InstUsingROData)) {
|
||||
assert(!hasRODataAccess(Inst) && "ROData annotation already exists");
|
||||
Inst->copyMetadata(*InstUsingROData);
|
||||
|
@ -1291,7 +1291,7 @@ X86RaisedValueTracker::setInstMetadataRODataContent(LoadInst *LdInst) {
|
|||
// Get the load address.
|
||||
Value *SrcValue = LdInst->getOperand(0);
|
||||
// Check if SrcValue is an index into rodata
|
||||
if (auto RODataIndex = dyn_cast<ConstantExpr>(SrcValue)) {
|
||||
if (auto *RODataIndex = dyn_cast<ConstantExpr>(SrcValue)) {
|
||||
std::string OpcodeName(RODataIndex->getOpcodeName());
|
||||
if (OpcodeName.compare("getelementptr") == 0) {
|
||||
if (RODataIndex->getOperand(0)->getName().startswith("rodata_")) {
|
||||
|
@ -1302,20 +1302,20 @@ X86RaisedValueTracker::setInstMetadataRODataContent(LoadInst *LdInst) {
|
|||
// index.
|
||||
// Add metadata to indicate that this instruction abstracts rodata
|
||||
// content.
|
||||
auto ROMD = ValueAsMetadata::get(SrcValue);
|
||||
auto *ROMD = ValueAsMetadata::get(SrcValue);
|
||||
LdInst->setMetadata(
|
||||
RODATA_CONTENT_MD_STR,
|
||||
MDNode::get(LdInst->getContext(), ArrayRef<Metadata *>{ROMD}));
|
||||
}
|
||||
}
|
||||
} else if (auto SrcValueAsInst = dyn_cast<Instruction>(SrcValue)) {
|
||||
} else if (auto *SrcValueAsInst = dyn_cast<Instruction>(SrcValue)) {
|
||||
if (hasRODataAccess(SrcValueAsInst)) {
|
||||
assert(!hasRODataAccess(LdInst) && "ROData annotation already exists");
|
||||
// Get metadata representing the rodata index. Note that this may NOT be
|
||||
// the rodata index represented by SrcValue. SrcValue may be an
|
||||
// instruction representing the address computation based on this rodata
|
||||
// index.
|
||||
auto ROMD = SrcValueAsInst->getMetadata(RODATA_INDEX_MD_STR);
|
||||
auto *ROMD = SrcValueAsInst->getMetadata(RODATA_INDEX_MD_STR);
|
||||
if (ROMD != nullptr) {
|
||||
// Set the metadata kind to rodata content
|
||||
LdInst->setMetadata(
|
||||
|
@ -1398,7 +1398,7 @@ Value *X86RaisedValueTracker::getRelocOffsetForRODataAddress(
|
|||
assert(RaisedRODataInstMD->getNumOperands() == 1 &&
|
||||
"Expect one operand of rodata metadata");
|
||||
// Get the metadata as MetadataAsvalue
|
||||
auto RaisedRODataMDAsVal =
|
||||
auto *RaisedRODataMDAsVal =
|
||||
MetadataAsValue::get(RaisedRODataAddrAsInst->getContext(),
|
||||
RaisedRODataInstMD->getOperand(0).get());
|
||||
assert(RaisedRODataMDAsVal != nullptr && "Failed to get metadata as value");
|
||||
|
@ -1416,7 +1416,7 @@ Value *X86RaisedValueTracker::getRelocOffsetForRODataAddress(
|
|||
// a global array of bytes.
|
||||
if (OpcodeName.compare("getelementptr") == 0) {
|
||||
if (RaisedRODataIndex->getOperand(0)->getName().startswith("rodata_")) {
|
||||
auto RaisedRODataArrValue = RaisedRODataIndex->getOperand(0);
|
||||
auto *RaisedRODataArrValue = RaisedRODataIndex->getOperand(0);
|
||||
// Get the global variable corresponding to constant expression
|
||||
// representing abstracted rodata array.
|
||||
if (GlobalVariable *RaisedRODataArrGV =
|
||||
|
@ -1426,7 +1426,7 @@ Value *X86RaisedValueTracker::getRelocOffsetForRODataAddress(
|
|||
|
||||
// Global variable representing rodata array is annotated with
|
||||
// rodata section start value of the source binary.
|
||||
auto RaisedRODataSecInfoMD =
|
||||
auto *RaisedRODataSecInfoMD =
|
||||
RaisedRODataArrGV->getMetadata(RODATA_SEC_INFO_MD_STR);
|
||||
assert(RaisedRODataSecInfoMD != nullptr &&
|
||||
"Expected rodata section info - not found");
|
||||
|
@ -1458,7 +1458,7 @@ Value *X86RaisedValueTracker::getRelocOffsetForRODataAddress(
|
|||
// comparison
|
||||
Value *InVal = castValue(RaisedRODataAddrVal, Int64Ty, RaisedBB);
|
||||
// Cast global variable address
|
||||
auto RaisedRODataArrGVAddrVal =
|
||||
auto *RaisedRODataArrGVAddrVal =
|
||||
castValue(RaisedRODataArrGV, Int64Ty, RaisedBB);
|
||||
|
||||
// Call the relocation function
|
||||
|
|
|
@ -106,14 +106,14 @@ public:
|
|||
enum { INVALID_MBB = -1 };
|
||||
|
||||
private:
|
||||
X86MachineInstructionRaiser *x86MIRaiser;
|
||||
X86MachineInstructionRaiser *X86MIRaiser;
|
||||
// Map of physical registers -> MBBNoToValueMap, representing per-block
|
||||
// register definitions.
|
||||
PhysRegMBBValueDefMap physRegDefsInMBB;
|
||||
PhysRegMBBValueDefMap PhysRegDefsInMBB;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace mctoll
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LVM_TOOLS_LLVM_MCTOLL_X86_X86RAISEDVALUETRACKER_H
|
||||
#endif // LLVM_TOOLS_LLVM_MCTOLL_X86_X86RAISEDVALUETRACKER_H
|
||||
|
|
|
@ -50,12 +50,11 @@ bool X86RegisterUtils::isEflagBit(unsigned RegNo) {
|
|||
|
||||
int X86RegisterUtils::getEflagBitIndex(unsigned EFBit) {
|
||||
assert(isEflagBit(EFBit) && "Undefined EFLAGS bit");
|
||||
int index = 0;
|
||||
for (auto v : X86RegisterUtils::EFlagBits) {
|
||||
if (v == EFBit)
|
||||
return index;
|
||||
else
|
||||
index++;
|
||||
int Index = 0;
|
||||
for (auto V : X86RegisterUtils::EFlagBits) {
|
||||
if (V == EFBit)
|
||||
return Index;
|
||||
Index++;
|
||||
}
|
||||
assert(false && "Unknown EFLAGS bit");
|
||||
return -1;
|
||||
|
@ -114,13 +113,13 @@ bool X86RegisterUtils::is8BitPhysReg(unsigned int PReg) {
|
|||
unsigned int X86RegisterUtils::getPhysRegSizeInBits(unsigned int PReg) {
|
||||
if (X86RegisterUtils::is64BitPhysReg(PReg) || X86RegisterUtils::is64BitSSE2Reg(PReg))
|
||||
return 64;
|
||||
else if (X86RegisterUtils::is32BitPhysReg(PReg) || X86RegisterUtils::is32BitSSE2Reg(PReg))
|
||||
if (X86RegisterUtils::is32BitPhysReg(PReg) || X86RegisterUtils::is32BitSSE2Reg(PReg))
|
||||
return 32;
|
||||
else if (X86RegisterUtils::is16BitPhysReg(PReg))
|
||||
if (X86RegisterUtils::is16BitPhysReg(PReg))
|
||||
return 16;
|
||||
else if (X86RegisterUtils::is8BitPhysReg(PReg))
|
||||
if (X86RegisterUtils::is8BitPhysReg(PReg))
|
||||
return 8;
|
||||
else if (isEflagBit(PReg))
|
||||
if (isEflagBit(PReg))
|
||||
return 1;
|
||||
|
||||
llvm_unreachable("Unhandled physical register specified");
|
||||
|
@ -141,11 +140,14 @@ unsigned X86RegisterUtils::getArgumentReg(int Index, Type *Ty) {
|
|||
// Note: any pointer is an address and hence uses a 64-bit register
|
||||
if ((Ty == Type::getInt64Ty(Ctx)) || (Ty->isPointerTy())) {
|
||||
return X86RegisterUtils::GPR64ArgRegs64Bit[Index];
|
||||
} else if (Ty == Type::getInt32Ty(Ctx)) {
|
||||
}
|
||||
if (Ty == Type::getInt32Ty(Ctx)) {
|
||||
return X86RegisterUtils::GPR64ArgRegs32Bit[Index];
|
||||
} else if (Ty == Type::getInt16Ty(Ctx)) {
|
||||
}
|
||||
if (Ty == Type::getInt16Ty(Ctx)) {
|
||||
return X86RegisterUtils::GPR64ArgRegs16Bit[Index];
|
||||
} else if (Ty == Type::getInt8Ty(Ctx)) {
|
||||
}
|
||||
if (Ty == Type::getInt8Ty(Ctx)) {
|
||||
return X86RegisterUtils::GPR64ArgRegs8Bit[Index];
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -302,9 +302,9 @@ static const Target *getTarget(const ObjectFile *Obj = nullptr) {
|
|||
TargetRegistry::lookupTarget(mctoll::ArchName, TheTriple, Error);
|
||||
if (!TheTarget) {
|
||||
if (Obj)
|
||||
report_error(Obj->getFileName(), "Support for raising " +
|
||||
TheTriple.getArchName() +
|
||||
" not included");
|
||||
reportError(Obj->getFileName(), "Support for raising " +
|
||||
TheTriple.getArchName() +
|
||||
" not included");
|
||||
else
|
||||
error("Unsupported target " + TheTriple.getArchName());
|
||||
}
|
||||
|
@ -557,25 +557,25 @@ static uint8_t getElfSymbolType(const ObjectFile *Obj, const SymbolRef &Sym) {
|
|||
if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj)) {
|
||||
auto SymbOrErr = Elf32LEObj->getSymbol(SymbImpl);
|
||||
if (!SymbOrErr)
|
||||
report_error(SymbOrErr.takeError(), "ELF32 symbol not found");
|
||||
reportError(SymbOrErr.takeError(), "ELF32 symbol not found");
|
||||
return SymbOrErr.get()->getType();
|
||||
}
|
||||
if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj)) {
|
||||
auto SymbOrErr = Elf64LEObj->getSymbol(SymbImpl);
|
||||
if (!SymbOrErr)
|
||||
report_error(SymbOrErr.takeError(), "ELF32 symbol not found");
|
||||
reportError(SymbOrErr.takeError(), "ELF32 symbol not found");
|
||||
return SymbOrErr.get()->getType();
|
||||
}
|
||||
if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj)) {
|
||||
auto SymbOrErr = Elf32BEObj->getSymbol(SymbImpl);
|
||||
if (!SymbOrErr)
|
||||
report_error(SymbOrErr.takeError(), "ELF32 symbol not found");
|
||||
reportError(SymbOrErr.takeError(), "ELF32 symbol not found");
|
||||
return SymbOrErr.get()->getType();
|
||||
}
|
||||
if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj)) {
|
||||
auto SymbOrErr = Elf64BEObj->getSymbol(SymbImpl);
|
||||
if (!SymbOrErr)
|
||||
report_error(SymbOrErr.takeError(), "ELF32 symbol not found");
|
||||
reportError(SymbOrErr.takeError(), "ELF32 symbol not found");
|
||||
return SymbOrErr.get()->getType();
|
||||
}
|
||||
llvm_unreachable("Unsupported binary format");
|
||||
|
@ -594,18 +594,18 @@ addDynamicElfSymbols(const ELFObjectFile<ELFT> *Obj,
|
|||
|
||||
Expected<uint64_t> AddressOrErr = Symbol.getAddress();
|
||||
if (!AddressOrErr)
|
||||
report_error(AddressOrErr.takeError(), Obj->getFileName());
|
||||
reportError(AddressOrErr.takeError(), Obj->getFileName());
|
||||
uint64_t Address = *AddressOrErr;
|
||||
|
||||
Expected<StringRef> Name = Symbol.getName();
|
||||
if (!Name)
|
||||
report_error(Name.takeError(), Obj->getFileName());
|
||||
reportError(Name.takeError(), Obj->getFileName());
|
||||
if (Name->empty())
|
||||
continue;
|
||||
|
||||
Expected<section_iterator> SectionOrErr = Symbol.getSection();
|
||||
if (!SectionOrErr)
|
||||
report_error(SectionOrErr.takeError(), Obj->getFileName());
|
||||
reportError(SectionOrErr.takeError(), Obj->getFileName());
|
||||
section_iterator SecI = *SectionOrErr;
|
||||
if (SecI == Obj->section_end())
|
||||
continue;
|
||||
|
@ -716,25 +716,25 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
|||
std::unique_ptr<const MCRegisterInfo> MRI(
|
||||
TheTarget->createMCRegInfo(TripleName));
|
||||
if (!MRI)
|
||||
report_error(Obj->getFileName(),
|
||||
"no register info for target " + TripleName);
|
||||
reportError(Obj->getFileName(),
|
||||
"no register info for target " + TripleName);
|
||||
|
||||
MCTargetOptions MCOptions;
|
||||
// Set up disassembler.
|
||||
std::unique_ptr<const MCAsmInfo> AsmInfo(
|
||||
TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
|
||||
if (!AsmInfo)
|
||||
report_error(Obj->getFileName(),
|
||||
"no assembly info for target " + TripleName);
|
||||
reportError(Obj->getFileName(),
|
||||
"no assembly info for target " + TripleName);
|
||||
std::unique_ptr<const MCSubtargetInfo> STI(
|
||||
TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
|
||||
if (!STI)
|
||||
report_error(Obj->getFileName(),
|
||||
"no subtarget info for target " + TripleName);
|
||||
reportError(Obj->getFileName(),
|
||||
"no subtarget info for target " + TripleName);
|
||||
std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
|
||||
if (!MII)
|
||||
report_error(Obj->getFileName(),
|
||||
"no instruction info for target " + TripleName);
|
||||
reportError(Obj->getFileName(),
|
||||
"no instruction info for target " + TripleName);
|
||||
MCObjectFileInfo MOFI;
|
||||
MCContext Ctx(Triple(TripleName), AsmInfo.get(), MRI.get(), STI.get());
|
||||
// FIXME: for now initialize MCObjectFileInfo with default values
|
||||
|
@ -743,8 +743,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
|||
std::unique_ptr<MCDisassembler> DisAsm(
|
||||
TheTarget->createMCDisassembler(*STI, Ctx));
|
||||
if (!DisAsm)
|
||||
report_error(Obj->getFileName(),
|
||||
"no disassembler for target " + TripleName);
|
||||
reportError(Obj->getFileName(), "no disassembler for target " + TripleName);
|
||||
|
||||
std::unique_ptr<const MCInstrAnalysis> MIA(
|
||||
TheTarget->createMCInstrAnalysis(MII.get()));
|
||||
|
@ -753,8 +752,8 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
|||
std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
|
||||
Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
|
||||
if (!IP)
|
||||
report_error(Obj->getFileName(),
|
||||
"no instruction printer for target " + TripleName);
|
||||
reportError(Obj->getFileName(),
|
||||
"no instruction printer for target " + TripleName);
|
||||
IP->setPrintImmHex(PrintImmHex);
|
||||
PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
|
||||
|
||||
|
@ -806,18 +805,18 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
|||
for (const SymbolRef &Symbol : Obj->symbols()) {
|
||||
Expected<uint64_t> AddressOrErr = Symbol.getAddress();
|
||||
if (!AddressOrErr)
|
||||
report_error(AddressOrErr.takeError(), Obj->getFileName());
|
||||
reportError(AddressOrErr.takeError(), Obj->getFileName());
|
||||
uint64_t Address = *AddressOrErr;
|
||||
|
||||
Expected<StringRef> Name = Symbol.getName();
|
||||
if (!Name)
|
||||
report_error(Name.takeError(), Obj->getFileName());
|
||||
reportError(Name.takeError(), Obj->getFileName());
|
||||
if (Name->empty())
|
||||
continue;
|
||||
|
||||
Expected<section_iterator> SectionOrErr = Symbol.getSection();
|
||||
if (!SectionOrErr)
|
||||
report_error(SectionOrErr.takeError(), Obj->getFileName());
|
||||
reportError(SectionOrErr.takeError(), Obj->getFileName());
|
||||
section_iterator SecI = *SectionOrErr;
|
||||
if (SecI == Obj->section_end())
|
||||
continue;
|
||||
|
@ -1402,7 +1401,7 @@ static void DumpArchive(const Archive *a) {
|
|||
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
|
||||
if (!ChildOrErr) {
|
||||
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
|
||||
report_error(std::move(E), a->getFileName(), C);
|
||||
reportError(std::move(E), a->getFileName(), C);
|
||||
continue;
|
||||
}
|
||||
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
|
||||
|
@ -1410,11 +1409,11 @@ static void DumpArchive(const Archive *a) {
|
|||
else if (COFFImportFile *I = dyn_cast<COFFImportFile>(&*ChildOrErr.get()))
|
||||
DumpObject(I, a);
|
||||
else
|
||||
report_error(errorCodeToError(object_error::invalid_file_type),
|
||||
reportError(errorCodeToError(object_error::invalid_file_type),
|
||||
a->getFileName());
|
||||
}
|
||||
if (Err)
|
||||
report_error(std::move(Err), a->getFileName());
|
||||
reportError(std::move(Err), a->getFileName());
|
||||
}
|
||||
|
||||
/// @brief Open file and figure out how to dump it.
|
||||
|
@ -1430,7 +1429,7 @@ static void DumpInput(StringRef file) {
|
|||
// Attempt to open the binary.
|
||||
Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
|
||||
if (!BinaryOrErr)
|
||||
report_error(BinaryOrErr.takeError(), file);
|
||||
reportError(BinaryOrErr.takeError(), file);
|
||||
Binary &Binary = *BinaryOrErr.get().getBinary();
|
||||
|
||||
if (Archive *a = dyn_cast<Archive>(&Binary))
|
||||
|
@ -1462,7 +1461,7 @@ static void DumpInput(StringRef file) {
|
|||
exit(1);
|
||||
}
|
||||
} else
|
||||
report_error(errorCodeToError(object_error::invalid_file_type), file);
|
||||
reportError(errorCodeToError(object_error::invalid_file_type), file);
|
||||
}
|
||||
|
||||
[[noreturn]] static void reportCmdLineError(const Twine &Message) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче