void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIEpilogStart() {
  auto &S = getStreamer();
  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
  if (!CurFrame)
    return;

  InEpilogCFI = true;
  CurrentEpilog = S.EmitCFILabel();
}
Beispiel #2
0
int TableGenMain(char *argv0, TableGenMainFn *MainFn) {
  RecordKeeper Records;

  try {
    // Parse the input file.
    OwningPtr<MemoryBuffer> File;
    if (error_code ec =
          MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) {
      errs() << "Could not open input file '" << InputFilename << "': "
             << ec.message() <<"\n";
      return 1;
    }
    MemoryBuffer *F = File.take();

    // Tell SrcMgr about this buffer, which is what TGParser will pick up.
    SrcMgr.AddNewSourceBuffer(F, SMLoc());

    // Record the location of the include directory so that the lexer can find
    // it later.
    SrcMgr.setIncludeDirs(IncludeDirs);

    TGParser Parser(SrcMgr, Records);

    if (Parser.ParseFile())
      return 1;

    std::string Error;
    tool_output_file Out(OutputFilename.c_str(), Error);
    if (!Error.empty()) {
      errs() << argv0 << ": error opening " << OutputFilename
        << ":" << Error << "\n";
      return 1;
    }
    if (!DependFilename.empty())
      if (int Ret = createDependencyFile(Parser, argv0))
        return Ret;

    if (MainFn(Out.os(), Records))
      return 1;

    // Declare success.
    Out.keep();
    return 0;

  } catch (const TGError &Error) {
    PrintError(Error);
  } catch (const std::string &Error) {
    PrintError(Error);
  } catch (const char *Error) {
    PrintError(Error);
  } catch (...) {
    errs() << argv0 << ": Unknown unexpected exception occurred.\n";
  }

  return 1;
}
void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIEpilogEnd() {
  auto &S = getStreamer();
  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
  if (!CurFrame)
    return;

  InEpilogCFI = false;
  MCSymbol *Label = S.EmitCFILabel();
  WinEH::Instruction Inst = WinEH::Instruction(Win64EH::UOP_End, Label, -1, 0);
  CurFrame->EpilogMap[CurrentEpilog].push_back(Inst);
  CurrentEpilog = nullptr;
}
// The functions below handle opcodes that can end up in either a prolog or
// an epilog, but not both.
void AArch64TargetWinCOFFStreamer::EmitARM64WinCFIPrologEnd() {
  auto &S = getStreamer();
  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
  if (!CurFrame)
    return;

  MCSymbol *Label = S.EmitCFILabel();
  CurFrame->PrologEnd = Label;
  WinEH::Instruction Inst = WinEH::Instruction(Win64EH::UOP_End, Label, -1, 0);
  auto it = CurFrame->Instructions.begin();
  CurFrame->Instructions.insert(it, Inst);
}
// Helper function to common out unwind code setup for those codes that can
// belong to both prolog and epilog.
// There are three types of Windows ARM64 SEH codes.  They can
// 1) take no operands: SEH_Nop, SEH_PrologEnd, SEH_EpilogStart, SEH_EpilogEnd
// 2) take an offset: SEH_StackAlloc, SEH_SaveFPLR, SEH_SaveFPLR_X
// 3) take a register and an offset/size: all others
void AArch64TargetWinCOFFStreamer::EmitARM64WinUnwindCode(unsigned UnwindCode,
                                                          int Reg,
                                                          int Offset) {
  auto &S = getStreamer();
  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
  if (!CurFrame)
    return;
  MCSymbol *Label = S.EmitCFILabel();
  auto Inst = WinEH::Instruction(UnwindCode, Label, Reg, Offset);
  if (InEpilogCFI)
    CurFrame->EpilogMap[CurrentEpilog].push_back(Inst);
  else
    CurFrame->Instructions.push_back(Inst);
}
Beispiel #6
0
void SSPParser::printError(StringRef Msg, bool PrintLoc) {
  StringRef   BufferData = Buf->getBuffer();
  const char *Data       = BufferData.data();
  unsigned    Pos        = CurPos;

  if (Pos > 0) {
    // The actual error will be one less than the *current* character
    --Pos;
  }
  
  if (Pos >= BufferData.size()) {
    Pos = BufferData.size()-1;
  }

  SMLoc Loc = SMLoc();
  if (PrintLoc) {
    Loc     = SMLoc::getFromPointer(Data+Pos);
  }
  
  SrcMgr.PrintMessage(Loc, SourceMgr::DK_Error, Msg);
}
Beispiel #7
0
LLVM_ATTRIBUTE_NORETURN
void MCWinCOFFStreamer::FatalError(const Twine &Msg) const {
  getContext().reportFatalError(SMLoc(), Msg);
}
Beispiel #8
0
void MCWinCOFFStreamer::Error(const Twine &Msg) const {
  getContext().reportError(SMLoc(), Msg);
}
Beispiel #9
0
int TableGenMain(char *argv0, TableGenAction &Action) {
  RecordKeeper Records;

  try {
    // Parse the input file.
    OwningPtr<MemoryBuffer> File;
    if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) {
      errs() << "Could not open input file '" << InputFilename << "': "
             << ec.message() <<"\n";
      return 1;
    }
    MemoryBuffer *F = File.take();

    // Tell SrcMgr about this buffer, which is what TGParser will pick up.
    SrcMgr.AddNewSourceBuffer(F, SMLoc());

    // Record the location of the include directory so that the lexer can find
    // it later.
    SrcMgr.setIncludeDirs(IncludeDirs);

    TGParser Parser(SrcMgr, Records);

    if (Parser.ParseFile())
      return 1;

    std::string Error;
    tool_output_file Out(OutputFilename.c_str(), Error);
    if (!Error.empty()) {
      errs() << argv0 << ": error opening " << OutputFilename
        << ":" << Error << "\n";
      return 1;
    }
    if (!DependFilename.empty()) {
      if (OutputFilename == "-") {
        errs() << argv0 << ": the option -d must be used together with -o\n";
        return 1;
      }
      tool_output_file DepOut(DependFilename.c_str(), Error);
      if (!Error.empty()) {
        errs() << argv0 << ": error opening " << DependFilename
          << ":" << Error << "\n";
        return 1;
      }
      DepOut.os() << OutputFilename << ":";
      const std::vector<std::string> &Dependencies = Parser.getDependencies();
      for (std::vector<std::string>::const_iterator I = Dependencies.begin(),
                                                          E = Dependencies.end();
           I != E; ++I) {
        DepOut.os() << " " << (*I);
      }
      DepOut.os() << "\n";
      DepOut.keep();
    }

    if (Action(Out.os(), Records))
      return 1;

    // Declare success.
    Out.keep();
    return 0;

  } catch (const TGError &Error) {
    PrintError(Error);
  } catch (const std::string &Error) {
    PrintError(Error);
  } catch (const char *Error) {
    PrintError(Error);
  } catch (...) {
    errs() << argv0 << ": Unknown unexpected exception occurred.\n";
  }

  return 1;
}
Beispiel #10
0
SSPParser::SSPParser(MemoryBuffer *Buffer, SourceMgr &SM)
  : SrcMgr(SM),
    Buf(Buffer),
    G(NULL) {
  SM.AddNewSourceBuffer(Buffer, SMLoc());
}
Beispiel #11
0
 void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
                   uint64_t Size = 0, unsigned ByteAlignment = 0,
                   SMLoc Loc = SMLoc()) override {}
