Skip to content
Snippets Groups Projects
mg.cpp 71.7 KiB
Newer Older
				// we just created s2 in this pass, right?
				// no, s2 could be one of the sections from the orig binary that we've been asked to move
				// and it might have relocs for unpinning
				//assert(s2->getRelocations().size()==0); // assert no relocs that're part of s2.

				// add s2's relocs to s1.
				for(auto reloc : s2->getRelocations())
				{
					cout<<"Adjusting reloc "<< s2->getName()<<"+"<<reloc->getOffset()<<":"<<reloc->getType()<<" to ";

					reloc->setOffset(reloc->getOffset()+old_s1_size);

					auto s1_relocs=s1->getRelocations();
					s1_relocs.insert(reloc);
					s1->setRelocations(s1_relocs);
	
					cout << s1->getName()<<"+"<<reloc->getOffset()<<":"<<reloc->getType()<<endl;
				}

				// tell s2 it has no relocs so when we remove it, they don't go away.
				s2->setRelocations({});

				// we've processed this one.
				tied_scoops.erase(current);	
				auto scoop_pair_first_finder=
					[s2](const ScoopPair_t& p2)
					{
						return (p2.first==s2);	
					};
				auto found=find_if(ALLOF(tied_scoops), scoop_pair_first_finder);
				if( found!=tied_scoops.end())
				{
					ScoopPair_t p2=*found;
					p2.first=s1;
					tied_scoops.erase(found);
					tied_scoops.insert(p2);
				}
				assert(find_if(ALLOF(tied_scoops), scoop_pair_first_finder) ==tied_scoops.end());

				// finally remove s2 from the IR.
				getFileIR()->removeScoop(s2);
				changed=true;
				break;
			}
			else
				assert(0); // why are there pinned scoops still?
		}
	}
	// ensure we handled eveything.
	assert(tied_scoops.size()==0);
	
}

template <class T_Sym, class  T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
void MoveGlobals_t<T_Sym,T_Rela,T_Rel,T_Dyn,T_Extractor>::UpdateScoopLocations()
{

	// apply all 3 types of relocs for instructions
	for_each(ALLOF(pcrel_refs_to_scoops),
		[this] (const Insn_fixup_t  & it)
	{
			cout << "Applying pcrel w/wrt from " << it.from->getDisassembly() << " to " << it.to->getName() << " at " << hex << it.from->getBaseID() << endl;
		ApplyPcrelMemoryRelocation(it.from,it.to);
	});

	for_each(ALLOF(absolute_refs_to_scoops),
		[this] (const Insn_fixup_t  & it)
	{
			cout << "Applying absptr_to_scoop from " << it.from->getDisassembly() << " to " << it.to->getName() << " at " << hex << it.from->getBaseID() << endl;
		ApplyAbsoluteMemoryRelocation(it.from,it.to);
	});

	for_each(ALLOF(immed_refs_to_scoops),
		[this] (const Insn_fixup_t  & it)
	{
			cout << "Applying immedptr_to_scoop from " << it.from->getDisassembly() << " to " << it.to->getName() << " at " << hex << it.from->getBaseID() << endl;
		ApplyImmediateRelocation(it.from, it.to);
	});
	for_each(ALLOF(data_refs_to_scoops),
		[this] (const Scoop_fixup_t  & it)
	{
			cout << "Applying dataptr_to_scoop from " << it.from->getName() << " to " << it.to->getName() << " at " << hex << it.offset << endl;
		ApplyDataRelocation(it.from, it.offset, it.to);
	});


	// unpin all the moveable scoops.
	for (auto sit : moveable_scoops)
	{
		VirtualOffset_t newend = sit->getEnd()->getVirtualOffset() -  sit->getStart()->getVirtualOffset();
		sit->getEnd()->setVirtualOffset(newend);
		sit->getStart()->setVirtualOffset(0);
	}
}

// would be nice to have a FindRelocation function that takes a parameterized type.
template <class T_Sym, class  T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
Relocation_t* MoveGlobals_t<T_Sym,T_Rela,T_Rel,T_Dyn,T_Extractor>::FindRelocationWithType(BaseObj_t* obj, std::string type)
{
	for(auto reloc : obj->getRelocations())
	{
		if (reloc->getType() == type)
			return reloc;
	}
	return NULL;
}

