Skip to content
Snippets Groups Projects
Commit 96c24d06 authored by Jason Hiser's avatar Jason Hiser :tractor:
Browse files

building with pinner separated!

parent c45ce87c
No related branches found
No related tags found
No related merge requests found
#ifndef ZIPR_PINNER
#define ZIPR_PINNER
#ifndef ZIPR_PINNER_ARM64
#define ZIPR_PINNER_ARM64
class ZiprPinner_t
class ZiprPinnerARM64_t : public ZiprPinnerBase_t
{
public:
virtual void doPinning();
ZiprPinnerARM64_t(Zipr_SDK::Zipr_t* p_parent);
virtual void doPinning() override;
private:
Zipr_SDK::Zipr_t* m_parent;
};
......
#ifndef ZIPR_PINNER
#define ZIPR_PINNER
#ifndef ZIPR_PINNER_X86
#define ZIPR_PINNER_X86
class ZiprPinner_t
class ZiprPinnerX86_t : public ZiprPinnerBase_t
{
public:
virtual void doPinning()=0;
static unique_ptr<ZiprPinner_t> factory(Zipr_SDK::Zipr_t* parent);
ZiprPinnerX86_t(Zipr_SDK::Zipr_t* p_parent);
virtual void doPinning() override;
private:
// methods , remove from zipr_impl
void AddPinnedInstructions();
void RecordPinnedInsnAddrs();
bool ShouldPinImmediately(libIRDB::Instruction_t *upinsn);
void PreReserve2ByteJumpTargets();
void InsertJumpPoints68SledArea(Sled_t &sled);
libIRDB::Instruction_t* Emit68Sled(RangeAddress_t addr, Sled_t sled, libIRDB::Instruction_t* next_sled);
libIRDB::Instruction_t* Emit68Sled(Sled_t sled);
void Update68Sled(Sled_t new_sled, Sled_t &existing_sled);
RangeAddress_t Do68Sled(RangeAddress_t addr);
void Clear68SledArea(Sled_t sled);
int Calc68SledSize(RangeAddress_t addr, size_t sled_overhead);
bool IsPinFreeZone(RangeAddress_t addr, int size);
void ReservePinnedInstructions();
void ExpandPinnedInstructions();
void Fix2BytePinnedInstructions();
void OptimizePinnedInstructions();
libIRDB::Instruction_t* FindPinnedInsnAtAddr(RangeAddress_t addr);
// shortcut
libIRDB::Instruction_t* FindPatchTargetAtAddr(RangeAddress_t addr) { return m_parent->FindPatchTargetAtAddr(addr); }
void PatchJump(RangeAddress_t at_addr, RangeAddress_t to_addr) { return m_parent->PatchJump(at_addr,to_addr); }
// data
zipr::ZiprImpl_t* m_parent;
Zipr_SDK::MemorySpace_t &memory_space;
Zipr_SDK::DollopManager_t &m_dollop_mgr;
libIRDB::FileIR_t* m_firp;
Zipr_SDK::PlacementQueue_t &placement_queue;
bool m_verbose;
Stats_t* m_stats;
Zipr_SDK::InstructionLocationMap_t &final_insn_locations;
// notes: move these out of zipr_impl.h
std::set<UnresolvedPinned_t> two_byte_pins;
std::map<UnresolvedPinned_t,RangeAddress_t> five_byte_pins;
std::set<UnresolvedPinned_t,pin_sorter_t> unresolved_pinned_addrs;
std::map<RangeAddress_t,std::pair<libIRDB::Instruction_t*, size_t> > m_InsnSizeAtAddrs;
std::map<RangeAddress_t, bool> m_AddrInSled;
std::set<Sled_t> m_sleds;
};
......
#ifndef ZIPR_PINNER
#define ZIPR_PINNER
class ZiprPinner_t
class ZiprPinnerBase_t
{
public:
virtual void doPinning()=0;
static unique_ptr<ZiprPinner_t> factory(Zipr_SDK::Zipr_t* parent);
static unique_ptr<ZiprPinnerBase_t> factory(Zipr_SDK::Zipr_t* parent);
};
......
......@@ -59,7 +59,7 @@ using namespace Zipr_SDK;
#include <zipr_dollop_man.h>
#include <zipr_utils.h>
#include <arch/archbase.hpp>
#include <pinner/pinner_base.h>
#include <pinner/pinner_base.hpp>
#include <zipr_impl.h>
#include <zipr_optimizations.h>
#include <zipr_stats.h>
......
......@@ -36,10 +36,27 @@
#include <memory>
class Stats_t;
class pin_sorter_t
{
public:
bool operator() (const UnresolvedPinned_t& p1, const UnresolvedPinned_t& p2)
{
assert(p1.GetInstruction());
assert(p2.GetInstruction());
assert(p1.GetInstruction()->GetIndirectBranchTargetAddress()
&& p1.GetInstruction()->GetIndirectBranchTargetAddress()->GetVirtualOffset()!=0);
assert(p2.GetInstruction()->GetIndirectBranchTargetAddress()
&& p2.GetInstruction()->GetIndirectBranchTargetAddress()->GetVirtualOffset()!=0);
return p1.GetInstruction()->GetIndirectBranchTargetAddress()->GetVirtualOffset() <
p2.GetInstruction()->GetIndirectBranchTargetAddress()->GetVirtualOffset() ;
}
};
class ZiprImpl_t : public Zipr_t
{
public:
ZiprImpl_t(int argc, char **argv) :
m_stats(NULL),
......@@ -111,6 +128,29 @@ class ZiprImpl_t : public Zipr_t
*/
void AskPluginsAboutPlopping();
bool AskPluginsAboutPlopping(libIRDB::Instruction_t *);
void RecordNewPatch(const std::pair<RangeAddress_t, UnresolvedUnpinnedPatch_t>& p)
{
m_PatchAtAddrs.insert(p);
}
UnresolvedUnpinnedPatch_t FindPatch(const RangeAddress_t r) const
{
return m_PatchAtAddrs.at(r);
}
void RemovePatch(const RangeAddress_t r)
{
auto patch_it = m_PatchAtAddrs.find(r);
assert(patch_it != m_PatchAtAddrs.end());
m_PatchAtAddrs.erase(patch_it);
}
libIRDB::Instruction_t *FindPatchTargetAtAddr(RangeAddress_t addr);
void PatchJump(RangeAddress_t at_addr, RangeAddress_t to_addr);
void AddPatch(const UnresolvedUnpinned_t& uu, const Patch_t& thepatch)
{
patch_list.insert(pair<const UnresolvedUnpinned_t,Patch_t>(uu,thepatch));
}
private:
void Init();
......@@ -342,6 +382,8 @@ class ZiprImpl_t : public Zipr_t
void RecordPinnedInsnAddrs();
void PerformPinning();
// zipr has some internal assumptions that multiple fallthroughs to the same instruction
// are problematic. this function adjusts the IR such that no multiple fallthroughs
// exist by adding direct jump instructions where necessary to eliminate multiple fallthroughs.
......@@ -369,7 +411,6 @@ class ZiprImpl_t : public Zipr_t
size_t DetermineWorstCaseInsnSize(libIRDB::Instruction_t*, bool account_for_trampoline);
// patching
void PatchJump(RangeAddress_t at_addr, RangeAddress_t to_addr);
void ApplyPatches(libIRDB::Instruction_t* insn);
void PatchInstruction(RangeAddress_t addr, libIRDB::Instruction_t* insn);
void RewritePCRelOffset(RangeAddress_t from_addr,RangeAddress_t to_addr, int insn_length, int offset_pos);
......@@ -391,7 +432,6 @@ class ZiprImpl_t : public Zipr_t
std::string AddCallbacksToNewSegment(const std::string& tmpname, RangeAddress_t end_of_new_space);
RangeAddress_t FindCallbackAddress(RangeAddress_t end_of_new_space,RangeAddress_t start_addr, const std::string &callback);
libIRDB::Instruction_t *FindPinnedInsnAtAddr(RangeAddress_t addr);
libIRDB::Instruction_t *FindPatchTargetAtAddr(RangeAddress_t addr);
bool ShouldPinImmediately(libIRDB::Instruction_t *upinsn);
bool IsPinFreeZone(RangeAddress_t addr, int size);
......@@ -413,6 +453,7 @@ class ZiprImpl_t : public Zipr_t
void dump_scoop_map();
void dump_instruction_map();
virtual void RelayoutEhInfo();
public:
......@@ -423,8 +464,7 @@ class ZiprImpl_t : public Zipr_t
virtual Zipr_SDK::InstructionLocationMap_t *GetLocationMap() { return &final_insn_locations; }
virtual Zipr_SDK::PlacementQueue_t* GetPlacementQueue() { return &placement_queue; }
virtual Zipr_SDK::RangeAddress_t PlaceUnplacedScoops(Zipr_SDK::RangeAddress_t max);
virtual void RelayoutEhInfo();
Stats_t* GetStats() { return m_stats; }
private:
......@@ -439,36 +479,19 @@ class ZiprImpl_t : public Zipr_t
bool m_error;
class pin_sorter_t
{
public:
bool operator() (const UnresolvedPinned_t& p1, const UnresolvedPinned_t& p2)
{
assert(p1.GetInstruction());
assert(p2.GetInstruction());
assert(p1.GetInstruction()->GetIndirectBranchTargetAddress()
&& p1.GetInstruction()->GetIndirectBranchTargetAddress()->GetVirtualOffset()!=0);
assert(p2.GetInstruction()->GetIndirectBranchTargetAddress()
&& p2.GetInstruction()->GetIndirectBranchTargetAddress()->GetVirtualOffset()!=0);
return p1.GetInstruction()->GetIndirectBranchTargetAddress()->GetVirtualOffset() <
p2.GetInstruction()->GetIndirectBranchTargetAddress()->GetVirtualOffset() ;
}
};
std::set<Sled_t> m_sleds;
// structures necessary for ZIPR algorithm.
std::set<UnresolvedUnpinned_t> unresolved_unpinned_addrs;
std::set<UnresolvedPinned_t,pin_sorter_t> unresolved_pinned_addrs;
std::multimap<UnresolvedUnpinned_t,Patch_t> patch_list;
// map of where bytes will actually go.
// std::map<RangeAddress_t,char> byte_map;
// structures to pinned things.
std::set<UnresolvedPinned_t> two_byte_pins;
std::map<UnresolvedPinned_t,RangeAddress_t> five_byte_pins;
std::set<Sled_t> m_sleds;
std::map<RangeAddress_t,std::pair<libIRDB::Instruction_t*, size_t> > m_InsnSizeAtAddrs;
std::map<RangeAddress_t, bool> m_AddrInSled;
// a manager for all dollops
ZiprDollopManager_t m_dollop_mgr;
......@@ -476,8 +499,6 @@ class ZiprImpl_t : public Zipr_t
// final mapping of instruction to address.
// std::map<libIRDB::Instruction_t*,RangeAddress_t>
Zipr_SDK::InstructionLocationMap_t final_insn_locations;
std::map<RangeAddress_t,std::pair<libIRDB::Instruction_t*, size_t> > m_InsnSizeAtAddrs;
std::map<RangeAddress_t, bool> m_AddrInSled;
std::map<RangeAddress_t,UnresolvedUnpinnedPatch_t> m_PatchAtAddrs;
// unpatched callbacks
......@@ -505,7 +526,7 @@ class ZiprImpl_t : public Zipr_t
ZiprPluginManager_t plugman;
std::map<libIRDB::Instruction_t*,
std::unique_ptr<std::list<DLFunctionHandle_t>>> plopping_plugins;
std::unique_ptr<std::list<DLFunctionHandle_t>>> plopping_plugins;
// Options
ZiprOptions_t m_zipr_options;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment