Beispiel #1
0
void FunctionAddressRegistry::registerFunction(const std::string& name, void* addr, int length,
        llvm::Function* llvm_func) {
    assert(addr);
    assert(functions.count(addr) == 0);
    functions.insert(std::make_pair(addr, FuncInfo(name, length, llvm_func)));
}
Beispiel #2
0
FuncInfo find_func_info(const Func* func) {
  auto finfo = FuncInfo(func->unit(), func);

  auto label_num = uint32_t{0};
  auto gen_label = [&] (const char* kind) {
    return folly::format("{}{}", kind, label_num++).str();
  };

  auto add_target = [&] (const char* kind, Offset off) -> std::string {
    auto it = finfo.labels.find(off);
    if (it != end(finfo.labels)) return it->second;
    auto const label = gen_label(kind);
    finfo.labels[off] = label;
    return label;
  };

  auto find_jump_targets = [&] {
    auto it           = func->unit()->at(func->base());
    auto const stop   = func->unit()->at(func->past());
    auto const bcBase = reinterpret_cast<const Op*>(func->unit()->at(0));

    for (; it != stop; it += instrLen(reinterpret_cast<const Op*>(it))) {
      auto const pop = reinterpret_cast<const Op*>(it);
      auto const off = func->unit()->offsetOf(pop);
      if (isSwitch(*pop)) {
        foreachSwitchTarget(pop, [&] (Offset off) {
          add_target("L", pop - bcBase + off);
        });
        continue;
      }
      auto const target = instrJumpTarget(bcBase, off);
      if (target != InvalidAbsoluteOffset) {
        add_target("L", target);
        continue;
      }
    }
  };

  auto find_eh_entries = [&] {
    for (auto& eh : func->ehtab()) {
      finfo.ehInfo[&eh] = [&]() -> EHInfo {
        switch (eh.m_type) {
        case EHEnt::Type::Catch:
          {
            auto catches = EHCatch {};
            for (auto& kv : eh.m_catches) {
              auto const clsName = func->unit()->lookupLitstrId(kv.first);
              catches.blocks[clsName->data()] = add_target("C", kv.second);
            }
            return catches;
          }
        case EHEnt::Type::Fault:
          return EHFault { add_target("F", eh.m_fault) };
        }
        not_reached();
      }();
      finfo.ehStarts.emplace_back(eh.m_base, &eh);
    }
  };

  auto find_dv_entries = [&] {
    for (auto i = uint32_t{0}; i < func->numParams(); ++i) {
      auto& param = func->params()[i];
      if (param.hasDefaultValue()) {
        add_target("DV", func->params()[i].funcletOff());
      }
    }
  };

  find_jump_targets();
  find_eh_entries();
  find_dv_entries();
  return finfo;
}