From 678c69979e47d7b477291008075d6521ac53389f Mon Sep 17 00:00:00 2001 From: jdh8d <jdh8d@git.zephyr-software.com> Date: Thu, 9 Jun 2016 18:24:48 +0000 Subject: [PATCH] support in zipr for better mapping of scoops->section types, support in move-globals to move only the necessary bits for adding to the .got.plt, and relocation tables, etc. also first support in CFI for multi-module support (not working yet, but can add relocations and got entries for dladdr, dlsym, and,zestcfi) --- include/elfwrite.h | 9 ++- src/elfwrite.cpp | 181 +++++++++++++++++++++++++++------------------ src/zipr.cpp | 2 +- 3 files changed, 114 insertions(+), 78 deletions(-) diff --git a/include/elfwrite.h b/include/elfwrite.h index be4aa2f..d984fab 100644 --- a/include/elfwrite.h +++ b/include/elfwrite.h @@ -129,7 +129,7 @@ class ElfWriter // -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> class ElfWriterImpl : public ElfWriter { public: @@ -170,8 +170,11 @@ class ElfWriterImpl : public ElfWriter std::vector<T_Elf_Phdr> new_phdrs; }; -typedef class ElfWriterImpl<ELFIO::Elf64_Ehdr, ELFIO::Elf64_Phdr, ELFIO::Elf64_Addr, ELFIO::Elf64_Shdr> ElfWriter64; -typedef class ElfWriterImpl<ELFIO::Elf32_Ehdr, ELFIO::Elf32_Phdr, ELFIO::Elf32_Addr, ELFIO::Elf32_Shdr> ElfWriter32; +typedef class ElfWriterImpl<ELFIO::Elf64_Ehdr, ELFIO::Elf64_Phdr, ELFIO::Elf64_Addr, + ELFIO::Elf64_Shdr, ELFIO::Elf64_Sym, ELFIO::Elf64_Rel, ELFIO::Elf64_Rela, ELFIO::Elf64_Dyn> ElfWriter64; + +typedef class ElfWriterImpl<ELFIO::Elf32_Ehdr, ELFIO::Elf32_Phdr, ELFIO::Elf32_Addr, + ELFIO::Elf32_Shdr, ELFIO::Elf32_Sym, ELFIO::Elf32_Rel, ELFIO::Elf32_Rela, ELFIO::Elf32_Dyn> ElfWriter32; diff --git a/src/elfwrite.cpp b/src/elfwrite.cpp index cbdf7fa..3c30349 100644 --- a/src/elfwrite.cpp +++ b/src/elfwrite.cpp @@ -213,15 +213,15 @@ void ElfWriter::CreateSegmap(const ELFIO::elfio *elfiop, FileIR_t* firp, const s -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr, T_Elf_Shdr>::LoadEhdr(FILE* fin) +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr, T_Elf_Shdr, T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::LoadEhdr(FILE* fin) { fseek(fin,0,SEEK_SET); fread(&ehdr,sizeof(ehdr), 1, fin); }; -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::LoadPhdrs(FILE* fin) +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr, T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::LoadPhdrs(FILE* fin) { fseek(fin,ehdr.e_phoff,SEEK_SET); phdrs.resize(ehdr.e_phnum); @@ -231,8 +231,8 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::LoadPhdrs(FILE* } }; -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs( +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr, T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::CreateNewPhdrs( const libIRDB::virtual_offset_t &min_addr, const libIRDB::virtual_offset_t &max_addr) { @@ -263,16 +263,16 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs( } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs_PostAllocate( +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::CreateNewPhdrs_PostAllocate( const libIRDB::virtual_offset_t &min_addr, const libIRDB::virtual_offset_t &max_addr) { // post allocation not enabled, yet. return false; } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs_FirstPageAllocate( +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::CreateNewPhdrs_FirstPageAllocate( const libIRDB::virtual_offset_t &min_addr, const libIRDB::virtual_offset_t &max_addr) { // check to see if there's room on the first page for @@ -286,8 +286,8 @@ bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs_ assert(0); } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr, T_Elf_Shdr>::readonly_space_at( +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr, T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::readonly_space_at( const libIRDB::virtual_offset_t addr, const unsigned int size) { for(unsigned int i=0;i<size;i++) @@ -309,8 +309,8 @@ bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr, T_Elf_Shdr>::readonly_space return true; } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -int ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::locate_segment_index(const libIRDB::virtual_offset_t addr) +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +int ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::locate_segment_index(const libIRDB::virtual_offset_t addr) { // segment's are sorted by address. for(unsigned int i=0;i<segvec.size();i++) @@ -330,8 +330,8 @@ int ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::locate_segment_i return -1; } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -unsigned int ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::count_filesz_to_seg(unsigned int seg) +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +unsigned int ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::count_filesz_to_seg(unsigned int seg) { unsigned int filesz=0; // segment's are sorted by address. @@ -342,8 +342,8 @@ unsigned int ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::count_f return filesz; } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs_GapAllocate( +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::CreateNewPhdrs_GapAllocate( const libIRDB::virtual_offset_t &min_addr, const libIRDB::virtual_offset_t &max_addr) { /* for shared objects, we need the PHDR file offset to be equal to the @@ -421,16 +421,16 @@ bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs_ } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs_PreAllocate( +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::CreateNewPhdrs_PreAllocate( const libIRDB::virtual_offset_t &min_addr, const libIRDB::virtual_offset_t &max_addr) { libIRDB::virtual_offset_t new_phdr_addr=(T_Elf_Addr)page_align(min_addr)-PAGE_SIZE+sizeof(T_Elf_Ehdr); return CreateNewPhdrs_internal(min_addr,max_addr,0x1000,true, sizeof(T_Elf_Ehdr), new_phdr_addr); } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -DataScoop_t* ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::find_scoop_by_name(const string& name, FileIR_t* firp) +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +DataScoop_t* ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::find_scoop_by_name(const string& name, FileIR_t* firp) { for(DataScoopSet_t::iterator it=firp->GetDataScoops().begin(); it!=firp->GetDataScoops().end(); ++it) { @@ -442,28 +442,28 @@ DataScoop_t* ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::find_sc return NULL; } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::update_phdr_for_scoop_sections(FileIR_t* firp) +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::update_phdr_for_scoop_sections(FileIR_t* firp) { // look at each header. - for(auto i=0;i<new_phdrs.size(); i++) + for(unsigned i=0;i<new_phdrs.size(); i++) { // this struct is a table/constant for mapping PT_names to section names. struct pt_type_to_sec_name_t { - int pt_type; + unsigned int pt_type; const char* sec_name; } pt_type_to_sec_name[] = { {PT_INTERP, ".interp"}, {PT_DYNAMIC, ".dynamic"}, {PT_NOTE, ".note.ABI-tag"}, - {PT_GNU_EH_FRAME, ".eh_frame_hdr"}, + {PT_GNU_EH_FRAME, ".eh_frame_hdr"} }; // check if a type of header listed above. - for(auto k=0;k<(sizeof(pt_type_to_sec_name)/sizeof(pt_type_to_sec_name_t)); k++) + for(unsigned k=0;k<(sizeof(pt_type_to_sec_name)/sizeof(pt_type_to_sec_name_t)); k++) { // check if a type of header listed above. if(new_phdrs[i].p_type==pt_type_to_sec_name[k].pt_type) @@ -480,7 +480,7 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::update_phdr_fo new_phdrs[i].p_memsz = scoop->GetEnd()->GetVirtualOffset() - scoop->GetStart()->GetVirtualOffset() + 1; new_phdrs[i].p_offset=0; - for(auto j=0;j<new_phdrs.size(); j++) + for(unsigned j=0;j<new_phdrs.size(); j++) { if( new_phdrs[j].p_vaddr<= new_phdrs[i].p_vaddr && new_phdrs[i].p_vaddr < new_phdrs[j].p_vaddr+new_phdrs[j].p_filesz) @@ -497,8 +497,8 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::update_phdr_fo } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs_internal( +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::CreateNewPhdrs_internal( const libIRDB::virtual_offset_t &min_addr, const libIRDB::virtual_offset_t &max_addr, const int &first_seg_file_offset, @@ -668,8 +668,8 @@ bool ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::CreateNewPhdrs_ return true; } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::WriteElf(FILE* fout) +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::WriteElf(FILE* fout) { assert(fout); @@ -722,8 +722,8 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::WriteElf(FILE* fwrite(new_phdrs.data(), sizeof(new_phdrs[0]), new_phdrs.size(), fout); } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -unsigned int ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::DetermineMaxPhdrSize() +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +unsigned int ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::DetermineMaxPhdrSize() { unsigned int phdr_count=0; /* count phdr's that aren't pt_load or pt_phdr */ @@ -750,44 +750,12 @@ unsigned int ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::Determi return phdr_count*sizeof(T_Elf_Phdr); } -template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr> -void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr>::AddSections(FILE* fout) +template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> +void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_Rel, T_Elf_Rela, T_Elf_Dyn>::AddSections(FILE* fout) { fseek(fout,0,SEEK_END); long cur_file_pos=ftell(fout); - /* -struct { - Elf64_Word st_name; - unsigned char st_info; - unsigned char st_other; - Elf64_Section st_shndx; - Elf64_Addr st_value; - Elf64_Xword st_size; -} Elf64_Sym -struct { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Section st_shndx; -} Elf32_Sym - - typedef struct { - Elf32_Word sh_name; // index into str table - Elf32_Word sh_type; // sht_progbits, sht, sht_strtab, sht_symtab, - Elf32_Word sh_flags; // permissios - Elf32_Addr sh_addr; // scoop->GetStart() - Elf32_Off sh_offset; // correlate to a segment. - Elf32_Word sh_size; // GetStart-GetEnd - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; - } Elf32_Shdr - */ - StringTable_t strtab; map<DataScoop_t*,size_t> file_positions; @@ -829,13 +797,56 @@ struct { shdrs.push_back(null_shdr); + struct section_type_map_t + { + string name; + unsigned int type; + unsigned int sh_ent_size; + string link; + } section_type_map[]={ + {".init_array", SHT_INIT_ARRAY, 0, "" }, + {".fini_array", SHT_FINI_ARRAY, 0, "" }, + {".dynamic", SHT_DYNAMIC, sizeof(T_Elf_Dyn), ".dynstr"}, + {".note.ABI-tag", SHT_NOTE, 0, ""}, + {".note.gnu.build-id", SHT_NOTE, 0, ""}, + {".gnu.hash", SHT_GNU_HASH, 0, ".dynsym"}, + {".dynsym", SHT_DYNSYM, sizeof(T_Elf_Sym), ".dynstr"}, + {".dynstr", SHT_STRTAB, 0, ""}, + {".shstrtab", SHT_STRTAB, 0, ""}, + {".symtab", SHT_SYMTAB, sizeof(T_Elf_Sym), ""}, + {".strtab", SHT_STRTAB, 0, ""}, + {".rel.dyn", SHT_REL, sizeof(T_Elf_Rel), ""}, + {".rela.dyn", SHT_RELA, sizeof(T_Elf_Rela), ".dynsym"}, + {".rel.plt", SHT_REL, sizeof(T_Elf_Rel), ".dynsym"}, + {".rela.plt", SHT_RELA, sizeof(T_Elf_Rela), ".dynsym"}, + {".gnu.version", SHT_GNU_versym, 2, ".dynsym"}, + {".gnu.version_r",SHT_GNU_verneed, 0, ".dynstr"}, + {".rela.dyn coalesced w/.rela.plt", SHT_RELA, sizeof(T_Elf_Rela), ".dynsym"} + }; + + // for each scoop, pushback an shdr for_each(m_firp->GetDataScoops().begin(), m_firp->GetDataScoops().end(), [&](DataScoop_t* scoop) { T_Elf_Shdr shdr; shdr. sh_name =strtab.location(scoop->GetName()); - shdr. sh_type = SHT_PROGBITS; // sht_progbits, sht, sht_strtab, sht_symtab, ... + + auto it=find_if(begin(section_type_map), end(section_type_map), [&scoop](const section_type_map_t &sm) + { + return scoop->GetName()==sm.name; + }); + if(end(section_type_map) != it) + { + cout<<"Setting ent-size for "<<scoop->GetName()<<" to "<<dec<<it->sh_ent_size<<endl; + shdr. sh_type = it->type; // sht_progbits, sht, sht_strtab, sht_symtab, ... + shdr. sh_entsize = it->sh_ent_size; + } + else + { + shdr. sh_type = SHT_PROGBITS; // sht_progbits, sht, sht_strtab, sht_symtab, ... + shdr. sh_entsize = 0; + } shdr. sh_flags = SHF_ALLOC; // scoop->getRawPerms(); if(scoop->isExecuteable()) shdr. sh_flags |= SHF_EXECINSTR; @@ -843,14 +854,36 @@ struct { shdr. sh_flags |= SHF_WRITE; shdr. sh_addr = scoop->GetStart()->GetVirtualOffset(); shdr. sh_offset =file_positions[scoop]; - shdr. sh_size = scoop->GetEnd()->GetVirtualOffset() - scoop->GetStart()->GetVirtualOffset(); + shdr. sh_size = scoop->GetEnd()->GetVirtualOffset() - scoop->GetStart()->GetVirtualOffset() + 1; shdr. sh_link = SHN_UNDEF; shdr. sh_info = 0 ; shdr. sh_addralign= 0 ; // scoop->GetAlign(); doesn't exist? - shdr. sh_entsize =0 ; shdrs.push_back(shdr); }); + auto scoop_it=m_firp->GetDataScoops().begin(); + for(unsigned int i=1; i<shdrs.size(); i++) // skip null shdr + { + T_Elf_Shdr & shdr = shdrs[i]; + auto map_it=find_if(begin(section_type_map), end(section_type_map), [&scoop_it](const section_type_map_t &sm) + { + return (*scoop_it)->GetName()==sm.name; + }); + if(end(section_type_map) != map_it && map_it->link!="") + { + auto link_it=m_firp->GetDataScoops().begin(); + for(unsigned int j=1; j<shdrs.size(); j++) // skip null shdr + { + if((*link_it)->GetName() == map_it->link) + { + shdr.sh_link=j; + break; + } + link_it++; + } + } + scoop_it++; + } T_Elf_Shdr symtab_shdr; symtab_shdr. sh_name =strtab.location(zipr_symtab); @@ -882,6 +915,6 @@ struct { } // explicit instantation of methods for 32- and 64-bit classes. -template class ElfWriterImpl<ELFIO::Elf64_Ehdr, ELFIO::Elf64_Phdr, ELFIO::Elf64_Addr, ELFIO::Elf64_Shdr>; -template class ElfWriterImpl<ELFIO::Elf32_Ehdr, ELFIO::Elf32_Phdr, ELFIO::Elf32_Addr, ELFIO::Elf32_Shdr>; +template class ElfWriterImpl<ELFIO::Elf64_Ehdr, ELFIO::Elf64_Phdr, ELFIO::Elf64_Addr, ELFIO::Elf64_Shdr, ELFIO::Elf64_Sym, ELFIO::Elf64_Rel, ELFIO::Elf64_Rela, ELFIO::Elf64_Dyn>; +template class ElfWriterImpl<ELFIO::Elf32_Ehdr, ELFIO::Elf32_Phdr, ELFIO::Elf32_Addr, ELFIO::Elf32_Shdr, ELFIO::Elf32_Sym, ELFIO::Elf32_Rel, ELFIO::Elf32_Rela, ELFIO::Elf32_Dyn>; diff --git a/src/zipr.cpp b/src/zipr.cpp index b305610..4fc5265 100644 --- a/src/zipr.cpp +++ b/src/zipr.cpp @@ -488,7 +488,7 @@ void ZiprImpl_t::CreateExecutableScoops(const std::map<RangeAddress_t, int> &ord // setup a scoop for this section. // zero init is OK, after zipring we'll update with the right bytes. string text_contents; - text_contents.resize(text_end->GetVirtualOffset() - text_start->GetVirtualOffset()); + text_contents.resize(text_end->GetVirtualOffset() - text_start->GetVirtualOffset()+1); DataScoop_t* text_scoop=new DataScoop_t(BaseObj_t::NOT_IN_DATABASE, string(".zipr_text_")+to_string(count++), text_start, text_end, NULL, 5, false, text_contents); m_firp->GetDataScoops().insert(text_scoop); -- GitLab