Exemplo n.º 1
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;
}
Exemplo n.º 2
0
bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
  PatternLoc = SMLoc::getFromPointer(PatternStr.data());

  // Ignore trailing whitespace.
  while (!PatternStr.empty() &&
         (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
    PatternStr = PatternStr.substr(0, PatternStr.size()-1);

  // Check that there is something on the line.
  if (PatternStr.empty()) {
    SM.PrintMessage(PatternLoc, "found empty check string with prefix '" +
                    CheckPrefix+":'", "error");
    return true;
  }

  // Check to see if this is a fixed string, or if it has regex pieces.
  if (PatternStr.size() < 2 ||
      (PatternStr.find("{{") == StringRef::npos &&
       PatternStr.find("[[") == StringRef::npos)) {
    FixedStr = PatternStr;
    return false;
  }

  // Paren value #0 is for the fully matched string.  Any new parenthesized
  // values add from their.
  unsigned CurParen = 1;

  // Otherwise, there is at least one regex piece.  Build up the regex pattern
  // by escaping scary characters in fixed strings, building up one big regex.
  while (!PatternStr.empty()) {
    // RegEx matches.
    if (PatternStr.size() >= 2 &&
        PatternStr[0] == '{' && PatternStr[1] == '{') {

      // Otherwise, this is the start of a regex match.  Scan for the }}.
      size_t End = PatternStr.find("}}");
      if (End == StringRef::npos) {
        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
                        "found start of regex string with no end '}}'", "error");
        return true;
      }

      if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
        return true;
      PatternStr = PatternStr.substr(End+2);
      continue;
    }

    // Named RegEx matches.  These are of two forms: [[foo:.*]] which matches .*
    // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
    // second form is [[foo]] which is a reference to foo.  The variable name
    // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
    // it.  This is to catch some common errors.
    if (PatternStr.size() >= 2 &&
        PatternStr[0] == '[' && PatternStr[1] == '[') {
      // Verify that it is terminated properly.
      size_t End = PatternStr.find("]]");
      if (End == StringRef::npos) {
        SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
                        "invalid named regex reference, no ]] found", "error");
        return true;
      }

      StringRef MatchStr = PatternStr.substr(2, End-2);
      PatternStr = PatternStr.substr(End+2);

      // Get the regex name (e.g. "foo").
      size_t NameEnd = MatchStr.find(':');
      StringRef Name = MatchStr.substr(0, NameEnd);

      if (Name.empty()) {
        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
                        "invalid name in named regex: empty name", "error");
        return true;
      }

      // Verify that the name is well formed.
      for (unsigned i = 0, e = Name.size(); i != e; ++i)
        if (Name[i] != '_' &&
            (Name[i] < 'a' || Name[i] > 'z') &&
            (Name[i] < 'A' || Name[i] > 'Z') &&
            (Name[i] < '0' || Name[i] > '9')) {
          SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
                          "invalid name in named regex", "error");
          return true;
        }

      // Name can't start with a digit.
      if (isdigit(Name[0])) {
        SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
                        "invalid name in named regex", "error");
        return true;
      }

      // Handle [[foo]].
      if (NameEnd == StringRef::npos) {
        VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
        continue;
      }

      // Handle [[foo:.*]].
      VariableDefs.push_back(std::make_pair(Name, CurParen));
      RegExStr += '(';
      ++CurParen;

      if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM))
        return true;

      RegExStr += ')';
    }

    // Handle fixed string matches.
    // Find the end, which is the start of the next regex.
    size_t FixedMatchEnd = PatternStr.find("{{");
    FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
    AddFixedStringToRegEx(PatternStr.substr(0, FixedMatchEnd), RegExStr);
    PatternStr = PatternStr.substr(FixedMatchEnd);
    continue;
  }

  return false;
}
Exemplo n.º 3
0
/// ReadCheckFile - Read the check file, which specifies the sequence of
/// expected strings.  The strings are added to the CheckStrings vector.
static bool ReadCheckFile(SourceMgr &SM,
                          std::vector<CheckString> &CheckStrings) {
  // Open the check file, and tell SourceMgr about it.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open check file '" << CheckFilename << "': "
           << ErrorStr << '\n';
    return true;
  }

  // If we want to canonicalize whitespace, strip excess whitespace from the
  // buffer containing the CHECK lines.
  if (!NoCanonicalizeWhiteSpace)
    F = CanonicalizeInputFile(F);

  SM.AddNewSourceBuffer(F, SMLoc());

  // Find all instances of CheckPrefix followed by : in the file.
  StringRef Buffer = F->getBuffer();

  std::vector<std::pair<SMLoc, Pattern> > NotMatches;

  while (1) {
    // See if Prefix occurs in the memory buffer.
    Buffer = Buffer.substr(Buffer.find(CheckPrefix));

    // If we didn't find a match, we're done.
    if (Buffer.empty())
      break;

    const char *CheckPrefixStart = Buffer.data();

    // When we find a check prefix, keep track of whether we find CHECK: or
    // CHECK-NEXT:
    bool IsCheckNext = false, IsCheckNot = false;

    // Verify that the : is present after the prefix.
    if (Buffer[CheckPrefix.size()] == ':') {
      Buffer = Buffer.substr(CheckPrefix.size()+1);
    } else if (Buffer.size() > CheckPrefix.size()+6 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NEXT:", 6) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+7);
      IsCheckNext = true;
    } else if (Buffer.size() > CheckPrefix.size()+5 &&
               memcmp(Buffer.data()+CheckPrefix.size(), "-NOT:", 5) == 0) {
      Buffer = Buffer.substr(CheckPrefix.size()+6);
      IsCheckNot = true;
    } else {
      Buffer = Buffer.substr(1);
      continue;
    }

    // Okay, we found the prefix, yay.  Remember the rest of the line, but
    // ignore leading and trailing whitespace.
    Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));

    // Scan ahead to the end of line.
    size_t EOL = Buffer.find_first_of("\n\r");

    // Remember the location of the start of the pattern, for diagnostics.
    SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());

    // Parse the pattern.
    Pattern P;
    if (P.ParsePattern(Buffer.substr(0, EOL), SM))
      return true;

    Buffer = Buffer.substr(EOL);


    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
    if (IsCheckNext && CheckStrings.empty()) {
      SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
                      "found '"+CheckPrefix+"-NEXT:' without previous '"+
                      CheckPrefix+ ": line", "error");
      return true;
    }

    // Handle CHECK-NOT.
    if (IsCheckNot) {
      NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
                                          P));
      continue;
    }


    // Okay, add the string we captured to the output vector and move on.
    CheckStrings.push_back(CheckString(P,
                                       PatternLoc,
                                       IsCheckNext));
    std::swap(NotMatches, CheckStrings.back().NotStrings);
  }

  if (CheckStrings.empty()) {
    errs() << "error: no check strings found with prefix '" << CheckPrefix
           << ":'\n";
    return true;
  }

  if (!NotMatches.empty()) {
    errs() << "error: '" << CheckPrefix
           << "-NOT:' not supported after last check line.\n";
    return true;
  }

  return false;
}
Exemplo n.º 4
0
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
                               InlineAsm::AsmDialect Dialect) const {
  assert(!Str.empty() && "Can't emit empty inline asm block");

  // Remember if the buffer is nul terminated or not so we can avoid a copy.
  bool isNullTerminated = Str.back() == 0;
  if (isNullTerminated)
    Str = Str.substr(0, Str.size()-1);

  // If the output streamer does not have mature MC support or the integrated
  // assembler has been disabled, just emit the blob textually.
  // Otherwise parse the asm and emit it via MC support.
  // This is useful in case the asm parser doesn't handle something but the
  // system assembler does.
  const MCAsmInfo *MCAI = TM.getMCAsmInfo();
  assert(MCAI && "No MCAsmInfo");
  if (!MCAI->useIntegratedAssembler() &&
      !OutStreamer.isIntegratedAssemblerRequired()) {
    OutStreamer.EmitRawText(Str);
    emitInlineAsmEnd(TM.getSubtarget<MCSubtargetInfo>(), 0);
    return;
  }

  SourceMgr SrcMgr;
  SrcMgrDiagInfo DiagInfo;

  // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
  LLVMContext &LLVMCtx = MMI->getModule()->getContext();
  bool HasDiagHandler = false;
  if (LLVMCtx.getInlineAsmDiagnosticHandler() != 0) {
    // If the source manager has an issue, we arrange for srcMgrDiagHandler
    // to be invoked, getting DiagInfo passed into it.
    DiagInfo.LocInfo = LocMDNode;
    DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
    DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
    SrcMgr.setDiagHandler(srcMgrDiagHandler, &DiagInfo);
    HasDiagHandler = true;
  }

  MemoryBuffer *Buffer;
  if (isNullTerminated)
    Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
  else
    Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");

  // Tell SrcMgr about this buffer, it takes ownership of the buffer.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, OutContext, OutStreamer, *MAI));

  // Initialize the parser with a fresh subtarget info. It is better to use a
  // new STI here because the parser may modify it and we do not want those
  // modifications to persist after parsing the inlineasm. The modifications
  // made by the parser will be seen by the code emitters because it passes
  // the current STI down to the EncodeInstruction() method.
  std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
      TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString()));

  // Preserve a copy of the original STI because the parser may modify it.  For
  // example, when switching between arm and thumb mode. If the target needs to
  // emit code to return to the original state it can do so in
  // emitInlineAsmEnd().
  MCSubtargetInfo STIOrig = *STI;

  std::unique_ptr<MCTargetAsmParser> TAP(
      TM.getTarget().createMCAsmParser(*STI, *Parser, *MII));
  if (!TAP)
    report_fatal_error("Inline asm not supported by this streamer because"
                       " we don't have an asm parser for this target\n");
  Parser->setAssemblerDialect(Dialect);
  Parser->setTargetParser(*TAP.get());

  // Don't implicitly switch to the text section before the asm.
  int Res = Parser->Run(/*NoInitialTextSection*/ true,
                        /*NoFinalize*/ true);
  emitInlineAsmEnd(STIOrig, STI.get());
  if (Res && !HasDiagHandler)
    report_fatal_error("Error parsing inline asm\n");
}
Exemplo n.º 5
0
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets and assembly printers/parsers.
  llvm::InitializeAllTargetInfos();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmParsers();
  llvm::InitializeAllDisassemblers();

  // Register the target printer for --version.
  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

  cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
  TripleName = Triple::normalize(TripleName);
  setDwarfDebugFlags(argc, argv);

  setDwarfDebugProducer();

  const char *ProgName = argv[0];
  const Target *TheTarget = GetTarget(ProgName);
  if (!TheTarget)
    return 1;

  OwningPtr<MemoryBuffer> BufferPtr;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) {
    errs() << ProgName << ": " << ec.message() << '\n';
    return 1;
  }
  MemoryBuffer *Buffer = BufferPtr.take();

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

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

  llvm::OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  assert(MRI && "Unable to create target register info!");

  llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
  assert(MAI && "Unable to create target asm info!");

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
  MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx);

  if (SaveTempLabels)
    Ctx.setAllowTemporaryLabels(false);

  Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
  if (!DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags));
  if (!DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer));
  if (!DebugCompilationDir.empty())
    Ctx.setCompilationDir(DebugCompilationDir);
  if (!MainFileName.empty())
    Ctx.setMainFileName(MainFileName);

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  OwningPtr<tool_output_file> Out(GetOutputStream());
  if (!Out)
    return 1;

  formatted_raw_ostream FOS(Out->os());
  OwningPtr<MCStreamer> Str;

  OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  OwningPtr<MCSubtargetInfo>
    STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));

  MCInstPrinter *IP = NULL;
  if (FileType == OFT_AssemblyFile) {
    IP =
      TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
    MCCodeEmitter *CE = 0;
    MCAsmBackend *MAB = 0;
    if (ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
      MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
    }
    bool UseCFI = !DisableCFI;
    Str.reset(TheTarget->createAsmStreamer(
        Ctx, FOS, /*asmverbose*/ true, UseCFI,
        /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst));

  } else if (FileType == OFT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(FileType == OFT_ObjectFile && "Invalid file type!");
    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
    Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
                                                FOS, CE, *STI, RelaxAll,
                                                NoExecStack));
  }

  int Res = 1;
  bool disassemble = false;
  switch (Action) {
  case AC_AsLex:
    Res = AsLexInput(SrcMgr, *MAI, Out.get());
    break;
  case AC_Assemble:
    Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII);
    break;
  case AC_MDisassemble:
    assert(IP && "Expected assembly output");
    IP->setUseMarkup(1);
    disassemble = true;
    break;
  case AC_HDisassemble:
    assert(IP && "Expected assembly output");
    IP->setPrintImmHex(1);
    disassemble = true;
    break;
  case AC_Disassemble:
    disassemble = true;
    break;
  }
  if (disassemble)
    Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
                                    *Buffer, SrcMgr, Out->os());

  // Keep output if no errors.
  if (Res == 0) Out->keep();
  return Res;
}
Exemplo n.º 6
0
static bool ExecuteAssembler(AssemblerInvocation &Opts,
                             DiagnosticsEngine &Diags) {
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
  if (!TheTarget)
    return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
      MemoryBuffer::getFileOrSTDIN(Opts.InputFile);

  if (std::error_code EC = Buffer.getError()) {
    Error = EC.message();
    return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
  }

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(Opts.IncludePaths);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
  assert(MAI && "Unable to create target asm info!");

  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
  // may be created with a combination of default and explicit settings.
  MAI->setCompressDebugSections(Opts.CompressDebugSections);

  MAI->setRelaxELFRelocations(Opts.RelaxELFRelocations);

  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
  if (Opts.OutputPath.empty())
    Opts.OutputPath = "-";
  std::unique_ptr<raw_fd_ostream> FDOS =
      getOutputStream(Opts.OutputPath, Diags, IsBinary);
  if (!FDOS)
    return true;
  std::unique_ptr<raw_fd_ostream> DwoOS;
  if (!Opts.SplitDwarfFile.empty())
    DwoOS = getOutputStream(Opts.SplitDwarfFile, Diags, IsBinary);

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());

  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);

  bool PIC = false;
  if (Opts.RelocationModel == "static") {
    PIC = false;
  } else if (Opts.RelocationModel == "pic") {
    PIC = true;
  } else {
    assert(Opts.RelocationModel == "dynamic-no-pic" &&
           "Invalid PIC model!");
    PIC = false;
  }

  MOFI->InitMCObjectFileInfo(Triple(Opts.Triple), PIC, Ctx);
  if (Opts.SaveTemporaryLabels)
    Ctx.setAllowTemporaryLabels(false);
  if (Opts.GenDwarfForAssembly)
    Ctx.setGenDwarfForAssembly(true);
  if (!Opts.DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
  if (!Opts.DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
  if (!Opts.DebugCompilationDir.empty())
    Ctx.setCompilationDir(Opts.DebugCompilationDir);
  if (!Opts.DebugPrefixMap.empty())
    for (const auto &KV : Opts.DebugPrefixMap)
      Ctx.addDebugPrefixMapEntry(KV.first, KV.second);
  if (!Opts.MainFileName.empty())
    Ctx.setMainFileName(StringRef(Opts.MainFileName));
  Ctx.setDwarfVersion(Opts.DwarfVersion);

  // Build up the feature string from the target feature list.
  std::string FS;
  if (!Opts.Features.empty()) {
    FS = Opts.Features[0];
    for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
      FS += "," + Opts.Features[i];
  }

  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));

  raw_pwrite_stream *Out = FDOS.get();
  std::unique_ptr<buffer_ostream> BOS;

  // FIXME: There is a bit of code duplication with addPassesToEmitFile.
  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
    MCInstPrinter *IP = TheTarget->createMCInstPrinter(
        llvm::Triple(Opts.Triple), Opts.OutputAsmVariant, *MAI, *MCII, *MRI);

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

    auto FOut = llvm::make_unique<formatted_raw_ostream>(*Out);
    Str.reset(TheTarget->createAsmStreamer(
        Ctx, std::move(FOut), /*asmverbose*/ true,
        /*useDwarfDirectory*/ true, IP, std::move(CE), std::move(MAB),
        Opts.ShowInst));
  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
           "Invalid file type!");
    if (!FDOS->supportsSeeking()) {
      BOS = make_unique<buffer_ostream>(*FDOS);
      Out = BOS.get();
    }

    std::unique_ptr<MCCodeEmitter> CE(
        TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
    MCTargetOptions MCOptions;
    std::unique_ptr<MCAsmBackend> MAB(
        TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
    std::unique_ptr<MCObjectWriter> OW =
        DwoOS ? MAB->createDwoObjectWriter(*Out, *DwoOS)
              : MAB->createObjectWriter(*Out);

    Triple T(Opts.Triple);
    Str.reset(TheTarget->createMCObjectStreamer(
        T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI,
        Opts.RelaxAll, Opts.IncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ true));
    Str.get()->InitSections(Opts.NoExecStack);
  }

  // Assembly to object compilation should leverage assembly info.
  Str->setUseAssemblerInfoForParsing(true);

  bool Failed = false;

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));

  // FIXME: init MCTargetOptions from sanitizer flags here.
  MCTargetOptions Options;
  std::unique_ptr<MCTargetAsmParser> TAP(
      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
  if (!TAP)
    Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  // Set values for symbols, if any.
  for (auto &S : Opts.SymbolDefs) {
    auto Pair = StringRef(S).split('=');
    auto Sym = Pair.first;
    auto Val = Pair.second;
    int64_t Value = 1;
    // We have already error checked this in the driver.
    Val.getAsInteger(0, Value);
    Ctx.setSymbolValue(Parser->getStreamer(), Sym, Value);
  }

  if (!Failed) {
    Parser->setTargetParser(*TAP.get());
    Failed = Parser->Run(Opts.NoInitialTextSection);
  }

  // Close Streamer first.
  // It might have a reference to the output stream.
  Str.reset();
  // Close the output stream early.
  BOS.reset();
  FDOS.reset();

  // Delete output file if there were errors.
  if (Failed) {
    if (Opts.OutputPath != "-")
      sys::fs::remove(Opts.OutputPath);
    if (!Opts.SplitDwarfFile.empty() && Opts.SplitDwarfFile != "-")
      sys::fs::remove(Opts.SplitDwarfFile);
  }

  return Failed;
}
Exemplo n.º 7
0
void PrintWarning(const char *Loc, const Twine &Msg) {
  SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Warning, Msg);
}
Exemplo n.º 8
0
int Disassembler::disassemble(const Target &T,
                              const std::string &Triple,
                              MCSubtargetInfo &STI,
                              MCStreamer &Streamer,
                              MemoryBuffer &Buffer,
                              SourceMgr &SM,
                              raw_ostream &Out) {

  std::unique_ptr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple));
  if (!MRI) {
    errs() << "error: no register info for target " << Triple << "\n";
    return -1;
  }

  std::unique_ptr<const MCAsmInfo> MAI(T.createMCAsmInfo(*MRI, Triple));
  if (!MAI) {
    errs() << "error: no assembly info for target " << Triple << "\n";
    return -1;
  }

  // Set up the MCContext for creating symbols and MCExpr's.
  MCContext Ctx(MAI.get(), MRI.get(), nullptr);

  std::unique_ptr<const MCDisassembler> DisAsm(
    T.createMCDisassembler(STI, Ctx));
  if (!DisAsm) {
    errs() << "error: no disassembler for target " << Triple << "\n";
    return -1;
  }

  // Set up initial section manually here
  Streamer.InitSections(false);

  bool ErrorOccurred = false;

  // Convert the input to a vector for disassembly.
  ByteArrayTy ByteArray;
  StringRef Str = Buffer.getBuffer();
  bool InAtomicBlock = false;

  while (SkipToToken(Str)) {
    ByteArray.first.clear();
    ByteArray.second.clear();

    if (Str[0] == '[') {
      if (InAtomicBlock) {
        SM.PrintMessage(SMLoc::getFromPointer(Str.data()), SourceMgr::DK_Error,
                        "nested atomic blocks make no sense");
        ErrorOccurred = true;
      }
      InAtomicBlock = true;
      Str = Str.drop_front();
      continue;
    } else if (Str[0] == ']') {
      if (!InAtomicBlock) {
        SM.PrintMessage(SMLoc::getFromPointer(Str.data()), SourceMgr::DK_Error,
                        "attempt to close atomic block without opening");
        ErrorOccurred = true;
      }
      InAtomicBlock = false;
      Str = Str.drop_front();
      continue;
    }

    // It's a real token, get the bytes and emit them
    ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM);

    if (!ByteArray.first.empty())
      ErrorOccurred |= PrintInsts(*DisAsm, ByteArray, SM, Out, Streamer,
                                  InAtomicBlock, STI);
  }

  if (InAtomicBlock) {
    SM.PrintMessage(SMLoc::getFromPointer(Str.data()), SourceMgr::DK_Error,
                    "unclosed atomic block");
    ErrorOccurred = true;
  }

  return ErrorOccurred;
}
Exemplo n.º 9
0
static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI,
                      raw_ostream &OS) {

  AsmLexer Lexer(MAI);
  Lexer.setBuffer(SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer());

  bool Error = false;
  while (Lexer.Lex().isNot(AsmToken::Eof)) {
    const AsmToken &Tok = Lexer.getTok();

    switch (Tok.getKind()) {
    default:
      SrcMgr.PrintMessage(Lexer.getLoc(), SourceMgr::DK_Warning,
                          "unknown token");
      Error = true;
      break;
    case AsmToken::Error:
      Error = true; // error already printed.
      break;
    case AsmToken::Identifier:
      OS << "identifier: " << Lexer.getTok().getString();
      break;
    case AsmToken::Integer:
      OS << "int: " << Lexer.getTok().getString();
      break;
    case AsmToken::Real:
      OS << "real: " << Lexer.getTok().getString();
      break;
    case AsmToken::String:
      OS << "string: " << Lexer.getTok().getString();
      break;

    case AsmToken::Amp:            OS << "Amp"; break;
    case AsmToken::AmpAmp:         OS << "AmpAmp"; break;
    case AsmToken::At:             OS << "At"; break;
    case AsmToken::Caret:          OS << "Caret"; break;
    case AsmToken::Colon:          OS << "Colon"; break;
    case AsmToken::Comma:          OS << "Comma"; break;
    case AsmToken::Dollar:         OS << "Dollar"; break;
    case AsmToken::Dot:            OS << "Dot"; break;
    case AsmToken::EndOfStatement: OS << "EndOfStatement"; break;
    case AsmToken::Eof:            OS << "Eof"; break;
    case AsmToken::Equal:          OS << "Equal"; break;
    case AsmToken::EqualEqual:     OS << "EqualEqual"; break;
    case AsmToken::Exclaim:        OS << "Exclaim"; break;
    case AsmToken::ExclaimEqual:   OS << "ExclaimEqual"; break;
    case AsmToken::Greater:        OS << "Greater"; break;
    case AsmToken::GreaterEqual:   OS << "GreaterEqual"; break;
    case AsmToken::GreaterGreater: OS << "GreaterGreater"; break;
    case AsmToken::Hash:           OS << "Hash"; break;
    case AsmToken::LBrac:          OS << "LBrac"; break;
    case AsmToken::LCurly:         OS << "LCurly"; break;
    case AsmToken::LParen:         OS << "LParen"; break;
    case AsmToken::Less:           OS << "Less"; break;
    case AsmToken::LessEqual:      OS << "LessEqual"; break;
    case AsmToken::LessGreater:    OS << "LessGreater"; break;
    case AsmToken::LessLess:       OS << "LessLess"; break;
    case AsmToken::Minus:          OS << "Minus"; break;
    case AsmToken::Percent:        OS << "Percent"; break;
    case AsmToken::Pipe:           OS << "Pipe"; break;
    case AsmToken::PipePipe:       OS << "PipePipe"; break;
    case AsmToken::Plus:           OS << "Plus"; break;
    case AsmToken::RBrac:          OS << "RBrac"; break;
    case AsmToken::RCurly:         OS << "RCurly"; break;
    case AsmToken::RParen:         OS << "RParen"; break;
    case AsmToken::Slash:          OS << "Slash"; break;
    case AsmToken::Star:           OS << "Star"; break;
    case AsmToken::Tilde:          OS << "Tilde"; break;
    case AsmToken::PercentCall16:
      OS << "PercentCall16";
      break;
    case AsmToken::PercentCall_Hi:
      OS << "PercentCall_Hi";
      break;
    case AsmToken::PercentCall_Lo:
      OS << "PercentCall_Lo";
      break;
    case AsmToken::PercentDtprel_Hi:
      OS << "PercentDtprel_Hi";
      break;
    case AsmToken::PercentDtprel_Lo:
      OS << "PercentDtprel_Lo";
      break;
    case AsmToken::PercentGot:
      OS << "PercentGot";
      break;
    case AsmToken::PercentGot_Disp:
      OS << "PercentGot_Disp";
      break;
    case AsmToken::PercentGot_Hi:
      OS << "PercentGot_Hi";
      break;
    case AsmToken::PercentGot_Lo:
      OS << "PercentGot_Lo";
      break;
    case AsmToken::PercentGot_Ofst:
      OS << "PercentGot_Ofst";
      break;
    case AsmToken::PercentGot_Page:
      OS << "PercentGot_Page";
      break;
    case AsmToken::PercentGottprel:
      OS << "PercentGottprel";
      break;
    case AsmToken::PercentGp_Rel:
      OS << "PercentGp_Rel";
      break;
    case AsmToken::PercentHi:
      OS << "PercentHi";
      break;
    case AsmToken::PercentHigher:
      OS << "PercentHigher";
      break;
    case AsmToken::PercentHighest:
      OS << "PercentHighest";
      break;
    case AsmToken::PercentLo:
      OS << "PercentLo";
      break;
    case AsmToken::PercentNeg:
      OS << "PercentNeg";
      break;
    case AsmToken::PercentPcrel_Hi:
      OS << "PercentPcrel_Hi";
      break;
    case AsmToken::PercentPcrel_Lo:
      OS << "PercentPcrel_Lo";
      break;
    case AsmToken::PercentTlsgd:
      OS << "PercentTlsgd";
      break;
    case AsmToken::PercentTlsldm:
      OS << "PercentTlsldm";
      break;
    case AsmToken::PercentTprel_Hi:
      OS << "PercentTprel_Hi";
      break;
    case AsmToken::PercentTprel_Lo:
      OS << "PercentTprel_Lo";
      break;
    }

    // Print the token string.
    OS << " (\"";
    OS.write_escaped(Tok.getString());
    OS << "\")\n";
  }

  return Error;
}
Exemplo n.º 10
0
int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
                              SmallVectorImpl<AsmToken> &tokens,
                              const std::string &str) {
  int ret = 0;
  
  switch (Key.Arch) {
  default:
    return -1;
  case Triple::x86:
  case Triple::x86_64:
  case Triple::arm:
  case Triple::thumb:
    break;
  }
  
  const char *cStr = str.c_str();
  MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
  
  StringRef instName;
  SMLoc instLoc;
  
  SourceMgr sourceMgr;
  sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over
  MCContext context(*AsmInfo, NULL);
  OwningPtr<MCStreamer> streamer(createNullStreamer(context));
  OwningPtr<MCAsmParser> genericParser(createMCAsmParser(*Tgt, sourceMgr,
                                                         context, *streamer,
                                                         *AsmInfo));
  OwningPtr<TargetAsmParser> TargetParser(Tgt->createAsmParser(*genericParser,
                                                               *TargetMachine));
  
  AsmToken OpcodeToken = genericParser->Lex();
  AsmToken NextToken = genericParser->Lex();  // consume next token, because specificParser expects us to
    
  if (OpcodeToken.is(AsmToken::Identifier)) {
    instName = OpcodeToken.getString();
    instLoc = OpcodeToken.getLoc();
    
    if (NextToken.isNot(AsmToken::Eof) &&
        TargetParser->ParseInstruction(instName, instLoc, operands))
      ret = -1;
  } else {
    ret = -1;
  }
  
  ParserMutex.acquire();
  
  if (!ret) {
    GenericAsmLexer->setBuffer(buf);
  
    while (SpecificAsmLexer->Lex(),
           SpecificAsmLexer->isNot(AsmToken::Eof) &&
           SpecificAsmLexer->isNot(AsmToken::EndOfStatement)) {
      if (SpecificAsmLexer->is(AsmToken::Error)) {
        ret = -1;
        break;
      }
      tokens.push_back(SpecificAsmLexer->getTok());
    }
  }

  ParserMutex.release();
  
  return ret;
}
Exemplo n.º 11
0
static bool ExecuteAssembler(AssemblerInvocation &Opts,
                             DiagnosticsEngine &Diags) {
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error));
  if (!TheTarget) {
    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
    return false;
  }

  OwningPtr<MemoryBuffer> BufferPtr;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, BufferPtr)) {
    Error = ec.message();
    Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
    return false;
  }
  MemoryBuffer *Buffer = BufferPtr.take();

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(Opts.IncludePaths);

  OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
  assert(MRI && "Unable to create target register info!");

  OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
  assert(MAI && "Unable to create target asm info!");

  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
  formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary);
  if (!Out)
    return false;

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
  // FIXME: Assembler behavior can change with -static.
  MOFI->InitMCObjectFileInfo(Opts.Triple,
                             Reloc::Default, CodeModel::Default, Ctx);
  if (Opts.SaveTemporaryLabels)
    Ctx.setAllowTemporaryLabels(false);
  if (Opts.GenDwarfForAssembly)
    Ctx.setGenDwarfForAssembly(true);
  if (!Opts.DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
  if (!Opts.DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
  if (!Opts.DebugCompilationDir.empty())
    Ctx.setCompilationDir(Opts.DebugCompilationDir);
  if (!Opts.MainFileName.empty())
    Ctx.setMainFileName(StringRef(Opts.MainFileName));

  // Build up the feature string from the target feature list.
  std::string FS;
  if (!Opts.Features.empty()) {
    FS = Opts.Features[0];
    for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
      FS += "," + Opts.Features[i];
  }

  OwningPtr<MCStreamer> Str;

  OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  OwningPtr<MCSubtargetInfo>
    STI(TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));

  // FIXME: There is a bit of code duplication with addPassesToEmitFile.
  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
    MCInstPrinter *IP =
      TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI,
                                     *STI);
    MCCodeEmitter *CE = 0;
    MCAsmBackend *MAB = 0;
    if (Opts.ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
      MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
    }
    Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
                                           /*useLoc*/ true,
                                           /*useCFI*/ true,
                                           /*useDwarfDirectory*/ true,
                                           IP, CE, MAB,
                                           Opts.ShowInst));
  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
           "Invalid file type!");
    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
                                                      Opts.CPU);
    Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
                                                CE, Opts.RelaxAll,
                                                Opts.NoExecStack));
    Str.get()->InitSections();
  }

  OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
                                                  *Str.get(), *MAI));
  OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser));
  if (!TAP) {
    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
    return false;
  }

  Parser->setTargetParser(*TAP.get());

  bool Success = !Parser->Run(Opts.NoInitialTextSection);

  // Close the output.
  delete Out;

  // Delete output on errors.
  if (!Success && Opts.OutputPath != "-")
    sys::fs::remove(Opts.OutputPath);

  return Success;
}
Exemplo n.º 12
0
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
                               InlineAsm::AsmDialect Dialect) const {
  assert(!Str.empty() && "Can't emit empty inline asm block");

  // Remember if the buffer is nul terminated or not so we can avoid a copy.
  bool isNullTerminated = Str.back() == 0;
  if (isNullTerminated)
    Str = Str.substr(0, Str.size()-1);

  // If the output streamer is actually a .s file, just emit the blob textually.
  // This is useful in case the asm parser doesn't handle something but the
  // system assembler does.
  if (OutStreamer.hasRawTextSupport()) {
    OutStreamer.EmitRawText(Str);
    return;
  }

  SourceMgr SrcMgr;
  SrcMgrDiagInfo DiagInfo;

  // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
  LLVMContext &LLVMCtx = MMI->getModule()->getContext();
  bool HasDiagHandler = false;
  if (LLVMCtx.getInlineAsmDiagnosticHandler() != 0) {
    // If the source manager has an issue, we arrange for srcMgrDiagHandler
    // to be invoked, getting DiagInfo passed into it.
    DiagInfo.LocInfo = LocMDNode;
    DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
    DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
    SrcMgr.setDiagHandler(srcMgrDiagHandler, &DiagInfo);
    HasDiagHandler = true;
  }

  MemoryBuffer *Buffer;
  if (isNullTerminated)
    Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
  else
    Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");

  // Tell SrcMgr about this buffer, it takes ownership of the buffer.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

  OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr,
                                                  OutContext, OutStreamer,
                                                  *MAI));

  // FIXME: It would be nice if we can avoid createing a new instance of
  // MCSubtargetInfo here given TargetSubtargetInfo is available. However,
  // we have to watch out for asm directives which can change subtarget
  // state. e.g. .code 16, .code 32.
  OwningPtr<MCSubtargetInfo>
    STI(TM.getTarget().createMCSubtargetInfo(TM.getTargetTriple(),
                                             TM.getTargetCPU(),
                                             TM.getTargetFeatureString()));
  OwningPtr<MCTargetAsmParser>
    TAP(TM.getTarget().createMCAsmParser(*STI, *Parser, *MII));
  if (!TAP)
    report_fatal_error("Inline asm not supported by this streamer because"
                       " we don't have an asm parser for this target\n");
  Parser->setAssemblerDialect(Dialect);
  Parser->setTargetParser(*TAP.get());

  // Don't implicitly switch to the text section before the asm.
  int Res = Parser->Run(/*NoInitialTextSection*/ true,
                        /*NoFinalize*/ true);
  if (Res && !HasDiagHandler)
    report_fatal_error("Error parsing inline asm\n");
}
Exemplo n.º 13
0
static bool ExecuteAssembler(AssemblerInvocation &Opts,
                             DiagnosticsEngine &Diags) {
  // Get the target specific parser.
  std::string Error;
  const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
  if (!TheTarget)
    return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
      MemoryBuffer::getFileOrSTDIN(Opts.InputFile);

  if (std::error_code EC = Buffer.getError()) {
    Error = EC.message();
    return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
  }

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());

  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(Opts.IncludePaths);

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
  assert(MAI && "Unable to create target asm info!");

  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
  // may be created with a combination of default and explicit settings.
  if (Opts.CompressDebugSections)
    MAI->setCompressDebugSections(true);

  bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
  std::unique_ptr<formatted_raw_ostream> Out(
      GetOutputStream(Opts, Diags, IsBinary));
  if (!Out)
    return true;

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());

  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
  // FIXME: Assembler behavior can change with -static.
  MOFI->InitMCObjectFileInfo(Opts.Triple,
                             Reloc::Default, CodeModel::Default, Ctx);
  if (Opts.SaveTemporaryLabels)
    Ctx.setAllowTemporaryLabels(false);
  if (Opts.GenDwarfForAssembly)
    Ctx.setGenDwarfForAssembly(true);
  if (!Opts.DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
  if (!Opts.DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
  if (!Opts.DebugCompilationDir.empty())
    Ctx.setCompilationDir(Opts.DebugCompilationDir);
  if (!Opts.MainFileName.empty())
    Ctx.setMainFileName(StringRef(Opts.MainFileName));
  Ctx.setDwarfVersion(Opts.DwarfVersion);

  // Build up the feature string from the target feature list.
  std::string FS;
  if (!Opts.Features.empty()) {
    FS = Opts.Features[0];
    for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
      FS += "," + Opts.Features[i];
  }

  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));

  // FIXME: There is a bit of code duplication with addPassesToEmitFile.
  if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
    MCInstPrinter *IP =
      TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI,
                                     *STI);
    MCCodeEmitter *CE = nullptr;
    MCAsmBackend *MAB = nullptr;
    if (Opts.ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
      MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
    }
    Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
                                           /*useDwarfDirectory*/ true,
                                           IP, CE, MAB,
                                           Opts.ShowInst));
  } else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
           "Invalid file type!");
    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
                                                      Opts.CPU);
    Triple T(Opts.Triple);
    Str.reset(TheTarget->createMCObjectStreamer(T, Ctx, *MAB, *Out, CE, *STI,
                                                Opts.RelaxAll,
                                                /*DWARFMustBeAtTheEnd*/ true));
    Str.get()->InitSections(Opts.NoExecStack);
  }

  bool Failed = false;

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));

  // FIXME: init MCTargetOptions from sanitizer flags here.
  MCTargetOptions Options;
  std::unique_ptr<MCTargetAsmParser> TAP(
      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
  if (!TAP)
    Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;

  if (!Failed) {
    Parser->setTargetParser(*TAP.get());
    Failed = Parser->Run(Opts.NoInitialTextSection);
  }

  // Close the output stream early.
  Out.reset();

  // Delete output file if there were errors.
  if (Failed && Opts.OutputPath != "-")
    sys::fs::remove(Opts.OutputPath);

  return Failed;
}
Exemplo n.º 14
0
// Parse inline ASM and collect the list of symbols that are not defined in
// the current module. This is inspired from IRObjectFile.
void IRObjectFile::CollectAsmUndefinedRefs(
    const Triple &TT, StringRef InlineAsm,
    function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmUndefinedRefs) {
  if (InlineAsm.empty())
    return;

  std::string Err;
  const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
  assert(T && T->hasMCAsmParser());

  std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(TT.str()));
  if (!MRI)
    return;

  std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str()));
  if (!MAI)
    return;

  std::unique_ptr<MCSubtargetInfo> STI(
      T->createMCSubtargetInfo(TT.str(), "", ""));
  if (!STI)
    return;

  std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo());
  if (!MCII)
    return;

  MCObjectFileInfo MOFI;
  MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
  MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx);
  RecordStreamer Streamer(MCCtx);
  T->createNullTargetStreamer(Streamer);

  std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
  SourceMgr SrcMgr;
  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));

  MCTargetOptions MCOptions;
  std::unique_ptr<MCTargetAsmParser> TAP(
      T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
  if (!TAP)
    return;

  Parser->setTargetParser(*TAP);
  if (Parser->Run(false))
    return;

  for (auto &KV : Streamer) {
    StringRef Key = KV.first();
    RecordStreamer::State Value = KV.second;
    uint32_t Res = BasicSymbolRef::SF_None;
    switch (Value) {
    case RecordStreamer::NeverSeen:
      llvm_unreachable("NeverSeen should have been replaced earlier");
    case RecordStreamer::DefinedGlobal:
      Res |= BasicSymbolRef::SF_Global;
      break;
    case RecordStreamer::Defined:
      break;
    case RecordStreamer::Global:
    case RecordStreamer::Used:
      Res |= BasicSymbolRef::SF_Undefined;
      Res |= BasicSymbolRef::SF_Global;
      break;
    case RecordStreamer::DefinedWeak:
      Res |= BasicSymbolRef::SF_Weak;
      Res |= BasicSymbolRef::SF_Global;
      break;
    case RecordStreamer::UndefinedWeak:
      Res |= BasicSymbolRef::SF_Weak;
      Res |= BasicSymbolRef::SF_Undefined;
    }
    AsmUndefinedRefs(Key, BasicSymbolRef::Flags(Res));
  }
}
Exemplo n.º 15
0
static int AsLexInput(const char *ProgName) {
  std::string ErrorMessage;
  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename,
                                                      &ErrorMessage);
  if (Buffer == 0) {
    errs() << ProgName << ": ";
    if (ErrorMessage.size())
      errs() << ErrorMessage << "\n";
    else
      errs() << "input file didn't read correctly.\n";
    return 1;
  }

  SourceMgr SrcMgr;
  
  // Tell SrcMgr about this buffer, which is what TGParser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
  
  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(IncludeDirs);

  const Target *TheTarget = GetTarget(ProgName);
  if (!TheTarget)
    return 1;

  llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(TripleName));
  assert(MAI && "Unable to create target asm info!");

  AsmLexer Lexer(*MAI);
  Lexer.setBuffer(SrcMgr.getMemoryBuffer(0));

  bool Error = false;
  while (Lexer.Lex().isNot(AsmToken::Eof)) {
    switch (Lexer.getKind()) {
    default:
      SrcMgr.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
      Error = true;
      break;
    case AsmToken::Error:
      Error = true; // error already printed.
      break;
    case AsmToken::Identifier:
      outs() << "identifier: " << Lexer.getTok().getString() << '\n';
      break;
    case AsmToken::String:
      outs() << "string: " << Lexer.getTok().getString() << '\n';
      break;
    case AsmToken::Integer:
      outs() << "int: " << Lexer.getTok().getString() << '\n';
      break;

    case AsmToken::Amp:            outs() << "Amp\n"; break;
    case AsmToken::AmpAmp:         outs() << "AmpAmp\n"; break;
    case AsmToken::Caret:          outs() << "Caret\n"; break;
    case AsmToken::Colon:          outs() << "Colon\n"; break;
    case AsmToken::Comma:          outs() << "Comma\n"; break;
    case AsmToken::Dollar:         outs() << "Dollar\n"; break;
    case AsmToken::EndOfStatement: outs() << "EndOfStatement\n"; break;
    case AsmToken::Eof:            outs() << "Eof\n"; break;
    case AsmToken::Equal:          outs() << "Equal\n"; break;
    case AsmToken::EqualEqual:     outs() << "EqualEqual\n"; break;
    case AsmToken::Exclaim:        outs() << "Exclaim\n"; break;
    case AsmToken::ExclaimEqual:   outs() << "ExclaimEqual\n"; break;
    case AsmToken::Greater:        outs() << "Greater\n"; break;
    case AsmToken::GreaterEqual:   outs() << "GreaterEqual\n"; break;
    case AsmToken::GreaterGreater: outs() << "GreaterGreater\n"; break;
    case AsmToken::LParen:         outs() << "LParen\n"; break;
    case AsmToken::Less:           outs() << "Less\n"; break;
    case AsmToken::LessEqual:      outs() << "LessEqual\n"; break;
    case AsmToken::LessGreater:    outs() << "LessGreater\n"; break;
    case AsmToken::LessLess:       outs() << "LessLess\n"; break;
    case AsmToken::Minus:          outs() << "Minus\n"; break;
    case AsmToken::Percent:        outs() << "Percent\n"; break;
    case AsmToken::Pipe:           outs() << "Pipe\n"; break;
    case AsmToken::PipePipe:       outs() << "PipePipe\n"; break;
    case AsmToken::Plus:           outs() << "Plus\n"; break;
    case AsmToken::RParen:         outs() << "RParen\n"; break;
    case AsmToken::Slash:          outs() << "Slash\n"; break;
    case AsmToken::Star:           outs() << "Star\n"; break;
    case AsmToken::Tilde:          outs() << "Tilde\n"; break;
    }
  }
  
  return Error;
}
Exemplo n.º 16
0
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal(argv[0]);
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets and assembly printers/parsers.
  llvm::InitializeAllTargetInfos();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmParsers();
  llvm::InitializeAllDisassemblers();

  // Register the target printer for --version.
  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

  cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n");
  MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags();
  TripleName = Triple::normalize(TripleName);
  setDwarfDebugFlags(argc, argv);

  setDwarfDebugProducer();

  const char *ProgName = argv[0];
  const Target *TheTarget = GetTarget(ProgName);
  if (!TheTarget)
    return 1;
  // Now that GetTarget() has (potentially) replaced TripleName, it's safe to
  // construct the Triple object.
  Triple TheTriple(TripleName);

  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr =
      MemoryBuffer::getFileOrSTDIN(InputFilename);
  if (std::error_code EC = BufferPtr.getError()) {
    errs() << InputFilename << ": " << EC.message() << '\n';
    return 1;
  }
  MemoryBuffer *Buffer = BufferPtr->get();

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(*BufferPtr), SMLoc());

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

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  assert(MRI && "Unable to create target register info!");

  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
  assert(MAI && "Unable to create target asm info!");

  MAI->setRelaxELFRelocations(RelaxELFRel);

  if (CompressDebugSections != DebugCompressionType::None) {
    if (!zlib::isAvailable()) {
      errs() << ProgName
             << ": build tools with zlib to enable -compress-debug-sections";
      return 1;
    }
    MAI->setCompressDebugSections(CompressDebugSections);
  }
  MAI->setPreserveAsmComments(PreserveComments);

  // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
  // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
  MCObjectFileInfo MOFI;
  MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr);
  MOFI.InitMCObjectFileInfo(TheTriple, PIC, CMModel, Ctx);

  if (SaveTempLabels)
    Ctx.setAllowTemporaryLabels(false);

  Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
  // Default to 4 for dwarf version.
  unsigned DwarfVersion = MCOptions.DwarfVersion ? MCOptions.DwarfVersion : 4;
  if (DwarfVersion < 2 || DwarfVersion > 5) {
    errs() << ProgName << ": Dwarf version " << DwarfVersion
           << " is not supported." << '\n';
    return 1;
  }
  Ctx.setDwarfVersion(DwarfVersion);
  if (!DwarfDebugFlags.empty())
    Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags));
  if (!DwarfDebugProducer.empty())
    Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer));
  if (!DebugCompilationDir.empty())
    Ctx.setCompilationDir(DebugCompilationDir);
  else {
    // If no compilation dir is set, try to use the current directory.
    SmallString<128> CWD;
    if (!sys::fs::current_path(CWD))
      Ctx.setCompilationDir(CWD);
  }
  if (!MainFileName.empty())
    Ctx.setMainFileName(MainFileName);

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MAttrs.size()) {
    SubtargetFeatures Features;
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  std::unique_ptr<tool_output_file> Out = GetOutputStream();
  if (!Out)
    return 1;

  std::unique_ptr<buffer_ostream> BOS;
  raw_pwrite_stream *OS = &Out->os();
  std::unique_ptr<MCStreamer> Str;

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));

  MCInstPrinter *IP = nullptr;
  if (FileType == OFT_AssemblyFile) {
    IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant,
                                        *MAI, *MCII, *MRI);

    if (!IP) {
      errs()
          << "error: unable to create instruction printer for target triple '"
          << TheTriple.normalize() << "' with assembly variant "
          << OutputAsmVariant << ".\n";
      return 1;
    }

    // Set the display preference for hex vs. decimal immediates.
    IP->setPrintImmHex(PrintImmHex);

    // Set up the AsmStreamer.
    MCCodeEmitter *CE = nullptr;
    MCAsmBackend *MAB = nullptr;
    if (ShowEncoding) {
      CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
      MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU, MCOptions);
    }
    auto FOut = llvm::make_unique<formatted_raw_ostream>(*OS);
    Str.reset(TheTarget->createAsmStreamer(
        Ctx, std::move(FOut), /*asmverbose*/ true,
        /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst));

  } else if (FileType == OFT_Null) {
    Str.reset(TheTarget->createNullStreamer(Ctx));
  } else {
    assert(FileType == OFT_ObjectFile && "Invalid file type!");

    // Don't waste memory on names of temp labels.
    Ctx.setUseNamesOnTempLabels(false);

    if (!Out->os().supportsSeeking()) {
      BOS = make_unique<buffer_ostream>(Out->os());
      OS = BOS.get();
    }

    MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
    MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU,
                                                      MCOptions);
    Str.reset(TheTarget->createMCObjectStreamer(
        TheTriple, Ctx, *MAB, *OS, CE, *STI, MCOptions.MCRelaxAll,
        MCOptions.MCIncrementalLinkerCompatible,
        /*DWARFMustBeAtTheEnd*/ false));
    if (NoExecStack)
      Str->InitSections(true);
  }

  int Res = 1;
  bool disassemble = false;
  switch (Action) {
  case AC_AsLex:
    Res = AsLexInput(SrcMgr, *MAI, Out->os());
    break;
  case AC_Assemble:
    Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI,
                        *MCII, MCOptions);
    break;
  case AC_MDisassemble:
    assert(IP && "Expected assembly output");
    IP->setUseMarkup(1);
    disassemble = true;
    break;
  case AC_Disassemble:
    disassemble = true;
    break;
  }
  if (disassemble)
    Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
                                    *Buffer, SrcMgr, Out->os());

  // Keep output if no errors.
  if (Res == 0) Out->keep();
  return Res;
}
Exemplo n.º 17
0
static int AssembleInput(const char *ProgName) {
  const Target *TheTarget = GetTarget(ProgName);
  if (!TheTarget)
    return 1;

  std::string Error;
  MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &Error);
  if (Buffer == 0) {
    errs() << ProgName << ": ";
    if (Error.size())
      errs() << Error << "\n";
    else
      errs() << "input file didn't read correctly.\n";
    return 1;
  }
  
  SourceMgr SrcMgr;
  
  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
  
  // Record the location of the include directories so that the lexer can find
  // it later.
  SrcMgr.setIncludeDirs(IncludeDirs);
  
  
  llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createAsmInfo(TripleName));
  assert(MAI && "Unable to create target asm info!");
  
  MCContext Ctx(*MAI);
  formatted_raw_ostream *Out = GetOutputStream();
  if (!Out)
    return 1;


  // FIXME: We shouldn't need to do this (and link in codegen).
  OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName, ""));

  if (!TM) {
    errs() << ProgName << ": error: could not create target for triple '"
           << TripleName << "'.\n";
    return 1;
  }

  OwningPtr<MCCodeEmitter> CE;
  OwningPtr<MCStreamer> Str;
  OwningPtr<TargetAsmBackend> TAB;

  if (FileType == OFT_AssemblyFile) {
    MCInstPrinter *IP =
      TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI);
    if (ShowEncoding)
      CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
    Str.reset(createAsmStreamer(Ctx, *Out,TM->getTargetData()->isLittleEndian(),
                                /*asmverbose*/true, IP, CE.get(), ShowInst));
  } else if (FileType == OFT_Null) {
    Str.reset(createNullStreamer(Ctx));
  } else {
    assert(FileType == OFT_ObjectFile && "Invalid file type!");
    CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
    TAB.reset(TheTarget->createAsmBackend(TripleName));
    Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
                                              *Out, CE.get(), RelaxAll));
  }

  if (EnableLogging) {
    Str.reset(createLoggingStreamer(Str.take(), errs()));
  }

  OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx,
                                                   *Str.get(), *MAI));
  OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*Parser, *TM));
  if (!TAP) {
    errs() << ProgName 
           << ": error: this target does not support assembly parsing.\n";
    return 1;
  }

  Parser->setTargetParser(*TAP.get());

  int Res = Parser->Run(NoInitialTextSection);
  delete Out;

  // Delete output on errors.
  if (Res && OutputFilename != "-")
    sys::Path(OutputFilename).eraseFromDisk();

  return Res;
}
Exemplo n.º 18
0
static bool ParseFile(const std::string &Filename,
                      const std::vector<std::string> &IncludeDirs,
                      SmallVectorImpl<std::string> &OutputFiles) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
      MemoryBuffer::getFileOrSTDIN(Filename);
  if (std::error_code EC = MBOrErr.getError()) {
    llvm::errs() << "Could not open input file '" << Filename << "': " 
                 << EC.message() <<"\n";
    return true;
  }
  std::unique_ptr<llvm::MemoryBuffer> MB = std::move(MBOrErr.get());

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

  // Tell SrcMgr about this buffer, which is what Parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(MB), llvm::SMLoc());

  LangOptions Opts;
  Opts.DefaultReal8 = DefaultReal8;
  Opts.DefaultDouble8 = DefaultDouble8;
  Opts.DefaultInt8 = DefaultInt8;
  Opts.ReturnComments = ReturnComments;
  if(!FreeForm && !FixedForm) {
    llvm::StringRef Ext = llvm::sys::path::extension(Filename);
    if(Ext.equals_lower(".f")) {
      Opts.FixedForm = 1;
      Opts.FreeForm = 0;
    }
  } else if(FixedForm) {
    Opts.FixedForm = 1;
    Opts.FreeForm = 0;
  }

  TextDiagnosticPrinter TDP(SrcMgr);
  DiagnosticsEngine Diag(new DiagnosticIDs,&SrcMgr, &TDP, false);
  // Chain in -verify checker, if requested.
  if(RunVerifier)
    Diag.setClient(new VerifyDiagnosticConsumer(Diag));

  ASTContext Context(SrcMgr, Opts);
  Sema SA(Context, Diag);
  Parser P(SrcMgr, Opts, Diag, SA);
  Diag.getClient()->BeginSourceFile(Opts, &P.getLexer());
  P.ParseProgramUnits();
  Diag.getClient()->EndSourceFile();

  // Dump
  if(PrintAST || DumpAST) {
    auto Dumper = CreateASTDumper("");
    Dumper->HandleTranslationUnit(Context);
    delete Dumper;
  }

  // Emit
  if(!SyntaxOnly && !Diag.hadErrors()) {    
    flang::TargetOptions TargetOptions;
    TargetOptions.Triple = TargetTriple.empty()? llvm::sys::getDefaultTargetTriple() :
                                                 TargetTriple;
    TargetOptions.CPU = llvm::sys::getHostCPUName();

    auto CG = CreateLLVMCodeGen(Diag, Filename == ""? std::string("module") : Filename,
                                CodeGenOptions(), TargetOptions, llvm::getGlobalContext());
    CG->Initialize(Context);
    CG->HandleTranslationUnit(Context);

    BackendAction BA = Backend_EmitObj;
    if(EmitASM)   BA = Backend_EmitAssembly;
    if(EmitLLVM)  BA = Backend_EmitLL;

    const llvm::Target *TheTarget = 0;
    std::string Err;
    TheTarget = llvm::TargetRegistry::lookupTarget(TargetOptions.Triple, Err);

    CodeGenOpt::Level TMOptLevel = CodeGenOpt::Default;
    switch(OptLevel) {
    case 0:  TMOptLevel = CodeGenOpt::None; break;
    case 3:  TMOptLevel = CodeGenOpt::Aggressive; break;
    }

    llvm::TargetOptions Options;

    auto TM = TheTarget->createTargetMachine(TargetOptions.Triple, TargetOptions.CPU, "", Options,
                                             Reloc::Default, CodeModel::Default,
                                             TMOptLevel);

    if(!(EmitLLVM && OptLevel == 0)) {
      auto TheModule = CG->GetModule();
      auto PM = new llvm::legacy::PassManager();
      //llvm::legacy::FunctionPassManager *FPM = new llvm::legacy::FunctionPassManager(TheModule);
      //FPM->add(new DataLayoutPass());
      //PM->add(new llvm::DataLayoutPass());
      //TM->addAnalysisPasses(*PM);
      PM->add(createPromoteMemoryToRegisterPass());

      PassManagerBuilder PMBuilder;
      PMBuilder.OptLevel = OptLevel;
      PMBuilder.SizeLevel = 0;
      PMBuilder.LoopVectorize = true;
      PMBuilder.SLPVectorize = true;
      unsigned Threshold = 225;
      if (OptLevel > 2)
        Threshold = 275;
      PMBuilder.Inliner = createFunctionInliningPass(Threshold);


      PMBuilder.populateModulePassManager(*PM);
      //llvm::legacy::PassManager *MPM = new llvm::legacy::PassManager();
      //PMBuilder.populateModulePassManager(*MPM);

      PM->run(*TheModule);
      //MPM->run(*TheModule);
      delete PM;
      //delete MPM;
    }

    if(Interpret) {
      //const char *Env[] = { "", nullptr };
      //Execute(CG->ReleaseModule(), Env);
    } else if(OutputFile == "-"){
      // FIXME: outputting to stdout is broken 
      //EmitFile(llvm::outs(), CG->GetModule(), TM, BA);
      OutputFiles.push_back(GetOutputName("stdout",BA));
      EmitOutputFile(OutputFiles.back(), CG->GetModule(), TM, BA);
    }else {
      OutputFiles.push_back(GetOutputName(Filename, BA));
      EmitOutputFile(OutputFiles.back(), CG->GetModule(), TM, BA);
    }
    delete CG;
  }

  return Diag.hadErrors();
}
Exemplo n.º 19
0
static void parseMCMarkup(StringRef Filename) {
  OwningPtr<MemoryBuffer> BufferPtr;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, BufferPtr)) {
    errs() << ToolName << ": " << ec.message() << '\n';
    return;
  }
  MemoryBuffer *Buffer = BufferPtr.take();

  SourceMgr SrcMgr;

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());

  StringRef InputSource = Buffer->getBuffer();
  MarkupLexer Lex(InputSource);
  MarkupParser Parser(Lex, SrcMgr);

  SmallVector<MarkupTag, 4> TagStack;

  for (int CurChar = Lex.getNextChar();
       CurChar != EOF;
       CurChar = Lex.getNextChar()) {
    switch (CurChar) {
    case '<': {
      // A "<<" is output as a literal '<' and does not start a markup tag.
      if (Lex.peekNextChar() == '<') {
        (void)Lex.getNextChar();
        break;
      }
      // Parse the markup entry.
      TagStack.push_back(Parser.parseTag());

      // Do any special handling for the start of a tag.
      processStartTag(TagStack.back());
      continue;
    }
    case '>': {
      SMLoc Loc = SMLoc::getFromPointer(Lex.getPosition() - 1);
      // A ">>" is output as a literal '>' and does not end a markup tag.
      if (Lex.peekNextChar() == '>') {
        (void)Lex.getNextChar();
        break;
      }
      // Close out the innermost tag.
      if (TagStack.empty())
        Parser.FatalError(Loc, "'>' without matching '<'");

      // Do any special handling for the end of a tag.
      processEndTag(TagStack.back());

      TagStack.pop_back();
      continue;
    }
    default:
      break;
    }
    // For anything else, just echo the character back out.
    if (!DumpTags && CurChar != EOF)
      outs() << (char)CurChar;
  }

  // If there are any unterminated markup tags, issue diagnostics for them.
  while (!TagStack.empty()) {
    MarkupTag &Tag = TagStack.back();
    SrcMgr.PrintMessage(Tag.getLoc(), SourceMgr::DK_Error,
                        "unterminated markup tag");
    TagStack.pop_back();
  }
}
Exemplo n.º 20
0
void jl_dump_function_asm(void* Fptr, size_t Fsize,
                          std::vector<JITEvent_EmittedFunctionDetails::LineStart> lineinfo,
                          formatted_raw_ostream &stream) {

    // Initialize targets and assembly printers/parsers.
    // Avoids hard-coded targets - will generally be only host CPU anyway.
    llvm::InitializeNativeTargetAsmParser();
    llvm::InitializeNativeTargetDisassembler();
  
    // Get the host information
    std::string TripleName;
    if (TripleName.empty())
        TripleName = sys::getDefaultTargetTriple();
    Triple TheTriple(Triple::normalize(TripleName));

    std::string MCPU = sys::getHostCPUName();
    SubtargetFeatures Features;
    Features.getDefaultSubtargetFeatures(TheTriple);

    std::string err;
    const Target* TheTarget = TargetRegistry::lookupTarget(TripleName, err);

    // Set up required helpers and streamer 
    OwningPtr<MCStreamer> Streamer;
    SourceMgr SrcMgr;

#ifdef LLVM34
    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TripleName),TripleName));
