diff --git a/.gitattributes b/.gitattributes index eee4d8beb560fe105b3dbc3757e01fe2637699ce..d08c3d57f93ae6655e6fee061a0d902e6db5bd1f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -198,6 +198,10 @@ libIRDB/include/core/reloc.hpp -text libIRDB/include/core/variantid.hpp -text libIRDB/include/libIRDB-cfg.hpp -text libIRDB/include/libIRDB-core.hpp -text +libIRDB/include/libIRDB-syscall.hpp -text +libIRDB/include/libIRDB-util.hpp -text +libIRDB/include/syscall/syscall.hpp -text +libIRDB/include/util/insn_preds.hpp -text libIRDB/include/utils.hpp -text libIRDB/install_libs.sh -text libIRDB/src/Makefile -text @@ -217,8 +221,13 @@ libIRDB/src/core/generate_spri.cpp -text libIRDB/src/core/instruction.cpp -text libIRDB/src/core/pqxxdb.cpp -text libIRDB/src/core/variantid.cpp -text +libIRDB/src/syscall/Makefile -text +libIRDB/src/syscall/syscall.cpp -text +libIRDB/src/util/Makefile -text +libIRDB/src/util/insn_preds.cpp -text libIRDB/test/Makefile -text libIRDB/test/build_callgraph.cpp -text +libIRDB/test/build_preds.cpp -text libIRDB/test/calc_conflicts.cpp -text libIRDB/test/check_thunks.cpp -text libIRDB/test/check_thunks.hpp -text diff --git a/libIRDB/include/core/archdesc.hpp b/libIRDB/include/core/archdesc.hpp index 4039d4cab7050d332d63fdabbe05513303748adb..761ef70225d5a9faaa0b5c2fc33c4b3e9640f728 100644 --- a/libIRDB/include/core/archdesc.hpp +++ b/libIRDB/include/core/archdesc.hpp @@ -19,6 +19,7 @@ */ +enum AD_FileType_t { AD_ELF, AD_CGC }; class ArchitectureDescription_t { @@ -29,8 +30,12 @@ class ArchitectureDescription_t int GetBitWidth() { return bits; } void SetBitWidth(int _bits) { bits=_bits; } + AD_FileType_t GetFileType() { return ft; } + void SetFileType(AD_FileType_t t) { ft=t; } + private: int bits; + AD_FileType_t ft; }; diff --git a/libIRDB/include/core/instruction.hpp b/libIRDB/include/core/instruction.hpp index 2e93edc7f9298706f1de5c3bdcf140f2a953f7e2..2dc87c9e778fd1870db12b0a6353d3567b60d7e8 100644 --- a/libIRDB/include/core/instruction.hpp +++ b/libIRDB/include/core/instruction.hpp @@ -59,7 +59,7 @@ class Instruction_t : public BaseObj_t void WriteToDB() { assert(0); } std::string WriteToDB(File_t *fid, db_id_t newid, bool p_withHeader); int Disassemble(DISASM &d) const; - std::string getDisassembly(); + std::string getDisassembly() const; bool Assemble(std::string assembly); bool IsFunctionExit() const; @@ -69,6 +69,8 @@ class Instruction_t : public BaseObj_t static bool SetsStackPointer(DISASM *disasm); static bool SetsStackPointer(ARGTYPE* arg); + bool IsSyscall() { return getDisassembly().find("int 0x80") != std::string::npos; } + private: AddressID_t *my_address; diff --git a/libIRDB/include/libIRDB-syscall.hpp b/libIRDB/include/libIRDB-syscall.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5eb8ba381484c5a8751b8e14e1f2bb307c40dee4 --- /dev/null +++ b/libIRDB/include/libIRDB-syscall.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef libIRDB_syscall +#define libIRDB_syscall + + +/* Building a CFG depends on core functionality */ +#include <libIRDB-core.hpp> +#include <libIRDB-util.hpp> + +#include <vector> +#include <set> +#include <map> +#include <ostream> + +namespace libIRDB +{ + +#include <syscall/syscall.hpp> + +}; + +#endif diff --git a/libIRDB/include/libIRDB-util.hpp b/libIRDB/include/libIRDB-util.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ca47f67ef3a544ccc492ed362fac8743bc34cead --- /dev/null +++ b/libIRDB/include/libIRDB-util.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef libIRDB_util +#define libIRDB_util + + +/* Building a CFG depends on core functionality */ +#include <libIRDB-core.hpp> + +#include <vector> +#include <set> +#include <map> +#include <ostream> + +namespace libIRDB +{ + +#include <util/insn_preds.hpp> + +}; + +#endif diff --git a/libIRDB/include/syscall/syscall.hpp b/libIRDB/include/syscall/syscall.hpp new file mode 100644 index 0000000000000000000000000000000000000000..857c1580579d08ecc0f033c00d6741719aff4948 --- /dev/null +++ b/libIRDB/include/syscall/syscall.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 - Zephyr Software + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#ifndef irdb_syscall_hpp +#define irdb_syscall_hpp + +typedef enum +{ + SNT_Unknown=-1, +#ifdef CGC + SNT_terminate=1, + SNT_transmit=2, + SNT_receive=3, + SNT_fdwait=4, + SNT_allocate=5, + SNT_deallocate=6, + SNT_random=7 +#else +/* LINUX here? */ +#endif +} SyscallNumber_t; + +class SyscallSite_t +{ + public: + SyscallSite_t(libIRDB::Instruction_t* p_site, libIRDB::SyscallNumber_t p_num) : site(p_site), num(p_num) {} + + bool operator<(const libIRDB::SyscallSite_t& rhs) const { return this->site < rhs.site; } + libIRDB::Instruction_t* GetSyscallSite() { return site; } + libIRDB::Instruction_t* GetSite() const { return site; } + libIRDB::SyscallNumber_t GetSyscallNumber() const { return num; } + private: + libIRDB::Instruction_t* site; + libIRDB::SyscallNumber_t num; +}; +typedef std::set<SyscallSite_t> SyscallSiteSet_t; + +class Syscalls_t +{ + public: + Syscalls_t(FileIR_t *the_firp=NULL) { if(the_firp) FindSystemCalls(the_firp); } + + + bool FindSystemCalls(const libIRDB::FileIR_t* firp); + + const libIRDB::SyscallSiteSet_t& GetSyscalls() {return syscalls;} + protected: + libIRDB::SyscallNumber_t FindSystemCallNumber(libIRDB::Instruction_t* insn, + const libIRDB::InstructionPredecessors_t& preds); + + private: + libIRDB::SyscallSiteSet_t syscalls; +}; + +#endif + diff --git a/libIRDB/include/util/insn_preds.hpp b/libIRDB/include/util/insn_preds.hpp new file mode 100644 index 0000000000000000000000000000000000000000..da9da560f0d90bf46dcbc8f220e3dc92ff1f23b3 --- /dev/null +++ b/libIRDB/include/util/insn_preds.hpp @@ -0,0 +1,33 @@ +#ifndef insn_preds_h +#define insn_preds_h + + +class InstructionPredecessors_t +{ + private: + typedef std::map<const Instruction_t*, InstructionSet_t> PredMap_t; + + public: + InstructionPredecessors_t(const FileIR_t* f=NULL) {Init(); if(f) AddFile(f);} + virtual void AddFile(const FileIR_t* ); + + const InstructionSet_t& operator[] (const Instruction_t* i) const + { + PredMap_t::const_iterator it=pred_map.find(i); + if (it!= pred_map.end()) + return it->second; + static InstructionSet_t empty; + return empty; + } + + protected: + virtual void Init() {}; + + private: + + virtual void AddPred(const Instruction_t* before, const Instruction_t* after); + + PredMap_t pred_map; +}; + +#endif diff --git a/libIRDB/src/Makefile b/libIRDB/src/Makefile index bd1cdd48d5acdbfb0e627a1c470496d878208d24..040dfecfd5df31e1e3b43cd7b8c43f7c727656e8 100644 --- a/libIRDB/src/Makefile +++ b/libIRDB/src/Makefile @@ -1,8 +1,9 @@ + +dirs=core cfg util syscall + all: - cd core; make - cd cfg; make + for i in ${dirs}; do echo ${PWD}; cd $$i; make || exit 1; cd ..; done clean: - cd core; make clean - cd cfg; make clean + for i in ${dirs}; do echo ${PWD}; cd $$i; make clean || exit 1; cd ..; done diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index 69d34c3fe4b4060a0b1a602f6b3509733ee61e88..b86c7cb1e8ed60b91fb722275588fcc3ff853824 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -609,16 +609,28 @@ void FileIR_t::SetArchitecture() loa.cread((char*)&e_ident, sizeof(e_ident)); - if((e_ident[EI_MAG0]!=ELFMAG0) || - (e_ident[EI_MAG1]!=ELFMAG1) || - (e_ident[EI_MAG2]!=ELFMAG2) || - (e_ident[EI_MAG3]!=ELFMAG3)) + archdesc=new ArchitectureDescription_t; + + if((e_ident[EI_MAG0]==ELFMAG0) && + (e_ident[EI_MAG1]==ELFMAG1) && + (e_ident[EI_MAG2]==ELFMAG2) && + (e_ident[EI_MAG3]==ELFMAG3)) + { + archdesc->SetFileType(AD_ELF); + } + else if((e_ident[EI_MAG0]==ELFMAG0) && + (e_ident[EI_MAG1]=='C') && + (e_ident[EI_MAG2]=='G') && + (e_ident[EI_MAG3]=='C')) + { + archdesc->SetFileType(AD_ELF); + } + else { cerr << "ELF magic number wrong: is this an ELF file? " <<endl; exit(-1); } - archdesc=new ArchitectureDescription_t; switch(e_ident[4]) { diff --git a/libIRDB/src/core/instruction.cpp b/libIRDB/src/core/instruction.cpp index ac207cd2809d001fed6b59bba6cd2e745fd9c1b3..645926c056fa792acf70122684739ecc2af9adc7 100644 --- a/libIRDB/src/core/instruction.cpp +++ b/libIRDB/src/core/instruction.cpp @@ -82,7 +82,7 @@ int Instruction_t::Disassemble(DISASM &disasm) const return instr_len; } -std::string Instruction_t::getDisassembly() +std::string Instruction_t::getDisassembly() const { DISASM disasm; Disassemble(disasm); diff --git a/libIRDB/src/syscall/Makefile b/libIRDB/src/syscall/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4fbfa41d998a0895b480731757de82637fd1b5c4 --- /dev/null +++ b/libIRDB/src/syscall/Makefile @@ -0,0 +1,29 @@ + +LIB=../../lib/libIRDB-syscall.a + +OBJS=syscall.o + +CXX=g++ +EXTRA_CXXFLAGS=-g -c -I. -I../../include -I../../../beaengine/include + +all: $(OBJS) + +-include $(OBJS:.o=.d) + +clean: + rm -f $(OBJS) *.d + +.cpp.o: + ar rc $(LIB) $@ + +%.o: %.cpp + $(CXX) -c $(EXTRA_CXXFLAGS) $*.cpp + $(AR) -r $(LIB) $*.o + @# + @# build dependencies -- http://scottmcpeak.com/autodepend/autodepend.html + @# + $(CXX) -MM $(EXTRA_CXXFLAGS) $*.cpp > $*.d + @cp -f $*.d $*.d.tmp + @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $*.d + @rm -f $*.d.tmp + diff --git a/libIRDB/src/syscall/syscall.cpp b/libIRDB/src/syscall/syscall.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f5c2469f3a81df15e5dd997280a154f48fae5928 --- /dev/null +++ b/libIRDB/src/syscall/syscall.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014 - Zephyr Software + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +//#include <libIRDB-core.hpp> +//#include <libIRDB-util.hpp> +#include <libIRDB-syscall.hpp> +#include <cstdlib> + +using namespace std; +using namespace libIRDB; + +SyscallNumber_t Syscalls_t::FindSystemCallNumber(Instruction_t* insn, const libIRDB::InstructionPredecessors_t& preds) +{ + Instruction_t *pred_insn=NULL; + + for( const InstructionSet_t *cs_preds=&preds[insn]; + cs_preds->size()==1; + cs_preds=&preds[pred_insn] + ) + { + pred_insn=*(cs_preds->begin()); + // cout<<"Pred is "<<pred_insn->getDisassembly()<<endl; + + string disass=pred_insn->getDisassembly(); + + /* look for eax being used or set */ + if(disass.find("eax")!=string::npos) + { + string to_find="mov eax,"; + size_t loc=disass.find(to_find); + // check to see if it's a mov of eax + if(loc ==string::npos) + { + // no, quit looking backwards + return SNT_Unknown; + } + size_t val=strtol(disass.substr(loc+to_find.length()).c_str(),NULL,16); + // check to see if it's a mov of eax + + return (SyscallNumber_t)val; + } + } + + return SNT_Unknown; + +} + +bool Syscalls_t::FindSystemCalls(const FileIR_t *firp2) +{ + FileIR_t* firp=(FileIR_t*)firp2; // discard const qualifer, but we aren't changing anything. + assert(firp); + libIRDB::InstructionPredecessors_t preds; + preds.AddFile(firp); + + bool found_one=false; + for(InstructionSet_t::iterator it=firp->GetInstructions().begin(); + it!=firp->GetInstructions().end(); + ++it + ) + { + Instruction_t* insn=*it; + if(insn->IsSyscall()) + { + SyscallNumber_t num=FindSystemCallNumber(insn, preds); + syscalls.insert(SyscallSite_t(insn,num)); + found_one=true; + + if(getenv("PRINTSYSCALLSFOUND")) + cout<<"Found system call "<< insn->GetBaseID()<< ":'"<< insn->getDisassembly() << "' with eax value "<< (size_t)num<<endl; + } + } + return found_one; + +} + + + diff --git a/libIRDB/src/util/Makefile b/libIRDB/src/util/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c3cf89e69f9d40824a73876a0555c785451b6d9d --- /dev/null +++ b/libIRDB/src/util/Makefile @@ -0,0 +1,15 @@ + +LIB=../../lib/libIRDB-util.a + +OBJS=insn_preds.o + +all: $(OBJS) + +$(OBJS): ../../include/core/*.hpp ../../include/util/*.hpp ../../include/*.hpp + +clean: + rm -f $(OBJS) + +.cpp.o: + g++ -g -c -I. -I../../include -I../../../beaengine/include $< + ar rc $(LIB) $@ diff --git a/libIRDB/src/util/insn_preds.cpp b/libIRDB/src/util/insn_preds.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b6b53dad4d7b988739a4a45c18351c987d1602a --- /dev/null +++ b/libIRDB/src/util/insn_preds.cpp @@ -0,0 +1,35 @@ + +#include <map> +#include <libIRDB-core.hpp> +#include <libIRDB-util.hpp> +#include <utils.hpp> + +using namespace libIRDB; +using namespace std; + + + +void InstructionPredecessors_t::AddPred(const Instruction_t* before, const Instruction_t* after) +{ + assert(before); + if(!after) return; + + if(getenv("DUMP_PRED_CREATE")) + cout<<"Found "<<after->GetBaseID()<<":"<<after->getDisassembly() << " follows "<< before->GetBaseID()<<":"<<before->getDisassembly()<<endl; + pred_map[after].insert((Instruction_t*)before); + +} + +void InstructionPredecessors_t::AddFile(const FileIR_t* firp2) +{ + FileIR_t* firp=(FileIR_t*)firp2; // discarding const qualifier because we know we won't change the set + for(InstructionSet_t::const_iterator it=firp->GetInstructions().begin(); + it!=firp->GetInstructions().end(); + ++it) + { + Instruction_t* insn=*it; + AddPred(insn, insn->GetTarget()); + AddPred(insn, insn->GetFallthrough()); + } + +} diff --git a/libIRDB/test/Makefile b/libIRDB/test/Makefile index a75e9d77adfcd90bc5dcbe085957fa59e6440893..73a17c2e35cb1139ad4d880b446ae86eec2737bd 100644 --- a/libIRDB/test/Makefile +++ b/libIRDB/test/Makefile @@ -1,13 +1,13 @@ INCLUDES= -I ../../include -I../include/ -I../../beaengine/include -LIBS=-L ../lib/ -lIRDB-core -lIRDB-cfg -lpqxx -L ../../beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d +LIBS=-L ../lib/ -lIRDB-core -lIRDB-cfg -lIRDB-util -lpqxx -L ../../beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d OPT=-g .SUFFIXES: .exe .cpp PROGS=print_variant.exe list_programs.exe create_variant.exe create_variantir.exe read_variantir.exe clone.exe ilr.exe \ drop_variant.exe generate_spri.exe fill_in_cfg.exe fix_calls.exe fill_in_indtargs.exe unfix_calls.exe \ - calc_conflicts.exe find_strings.exe build_callgraph.exe + calc_conflicts.exe find_strings.exe build_callgraph.exe build_preds.exe all: $(PROGS) diff --git a/libIRDB/test/build_preds.cpp b/libIRDB/test/build_preds.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53c6b0874429336f5b9c02b99024481798ecb50b --- /dev/null +++ b/libIRDB/test/build_preds.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + + + +#include <libIRDB-core.hpp> +#include <libIRDB-util.hpp> +#include <utils.hpp> // to_string function from libIRDB +#include <iostream> +#include <fstream> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +using namespace libIRDB; +using namespace std; + +// +// main routine to build and print a call graph. +// +main(int argc, char* argv[]) +{ + if(argc!=2) + { + cerr<<"Usage: "<<argv[0]<<" <variant id> "<<endl; + exit(-1); + } + + string filename; + ostream *fout; + fout=&cout; + + + VariantID_t *varidp=NULL; + FileIR_t *firp=NULL; + + /* setup the interface to the sql server */ + pqxxDB_t pqxx_interface; + BaseObj_t::SetInterface(&pqxx_interface); + + try + { + + cerr<<"Looking up variant "<<string(argv[1])<<" from database." << endl; + varidp=new VariantID_t(atoi(argv[1])); + + // A callgraph + InstructionPredecessors_t *ip=new InstructionPredecessors_t; + + assert(varidp->IsRegistered()==true); + + + for(set<File_t*>::iterator it=varidp->GetFiles().begin(); + it!=varidp->GetFiles().end(); + ++it + ) + { + File_t* this_file=*it; + assert(this_file); + cerr<<"Reading variant "<<string(argv[1])<<":"<<this_file->GetURL() + <<" from database." << endl; + + // read the db + firp=new FileIR_t(*varidp,this_file); + + // ILR only for the main file. + ip->AddFile(firp); + } + + + } + catch (DatabaseError_t pnide) + { + cerr<<"Unexpected database error: "<<pnide<<endl; + exit(-1); + } + + cerr<<"Done!"<<endl; + + if(fout!=&cout) + ((ofstream*)fout)->close(); + + + delete varidp; +} + + diff --git a/libIRDB/test/read_ehframe.cpp b/libIRDB/test/read_ehframe.cpp index 122d86cc00369f4508f26af453f3d217631c7644..a18737abdb0e707920cee5d2bbc967d479f960d1 100644 --- a/libIRDB/test/read_ehframe.cpp +++ b/libIRDB/test/read_ehframe.cpp @@ -726,17 +726,22 @@ void read_ehframe(FileIR_t* virp, ELFIO::elfio* elfiop) } cout<<"Found .eh_frame is section "<<std::dec<<eh_frame_index<<endl; + eh_frame_addr=(void*)elfiop->sections[eh_frame_index]->get_address(); + int total_size=0; + // char *p=&strtab[ sechdrs[secndx+1].sh_name]; const char *p=elfiop->sections[secndx+1]->get_name().c_str(); if (strcmp(".gcc_except_table",p)!=0) { cout<<"Did not find .gcc_except_table immediately after .eh_frame\n"; + total_size=elfiop->sections[eh_frame_index]->get_size()+1; } - - eh_frame_addr=(void*)elfiop->sections[eh_frame_index]->get_address(); - int total_size= + else + { + total_size= (elfiop->sections[eh_frame_index+1]->get_address()+ elfiop->sections[eh_frame_index+1]->get_size() ) - (uintptr_t)eh_frame_addr; + } // collect eh_frame and gcc_except_table into one memory region