static void StreamChar(llvm::raw_ostream& o, const char v) {
  if (isprint(v))
    o << '\'' << v << '\'';
  else {
    o << "\\0x";
    o.write_hex(v);
  }
}
Beispiel #2
0
void printName(llvm::raw_ostream &out, ObjectPtr x)
{
    switch (x->objKind) {
    case IDENTIFIER : {
        Identifier *y = (Identifier *)x.ptr();
        if (_safeNames > 0) {
            out << "#";
            for (unsigned i = 0; i < y->str.size(); ++i) {
                char ch = y->str[i];
                if (isSafe(ch))
                    out << ch;
                else
                    out << 'c' << (unsigned int)ch;
            }
        }
        else {
            out << "\"";
            for (unsigned i = 0; i < y->str.size(); ++i) {
                char ch = y->str[i];
                switch (ch) {
                case '\0':
                    out << "\\0";
                    break;
                case '\n':
                    out << "\\n";
                    break;
                case '\r':
                    out << "\\r";
                    break;
                case '\t':
                    out << "\\t";
                    break;
                case '\f':
                    out << "\\f";
                    break;
                case '\\':
                    out << "\\\\";
                    break;
                case '\'':
                    out << "\\'";
                    break;
                case '\"':
                    out << "\\\"";
                    break;
                default:
                    if (ch >= '\x20' && ch <= '\x7E')
                        out << ch;
                    else {
                        out << "\\x";
                        if (ch < 16)
                            out << '0';
                        out.write_hex((unsigned long long int)ch);
                    }
                    break;
                }
            }
            out << "\"";
        }
        break;
    }
    case GLOBAL_VARIABLE : {
        GlobalVariable *y = (GlobalVariable *)x.ptr();
        out << y->name->str;
        break;
    }
    case GLOBAL_ALIAS : {
        GlobalAlias *y = (GlobalAlias *)x.ptr();
        out << y->name->str;
        break;
    }
    case RECORD_DECL : {
        RecordDecl *y = (RecordDecl *)x.ptr();
        out << y->name->str;
        break;
    }
    case VARIANT_DECL : {
        VariantDecl *y = (VariantDecl *)x.ptr();
        out << y->name->str;
        break;
    }
    case PROCEDURE : {
        Procedure *y = (Procedure *)x.ptr();
        out << y->name->str;
        break;
    }
    case MODULE : {
        Module *m = (Module *)x.ptr();
        out << m->moduleName;
        break;
    }
    case INTRINSIC : {
        IntrinsicSymbol *intrin = (IntrinsicSymbol *)x.ptr();
        out << intrin->name->str;
        break;
    }
    case PRIM_OP : {
        out << primOpName((PrimOp *)x.ptr());
        break;
    }
    case TYPE : {
        typePrint(out, (Type *)x.ptr());
        break;
    }
    case VALUE_HOLDER : {
        ValueHolder *y = (ValueHolder *)x.ptr();
        if (isStaticOrTupleOfStatics(y->type)) {
            printStaticOrTupleOfStatics(out, y->type);
        }
        else {
            EValuePtr ev = new EValue(y->type, y->buf);
            printValue(out, ev);
        }
        break;
    }
    case EXTERNAL_PROCEDURE : {
        ExternalProcedure *proc = (ExternalProcedure*)x.ptr();
        out << "external " << proc->name->str;
        break;
    }
    default : {
        out << "UnknownNamedObject(" << x->objKind << ")";
        break;
    }
    }
}
DisassembleResult Disassemble(llvm::raw_ostream &pOutput, const char *pTriple,
                              const char *pFuncName, const uint8_t *pFunc,
                              size_t pFuncSize) {
  DisassembleResult result = kDisassembleSuccess;
  uint64_t i = 0;

  const llvm::MCSubtargetInfo *subtarget_info = NULL;
  const llvm::MCDisassembler *disassembler = NULL;
  const llvm::MCInstrInfo *mc_inst_info = NULL;
  const llvm::MCRegisterInfo *mc_reg_info = NULL;
  const llvm::MCAsmInfo *asm_info = NULL;
  llvm::MCInstPrinter *inst_printer = NULL;

  BufferMemoryObject *input_function = NULL;

  std::string error;
  const llvm::Target* target =
      llvm::TargetRegistry::lookupTarget(pTriple, error);

  if (target == NULL) {
    ALOGE("Invalid target triple for disassembler: %s (%s)!",
          pTriple, error.c_str());
    return kDisassembleUnknownTarget;
  }

  subtarget_info =
      target->createMCSubtargetInfo(pTriple, /* CPU */"", /* Features */"");;

  if (subtarget_info == NULL) {
    result = kDisassembleFailedSetup;
    goto bail;
  }

  disassembler = target->createMCDisassembler(*subtarget_info);

  mc_inst_info = target->createMCInstrInfo();

  mc_reg_info = target->createMCRegInfo(pTriple);

  asm_info = target->createMCAsmInfo(pTriple);

  if ((disassembler == NULL) || (mc_inst_info == NULL) ||
      (mc_reg_info == NULL) || (asm_info == NULL)) {
    result = kDisassembleFailedSetup;
    goto bail;
  }

  inst_printer = target->createMCInstPrinter(asm_info->getAssemblerDialect(),
                                             *asm_info, *mc_inst_info,
                                             *mc_reg_info, *subtarget_info);

  if (inst_printer == NULL) {
    result = kDisassembleFailedSetup;
    goto bail;
  }

  input_function = new (std::nothrow) BufferMemoryObject(pFunc, pFuncSize);

  if (input_function == NULL) {
    result = kDisassembleOutOfMemory;
    goto bail;
  }

  // Disassemble the given function
  pOutput << "Disassembled code: " << pFuncName << "\n";

  while (i < pFuncSize) {
    llvm::MCInst inst;
    uint64_t inst_size;

    llvm::MCDisassembler::DecodeStatus decode_result =
        disassembler->getInstruction(inst, inst_size, *input_function, i,
                                     llvm::nulls(), llvm::nulls());

    switch (decode_result) {
      case llvm::MCDisassembler::Fail: {
        ALOGW("Invalid instruction encoding encountered at %llu of function %s "
              "under %s.", i, pFuncName, pTriple);
        i++;
        break;
      }
      case llvm::MCDisassembler::SoftFail: {
        ALOGW("Potentially undefined instruction encoding encountered at %llu "
              "of function %s under %s.", i, pFuncName, pTriple);
        // fall-through
      }
      case llvm::MCDisassembler::Success : {
        const uint8_t *inst_addr = pFunc + i;

        pOutput.indent(4);
        pOutput << "0x";
        pOutput.write_hex(reinterpret_cast<uintptr_t>(inst_addr));
        pOutput << ": 0x";
        pOutput.write_hex(*reinterpret_cast<const uint32_t *>(inst_addr));
        inst_printer->printInst(&inst, pOutput, /* Annot */"");
        pOutput << "\n";

        i += inst_size;
        break;
      }
    }
  }

  pOutput << "\n";

bail:
  // Clean up
  delete input_function;
  delete inst_printer;
  delete asm_info;
  delete mc_reg_info;
  delete mc_inst_info;
  delete disassembler;
  delete subtarget_info;

  return result;
}