Beispiel #1
0
void DwarfBuf::dwarf_cfa_sfp(uint8_t reg, int offset, int scale) {
  DwarfBuf b;
  byte(DW_CFA_val_expression);
  byte(reg);
  b.dwarf_sfp_expr(offset, scale);
  /* this assumes expression fits in 127 bytes, else we have
   to LEB128 encode size */
  byte(b.size());
  dwarf_sfp_expr(offset, scale);
}
Beispiel #2
0
bool ElfWriter::addFrameInfo(DwarfChunk* d) {
  Dwarf_Error error = 0;
  DwarfBuf& b = d->m_buf;
  b.clear();
  /* Define common set of rules for unwinding frames in the VM stack*/

  /* Frame pointer (CFA) for previous frame is in RBP + 16 */
  b.dwarf_cfa_def_cfa(RBP, CFA_OFFSET);
  /* Previous RIP is at CFA - 1 . DWARF_DATA_ALIGN (8) */
  b.dwarf_cfa_offset_extended_sf(RIP, -1);
  /* Previous RBP is at CFA - 2 . DWARF_DATA_ALIGN (8) */
  b.dwarf_cfa_offset_extended_sf(RBP, -2);
  /*
   * RSP is unchanged in VM frames, except for some rare cases with
   * calls to functions that we assume don't throw.  (Technically
   * debug information will be wrong if we stop under one of those
   * cases.)
   *
   * Note: if rVmSp is ever changed to refer to rsp, this code needs
   * to change.
   */
  b.dwarf_cfa_same_value(RSP);

  /* register above rules in a CIE (common information entry) */
  Dwarf_Signed cie_index = dwarf_add_frame_cie(
    m_dwarfProducer,
    "",
    DWARF_CODE_ALIGN,
    DWARF_DATA_ALIGN,
    RIP,
    (void *)b.getBuf(),
    b.size(),
    &error
  );
  if (cie_index == DW_DLV_NOCOUNT) {
    logError("Unable to add CIE frame");
    return false;
  }

  /* for each tracelet, register tracelet address ranges in
   * an FDE (Frame Description entry) */
  FuncPtrDB::iterator it;
  for (it = d->m_functions.begin(); it != d->m_functions.end(); it++) {
    Dwarf_P_Fde fde = dwarf_new_fde(m_dwarfProducer, &error);
    if (reinterpret_cast<Dwarf_Addr>(fde) == DW_DLV_BADADDR) {
      logError("Unable to create FDE");
      return false;
    }
    DwarfBuf buf;
    int err = dwarf_insert_fde_inst_bytes(
      m_dwarfProducer, fde, buf.size(), buf.getBuf(), &error);
    if (err == DW_DLV_ERROR) {
      logError("Unable to add instructions to fde");
      return false;
    }
    Dwarf_Unsigned fde_index = dwarf_add_frame_fde(
      m_dwarfProducer, fde, 0, cie_index,
      (Dwarf_Unsigned)((*it)->range.begin()),
      (*it)->range.size(),
      0, &error);
    if (fde_index == DW_DLV_BADADDR) {
      logError("Unable to add FDE");
      return false;
    }
  }
  return true;
}