URL
https://opencores.org/ocsvn/forwardcom/forwardcom/trunk
Subversion Repositories forwardcom
Compare Revisions
- This comparison shows the changes necessary to convert path
/forwardcom
- from Rev 35 to Rev 36
- ↔ Reverse comparison
Rev 35 → Rev 36
/bintools/linker.h
0,0 → 1,210
/**************************** linker.h ************************************ |
* Author: Agner Fog |
* date created: 2017-11-14 |
* Last modified: 2020-05-19 |
* Version: 1.10 |
* Project: Binary tools for ForwardCom instruction set |
* Module: linker.h |
* Description: |
* header file for linker |
* |
* Copyright 2017-2020 GNU General Public License http://www.gnu.org/licenses |
*****************************************************************************/ |
|
// Structure for list of imported library modules |
struct SLibraryModule { |
uint32_t library; // library number. msb set if symbols have been registered |
uint32_t offset; // offset in executable file or library |
uint32_t modul; // index into modules2 buffer |
}; |
|
// operator < for sorting library modules |
static inline bool operator < (SLibraryModule const & a, SLibraryModule const & b) { |
if ((a.library << 1) != (b.library << 1)) return (a.library << 1) < (b.library << 1); |
return a.offset < b.offset; |
} |
|
// Structure for storing name of relinkable module from input file |
struct SRelinkModule { |
uint32_t libraryName; // name of library that the module comes from (as index into cmd.fileNameBuffer) |
uint32_t moduleName; // name of module (as index into cmd.fileNameBuffer) |
}; |
|
// operator < for sorting relink module list |
static inline bool operator < (SRelinkModule const & a, SRelinkModule const & b) { |
// compare library names. (libraryName = 0 will give "") |
int j = strcmp(cmd.getFilename(a.libraryName), cmd.getFilename(b.libraryName)); |
if (j) return j < 0; |
// compare module names |
j = strcmp(cmd.getFilename(a.moduleName), cmd.getFilename(b.moduleName)); |
return j < 0; |
} |
|
// operator < for sorting event list |
static inline bool operator < (ElfFwcEvent const & a, ElfFwcEvent const & b) { |
if (a.event != b.event) return a.event < b.event; |
if (a.key != b.key) return a.key < b.key; |
return a.priority > b.priority; |
} |
|
|
// Structure for list of sections. Sorted by the order in which they should be placed in the executable |
struct SLinkSection { |
uint64_t sh_size; // Section size in bytes |
uint64_t sh_addr; // address in executable |
uint32_t sh_flags; // Section flags |
uint32_t sh_type; // Section type |
uint32_t name; // section name as index into cmd.fileNameBuffer |
uint32_t sh_module; // module containing section (index into modules2) |
uint32_t sectioni; // section index within module |
uint32_t sectionx; // section index in final executable |
uint32_t order; // section must occur in this order in executable file |
uint8_t sh_align; // alignment = 1 << sh_align |
}; |
|
// Same structure, sorted by sh_module and sectioni |
struct SLinkSection2 : public SLinkSection { |
}; |
|
// operator < for sorting section list by the order in which they should be placed in the executable |
static inline bool operator < (SLinkSection const & a, SLinkSection const & b) { |
if (a.order != b.order) return a.order < b.order; |
// same type and flags. sort by name |
int j = strcmp(cmd.getFilename(a.name), cmd.getFilename(b.name)); |
if (j != 0) return j < 0; |
// same name. sort by module |
return a.sh_module < b.sh_module; |
} |
|
// operator < for sorting section list by sh_module and sectioni |
static inline bool operator < (SLinkSection2 const & a, SLinkSection2 const & b) { |
if (a.sh_module != b.sh_module) return a.sh_module < b.sh_module; |
return a.sectioni < b.sectioni; |
} |
|
// extended relocation record used temporarily during linking |
struct SReloc2 : public ElfFwcReloc { |
uint32_t modul; // module containing specified r_section |
bool symLocal; // r_sym is in same module. reference by number rather than by name |
bool refSymLocal; // r_refsym is in same module. reference by number rather than by name |
}; |
|
// symbol cross reference record for connecting symbol records in local modules to records in executable file |
struct SSymbolXref { |
uint32_t name; // symbol name as index into global symbolNameBuffer |
uint32_t modul; // module containing symbol |
uint32_t symi; // index into symbols buffer within module |
uint32_t symx; // index into symbols buffer in outFile |
bool isPublic; // symbol is public or exported |
bool isWeak; // symbol is weak |
}; |
|
struct SSymbolXref2 : public SSymbolXref { |
}; |
|
// operator < for sorting symbol cross reference records by modul and symi |
static inline bool operator < (SSymbolXref const & a, SSymbolXref const & b) { |
if (a.modul != b.modul) return a.modul < b.modul; |
return a.symi < b.symi; |
} |
|
// operator < for sorting symbol cross reference records by name |
static inline bool operator < (SSymbolXref2 const & a, SSymbolXref2 const & b) { |
return strcmp(symbolNameBuffer.getString(a.name), symbolNameBuffer.getString(b.name)) < 0; |
} |
|
// symbol record, sorted by name |
struct SSymbol2 : public ElfFwcSym { |
SSymbol2() {} // default constructor |
SSymbol2(ElfFwcSym const & s) { // constructor to convert from normal symbol record |
*static_cast<ElfFwcSym*>(this) = s; |
} |
}; |
|
// operator < for sorting symbol recordsby name |
static inline bool operator < (SSymbol2 const & a, SSymbol2 const & b) { |
return strcmp(symbolNameBuffer.getString(a.st_name), symbolNameBuffer.getString(b.st_name)) < 0; |
} |
|
|
// Class for linking or re-linking executable file |
class CLinker { |
public: |
CLinker(); // Constructor |
void go(); // Do whatever the command line says |
protected: |
void feedBackText1(); // write feedback text on stdout |
void loadExeFile(); // load executable file to be relinked |
void getReplaceNames(); // get names of modules and libraries to remove or replace |
void markSectionsInInputFile(); // check which sections to keep or remove in executable input file |
void extractModule(CELF & modul, uint32_t libname, uint32_t name); // extract a module from executable input file |
void countReusedModules(); // count number of modules and libraries to reuse when relinking |
void getRelinkObjects(); // get all reused objects into modules1 metabuffer |
void extractModuleToFile(CELF & modu); // extract a module from relinkable file if requested |
void getRelinkLibraries(); // recover relinkable library modules |
void feedBackText2(); // write feedback to console |
uint64_t ip_base; // pointer to end of const, begin of code |
uint64_t datap_base; // pointer to end of data, begin of bss |
uint64_t threadp_base; // pointer to begin of thread local memory |
uint64_t entry_point; // entry point for executable startup code |
uint32_t event_table; // address of event table |
uint32_t event_table_num; // number of entries in event table |
uint32_t unresolvedWeak; // there are unresolved weak imports |
uint32_t unresolvedWeakNum; // number of unresolved weak imports for writeable data |
uint32_t dummyConst; // address of dummy constant symbol for unresolved weak imports |
uint32_t dummyData; // address of dummy data symbol for unresolved weak imports |
uint32_t dummyThreadData; // address of dummy thread data symbol for unresolved weak imports |
uint32_t dummyFunc; // address of dummy function for unresolved weak imports |
uint32_t eventDataSize; // total size of all event data sections |
uint32_t numObjects; // number of object files to add |
uint32_t numLibraries; // number of library files to add |
uint32_t numRelinkObjects; // number of relinkable object modules to reuse |
uint32_t numRelinkLibraries; // number of relinkable library files to reuse |
void fillBuffers(); // load specified object files and library files into buffers |
void countModules(); // count number of modules and libraries to add |
void makeSymbolList(); // make list of imported and exported symbols |
void matchSymbols(); // match lists of imported and exported symbols |
void librarySearch(); // search libraries for imported symbols |
void checkDuplicateSymbols(); // check for duplicate symbols |
void readLibraryModules(); // get imported library modules into modules2 buffer |
void makeSectionList(); // make list of all sections |
void sortSections(); // sort sections in the order in which they should occur in the executable file |
void joinCommunalSections(); // join communal sections with same name |
void makeDummySections(); // make dummy segments for unresolved weak externals |
void makeEventList(); // make sorted list of events |
void makeProgramHeaders(); // make program headers and assign addresses to sections |
void specialSymbolsOverride(); // check if automatic symbols have been overridden |
int32_t findModule(uint32_t library, uint32_t memberos);// find a module from a record in symbolExports |
void relocate(); // put values into all cross references |
void checkRegisterUse(ElfFwcSym * sym1, ElfFwcSym * sym2, uint32_t modul);// Check if external function call has compatible register use |
ElfFwcSym * findSymbolAddress(uint64_t * a, uint32_t * targetModule, ElfFwcSym * sym, uint32_t modul); // find a symbol and its address |
uint64_t findSymbolAddress(const char * name); // find the address of a symbol from its name |
void copySections(); // copy sections to output file |
void copySymbols(); // copy symbols to output file |
void copyRelocations(); // copy relocation records to output file if needed |
uint32_t resolveRelocationTarget(uint32_t modul, uint32_t symi);// resolve relocation target for executable file record |
void makeFileHeader(); // make file header |
CELF inputFile; // input file if relinking |
CELF outFile; // output file |
CMetaBuffer<CELF> modules1; // object files and modules from input exe file |
CMetaBuffer<CELF> modules2; // same + object files from libraries |
CMetaBuffer<CLibrary> libraries; // library files |
CDynamicArray<SSymbolEntry> symbolExports; // list of exported symbols |
CDynamicArray<SSymbolEntry> symbolImports; // list of imported symbols |
CDynamicArray<SLinkSection> sections; // list of sections, sorted in memory order |
CDynamicArray<SLinkSection> communalSections;// list of communal sections |
CDynamicArray<SLinkSection2> sections2; // list of sections, sorted by module and section index |
CDynamicArray<SLibraryModule> libmodules; // list of imported library modules |
CDynamicArray<SReloc2> relocations2; // extended relocation records to be copied to executable file |
CDynamicArray<SSymbolXref> symbolXref; // symbol index cross reference |
CDynamicArray<SSymbolXref2> unresWeakSym; // list of unresolved weak symbols |
CDynamicArray<SRelinkModule> relinkModules; // list of modules and libraries in input file to relink |
CDynamicArray<SLCommand> rnames; // List of modules and libraries to delete or replace |
CDynamicArray<ElfFwcEvent> eventData; // container for all event records |
CELF memberBuffer; // buffer containing temporary copy of single library member |
ElfFwcEhdr fileHeader; // file header for executable file |
bool relinkable; // output file is relinkable |
bool relinking; // relinking existing file |
}; |
|
const uint32_t fillerInstruction = 0x7FFFFFFF; // binary representation of filler instruction |