#else
    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TripleName));
#endif
    assert(MAI && "Unable to create target asm info!");

    llvm::OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
    assert(MRI && "Unable to create target register info!");

    OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
#ifdef LLVM34
    MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
#else
    MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
#endif    
    MOFI->InitMCObjectFileInfo(TripleName, Reloc::Default, CodeModel::Default, Ctx);

    // Set up Subtarget and Disassembler
    OwningPtr<MCSubtargetInfo>
        STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
#ifdef LLVM35
    OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI, Ctx));
#else
    OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
#endif
    if (!DisAsm) {
        JL_PRINTF(JL_STDERR, "error: no disassembler for target", TripleName.c_str(), "\n");
        return;
    }

    unsigned OutputAsmVariant = 1;
    bool ShowEncoding = false;
    bool ShowInst = false;

    OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
    MCInstPrinter* IP =
        TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
    MCCodeEmitter *CE = 0;
    MCAsmBackend *MAB = 0;
    if (ShowEncoding) {
        CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
#ifdef LLVM34
        MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
#else
        MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
#endif
    }

    Streamer.reset(TheTarget->createAsmStreamer(Ctx, stream, /*asmverbose*/true,
#ifndef LLVM35
                                           /*useLoc*/ true,
                                           /*useCFI*/ true,
#endif
                                           /*useDwarfDirectory*/ true,
                                           IP, CE, MAB, ShowInst));
    Streamer->InitSections();
    // Make the MemoryObject wrapper
    FuncMCView memoryObject(Fptr, Fsize);
  
    uint64_t Size;
    uint64_t Index;
    uint64_t absAddr;

    // Set up the line info
    typedef std::vector<JITEvent_EmittedFunctionDetails::LineStart> LInfoVec;
    LInfoVec::iterator lineIter = lineinfo.begin();
    lineIter = lineinfo.begin();
    uint64_t nextLineAddr = -1;
    DISubprogram debugscope;

    if (lineIter != lineinfo.end()) {
        nextLineAddr = (*lineIter).Address;
        debugscope = DISubprogram((*lineIter).Loc.getScope(jl_LLVMContext));

        stream << "Filename: " << debugscope.getFilename().data() << "\n";
        stream << "Source line: " << (*lineIter).Loc.getLine() << "\n";
    }
    
    // Do the disassembly
    for (Index = 0, absAddr = (uint64_t)Fptr;
         Index < memoryObject.getExtent(); Index += Size, absAddr += Size) {
        
        if (nextLineAddr != (uint64_t)-1 && absAddr == nextLineAddr) {
            stream << "Source line: " << (*lineIter).Loc.getLine() << "\n";
            nextLineAddr = (*++lineIter).Address;
        }

        MCInst Inst;

        MCDisassembler::DecodeStatus S;
        S = DisAsm->getInstruction(Inst, Size, memoryObject, Index,
                                  /*REMOVE*/ nulls(), nulls());
        switch (S) {
        case MCDisassembler::Fail:
        SrcMgr.PrintMessage(SMLoc::getFromPointer(memoryObject[Index]),
                            SourceMgr::DK_Warning,
                            "invalid instruction encoding");
        if (Size == 0)
            Size = 1; // skip illegible bytes
        break;

        case MCDisassembler::SoftFail:
        SrcMgr.PrintMessage(SMLoc::getFromPointer(memoryObject[Index]),
                            SourceMgr::DK_Warning,
                            "potentially undefined instruction encoding");
        // Fall through

        case MCDisassembler::Success:
        #ifdef LLVM35
            Streamer->EmitInstruction(Inst, *STI);
        #else
            Streamer->EmitInstruction(Inst);
        #endif
        break;
        }
    }
}
Exemplo n.º 21
0
void PrintError(const char *Loc, const Twine &Msg) {
  SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
}
Exemplo n.º 22
0
int Disassembler::disassemble(const Target &T,
                              const std::string &Triple,
                              const std::string &Cpu,
                              const std::string &FeaturesStr,
                              MemoryBuffer &Buffer,
                              raw_ostream &Out) {
  // Set up disassembler.
  OwningPtr<const MCAsmInfo> AsmInfo(T.createMCAsmInfo(Triple));

  if (!AsmInfo) {
    errs() << "error: no assembly info for target " << Triple << "\n";
    return -1;
  }

  OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu,
                                                               FeaturesStr));
  if (!STI) {
    errs() << "error: no subtarget info for target " << Triple << "\n";
    return -1;
  }

  OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(*STI));
  if (!DisAsm) {
    errs() << "error: no disassembler for target " << Triple << "\n";
    return -1;
  }

  OwningPtr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple));
  if (!MRI) {
    errs() << "error: no register info for target " << Triple << "\n";
    return -1;
  }

  OwningPtr<const MCInstrInfo> MII(T.createMCInstrInfo());
  if (!MII) {
    errs() << "error: no instruction info for target " << Triple << "\n";
    return -1;
  }

  int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
  OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant, *AsmInfo,
                                                    *MII, *MRI, *STI));
  if (!IP) {
    errs() << "error: no instruction printer for target " << Triple << '\n';
    return -1;
  }

  bool ErrorOccurred = false;

  SourceMgr SM;
  SM.AddNewSourceBuffer(&Buffer, SMLoc());

  // Convert the input to a vector for disassembly.
  ByteArrayTy ByteArray;
  StringRef Str = Buffer.getBuffer();

  ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM);

  if (!ByteArray.empty())
    ErrorOccurred |= PrintInsts(*DisAsm, *IP, ByteArray, SM, Out);

  return ErrorOccurred;
}
Exemplo n.º 23
0
static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out) {

  AsmLexer Lexer(MAI);
  Lexer.setBuffer(SrcMgr.getMemoryBuffer(0));

  bool Error = false;
  while (Lexer.Lex().isNot(AsmToken::Eof)) {
    AsmToken Tok = Lexer.getTok();

    switch (Tok.getKind()) {
    default:
      SrcMgr.PrintMessage(Lexer.getLoc(), SourceMgr::DK_Warning,
                          "unknown token");
      Error = true;
      break;
    case AsmToken::Error:
      Error = true; // error already printed.
      break;
    case AsmToken::Identifier:
      Out->os() << "identifier: " << Lexer.getTok().getString();
      break;
    case AsmToken::Integer:
      Out->os() << "int: " << Lexer.getTok().getString();
      break;
    case AsmToken::Real:
      Out->os() << "real: " << Lexer.getTok().getString();
      break;
    case AsmToken::String:
      Out->os() << "string: " << Lexer.getTok().getString();
      break;

    case AsmToken::Amp:            Out->os() << "Amp"; break;
    case AsmToken::AmpAmp:         Out->os() << "AmpAmp"; break;
    case AsmToken::At:             Out->os() << "At"; break;
    case AsmToken::Caret:          Out->os() << "Caret"; break;
    case AsmToken::Colon:          Out->os() << "Colon"; break;
    case AsmToken::Comma:          Out->os() << "Comma"; break;
    case AsmToken::Dollar:         Out->os() << "Dollar"; break;
    case AsmToken::Dot:            Out->os() << "Dot"; break;
    case AsmToken::EndOfStatement: Out->os() << "EndOfStatement"; break;
    case AsmToken::Eof:            Out->os() << "Eof"; break;
    case AsmToken::Equal:          Out->os() << "Equal"; break;
    case AsmToken::EqualEqual:     Out->os() << "EqualEqual"; break;
    case AsmToken::Exclaim:        Out->os() << "Exclaim"; break;
    case AsmToken::ExclaimEqual:   Out->os() << "ExclaimEqual"; break;
    case AsmToken::Greater:        Out->os() << "Greater"; break;
    case AsmToken::GreaterEqual:   Out->os() << "GreaterEqual"; break;
    case AsmToken::GreaterGreater: Out->os() << "GreaterGreater"; break;
    case AsmToken::Hash:           Out->os() << "Hash"; break;
    case AsmToken::LBrac:          Out->os() << "LBrac"; break;
    case AsmToken::LCurly:         Out->os() << "LCurly"; break;
    case AsmToken::LParen:         Out->os() << "LParen"; break;
    case AsmToken::Less:           Out->os() << "Less"; break;
    case AsmToken::LessEqual:      Out->os() << "LessEqual"; break;
    case AsmToken::LessGreater:    Out->os() << "LessGreater"; break;
    case AsmToken::LessLess:       Out->os() << "LessLess"; break;
    case AsmToken::Minus:          Out->os() << "Minus"; break;
    case AsmToken::Percent:        Out->os() << "Percent"; break;
    case AsmToken::Pipe:           Out->os() << "Pipe"; break;
    case AsmToken::PipePipe:       Out->os() << "PipePipe"; break;
    case AsmToken::Plus:           Out->os() << "Plus"; break;
    case AsmToken::RBrac:          Out->os() << "RBrac"; break;
    case AsmToken::RCurly:         Out->os() << "RCurly"; break;
    case AsmToken::RParen:         Out->os() << "RParen"; break;
    case AsmToken::Slash:          Out->os() << "Slash"; break;
    case AsmToken::Star:           Out->os() << "Star"; break;
    case AsmToken::Tilde:          Out->os() << "Tilde"; break;
    }

    // Print the token string.
    Out->os() << " (\"";
    Out->os().write_escaped(Tok.getString());
    Out->os() << "\")\n";
  }

  return Error;
}
Exemplo n.º 24
0
int Disassembler::disassembleEnhanced(const std::string &TS,
                                      MemoryBuffer &Buffer,
                                      raw_ostream &Out) {
  ByteArrayTy ByteArray;
  StringRef Str = Buffer.getBuffer();
  SourceMgr SM;

  SM.AddNewSourceBuffer(&Buffer, SMLoc());

  if (ByteArrayFromString(ByteArray, Str, SM)) {
    return -1;
  }

  Triple T(TS);
  EDDisassembler::AssemblySyntax AS;

  switch (T.getArch()) {
  default:
    errs() << "error: no default assembly syntax for " << TS.c_str() << "\n";
    return -1;
  case Triple::arm:
  case Triple::thumb:
    AS = EDDisassembler::kEDAssemblySyntaxARMUAL;
    break;
  case Triple::x86:
  case Triple::x86_64:
    AS = EDDisassembler::kEDAssemblySyntaxX86ATT;
    break;
  }

  OwningPtr<EDDisassembler>
    disassembler(EDDisassembler::getDisassembler(TS.c_str(), AS));

  if (disassembler == 0) {
    errs() << "error: couldn't get disassembler for " << TS << '\n';
    return -1;
  }

  while (ByteArray.size()) {
    OwningPtr<EDInst>
      inst(disassembler->createInst(byteArrayReader, 0, &ByteArray));

    if (inst == 0) {
      errs() << "error: Didn't get an instruction\n";
      return -1;
    }

    ByteArray.erase (ByteArray.begin(), ByteArray.begin() + inst->byteSize());

    unsigned numTokens = inst->numTokens();
    if ((int)numTokens < 0) {
      errs() << "error: couldn't count the instruction's tokens\n";
      return -1;
    }

    for (unsigned tokenIndex = 0; tokenIndex != numTokens; ++tokenIndex) {
      EDToken *token;

      if (inst->getToken(token, tokenIndex)) {
        errs() << "error: Couldn't get token\n";
        return -1;
      }

      const char *buf;
      if (token->getString(buf)) {
        errs() << "error: Couldn't get string for token\n";
        return -1;
      }

      Out << '[';
      int operandIndex = token->operandID();

      if (operandIndex >= 0)
        Out << operandIndex << "-";

      switch (token->type()) {
      case EDToken::kTokenWhitespace: Out << "w"; break;
      case EDToken::kTokenPunctuation: Out << "p"; break;
      case EDToken::kTokenOpcode: Out << "o"; break;
      case EDToken::kTokenLiteral: Out << "l"; break;
      case EDToken::kTokenRegister: Out << "r"; break;
      }

      Out << ":" << buf;

      if (token->type() == EDToken::kTokenLiteral) {
        Out << "=";
        if (token->literalSign())
          Out << "-";
        uint64_t absoluteValue;
        if (token->literalAbsoluteValue(absoluteValue)) {
          errs() << "error: Couldn't get the value of a literal token\n";
          return -1;
        }
        Out << absoluteValue;
      } else if (token->type() == EDToken::kTokenRegister) {
        Out << "=";
        unsigned regID;
        if (token->registerID(regID)) {
          errs() << "error: Couldn't get the ID of a register token\n";
          return -1;
        }
        Out << "r" << regID;
      }

      Out << "]";
    }

    Out << " ";

    if (inst->isBranch())
      Out << "<br> ";
    if (inst->isMove())
      Out << "<mov> ";

    unsigned numOperands = inst->numOperands();

    if ((int)numOperands < 0) {
      errs() << "error: Couldn't count operands\n";
      return -1;
    }

    for (unsigned operandIndex = 0; operandIndex != numOperands;
         ++operandIndex) {
      Out << operandIndex << ":";

      EDOperand *operand;
      if (inst->getOperand(operand, operandIndex)) {
        errs() << "error: couldn't get operand\n";
        return -1;
      }

      uint64_t evaluatedResult;
      void *Arg[] = { disassembler.get(), &Out };
      if (operand->evaluate(evaluatedResult, verboseEvaluator, Arg)) {
        errs() << "error: Couldn't evaluate an operand\n";
        return -1;
      }
      Out << "=" << evaluatedResult << " ";
    }

    Out << '\n';
  }

  return 0;
}
Exemplo n.º 25
0
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
                               const MDNode *LocMDNode,
                               InlineAsm::AsmDialect Dialect) const {
  assert(!Str.empty() && "Can't emit empty inline asm block");

  // Remember if the buffer is nul terminated or not so we can avoid a copy.
  bool isNullTerminated = Str.back() == 0;
  if (isNullTerminated)
    Str = Str.substr(0, Str.size()-1);

  // If the output streamer does not have mature MC support or the integrated
  // assembler has been disabled, just emit the blob textually.
  // Otherwise parse the asm and emit it via MC support.
  // This is useful in case the asm parser doesn't handle something but the
  // system assembler does.
  const MCAsmInfo *MCAI = TM.getMCAsmInfo();
  assert(MCAI && "No MCAsmInfo");
  if (!MCAI->useIntegratedAssembler() &&
      !OutStreamer->isIntegratedAssemblerRequired()) {
    emitInlineAsmStart();
    OutStreamer->EmitRawText(Str);
    emitInlineAsmEnd(STI, nullptr);
    return;
  }

  SourceMgr SrcMgr;
  SrcMgrDiagInfo DiagInfo;

  // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
  LLVMContext &LLVMCtx = MMI->getModule()->getContext();
  bool HasDiagHandler = false;
  if (LLVMCtx.getInlineAsmDiagnosticHandler() != nullptr) {
    // If the source manager has an issue, we arrange for srcMgrDiagHandler
    // to be invoked, getting DiagInfo passed into it.
    DiagInfo.LocInfo = LocMDNode;
    DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
    DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
    SrcMgr.setDiagHandler(srcMgrDiagHandler, &DiagInfo);
    HasDiagHandler = true;
  }

  std::unique_ptr<MemoryBuffer> Buffer;
  if (isNullTerminated)
    Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
  else
    Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");

  // Tell SrcMgr about this buffer, it takes ownership of the buffer.
  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());

  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI));

  // Create a temporary copy of the original STI because the parser may modify
  // it. For example, when switching between arm and thumb mode. If the target
  // needs to emit code to return to the original state it can do so in
  // emitInlineAsmEnd().
  MCSubtargetInfo TmpSTI = STI;

  // We create a new MCInstrInfo here since we might be at the module level
  // and not have a MachineFunction to initialize the TargetInstrInfo from and
  // we only need MCInstrInfo for asm parsing. We create one unconditionally
  // because it's not subtarget dependent.
  std::unique_ptr<MCInstrInfo> MII(TM.getTarget().createMCInstrInfo());
  std::unique_ptr<MCTargetAsmParser> TAP(TM.getTarget().createMCAsmParser(
      TmpSTI, *Parser, *MII, TM.Options.MCOptions));
  if (!TAP)
    report_fatal_error("Inline asm not supported by this streamer because"
                       " we don't have an asm parser for this target\n");
  Parser->setAssemblerDialect(Dialect);
  Parser->setTargetParser(*TAP.get());
  if (MF) {
    const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
    TAP->SetFrameRegister(TRI->getFrameRegister(*MF));
  }

  emitInlineAsmStart();
  // Don't implicitly switch to the text section before the asm.
  int Res = Parser->Run(/*NoInitialTextSection*/ true,
                        /*NoFinalize*/ true);
  emitInlineAsmEnd(STI, &TmpSTI);
  if (Res && !HasDiagHandler)
    report_fatal_error("Error parsing inline asm\n");
}
Exemplo n.º 26
0
bool
MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
                                         MachineFunction &MF) {
  // TODO: Recreate the machine function.
  initNames2RegClasses(MF);
  initNames2RegBanks(MF);
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);

  if (YamlMF.Legalized)
    MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
  if (YamlMF.RegBankSelected)
    MF.getProperties().set(
        MachineFunctionProperties::Property::RegBankSelected);
  if (YamlMF.Selected)
    MF.getProperties().set(MachineFunctionProperties::Property::Selected);

  PerFunctionMIParsingState PFS(MF, SM, IRSlots, Names2RegClasses,
                                Names2RegBanks);
  if (parseRegisterInfo(PFS, YamlMF))
    return true;
  if (!YamlMF.Constants.empty()) {
    auto *ConstantPool = MF.getConstantPool();
    assert(ConstantPool && "Constant pool must be created");
    if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
      return true;
  }

  StringRef BlockStr = YamlMF.Body.Value.Value;
  SMDiagnostic Error;
  SourceMgr BlockSM;
  BlockSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &BlockSM;
  if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  // Initialize the frame information after creating all the MBBs so that the
  // MBB references in the frame information can be resolved.
  if (initializeFrameInfo(PFS, YamlMF))
    return true;
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))
    return true;
  // Parse the machine instructions after creating all of the MBBs so that the
  // parser can resolve the MBB references.
  StringRef InsnStr = YamlMF.Body.Value.Value;
  SourceMgr InsnSM;
  InsnSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &InsnSM;
  if (parseMachineInstructions(PFS, InsnStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  if (setupRegisterInfo(PFS, YamlMF))
    return true;

  computeFunctionProperties(MF);

  MF.verify();
  return false;
}
Exemplo n.º 27
0
void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
                               const StringMap<StringRef> &VariableTable) const{
  // If this was a regular expression using variables, print the current
  // variable values.
  if (!VariableUses.empty()) {
    for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
      StringRef Var = VariableUses[i].first;
      StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
      SmallString<256> Msg;
      raw_svector_ostream OS(Msg);

      // Check for undefined variable references.
      if (it == VariableTable.end()) {
        OS << "uses undefined variable \"";
        OS.write_escaped(Var) << "\"";;
      } else {
        OS << "with variable \"";
        OS.write_escaped(Var) << "\" equal to \"";
        OS.write_escaped(it->second) << "\"";
      }

      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note",
                      /*ShowLine=*/false);
    }
  }

  // Attempt to find the closest/best fuzzy match.  Usually an error happens
  // because some string in the output didn't exactly match. In these cases, we
  // would like to show the user a best guess at what "should have" matched, to
  // save them having to actually check the input manually.
  size_t NumLinesForward = 0;
  size_t Best = StringRef::npos;
  double BestQuality = 0;

  // Use an arbitrary 4k limit on how far we will search.
  for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
    if (Buffer[i] == '\n')
      ++NumLinesForward;

    // Patterns have leading whitespace stripped, so skip whitespace when
    // looking for something which looks like a pattern.
    if (Buffer[i] == ' ' || Buffer[i] == '\t')
      continue;

    // Compute the "quality" of this match as an arbitrary combination of the
    // match distance and the number of lines skipped to get to this match.
    unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
    double Quality = Distance + (NumLinesForward / 100.);

    if (Quality < BestQuality || Best == StringRef::npos) {
      Best = i;
      BestQuality = Quality;
    }
  }

  // Print the "possible intended match here" line if we found something
  // reasonable and not equal to what we showed in the "scanning from here"
  // line.
  if (Best && Best != StringRef::npos && BestQuality < 50) {
      SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
                      "possible intended match here", "note");

    // FIXME: If we wanted to be really friendly we would show why the match
    // failed, as it can be hard to spot simple one character differences.
  }
}
Exemplo n.º 28
0
void jl_dump_function_asm(const char *Fptr, size_t Fsize,
#ifndef USE_MCJIT
                          std::vector<JITEvent_EmittedFunctionDetails::LineStart> lineinfo,
#else
                          object::ObjectFile *objectfile,
#endif
                          formatted_raw_ostream &stream)
{
    // Initialize targets and assembly printers/parsers.
    // Avoids hard-coded targets - will generally be only host CPU anyway.
    llvm::InitializeNativeTargetAsmParser();
    llvm::InitializeNativeTargetDisassembler();

    // Get the host information
    std::string TripleName;
    if (TripleName.empty())
        TripleName = sys::getDefaultTargetTriple();
    Triple TheTriple(Triple::normalize(TripleName));

    std::string MCPU = sys::getHostCPUName();
    SubtargetFeatures Features;
    Features.getDefaultSubtargetFeatures(TheTriple);

    std::string err;
    const Target* TheTarget = TargetRegistry::lookupTarget(TripleName, err);

    // Set up required helpers and streamer
#ifdef LLVM35
    std::unique_ptr<MCStreamer> Streamer;
#else
    OwningPtr<MCStreamer> Streamer;
#endif
    SourceMgr SrcMgr;

#ifdef LLVM35
    std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TripleName),TripleName));
