/// computePCBegin - return the address of FDE's pc
/// @ref binutils gold: ehframe.cc:222
uint32_t EhFrameHdr::computePCBegin(const EhFrame::FDE& pFDE,
                                    const MemoryRegion& pEhFrameRegion)
{
    uint8_t fde_encoding = pFDE.getCIE().getFDEEncode();
    unsigned int eh_value = fde_encoding & 0x7;

    // check the size to read in
    if (eh_value == llvm::dwarf::DW_EH_PE_absptr) {
        eh_value = DW_EH_PE_udata4;
    }

    size_t pc_size = 0x0;
    switch (eh_value) {
    case DW_EH_PE_udata2:
        pc_size = 2;
        break;
    case DW_EH_PE_udata4:
        pc_size = 4;
        break;
    case DW_EH_PE_udata8:
        pc_size = 8;
        break;
    default:
        // TODO
        break;
    }

    SizeTraits<32>::Address pc = 0x0;
    const uint8_t* offset = (const uint8_t*) pEhFrameRegion.start() +
                            pFDE.getOffset() +
                            pFDE.getDataStart();
    std::memcpy(&pc, offset, pc_size);

    // adjust the signed value
    bool is_signed = (fde_encoding & llvm::dwarf::DW_EH_PE_signed) != 0x0;
    if (DW_EH_PE_udata2 == eh_value && is_signed)
        pc = (pc ^ 0x8000) - 0x8000;

    // handle eh application
    switch (fde_encoding & 0x70)
    {
    case DW_EH_PE_absptr:
        break;
    case DW_EH_PE_pcrel:
        pc += m_EhFrame.addr() + pFDE.getOffset() + pFDE.getDataStart();
        break;
    case DW_EH_PE_datarel:
        // TODO
        break;
    default:
        // TODO
        break;
    }
    return pc;
}
Exemple #2
0
void EhFrame::addFDE(EhFrame::FDE& pFDE, bool pAlsoAddFragment)
{
  pFDE.getCIE().add(pFDE);
  if (pAlsoAddFragment)
    addFragment(pFDE);
}