diff --git a/libIRDB/test/fill_in_cfg.cpp b/libIRDB/test/fill_in_cfg.cpp index d6df1244444f48c3cc82fbfa67286f10e7691994..1ad77e1de5731e96ab69e593c7786f2d31301efe 100644 --- a/libIRDB/test/fill_in_cfg.cpp +++ b/libIRDB/test/fill_in_cfg.cpp @@ -43,17 +43,12 @@ void PopulateCFG::populate_instruction_map /* for each instruction in the IR */ - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->GetInstructions()) { - Instruction_t *insn=*it; - db_id_t fileID=insn->GetAddress()->GetFileID(); - virtual_offset_t vo=insn->GetAddress()->GetVirtualOffset(); + auto fileID=insn->GetAddress()->GetFileID(); + auto vo=insn->GetAddress()->GetVirtualOffset(); - pair<db_id_t,virtual_offset_t> p(fileID,vo); + auto p=pair<db_id_t,virtual_offset_t>(fileID,vo); assert(insnMap[p]==NULL); insnMap[p]=insn; @@ -75,9 +70,6 @@ void PopulateCFG::set_fallthrough // check for branches with targets if( - //(disasm->Instruction.BranchType==JmpType) || // it is a unconditional branch - //(disasm->Instruction.BranchType==RetType) // or a return - (disasm->isUnconditionalBranch() ) || // it is a unconditional branch (disasm->isReturn()) // or a return ) @@ -88,13 +80,13 @@ void PopulateCFG::set_fallthrough /* get the address of the next instrution */ - virtual_offset_t virtual_offset=insn->GetAddress()->GetVirtualOffset() + insn->GetDataBits().size(); + auto virtual_offset=insn->GetAddress()->GetVirtualOffset() + insn->GetDataBits().size(); /* create a pair of offset/file */ - pair<db_id_t,virtual_offset_t> p(insn->GetAddress()->GetFileID(),virtual_offset); + auto p=pair<db_id_t,virtual_offset_t>(insn->GetAddress()->GetFileID(),virtual_offset); /* lookup the target insn from the map */ - Instruction_t *fallthrough_insn=insnMap[p]; + auto fallthrough_insn=insnMap[p]; /* sanity, note we may see odd control transfers to 0x0 */ if(fallthrough_insn==NULL && virtual_offset!=0) @@ -143,14 +135,13 @@ void PopulateCFG::set_target // disasm->Argument1.ArgMnemonic<<"."<<endl; /* get the offset */ - // virtual_offset_t virtual_offset=strtoul(disasm->Argument1.ArgMnemonic, NULL, 16); - virtual_offset_t virtual_offset=disasm->getAddress(); + auto virtual_offset=disasm->getAddress(); /* create a pair of offset/file */ - pair<db_id_t,virtual_offset_t> p(insn->GetAddress()->GetFileID(),virtual_offset); + auto p=pair<db_id_t,virtual_offset_t>(insn->GetAddress()->GetFileID(),virtual_offset); /* lookup the target insn from the map */ - Instruction_t *target_insn=insnMap[p]; + auto target_insn=insnMap[p]; /* sanity, note we may see odd control transfers to 0x0 */ if(target_insn==NULL) @@ -204,20 +195,16 @@ File_t* PopulateCFG::find_file(FileIR_t* firp, db_id_t fileid) void PopulateCFG::add_new_instructions(FileIR_t *firp) { int found_instructions=0; - for( - set< pair<db_id_t,virtual_offset_t> >::const_iterator it=missed_instructions.begin(); - it!=missed_instructions.end(); - ++it - ) + for(auto p : missed_instructions) { /* get the address we've missed */ - virtual_offset_t missed_address=(*it).second; + auto missed_address=p.second; /* get the address ID of the instruction that's missing the missed addressed */ - db_id_t missed_fileid=(*it).first; + auto missed_fileid=p.first; /* figure out which file we're looking at */ - File_t* filep=find_file(firp,missed_fileid); + auto filep=find_file(firp,missed_fileid); assert(filep); @@ -251,27 +238,10 @@ void PopulateCFG::add_new_instructions(FileIR_t *firp) /* disassemble the instruction */ DecodedInstruction_t disasm(missed_address, (void*)&data[offset_into_section], elfiop->sections[secndx]->get_size()-offset_into_section ); - /* - memset(&disasm, 0, sizeof(DecodeInstruction_t)); - - disasm.Options = NasmSyntax + PrefixedNumeral; - disasm.Archi = firp->GetArchitectureBitWidth(); - disasm.EIP = (uintptr_t) &data[offset_into_section]; - disasm.SecurityBlock=elfiop->sections[secndx]->get_size()-offset_into_section; - disasm.VirtualAddr = missed_address; - */ - - - - -/* bea docs say OUT_OF_RANGE and UNKNOWN_OPCODE are defined, but they aren't */ -// #define OUT_OF_RANGE (0) -// #define UNKNOWN_OPCODE (-1) - /* if we found the instruction, but can't disassemble it, then we skip out for now */ - if(!disasm.valid()) // instr_len==OUT_OF_RANGE || instr_len==UNKNOWN_OPCODE) + if(!disasm.valid()) { if(getenv("VERBOSE_CFG")) cout<<"Found invalid insn at "<<missed_address<<endl; @@ -296,13 +266,13 @@ void PopulateCFG::add_new_instructions(FileIR_t *firp) newinsnbits[i]=data[offset_into_section+i]; /* create a new address */ - AddressID_t *newaddr=new AddressID_t(); + auto newaddr=new AddressID_t(); assert(newaddr); newaddr->SetVirtualOffset(missed_address); newaddr->SetFileID(missed_fileid); /* create a new instruction */ - Instruction_t *newinsn=new Instruction_t(); + auto newinsn=new Instruction_t(); assert(newinsn); newinsn->SetAddress(newaddr); newinsn->SetDataBits(newinsnbits); @@ -348,15 +318,9 @@ void PopulateCFG::fill_in_cfg(FileIR_t *firp) cout << "Found "<<firp->GetInstructions().size()<<" instructions." <<endl; /* for each instruction, disassemble it and set the target/fallthrough */ - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->GetInstructions()) { - Instruction_t *insn=*it; DecodedInstruction_t disasm(insn); - //memset(&disasm, 0, sizeof(DISASM)); const auto instr_len = disasm.length(); @@ -380,14 +344,10 @@ void PopulateCFG::fill_in_cfg(FileIR_t *firp) } while(missed_instructions.size()>failed_target_count); cout<<"Caution: Was unable to find instructions for these addresses:"<<hex<<endl; - for( - set< pair<db_id_t,virtual_offset_t> >::const_iterator it=missed_instructions.begin(); - it!=missed_instructions.end(); - ++it - ) + for(auto p : missed_instructions) { /* get the address we've missed */ - virtual_offset_t missed_address=(*it).second; + virtual_offset_t missed_address=p.second; cout << missed_address << ", "; } cout<<dec<<endl; @@ -399,16 +359,8 @@ void PopulateCFG::fill_in_cfg(FileIR_t *firp) /* for each instruction, set the original address id to be that of the address id, as fill_in_cfg is * designed to work on only original programs. */ - for( - std::set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) - { - Instruction_t* insn=*it; - + for(auto insn : firp->GetInstructions()) insn->SetOriginalAddressID(insn->GetAddress()->GetBaseID()); - } } @@ -420,7 +372,6 @@ bool PopulateCFG::is_in_relro_segment(const int secndx) return false; int segnum = real_elfiop->segments.size(); -// int segndx=0; virtual_offset_t sec_start=(virtual_offset_t)(elfiop->sections[secndx]->get_address()); virtual_offset_t sec_end=(virtual_offset_t)(elfiop->sections[secndx]->get_address() + elfiop->sections[secndx]->get_size() - 1 ); @@ -488,14 +439,14 @@ void PopulateCFG::fill_in_scoops(FileIR_t *firp) string name=elfiop->sections[secndx]->get_name(); /* start address */ - AddressID_t *startaddr=new AddressID_t(); + auto startaddr=new AddressID_t(); assert(startaddr); startaddr->SetVirtualOffset( elfiop->sections[secndx]->get_address()); startaddr->SetFileID(firp->GetFile()->GetBaseID()); firp->GetAddresses().insert(startaddr); /* end */ - AddressID_t *endaddr=new AddressID_t(); + auto endaddr=new AddressID_t(); assert(endaddr); endaddr->SetVirtualOffset( elfiop->sections[secndx]->get_address() + elfiop->sections[secndx]->get_size()-1); endaddr->SetFileID(firp->GetFile()->GetBaseID()); @@ -530,6 +481,62 @@ void PopulateCFG::fill_in_scoops(FileIR_t *firp) } +void PopulateCFG::detect_scoops_in_code(FileIR_t *firp) +{ + // only valid for arm64 + if(firp->GetArchitecture()->getMachineType() != admtAarch64) return; + + // check each insn for an ldr with a pcrel operand. + for(auto insn : firp->GetInstructions()) + { + const auto d=DecodedInstruction_t(insn); + // look for ldr's with a pcrel operand + if(d.getMnemonic()!="ldr") continue; + const auto op1=d.getOperand(1); + if( !op1.isPcrel()) continue; + + // sanity check that it's a memory operation. + assert(op1.isMemory()); + + const auto referenced_address=op1.getMemoryDisplacement(); + + const auto sec=elfiop->sections.findByAddress(referenced_address); + // can't find section. + if(sec==nullptr) continue; + + // only trying to do this for executable chunks, other code deals with + // scoops not in the .text section. + if(!sec->isExecutable()) continue; + + const auto sec_data=sec->get_data(); + const auto sec_start=sec->get_address(); + const auto the_contents=string(&sec_data[referenced_address-sec_start],8); + const auto fileid=firp->GetFile()->GetBaseID(); + + + auto start_addr=new AddressID_t(); + assert(start_addr); + start_addr->SetVirtualOffset(referenced_address); + start_addr->SetFileID(fileid); + firp->GetAddresses().insert(start_addr); + + auto end_addr=new AddressID_t(); + assert(end_addr); + end_addr->SetVirtualOffset(referenced_address+7); + end_addr->SetFileID(fileid); + firp->GetAddresses().insert(end_addr); + + const auto name="data_in_text_"+to_string(referenced_address); + const auto permissions=0x4; /* R-- */ + const auto is_relro=false; + auto newscoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, name, start_addr, end_addr, NULL, permissions, is_relro, the_contents); + firp->GetDataScoops().insert(newscoop); + + cout<<"Allocated data in text segment "<<name<<"=("<<start_addr->GetVirtualOffset()<<"-" + <<end_addr->GetVirtualOffset()<<")"<<endl; + } +} + void PopulateCFG::fill_in_landing_pads(FileIR_t *firp) { const auto eh_frame_rep_ptr = split_eh_frame_t::factory(firp); @@ -617,7 +624,7 @@ int PopulateCFG::parseArgs(const vector<string> step_args) int PopulateCFG::executeStep(IRDBObjects_t *const irdb_objects) { - try + try { const auto pqxx_interface = irdb_objects->getDBInterface(); // now set the DB interface for THIS PLUGIN LIBRARY -- VERY IMPORTANT @@ -641,6 +648,7 @@ int PopulateCFG::executeStep(IRDBObjects_t *const irdb_objects) fill_in_cfg(firp); fill_in_scoops(firp); + detect_scoops_in_code(firp); if (fix_landing_pads) { @@ -670,7 +678,6 @@ int PopulateCFG::executeStep(IRDBObjects_t *const irdb_objects) assert(scoops_detected > 5 ); } - return 0; } diff --git a/libIRDB/test/fill_in_cfg.hpp b/libIRDB/test/fill_in_cfg.hpp index 5beb37871fbc9ed11100e160271c39ac49f5e79b..42c72625acc3a8072f42f801203880498d6c1fe7 100644 --- a/libIRDB/test/fill_in_cfg.hpp +++ b/libIRDB/test/fill_in_cfg.hpp @@ -46,6 +46,7 @@ class PopulateCFG : public libIRDB::Transform_SDK::TransformStep_t // main workers void fill_in_cfg(libIRDB::FileIR_t *); void fill_in_scoops(libIRDB::FileIR_t *); + void detect_scoops_in_code(libIRDB::FileIR_t *firp); void fill_in_landing_pads(libIRDB::FileIR_t *); // helpers diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp index 7da29e83b5670a4d9425e4ddf351d3df508c1123..8a32d8db5335b42c29057a0c4ce8f4a316d8d60a 100644 --- a/libIRDB/test/fill_in_indtargs.cpp +++ b/libIRDB/test/fill_in_indtargs.cpp @@ -184,20 +184,25 @@ EXEIO::section* find_section(virtual_offset_t addr, EXEIO::exeio *elfiop) return nullptr; } -void handle_argument(const DecodedOperand_t *arg, Instruction_t* insn, ibt_provenance_t::provtype_t pt = ibt_provenance_t::ibtp_text) +void handle_argument( + const DecodedInstruction_t& decoded_insn, + const DecodedOperand_t *arg, + Instruction_t* insn, + ibt_provenance_t::provtype_t pt = ibt_provenance_t::ibtp_text + ) { - if(arg->isMemory()) // (arg->ArgType&MEMORY_TYPE) == MEMORY_TYPE ) + if(arg->isMemory() && decoded_insn.getMnemonic()=="lea") { - if(arg->isPcrel()) // (arg->ArgType&RELATIVE_)==RELATIVE_) + if(arg->isPcrel()) { assert(insn); assert(insn->GetAddress()); - possible_target(arg->getMemoryDisplacement() /*arg->Memory.Displacement*/+insn->GetAddress()->GetVirtualOffset()+ + possible_target(arg->getMemoryDisplacement() + insn->GetAddress()->GetVirtualOffset() + insn->GetDataBits().length(), insn->GetAddress()->GetVirtualOffset(), pt); } else { - possible_target(arg->getMemoryDisplacement() /* arg->Memory.Displacement*/, insn->GetAddress()->GetVirtualOffset(), pt); + possible_target(arg->getMemoryDisplacement(), insn->GetAddress()->GetVirtualOffset(), pt); } } } @@ -305,14 +310,8 @@ bool texttoprintf(FileIR_t *firp,Instruction_t* insn) void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<virtual_offset_t>& thunk_bases) { - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->GetInstructions()) { - Instruction_t *insn=*it; - // DISASM disasm; DecodedInstruction_t disasm(insn); virtual_offset_t instr_len = disasm.length(); // Disassemble(insn,disasm); @@ -360,7 +359,7 @@ void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<vir if(disasm.hasOperand(i)) { const auto op=disasm.getOperand(i); - handle_argument(&op, insn, prov); + handle_argument(disasm, &op, insn, prov); } } } @@ -444,6 +443,24 @@ void infer_targets(FileIR_t *firp, section* shdr) } +void handle_scoop_scanning(FileIR_t* firp) +{ + // check for addresses in scoops in the text section. + for(auto scoop : firp->GetDataScoops()) + { + // test if scoop was added by fill_in_cfg -- make this test better. + if(scoop->GetName().find("data_in_text_")==string::npos) continue; + + // at the moment, FIC only creates 8-byte scoops from the .text segment. if this changes, this code needs updating. + assert((scoop->GetEnd()->GetVirtualOffset() - scoop->GetStart()->GetVirtualOffset() + 1) == 8 ); + + // check ot see if the scoop has an IBTA + const auto addr=*(uint64_t*)(scoop->GetContents().c_str()); + possible_target(addr, scoop->GetStart()->GetVirtualOffset(), ibt_provenance_t::ibtp_unknown); + } +} + + void print_targets() { @@ -953,7 +970,7 @@ void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, Dec Instruction_t* I5=insn; // check if I5 is a jump - if(strstr(disasm.getMnemonic().c_str()/*Instruction.Mnemonic*/, "jmp")==nullptr) + if(strstr(disasm.getMnemonic().c_str(), "jmp")==nullptr) return; // return if it's not a jump to a memory address @@ -1785,6 +1802,13 @@ void calc_preds(FileIR_t* firp) } } +void handle_takes_address_annot(FileIR_t* firp,Instruction_t* insn, MEDS_TakesAddressAnnotation* p_takes_address_annotation) +{ + if(!p_takes_address_annotation->isCode()) + return; + const auto refd_addr=p_takes_address_annotation->GetReferencedAddress(); + possible_target(refd_addr,insn->GetAddress()->GetVirtualOffset(), ibt_provenance_t::ibtp_text); +} void handle_ib_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBAnnotation* p_ib_annotation) { @@ -1897,24 +1921,18 @@ void handle_ibt_annot(FileIR_t* firp,Instruction_t* insn, MEDS_IBTAnnotation* p_ void read_stars_xref_file(FileIR_t* firp) { - string BINARY_NAME="a.ncexe"; - string SHARED_OBJECTS_DIR="shared_objects"; + const auto BINARY_NAME=string("a.ncexe"); + const auto SHARED_OBJECTS_DIR=string("shared_objects"); - string fileBasename = basename((char*)firp->GetFile()->GetURL().c_str()); - int ibs=0; - int ibts=0; + const auto fileBasename = string(basename((char*)firp->GetFile()->GetURL().c_str())); - MEDS_AnnotationParser annotationParser; - string annotationFilename; + auto annotationParser=MEDS_AnnotationParser(); // need to map filename to integer annotation file produced by STARS // this should be retrieved from the IRDB but for now, we use files to store annotations // convention from within the peasoup subdirectory is: // a.ncexe.infoannot // shared_objects/<shared-lib-filename>.infoannot - if (fileBasename==BINARY_NAME) - annotationFilename = BINARY_NAME; - else - annotationFilename = SHARED_OBJECTS_DIR + "/" + fileBasename ; + const auto annotationFilename =(fileBasename==BINARY_NAME) ? BINARY_NAME : SHARED_OBJECTS_DIR + "/" + fileBasename ; try { @@ -1925,43 +1943,29 @@ void read_stars_xref_file(FileIR_t* firp) cout<<"Warning: annotation parser reports error: "<<s<<endl; } - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn : firp->GetInstructions()) { - Instruction_t* insn=*it; - virtual_offset_t irdb_vo = insn->GetAddress()->GetVirtualOffset(); - VirtualOffset vo(irdb_vo); + const auto irdb_vo = insn->GetAddress()->GetVirtualOffset(); + const auto vo=VirtualOffset(irdb_vo); /* find it in the annotations */ - pair<MEDS_Annotations_t::iterator,MEDS_Annotations_t::iterator> ret; - ret = annotationParser.getAnnotations().equal_range(vo); - MEDS_IBAnnotation* p_ib_annotation; - MEDS_IBTAnnotation* p_ibt_annotation; + const auto ret = annotationParser.getAnnotations().equal_range(vo); /* for each annotation for this instruction */ - for (MEDS_Annotations_t::iterator ait = ret.first; ait != ret.second; ++ait) + for (auto ait = ret.first; ait != ret.second; ++ait) { /* is this annotation a funcSafe annotation? */ - p_ib_annotation=dynamic_cast<MEDS_IBAnnotation*>(ait->second); + const auto p_ib_annotation=dynamic_cast<MEDS_IBAnnotation*>(ait->second); + const auto p_ibt_annotation=dynamic_cast<MEDS_IBTAnnotation*>(ait->second); + const auto p_takes_address_annotation=dynamic_cast<MEDS_TakesAddressAnnotation*>(ait->second); if(p_ib_annotation && p_ib_annotation->isValid()) - { - ibs++; handle_ib_annot(firp,insn,p_ib_annotation); - } - p_ibt_annotation=dynamic_cast<MEDS_IBTAnnotation*>(ait->second); - if(p_ibt_annotation && p_ibt_annotation->isValid()) - { - ibts++; + else if(p_ibt_annotation && p_ibt_annotation->isValid()) handle_ibt_annot(firp,insn,p_ibt_annotation); - } + else if(p_takes_address_annotation && p_takes_address_annotation->isValid()) + handle_takes_address_annot(firp,insn,p_takes_address_annotation); } } - - cout<<"Found "<<ibs<<" ibs and "<<ibts<<" ibts in the STARSxref file."<<endl; - } void process_dynsym(FileIR_t* firp) @@ -1978,22 +1982,11 @@ void process_dynsym(FileIR_t* firp) ICFS_t* setup_hellnode(FileIR_t* firp, EXEIO::exeio* elfiop, ibt_provenance_t allowed) { - ICFS_t* hn=new ICFS_t(ICFS_Analysis_Module_Complete); + auto hn=new ICFS_t(ICFS_Analysis_Module_Complete); - for( - set<Instruction_t*>::const_iterator it=firp->GetInstructions().begin(); - it!=firp->GetInstructions().end(); - ++it - ) + for(auto insn: firp->GetInstructions()) { - Instruction_t* insn=*it; - - /* - if(insn->GetIndirectBranchTargetAddress() == nullptr) - continue; - */ - - ibt_provenance_t prov=targets[insn->GetAddress()->GetVirtualOffset()]; + auto prov=targets[insn->GetAddress()->GetVirtualOffset()]; if(prov.isEmpty()) continue; @@ -2836,13 +2829,12 @@ void fill_in_indtargs(FileIR_t* firp, exeio* elfiop, int64_t do_unpin_opt) /* look through each section and look for target possibilities */ for (secndx=0; secndx<secnum; secndx++) infer_targets(firp, elfiop->sections[secndx]); + + handle_scoop_scanning(firp); /* should move to separate function */ - auto forced_iterator = forced_pins.begin(); - for (; forced_iterator != forced_pins.end(); forced_iterator++) - { - possible_target(*forced_iterator, 0, ibt_provenance_t::ibtp_user); - } + for(auto pin : forced_pins ) + possible_target(pin, 0, ibt_provenance_t::ibtp_user); /* look through the instructions in the program for targets */ get_instruction_targets(firp, elfiop, thunk_bases); diff --git a/libMEDSannotation/include/MEDS_TakesAddressAnnotation.hpp b/libMEDSannotation/include/MEDS_TakesAddressAnnotation.hpp new file mode 100644 index 0000000000000000000000000000000000000000..524b100ac030bfbba02a15512540e9912d792029 --- /dev/null +++ b/libMEDSannotation/include/MEDS_TakesAddressAnnotation.hpp @@ -0,0 +1,99 @@ +/* + * 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 _MEDS_TAKENADDRESSANNOTATION_H_ +#define _MEDS_TAKENADDRESSANNOTATION_H_ + +#include <string> +#include "VirtualOffset.hpp" +#include "MEDS_AnnotationBase.hpp" +#include <iostream> + +namespace MEDS_Annotation +{ + +using namespace std; +using namespace MEDS_Annotation; + +// +// Class to handle one MEDS shadow annotation +// +class MEDS_TakesAddressAnnotation : public MEDS_AnnotationBase +{ + public: + typedef enum { SWITCH, RET, UNKNOWN } ib_type_t; + + MEDS_TakesAddressAnnotation( const string& p_rawLine) : + referenced_address(0), + m_isCode(false) + { + setInvalid(); + parse(p_rawLine); + + }; + + + virtual const std::string toString() const + { + std::string ret="TakesAddress="+to_string(referenced_address); + return ret; + } + + ApplicationAddress GetReferencedAddress() const { return referenced_address; } + bool isCode() const { return m_isCode; } + bool isData() const { return !m_isCode; } + + protected: + + void parse(const string& p_rawLine) + { + const auto tofind=string("INSTR XREF TAKES_ADDRESS_OF "); + const auto codestring=string("CODE"); + const auto pos=p_rawLine.find(tofind); + if(pos==string::npos) + return; + + // she be valid + setValid(); + + m_isCode=(p_rawLine.find(codestring)!=string::npos); + m_virtualOffset = VirtualOffset(p_rawLine); + + // skips over INSTR*{code|data} + const auto rest=p_rawLine.substr(pos+tofind.length()+codestring.length()); + istringstream is(rest); + is >> hex >>referenced_address; /* get the address */ + + // cout<<"Found takes_address of "<<m_virtualOffset.to_string() << " to " + // << hex << referenced_address<< " from '" << rest << "'"<<endl; + + + } + + + private: + + ApplicationAddress referenced_address; + bool m_isCode; +}; + +} + +#endif diff --git a/libMEDSannotation/include/libMEDSAnnotation.h b/libMEDSannotation/include/libMEDSAnnotation.h index a4bb39f5d2ed179b79fb0d0d83d8dc444d899d03..a4f17f37c494c7f2e0d8b5279b617ecc553999e0 100644 --- a/libMEDSannotation/include/libMEDSAnnotation.h +++ b/libMEDSannotation/include/libMEDSAnnotation.h @@ -10,6 +10,8 @@ #include "MEDS_FuncAnnotation.hpp" #include "MEDS_FuncPrototypeAnnotation.hpp" #include "MEDS.hpp" +#include "MEDS_TakesAddressAnnotation.hpp" +#include "MEDS_IBAnnotation.hpp" #include "MEDS_IBAnnotation.hpp" #include "MEDS_IBTAnnotation.hpp" #include "MEDS_InstructionCheckAnnotation.hpp" diff --git a/libMEDSannotation/src/MEDS_AnnotationParser.cpp b/libMEDSannotation/src/MEDS_AnnotationParser.cpp index de2b10055a40425ad299441e89b7f1b3ad249a6a..85e85a2e4cba5465bf6f576786d1e5c518754329 100644 --- a/libMEDSannotation/src/MEDS_AnnotationParser.cpp +++ b/libMEDSannotation/src/MEDS_AnnotationParser.cpp @@ -30,6 +30,7 @@ #include "MEDS_FRSafeAnnotation.hpp" #include "MEDS_FPTRShadowAnnotation.hpp" #include "MEDS_DeadRegAnnotation.hpp" +#include "MEDS_TakesAddressAnnotation.hpp" #include "MEDS_IBAnnotation.hpp" #include "MEDS_IBTAnnotation.hpp" #include "MEDS_MemoryRangeAnnotation.hpp" @@ -87,26 +88,24 @@ template <class type> bool MEDS_AnnotationParser::add_if_valid(string line) void MEDS_AnnotationParser::parseFile(istream &p_inputStream) { - string line; - while (!p_inputStream.eof()) { + auto line=string(); getline(p_inputStream, line); if (line.empty()) continue; - - if(add_if_valid<MEDS_DeadRegAnnotation>(line)) continue; - if(add_if_valid<MEDS_FPTRShadowAnnotation>(line)) continue; - if(add_if_valid<MEDS_InstructionCheckAnnotation>(line)) continue; - if(add_if_valid<MEDS_FuncPrototypeAnnotation>(line)) continue; - if(add_if_valid<MEDS_SafeFuncAnnotation>(line)) continue; - if(add_if_valid<MEDS_ProblemFuncAnnotation>(line)) continue; - if(add_if_valid<MEDS_FRSafeAnnotation>(line)) continue; - if(add_if_valid<MEDS_FuncExitAnnotation>(line)) continue; - if(add_if_valid<MEDS_IBAnnotation>(line)) continue; - if(add_if_valid<MEDS_IBTAnnotation>(line)) continue; - if (add_if_valid<MEDS_MemoryRangeAnnotation>(line)) continue; - + if(add_if_valid<MEDS_DeadRegAnnotation> (line)) continue; + if(add_if_valid<MEDS_FPTRShadowAnnotation> (line)) continue; + if(add_if_valid<MEDS_InstructionCheckAnnotation> (line)) continue; + if(add_if_valid<MEDS_FuncPrototypeAnnotation> (line)) continue; + if(add_if_valid<MEDS_SafeFuncAnnotation> (line)) continue; + if(add_if_valid<MEDS_ProblemFuncAnnotation> (line)) continue; + if(add_if_valid<MEDS_FRSafeAnnotation> (line)) continue; + if(add_if_valid<MEDS_FuncExitAnnotation> (line)) continue; + if(add_if_valid<MEDS_TakesAddressAnnotation> (line)) continue; + if(add_if_valid<MEDS_IBAnnotation> (line)) continue; + if(add_if_valid<MEDS_IBTAnnotation> (line)) continue; + if(add_if_valid<MEDS_MemoryRangeAnnotation> (line)) continue; } }