Beispiel #12
0
int main(int ac, char **av)
{
    SourceMgr SrcMgr;

    //LLVMInitializeX86TargetInfo();
    llvm::InitializeAllTargetInfos();
    //LLVMInitializeX86AsmParser();
    llvm::InitializeAllTargetMCs();
    //LLVMInitializeX86TargetMC();
    llvm::InitializeAllAsmParsers();
    //LLVMInitializeX86AsmParser();
    llvm::InitializeAllDisassemblers();
    //LLVMInitializeX86Disassembler();

    // arg0:
    // llvm::Target encapsulating the "x86_64-apple-darwin14.5.0" information 

    // see /lib/Support/Triple.cpp for the details
    //spec = llvm::sys::getDefaultTargetTriple();
    //std::string machSpec = "x86_64-apple-windows"; // will produce a COFF
    //std::string machSpec = "x86_64-apple-darwin14.5.0"; // will produce a Mach-O
    std::string machSpec = "arm-none-none-eabi"; //
    //std::string machSpec = "x86_64-apple-darwin";
    //std::string machSpec = "x86_64-thumb-linux-gnu";
    //std::string machSpec = "x86_64-unknown-linux-gnu";
    printf("machine spec: %s\n", machSpec.c_str());
    machSpec = Triple::normalize(machSpec);
    printf("machine spec (normalized): %s\n", machSpec.c_str());
    Triple TheTriple(machSpec);

    // Get the target specific parser.
    std::string Error;
    const Target *TheTarget = TargetRegistry::lookupTarget(/*arch*/"", TheTriple, Error);
    if (!TheTarget) {
        errs() << Error;
        return -1;
    }

    machSpec = TheTriple.getTriple();
    printf("machine spec (returned): %s\n", machSpec.c_str());
    
    printf("Target.getName(): %s\n", TheTarget->getName());
    printf("Target.getShortDescription(): %s\n", TheTarget->getShortDescription());

    /* from the target we get almost everything */
    std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(machSpec));
    std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, machSpec));
    std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); /* describes target instruction set */
    MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(machSpec, "", ""); /* subtarget instr set */
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, machSpec, /* specific CPU */ "");

    // arg0:
    // llvm::SourceMgr (Support/SourceMgr.h) that holds assembler source
    // has vector of llvm::SrcBuffer encaps (Support/MemoryBuffer.h) and vector of include dirs
    //std::string asmSrc = ".org 0x100, 0xAA\nfoo:\nxor %eax, %ebx\npush %rbp\njmp foo\nrdtsc\n";
	//std::string asmSrc = ".text\n" "ldr pc, data_foo\n" "\n" "data_foo:\n" "    .int 0x8\n" "\n" "loop:\n" "b loop\n";
	//std::string asmSrc = ".text\n" "mov r2, r1\n";
	std::string asmSrc = ".text\n" "ldr pc, data_foo\n" "data_foo:\n" ".int 0x8\n" "loop:\n" "b loop\n";

    std::unique_ptr<MemoryBuffer> memBuf = MemoryBuffer::getMemBuffer(asmSrc);
    SrcMgr.AddNewSourceBuffer(std::move(memBuf), SMLoc());

    // arg1: the machine code context
    MCObjectFileInfo MOFI;
    MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr);
    MOFI.InitMCObjectFileInfo(TheTriple, Reloc::Default, CodeModel::Default, Ctx);

    // this is the assembler interface
    // -methods per .s statements (emit bytes, handle directive, etc.)
    // -remembers current section
    // -implementations that write a .s, or .o in various formats
    //
    //   1. the output stream ... a formatted_raw_ostream wraps a raw_ostream to provide
    //   tracking of line and column position for padding and shit
    //
    //   but raw_ostream is abstract and is implemented by raw_fd_ostream, raw_string_ostream, etc.

	/* output stream:
		raw_svector_ostream is a raw_pwrite_stream is a raw_ostream
		since a SmallString is SmallVector (svector) we can use this and 
		retrieve bytes later with its .data() method */
	SmallString<1024> smallString;
    raw_svector_ostream rso(smallString);

    /* code emitter needs 1) instruction set info 2) register info */
    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);

    MCStreamer *as = TheTarget->createMCObjectStreamer(
		TheTriple, /* Triple */	
        Ctx, /* the MCContext */
        *MAB,  /* the AsmBackend, (fixups, relaxation, objs and elfs) */
        rso, /* output stream raw_pwrite_stream */
        CE, /* code emitter */
		*STI, /* subtarget info */
		true, /* relax all fixups */
		true, /* incremental linker compatible */ 
        false /* DWARFMustBeAtTheEnd */
    );

    std::string abi = "none";
    MCTargetOptions toptions;
    toptions.MCUseDwarfDirectory = false;
    toptions.ABIName = abi;

    printf("trying to assemble, let's go..\n");
    AssembleInput(TheTarget, SrcMgr, Ctx, *as, *MAI, *STI,
        *MCII, toptions);
	printf("done with AssembleInput()\n");

	/* dump to file for debugging */
	FILE *fp;
	fp = fopen("out.bin", "wb");
	fwrite(smallString.data(), 1, smallString.size(), fp);
	fclose(fp);

	//int n = smallString.size();
	int codeOffset=0, codeSize = 0;
	char *data = smallString.data();
	if(*(uint32_t *)data == 0xFEEDFACF) {
		unsigned int idx = 0;
		idx += 0x20; /* skip mach_header_64 to first command */
		idx += 0x48; /* advance into segment_command_64 to first section */
		idx += 0x28; /* advance into section_64 to size */
		uint64_t scn_size = *(uint64_t *)(data + idx);
		idx += 0x8; /* advance into section_64 to offset */
		uint64_t scn_offset = *(uint64_t *)(data + idx);
		codeOffset = scn_offset;
		codeSize = scn_size;
	}
	else if(0==memcmp(data, "\x7F" "ELF\x01\x01\x01\x00", 8)) {
		/* assume four sections: NULL, .strtab, .text, .symtab */
		uint32_t e_shoff = *(uint32_t *)(data + 0x20);
		uint32_t sh_offset = *(uint32_t *)(data + e_shoff + 2*0x28 + 0x10); /* second shdr */
		uint32_t sh_size = *(uint32_t *)(data + e_shoff + 2*0x28 + 0x14); /* second shdr */
		codeOffset = sh_offset;
		codeSize = sh_size;
	}
	else {
		printf("ERROR: couldn't identify type of output file\n");
	}
	
	dump_bytes((unsigned char *)data + codeOffset, codeSize, 0);

    return 0;
}