#elif defined(LLVM34)
    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*TheTarget->createMCRegInfo(TripleName),TripleName));
#else
    llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TripleName));
#endif
    assert(MAI && "Unable to create target asm info!");

#ifdef LLVM35
    std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
#else
    llvm::OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
#endif
    assert(MRI && "Unable to create target register info!");

#ifdef LLVM35
    std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
#else
    OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
#endif
#ifdef LLVM34
    MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
#else
    MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
#endif
    MOFI->InitMCObjectFileInfo(TripleName, Reloc::Default, CodeModel::Default, Ctx);

    // Set up Subtarget and Disassembler
#ifdef LLVM35
    std::unique_ptr<MCSubtargetInfo>
        STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
    std::unique_ptr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI, Ctx));
#else
    OwningPtr<MCSubtargetInfo>
        STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
    OwningPtr<MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
#endif
    if (!DisAsm) {
        JL_PRINTF(JL_STDERR, "error: no disassembler for target", TripleName.c_str(), "\n");
        return;
    }

    unsigned OutputAsmVariant = 1;
    bool ShowEncoding = false;
    bool ShowInst = false;

#ifdef LLVM35
    std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
#else
    OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
    OwningPtr<MCInstrAnalysis>
        MCIA(TheTarget->createMCInstrAnalysis(MCII.get()));
