From 17c2172cfd219215d2fbd0b990c58cf57beed06a Mon Sep 17 00:00:00 2001 From: jdh8d <jdh8d@git.zephyr-software.com> Date: Fri, 15 Sep 2017 15:44:41 +0000 Subject: [PATCH] Added emt support for prefork+bilr+p1 (sketchy still), K6+NOG (seems stable with all xforms enabled). I also did some peasoup/cfar fixes to support determunistic ID assignment for IRDB objects -- this was needed for marshaling because the EMT plugin uses ID matching to find identical objects (stack, scoop, instruction, etc.) Next, I fixed bugs in p1transform where the p1.map wasn't getting proper IDs. Lastly, I added an option to zipr/elfwrite to disable bss-optimization, this was necessary for marshaling as that bss segments stay named/mapped to the binary and cannot be combined with other segments. --- include/elfwrite.h | 17 ++++++++++++++-- include/zipr_impl.h | 3 ++- src/elfwrite.cpp | 49 +++++++++++++++++++++++++++++++++------------ src/zipr.cpp | 6 ++++-- 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/include/elfwrite.h b/include/elfwrite.h index 0c412bb..eaa2bb9 100644 --- a/include/elfwrite.h +++ b/include/elfwrite.h @@ -70,6 +70,18 @@ class ElfWriter public: LoadSegment_t() :filesz(0), memsz(0), filepos(0), start_page(0), m_perms(0) { } + LoadSegment_t( unsigned int p_filesz, unsigned int p_memsz, unsigned int p_filepos, unsigned int p_start_page, unsigned int p_m_perms) + : + filesz(p_filesz), + memsz(p_memsz), + filepos(p_filepos), + start_page(p_start_page), + m_perms(p_m_perms) + { + + } + + unsigned int filesz; unsigned int memsz; unsigned int filepos; @@ -82,7 +94,7 @@ class ElfWriter typedef std::map<libIRDB::virtual_offset_t, PageData_t> PageMap_t; public: - ElfWriter(libIRDB::FileIR_t* firp, bool write_sections) : m_firp(firp), m_write_sections(write_sections) { } + ElfWriter(libIRDB::FileIR_t* firp, bool write_sections, bool bss_opts) : m_firp(firp), m_write_sections(write_sections), m_bss_opts(bss_opts) { } virtual ~ElfWriter() {} void Write(const ELFIO::elfio *elfiop, libIRDB::FileIR_t* firp, const std::string &out_file, const std::string &infile); @@ -112,6 +124,7 @@ class ElfWriter protected: libIRDB::FileIR_t* m_firp; bool m_write_sections; + bool m_bss_opts; private: libIRDB::virtual_offset_t DetectMinAddr(const ELFIO::elfio *elfiop, libIRDB::FileIR_t* firp, const std::string &out_file); libIRDB::virtual_offset_t DetectMaxAddr(const ELFIO::elfio *elfiop, libIRDB::FileIR_t* firp, const std::string &out_file); @@ -134,7 +147,7 @@ class ElfWriterImpl : public ElfWriter { public: - ElfWriterImpl(libIRDB::FileIR_t* firp, bool write_sections) : ElfWriter(firp, write_sections) { } + ElfWriterImpl(libIRDB::FileIR_t* firp, bool write_sections, bool bss_opts ) : ElfWriter(firp, write_sections, bss_opts) { } protected: int GetFileHeaderSize() { return sizeof(T_Elf_Ehdr); } diff --git a/include/zipr_impl.h b/include/zipr_impl.h index f4a340d..44824fd 100644 --- a/include/zipr_impl.h +++ b/include/zipr_impl.h @@ -55,6 +55,7 @@ class ZiprImpl_t : public Zipr_t m_verbose("verbose", true), m_apply_nop("apply_nop", false), m_add_sections("add-sections", false), + m_bss_opts("bss-opts", true), m_variant("variant"), m_architecture("architecture"), m_seed("seed", 0), @@ -490,7 +491,7 @@ class ZiprImpl_t : public Zipr_t // Options ZiprOptions_t m_zipr_options; ZiprStringOption_t m_output_filename, m_callbacks, m_objcopy; - ZiprBooleanOption_t m_replop, m_verbose, m_apply_nop, m_add_sections; + ZiprBooleanOption_t m_replop, m_verbose, m_apply_nop, m_add_sections, m_bss_opts; ZiprIntegerOption_t m_variant, m_architecture, m_seed; ZiprStringOption_t m_dollop_map_filename; diff --git a/src/elfwrite.cpp b/src/elfwrite.cpp index e65edb0..4b63029 100644 --- a/src/elfwrite.cpp +++ b/src/elfwrite.cpp @@ -156,34 +156,50 @@ void ElfWriter::SortSegmap() void ElfWriter::CreateSegmap(const ELFIO::elfio *elfiop, FileIR_t* firp, const string &out_file) { + const auto should_bss_optimize= [&] (const PageData_t& perms) + { + return (perms.is_zero_initialized() && m_bss_opts); + }; + + + // init some segment vars. - virtual_offset_t segstart=pagemap.begin()->first; - PageData_t segperms=pagemap.begin()->second; - virtual_offset_t segend=segstart+PAGE_SIZE; - virtual_offset_t initend=segstart; - if(pagemap.begin()->second.is_zero_initialized()) - initend=segstart; - else - initend=segend; + auto segstart=pagemap.begin()->first; + auto segperms=pagemap.begin()->second; + auto segend=segstart+PAGE_SIZE; + auto initend=segstart; - PageMap_t::iterator it=pagemap.begin(); + const auto update_initend=[&](const PageData_t& perms) + { + if(should_bss_optimize(perms)) + initend=segstart; + else + initend=segend; + }; + + update_initend(segperms); + + auto it=pagemap.begin(); ++it; // handled first one above. for( /* init'd above */; it!=pagemap.end(); ++it) { // grab page address and perms - virtual_offset_t pagestart=it->first; - const PageData_t &perms=it->second; + const auto pagestart=it->first; + const auto &perms=it->second; // if we switch perms, or skip a page if( (perms.m_perms!=segperms.m_perms) || (segend!=pagestart)) { +/* LoadSegment_t *seg=new LoadSegment_t; seg->memsz=segend-segstart; seg->filesz=initend-segstart; seg->start_page=segstart; seg->m_perms=segperms.m_perms; +*/ + const auto seg=new LoadSegment_t(initend-segstart, segend-segstart, 0, segstart,segperms.m_perms); segvec.push_back(seg); cout<<"Found segment "<<hex<<segstart<<"-"<<(segend-1)<<", perms="<<segperms.m_perms<<", memsz="<<seg->memsz<<", filesz="<<seg->filesz<<endl; @@ -191,28 +207,35 @@ void ElfWriter::CreateSegmap(const ELFIO::elfio *elfiop, FileIR_t* firp, const s segperms=perms; segstart=pagestart; segend=segstart+PAGE_SIZE; - if(perms.is_zero_initialized()) + + update_initend(perms); +/* + if( should_bss_optimize(perms) ) // perms.is_zero_initialized() && m_bss_opts) initend=segstart; else initend=segend; +*/ } else { // else, same permission and next page, extend segment. segend=pagestart+PAGE_SIZE; - if(!perms.is_zero_initialized()) + if(! should_bss_optimize(perms) ) // !perms.is_zero_initialized() || ! m_bss_opts) initend=pagestart+PAGE_SIZE; } } // make sure we print the last one +/* LoadSegment_t *seg=new LoadSegment_t; seg->memsz=segend-segstart; seg->filesz=initend-segstart; seg->start_page=segstart; seg->m_perms=segperms.m_perms; +*/ + const auto seg=new LoadSegment_t(initend-segstart, segend-segstart, 0, segstart,segperms.m_perms); segvec.push_back(seg); cout<<"Found segment "<<hex<<segstart<<"-"<<(segend-1)<<", perms="<<segperms.m_perms<<", memsz="<<seg->memsz<<", filesz="<<seg->filesz<<endl; diff --git a/src/zipr.cpp b/src/zipr.cpp index c71d9d1..addf5e7 100644 --- a/src/zipr.cpp +++ b/src/zipr.cpp @@ -156,6 +156,7 @@ ZiprOptionsNamespace_t *ZiprImpl_t::RegisterOptions(ZiprOptionsNamespace_t *glob m_add_sections.SetDescription("Enable writing of section headers using elfwriter."); + m_bss_opts.SetDescription("Enable/Disable optimizing BSS segments so they aren't written to the binary."); m_verbose.SetDescription("Enable verbose output"); m_apply_nop.SetDescription("Apply NOP to patches that fallthrough."); m_variant.SetDescription("Variant ID."); @@ -185,6 +186,7 @@ ZiprOptionsNamespace_t *ZiprImpl_t::RegisterOptions(ZiprOptionsNamespace_t *glob global->AddOption(&m_verbose); global->AddOption(&m_apply_nop); global->AddOption(&m_add_sections); + global->AddOption(&m_bss_opts); zipr_namespace->MergeNamespace(memory_space.RegisterOptions(global)); return zipr_namespace; @@ -3729,11 +3731,11 @@ void ZiprImpl_t::OutputBinaryFile(const string &name) ElfWriter *ew=NULL; if(m_firp->GetArchitectureBitWidth()==64) { - ew=new ElfWriter64(m_firp, m_add_sections); + ew=new ElfWriter64(m_firp, m_add_sections, m_bss_opts); } else if(m_firp->GetArchitectureBitWidth()==32) { - ew=new ElfWriter32(m_firp, m_add_sections); + ew=new ElfWriter32(m_firp, m_add_sections, m_bss_opts); } else assert(0); -- GitLab