#ifndef ElfWriter_h #define ElfWriter_h #include <iostream> class EhWriter_t { public: virtual void GenerateNewEhInfo() =0; }; static const std::string ehframe_s_filename="ehframe.s"; static const std::string ehframe_exe_filename="ehframe.exe"; template <int ptrsize> class EhWriterImpl_t : public EhWriter_t { private: class EhProgramListingManip_t : public libIRDB::EhProgramListing_t { public: EhProgramListingManip_t(){} EhProgramListingManip_t(const libIRDB::EhProgramListing_t &pgm) : libIRDB::EhProgramListing_t(pgm) { } bool canExtend(const EhProgramListingManip_t &other); void extend(const uint64_t inc_amt, const EhProgramListingManip_t &other); bool isAdvanceDirective(const std::string &s) const; std::string getPrintableString(const std::string &s) const; private: int getMergeIndex(const EhProgramListingManip_t &other); static const int DW_CFA_advance_loc1 = 0x02; static const int DW_CFA_advance_loc2 = 0x03; static const int DW_CFA_advance_loc4 = 0x04; }; class FDErepresentation_t; // forward decl class CIErepresentation_t { public: CIErepresentation_t(libIRDB::Instruction_t*, EhWriterImpl_t<ptrsize>* ehw); void emitAssembly(std::ostream& out) {} bool canSupport(libIRDB::Instruction_t* insn) const; libIRDB::Relocation_t* GetPersonalityReloc() const { return personality_reloc;} private: // need nothing? EhProgramListingManip_t pgm; uint64_t code_alignment_factor; int64_t data_alignment_factor; uint64_t return_reg; libIRDB::Relocation_t* personality_reloc; mutable bool has_been_output; friend class FDErepresentation_t; friend EhWriterImpl_t<ptrsize>; }; static void print_pers(libIRDB::Instruction_t* insn, CIErepresentation_t *cie); class FDErepresentation_t { private: class LSDArepresentation_t { public: LSDArepresentation_t(libIRDB::Instruction_t* insn); void extend(libIRDB::Instruction_t* insn); bool canExtend(libIRDB::Instruction_t* insn) const; bool exists() const { return callsite_table.size() > 0; } struct call_site_t { libIRDB::Instruction_t* cs_insn_start; libIRDB::Instruction_t* cs_insn_end; libIRDB::Instruction_t* landing_pad; int action_table_index; libIRDB::TTOrderVector_t actions; }; std::vector<call_site_t> callsite_table; std::vector<libIRDB::TTOrderVector_t> action_table; std::vector<libIRDB::Relocation_t*> type_table; uint64_t tt_encoding; }; LSDArepresentation_t lsda; CIErepresentation_t* cie; libIRDB::virtual_offset_t start_addr; libIRDB::virtual_offset_t end_addr; libIRDB::virtual_offset_t last_advance_addr; // the pgm for the fde EhProgramListingManip_t pgm; public: FDErepresentation_t(libIRDB::Instruction_t* insn, EhWriterImpl_t<ptrsize>* ehw); void extend(libIRDB::Instruction_t* insn, EhWriterImpl_t<ptrsize>* ehw); void emitAssembly(std::ostream& out); bool canExtend(libIRDB::Instruction_t* insn, EhWriterImpl_t<ptrsize>* ehw); bool hasLsda() const { return lsda.exists(); } friend EhWriterImpl_t<ptrsize>; }; friend class FDErepresentation_t; friend class CIErepresentation_t; ZiprImpl_t& zipr_obj; std::vector<FDErepresentation_t*> all_fdes; std::vector<CIErepresentation_t*> all_cies; void BuildFDEs(); void GenerateEhOutput(); void CompileEhOutput(); void ScoopifyEhOutput(); public: EhWriterImpl_t(ZiprImpl_t& p_zipr_obj) : zipr_obj(p_zipr_obj) { } virtual ~EhWriterImpl_t(); void GenerateNewEhInfo(); }; #endif