#endif
    MCInstPrinter* IP =
        TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
    MCCodeEmitter *CE = 0;
    MCAsmBackend *MAB = 0;
    if (ShowEncoding) {
        CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
#ifdef LLVM34
        MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
#else
        MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
#endif
    }

    Streamer.reset(TheTarget->createAsmStreamer(Ctx, stream, /*asmverbose*/true,
#ifndef LLVM35
                                           /*useLoc*/ true,
                                           /*useCFI*/ true,
#endif
                                           /*useDwarfDirectory*/ true,
                                           IP, CE, MAB, ShowInst));
#ifdef LLVM36
    Streamer->InitSections(true);
#else
    Streamer->InitSections();
#endif

#ifndef USE_MCJIT // LLVM33 version

    // Make the MemoryObject wrapper
#ifdef LLVM36
    ArrayRef<uint8_t> memoryObject((uint8_t*)Fptr,Fsize);
#else
    FuncMCView memoryObject(Fptr, Fsize);
#endif

    SymbolTable DisInfo(Ctx, memoryObject);

    // Take two passes: In the first pass we record all branch labels,
    // in the second we actually perform the output
    for (int pass = 0; pass < 2; ++ pass) {

        DisInfo.setPass(pass);
        if (pass != 0) {
            // Switch to symbolic disassembly. We cannot do this
            // before the first pass, because this changes branch
            // targets from immediate values (constants) to
            // expressions, which are not handled correctly by
            // MCIA->evaluateBranch. (It should be possible to rewrite
            // this routine to handle this case correctly as well.)
            // Could add OpInfoLookup here
            DisAsm->setupForSymbolicDisassembly
                (OpInfoLookup, SymbolLookup, &DisInfo, &Ctx);
        }

        uint64_t Size = 0;
        uint64_t Index = 0;
        uint64_t absAddr = 0;

        // Set up the line info
        typedef std::vector<JITEvent_EmittedFunctionDetails::LineStart>
            LInfoVec;
        LInfoVec::iterator lineIter = lineinfo.begin();
        LInfoVec::iterator lineEnd  = lineinfo.end();

        uint64_t nextLineAddr = -1;
        DISubprogram debugscope;

        if (lineIter != lineEnd) {
            nextLineAddr = (*lineIter).Address;
            debugscope = DISubprogram((*lineIter).Loc.getScope(jl_LLVMContext));

            if (pass != 0) {
                stream << "Filename: " << debugscope.getFilename() << "\n";
                stream << "Source line: " << (*lineIter).Loc.getLine() << "\n";
            }
        }

        // Do the disassembly
        for (Index = 0, absAddr = (uint64_t)Fptr;
             Index < memoryObject.getExtent(); Index += Size, absAddr += Size) {

            if (nextLineAddr != (uint64_t)-1 && absAddr == nextLineAddr) {
                if (pass != 0)
                    stream << "Source line: "
                           << (*lineIter).Loc.getLine() << "\n";
                nextLineAddr = (*++lineIter).Address;
            }
            if (pass != 0) {
                // Uncomment this to output addresses for all instructions
                // stream << Index << ": ";
                const char *symbolName = DisInfo.lookupSymbol(Index);
                if (symbolName)
                    stream << symbolName << ":";
            }

            MCInst Inst;

            MCDisassembler::DecodeStatus S;
            S = DisAsm->getInstruction(Inst, Size, memoryObject, Index,
                                      /*REMOVE*/ nulls(), nulls());
            switch (S) {
            case MCDisassembler::Fail:
            if (pass != 0)
                SrcMgr.PrintMessage(SMLoc::getFromPointer(memoryObject[Index]),
                                    SourceMgr::DK_Warning,
                                    "invalid instruction encoding");
            if (Size == 0)
                Size = 1; // skip illegible bytes
            break;

            case MCDisassembler::SoftFail:
            if (pass != 0)
                SrcMgr.PrintMessage(SMLoc::getFromPointer(memoryObject[Index]),
                                    SourceMgr::DK_Warning,
                                    "potentially undefined instruction encoding");
            // Fall through

            case MCDisassembler::Success:
            #ifdef LLVM35
                if (pass != 0)
                    Streamer->EmitInstruction(Inst, *STI);
            #else
                if (pass == 0) {
                    // Pass 0: Record all branch targets
                    if (MCIA->isBranch(Inst)) {
                        uint64_t addr = MCIA->evaluateBranch(Inst, Index, Size);
                        if (addr != uint64_t(-1))
                            DisInfo.insertAddress(addr);
                    }
                } else {
                    // Pass 1: Output instruction
                    Streamer->EmitInstruction(Inst);
                }
            #endif
            break;
            }
        }

        if (pass == 0)
            DisInfo.createSymbols();
    }