template <class T_Sym, class  T_Rela, class T_Rel, class T_Dyn, class T_Extractor>
void MoveGlobals_t<T_Sym,T_Rela,T_Rel,T_Dyn,T_Extractor>::PrintStats()
{
	const auto resorted_moveable_scoops=DataScoopSet_t(ALLOF(moveable_scoops));
	DataScoopSet_t unmoveable_scoops;
	unsigned long long moveable_scoop_bytes=0;
	unsigned long long unmoveable_scoop_bytes=0;
	unsigned long long total_scoop_bytes=0;

	set_difference(
		ALLOF(getFileIR()->getDataScoops()),
		ALLOF(resorted_moveable_scoops),
		inserter(unmoveable_scoops,unmoveable_scoops.end()));
		
	
	{
		cout<<"Moveable scoops: "<<endl;
		for_each(ALLOF(moveable_scoops), [](DataScoop_t* scoop)
		{
			cout<<"\t"<<scoop->getName()<<", contents: "<<endl;
			auto i=0u;
			const auto max_prints_env=getenv("MG_MAX_SCOOP_CONTENT_PRINT");
			const auto max_prints=max_prints_env ? strtoul(max_prints_env,NULL,0) : 16ul; 

			for(i=0;i+8<scoop->getSize() && i<max_prints;i+=8)
				cout<<"\t\tat:"<<hex<<i<<" value:0x"<<hex<<*(uint64_t*)&scoop->getContents().c_str()[i]<<" "<<endl;
			for(/* empty init */;i<scoop->getSize() && i<max_prints;i++)
				cout<<"\t\tat:"<<hex<<i<<" value:0x"<<hex<< + *(uint8_t*)&scoop->getContents().c_str()[i]<<" "<<endl;
		});
		cout<<"Not moveable scoops: "<<endl;
		for_each(ALLOF(unmoveable_scoops), [](DataScoop_t* scoop)
		{
			cout<<"\t"<<scoop->getName()<<" at  "<<hex<<scoop->getStart()->getVirtualOffset()<<endl;
		});
	}
	// gather number of moveable bytes	
	for_each(moveable_scoops.begin(), moveable_scoops.end(), [&moveable_scoop_bytes, &total_scoop_bytes](DataScoop_t* scoop)
	{
		moveable_scoop_bytes += scoop->getSize();
		total_scoop_bytes+=scoop->getSize();
	});

	// gather number of unmoveable bytes
	for_each(unmoveable_scoops.begin(), unmoveable_scoops.end(), [&unmoveable_scoop_bytes,&total_scoop_bytes](DataScoop_t* scoop)
	{
		unmoveable_scoop_bytes +=scoop->getSize();
		total_scoop_bytes+=scoop->getSize();
	});

        assert(getenv("SELF_VALIDATE")==nullptr || moveable_scoops.size() >= 5);
        assert(getenv("SELF_VALIDATE")==nullptr || (immed_refs_to_scoops.size() + pcrel_refs_to_scoops.size()+absolute_refs_to_scoops.size()) > 5);


	cout<<"# ATTRIBUTE ASSURANCE_Non-Overlapping_Globals::Total_data_items="<<dec<<unmoveable_scoops.size()+moveable_scoops.size()<<endl;
	cout<<"# ATTRIBUTE ASSURANCE_Non-Overlapping_Globals::Unmoveable_data_items="<<dec<<unmoveable_scoops.size()<<endl;
	cout<<"# ATTRIBUTE ASSURANCE_Non-Overlapping_Globals::Moveable_data_items="<<dec<<moveable_scoops.size()<<endl;
	cout<<"# ATTRIBUTE ASSURANCE_Non-Overlapping_Globals::Percent_data_items_moveable="<<std::fixed<<std::setprecision(1)<< ((float)moveable_scoops.size()/((float)(unmoveable_scoops.size()+moveable_scoops.size())))*100.00<<"%"<< endl; 

	cout<<"# ATTRIBUTE ASSURANCE_Non-Overlapping_Globals::Unmoveable_data_items_in_bytes="<<dec<<unmoveable_scoop_bytes<<endl;
	cout<<"# ATTRIBUTE ASSURANCE_Non-Overlapping_Globals::Moveable_data_items_in_bytes="<<dec<<moveable_scoop_bytes<<endl;
	cout<<"# ATTRIBUTE ASSURANCE_Non-Overlapping_Globals::Total_data_items_in_bytes="<<dec<<total_scoop_bytes<<endl;
	cout << "# ATTRIBUTE ASSURANCE_Non-Overlapping_Globals::Percent_data_item_bytes_moved="<<std::fixed<<std::setprecision(1) << ((double)moveable_scoop_bytes/(double)total_scoop_bytes)*100.00 <<"%"<< endl;
	cout << "# ATTRIBUTE ASSURANCE_Non-Overlapping_Globals::Percent_data_item_bytes_not_moved=" << std::fixed <<std::setprecision(1)<< ((double)unmoveable_scoop_bytes/(double)total_scoop_bytes)*100.00 <<"%"<< endl;

	cout<<"# ATTRIBUTE Non-Overlapping_Globals::tied_scoops="<<dec<<tied_scoops.size()<<endl;
	cout<<"# ATTRIBUTE Non-Overlapping_Globals::pcrel_refs="<<dec<<pcrel_refs_to_scoops.size()<<endl;
	cout<<"# ATTRIBUTE Non-Overlapping_Globals::abs_refs="<<dec<<absolute_refs_to_scoops.size()<<endl;
	cout<<"# ATTRIBUTE Non-Overlapping_Globals::imm_refs="<<dec<<immed_refs_to_scoops.size()<<endl;
	cout<<"# ATTRIBUTE Non-Overlapping_Globals::data_refs="<<dec<<data_refs_to_scoops.size()<<endl;
	cout<<"# ATTRIBUTE Non-Overlapping_Globals::coalesced_scoops="<<dec<<tied_unpinned<<endl;
	cout<<"# ATTRIBUTE Non-Overlapping_Globals::repinned_scoops="<<dec<<tied_pinned<<endl;
	cout<<"# ATTRIBUTE Non-Overlapping_Globals::ties_for_folded_constants="<<dec<<ties_for_folded_constants<<endl;
	cout<<"# ATTRIBUTE Non-Overlapping_Globals::tied_scoop_pairs_that_were_already_pinned="<<dec<<tied_nochange<<endl;
	cout<<"#ATTRIBUTE mg::unmoveable_scoops="<<dec<<unmoveable_scoops.size()<<endl;
	cout<<"#ATTRIBUTE mg::moveable_scoops="<<dec<<moveable_scoops.size()<<endl;
	cout<<"#ATTRIBUTE mg::pcrel_refs="<<dec<<pcrel_refs_to_scoops.size()<<endl;
	cout<<"#ATTRIBUTE mg::abs_refs="<<dec<<absolute_refs_to_scoops.size()<<endl;
	cout<<"#ATTRIBUTE mg::imm_refs="<<dec<<immed_refs_to_scoops.size()<<endl;
	cout<<"#ATTRIBUTE mg::data_refs="<<dec<<data_refs_to_scoops.size()<<endl;
	cout<<"#ATTRIBUTE mg::coalesced_scoops="<<dec<<tied_unpinned<<endl;
	cout<<"#ATTRIBUTE mg::repinned_scoops="<<dec<<tied_pinned<<endl;
	cout<<"#ATTRIBUTE mg::ties_for_folded_constants="<<dec<<ties_for_folded_constants<<endl;
	cout<<"#ATTRIBUTE mg::tied_scoop_pairs_that_were_already_pinned="<<dec<<tied_nochange<<endl;
}


// explicit instatnation for elf32 and elf64
template class MoveGlobals_t<Elf32_Sym, Elf32_Rela, Elf32_Rel, Elf32_Dyn, Extractor32_t>;
template class MoveGlobals_t<Elf64_Sym, Elf64_Rela, Elf64_Rel, Elf64_Dyn, Extractor64_t>;