#else // MCJIT version
#ifdef LLVM36
    ArrayRef<uint8_t> memoryObject((uint8_t*)Fptr,Fsize);
#else
    FuncMCView memoryObject(Fptr, Fsize); // MemoryObject wrapper
#endif


    if (!objectfile) return;
#ifdef LLVM36
    DIContext *di_ctx = DIContext::getDWARFContext(*objectfile);
#else
    DIContext *di_ctx = DIContext::getDWARFContext(objectfile);
#endif
    if (di_ctx == NULL) return;
    DILineInfoTable lineinfo = di_ctx->getLineInfoForAddressRange((size_t)Fptr, Fsize);

    // Set up the line info
    DILineInfoTable::iterator lineIter = lineinfo.begin();
    DILineInfoTable::iterator lineEnd = lineinfo.end();

    uint64_t nextLineAddr = -1;

    if (lineIter != lineEnd) {
        nextLineAddr = lineIter->first;
        #ifdef LLVM35
        stream << "Filename: " << lineIter->second.FileName << "\n";
        #else
        stream << "Filename: " << lineIter->second.getFileName() << "\n";
        #endif
    }

    uint64_t Index = 0;
    uint64_t absAddr = 0;
    uint64_t insSize = 0;

    // Do the disassembly
    for (Index = 0, absAddr = (uint64_t)Fptr;
         Index < Fsize; Index += insSize, absAddr += insSize) {

        if (nextLineAddr != (uint64_t)-1 && absAddr == nextLineAddr) {
            #ifdef LLVM35
            stream << "Source line: " << lineIter->second.Line << "\n";
            #else
            stream << "Source line: " << lineIter->second.getLine() << "\n";
            #endif
            nextLineAddr = (++lineIter)->first;
        }

        MCInst Inst;
        MCDisassembler::DecodeStatus S;
        S = DisAsm->getInstruction(Inst, insSize, memoryObject, Index,
                                  /*REMOVE*/ nulls(), nulls());
        switch (S) {
        case MCDisassembler::Fail:
        SrcMgr.PrintMessage(SMLoc::getFromPointer(Fptr + Index),
                            SourceMgr::DK_Warning,
                            "invalid instruction encoding");
        if (insSize == 0)
            insSize = 1; // skip illegible bytes
        break;

        case MCDisassembler::SoftFail:
        SrcMgr.PrintMessage(SMLoc::getFromPointer(Fptr + Index),
                            SourceMgr::DK_Warning,
                            "potentially undefined instruction encoding");
        // Fall through
        case MCDisassembler::Success:
        #ifdef LLVM35
            Streamer->EmitInstruction(Inst, *STI);
        #else
            Streamer->EmitInstruction(Inst);
        #endif
        break;
        }
    }

#endif
}
Exemplo n.º 29
0
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  cl::ParseCommandLineOptions(argc, argv);

  SourceMgr SM;

  // Read the expected strings from the check file.
  std::vector<CheckString> CheckStrings;
  if (ReadCheckFile(SM, CheckStrings))
    return 2;

  // Open the file to check and add it to SourceMgr.
  std::string ErrorStr;
  MemoryBuffer *F =
    MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr);
  if (F == 0) {
    errs() << "Could not open input file '" << InputFilename << "': "
           << ErrorStr << '\n';
    return true;
  }

  // Remove duplicate spaces in the input file if requested.
  if (!NoCanonicalizeWhiteSpace)
    F = CanonicalizeInputFile(F);

  SM.AddNewSourceBuffer(F, SMLoc());

  /// VariableTable - This holds all the current filecheck variables.
  StringMap<StringRef> VariableTable;

  // Check that we have all of the expected strings, in order, in the input
  // file.
  StringRef Buffer = F->getBuffer();

  const char *LastMatch = Buffer.data();

  for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
    const CheckString &CheckStr = CheckStrings[StrNo];

    StringRef SearchFrom = Buffer;

    // Find StrNo in the file.
    size_t MatchLen = 0;
    Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen, VariableTable));

    // If we didn't find a match, reject the input.
    if (Buffer.empty()) {
      PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
      return 1;
    }

    StringRef SkippedRegion(LastMatch, Buffer.data()-LastMatch);

    // If this check is a "CHECK-NEXT", verify that the previous match was on
    // the previous line (i.e. that there is one newline between them).
    if (CheckStr.IsCheckNext) {
      // Count the number of newlines between the previous match and this one.
      assert(LastMatch != F->getBufferStart() &&
             "CHECK-NEXT can't be the first check in a file");

      unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
      if (NumNewLines == 0) {
        SM.PrintMessage(CheckStr.Loc,
                    CheckPrefix+"-NEXT: is on the same line as previous match",
                        "error");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        "'next' match was here", "note");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
                        "previous match was here", "note");
        return 1;
      }

      if (NumNewLines != 1) {
        SM.PrintMessage(CheckStr.Loc,
                        CheckPrefix+
                        "-NEXT: is not on the line after the previous match",
                        "error");
        SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
                        "'next' match was here", "note");
        SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
                        "previous match was here", "note");
        return 1;
      }
    }

    // If this match had "not strings", verify that they don't exist in the
    // skipped region.
    for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size();
         ChunkNo != e; ++ChunkNo) {
      size_t MatchLen = 0;
      size_t Pos = CheckStr.NotStrings[ChunkNo].second.Match(SkippedRegion,
                                                             MatchLen,
                                                             VariableTable);
      if (Pos == StringRef::npos) continue;

      SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos),
                      CheckPrefix+"-NOT: string occurred!", "error");
      SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first,
                      CheckPrefix+"-NOT: pattern specified here", "note");
      return 1;
    }


    // Otherwise, everything is good.  Step over the matched text and remember
    // the position after the match as the end of the last match.
    Buffer = Buffer.substr(MatchLen);
    LastMatch = Buffer.data();
  }

  return 0;
}
Exemplo n.º 30
0
int LLVMTargetMachineAssembleToOutputStream(LLVMTargetMachineRef TM, LLVMMemoryBufferRef Mem, void *JOStream, LLVMBool RelaxAll, LLVMBool NoExecStack, char **ErrorMessage) {
  *ErrorMessage = NULL;

#if !defined(WIN32)
  locale_t loc = newlocale(LC_ALL_MASK, "C", 0);
  locale_t oldLoc = uselocale(loc);
#endif

  TargetMachine *TheTargetMachine = unwrap(TM);
  const Target *TheTarget = &(TheTargetMachine->getTarget());

  std::string TripleName = TheTargetMachine->getTargetTriple().str();
  std::string MCPU = TheTargetMachine->getTargetCPU().str();
  std::string FeaturesStr = TheTargetMachine->getTargetFeatureString().str();
  Reloc::Model RelocModel = TheTargetMachine->getRelocationModel();
  CodeModel::Model CMModel = TheTargetMachine->getCodeModel();

  std::unique_ptr<MemoryBuffer> Buffer(unwrap(Mem));

  std::string DiagStr;
  raw_string_ostream DiagStream(DiagStr);
  SourceMgr SrcMgr;
  SrcMgr.setDiagHandler(assembleDiagHandler, &DiagStream);

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());

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

  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
  MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
  MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx);

  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
  std::unique_ptr<MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));

  raw_java_ostream& Out = *((raw_java_ostream*) JOStream);

  std::unique_ptr<MCStreamer> Str;
  MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
  MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
  Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
                                              Out, CE, *STI, RelaxAll != 0));
  if (NoExecStack != 0)
    Str->InitSections(true);

  MCTargetOptions MCOptions;
  std::unique_ptr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, *Str, *MAI));
  std::unique_ptr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
  if (!TAP) {
    *ErrorMessage = strdup("this target does not support assembly parsing");
    goto done;
  }

  Parser->setTargetParser(*TAP.get());

  if (Parser->Run(false)) {
    *ErrorMessage = strdup(DiagStream.str().c_str());
    goto done;
  }
  Out.flush();

done:
#if !defined(WIN32)
  uselocale(oldLoc);
  freelocale(loc);
#endif
  return *ErrorMessage ? 1 : 0;
}