OpenCores
URL https://opencores.org/ocsvn/forwardcom/forwardcom/trunk

Subversion Repositories forwardcom

[/] [forwardcom/] [bintools/] [linker.h] - Blame information for rev 36

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 Agner
/****************************  linker.h   ************************************
2
* Author:        Agner Fog
3
* date created:  2017-11-14
4
* Last modified: 2020-05-19
5
* Version:       1.10
6
* Project:       Binary tools for ForwardCom instruction set
7
* Module:        linker.h
8
* Description:
9
* header file for linker
10
*
11
* Copyright 2017-2020 GNU General Public License http://www.gnu.org/licenses
12
*****************************************************************************/
13
 
14
// Structure for list of imported library modules
15
struct SLibraryModule {
16
    uint32_t library;                  // library number. msb set if symbols have been registered
17
    uint32_t offset;                   // offset in executable file or library
18
    uint32_t modul;                    // index into modules2 buffer
19
};
20
 
21
// operator < for sorting library modules
22
static inline bool operator < (SLibraryModule const & a, SLibraryModule const & b) {
23
    if ((a.library << 1) != (b.library << 1)) return (a.library << 1) < (b.library << 1);
24
    return a.offset < b.offset;
25
}
26
 
27
// Structure for storing name of relinkable module from input file
28
struct SRelinkModule {
29
    uint32_t libraryName;              // name of library that the module comes from (as index into cmd.fileNameBuffer)
30
    uint32_t moduleName;               // name of module (as index into cmd.fileNameBuffer)
31
};
32
 
33
// operator < for sorting relink module list
34
static inline bool operator < (SRelinkModule const & a, SRelinkModule const & b) {
35
    // compare library names. (libraryName = 0 will give "")
36
    int j = strcmp(cmd.getFilename(a.libraryName), cmd.getFilename(b.libraryName));
37
    if (j) return j < 0;
38
    // compare module names
39
    j = strcmp(cmd.getFilename(a.moduleName), cmd.getFilename(b.moduleName));
40
    return j < 0;
41
}
42
 
43
// operator < for sorting event list
44
static inline bool operator < (ElfFwcEvent const & a, ElfFwcEvent const & b) {
45
    if (a.event != b.event) return a.event < b.event;
46
    if (a.key != b.key) return a.key < b.key;
47
    return a.priority > b.priority;
48
}
49
 
50
 
51
// Structure for list of sections. Sorted by the order in which they should be placed in the executable
52
struct SLinkSection {
53
    uint64_t sh_size;                  // Section size in bytes
54
    uint64_t sh_addr;                  // address in executable
55
    uint32_t sh_flags;                 // Section flags
56
    uint32_t sh_type;                  // Section type
57
    uint32_t name;                     // section name as index into cmd.fileNameBuffer
58
    uint32_t sh_module;                // module containing section (index into modules2)
59
    uint32_t sectioni;                 // section index within module
60
    uint32_t sectionx;                 // section index in final executable
61
    uint32_t order;                    // section must occur in this order in executable file
62
    uint8_t  sh_align;                 // alignment = 1 << sh_align
63
};
64
 
65
// Same structure, sorted by sh_module and sectioni
66
struct SLinkSection2 : public SLinkSection {
67
};
68
 
69
// operator < for sorting section list by the order in which they should be placed in the executable
70
static inline bool operator < (SLinkSection const & a, SLinkSection const & b) {
71
    if (a.order != b.order) return a.order < b.order;
72
    // same type and flags. sort by name
73
    int j = strcmp(cmd.getFilename(a.name), cmd.getFilename(b.name));
74
    if (j != 0) return j < 0;
75
    // same name. sort by module
76
    return a.sh_module < b.sh_module;
77
}
78
 
79
// operator < for sorting section list by sh_module and sectioni
80
static inline bool operator < (SLinkSection2 const & a, SLinkSection2 const & b) {
81
    if (a.sh_module != b.sh_module) return a.sh_module < b.sh_module;
82
    return a.sectioni < b.sectioni;
83
}
84
 
85
// extended relocation record used temporarily during linking
86
struct SReloc2 : public ElfFwcReloc {
87
    uint32_t modul;                    // module containing specified r_section
88
    bool symLocal;                     // r_sym is in same module. reference by number rather than by name 
89
    bool refSymLocal;                  // r_refsym is in same module. reference by number rather than by name 
90
};
91
 
92
// symbol cross reference record for connecting symbol records in local modules to records in executable file
93
struct SSymbolXref {
94
    uint32_t  name;                    // symbol name as index into global symbolNameBuffer
95
    uint32_t  modul;                   // module containing symbol
96
    uint32_t  symi;                    // index into symbols buffer within module
97
    uint32_t  symx;                    // index into symbols buffer in outFile
98
    bool      isPublic;                // symbol is public or exported
99
    bool      isWeak;                  // symbol is weak
100
};
101
 
102
struct SSymbolXref2 : public SSymbolXref {
103
};
104
 
105
// operator < for sorting symbol cross reference records by modul and symi
106
static inline bool operator < (SSymbolXref const & a, SSymbolXref const & b) {
107
    if (a.modul != b.modul) return a.modul < b.modul;
108
    return a.symi < b.symi;
109
}
110
 
111
// operator < for sorting symbol cross reference records by name
112
static inline bool operator < (SSymbolXref2 const & a, SSymbolXref2 const & b) {
113
    return strcmp(symbolNameBuffer.getString(a.name), symbolNameBuffer.getString(b.name)) < 0;
114
}
115
 
116
// symbol record, sorted by name
117
struct SSymbol2 : public ElfFwcSym {
118
    SSymbol2() {}                                // default constructor
119
    SSymbol2(ElfFwcSym const & s) {             // constructor to convert from normal symbol record
120
        *static_cast<ElfFwcSym*>(this) = s;
121
    }
122
};
123
 
124
// operator < for sorting symbol recordsby name
125
static inline bool operator < (SSymbol2 const & a, SSymbol2 const & b) {
126
    return strcmp(symbolNameBuffer.getString(a.st_name), symbolNameBuffer.getString(b.st_name)) < 0;
127
}
128
 
129
 
130
// Class for linking or re-linking executable file
131
class CLinker {
132
public:
133
    CLinker();                                   // Constructor
134
    void go();                                   // Do whatever the command line says
135
protected:
136
    void feedBackText1();                         // write feedback text on stdout
137
    void loadExeFile();                          // load executable file to be relinked
138
    void getReplaceNames();                      // get names of modules and libraries to remove or replace
139
    void markSectionsInInputFile();              // check which sections to keep or remove in executable input file
140
    void extractModule(CELF & modul, uint32_t libname, uint32_t name); // extract a module from executable input file
141
    void countReusedModules();                   // count number of modules and libraries to reuse when relinking
142
    void getRelinkObjects();                     // get all reused objects into modules1 metabuffer
143
    void extractModuleToFile(CELF & modu);       // extract a module from relinkable file if requested
144
    void getRelinkLibraries();                   // recover relinkable library modules
145
    void feedBackText2();                        // write feedback to console
146
    uint64_t ip_base;                            // pointer to end of const, begin of code
147
    uint64_t datap_base;                         // pointer to end of data, begin of bss
148
    uint64_t threadp_base;                       // pointer to begin of thread local memory
149
    uint64_t entry_point;                        // entry point for executable startup code
150
    uint32_t event_table;                        // address of event table
151
    uint32_t event_table_num;                    // number of entries in event table
152
    uint32_t unresolvedWeak;                     // there are unresolved weak imports
153
    uint32_t unresolvedWeakNum;                  // number of unresolved weak imports for writeable data
154
    uint32_t dummyConst;                         // address of dummy constant symbol for unresolved weak imports
155
    uint32_t dummyData;                          // address of dummy data symbol for unresolved weak imports
156
    uint32_t dummyThreadData;                    // address of dummy thread data symbol for unresolved weak imports
157
    uint32_t dummyFunc;                          // address of dummy function for unresolved weak imports
158
    uint32_t eventDataSize;                      // total size of all event data sections
159
    uint32_t numObjects;                         // number of object files to add
160
    uint32_t numLibraries;                       // number of library files to add
161
    uint32_t numRelinkObjects;                   // number of relinkable object modules to reuse
162
    uint32_t numRelinkLibraries;                 // number of relinkable library files to reuse
163
    void fillBuffers();                          // load specified object files and library files into buffers
164
    void countModules();                         // count number of modules and libraries to add
165
    void makeSymbolList();                       // make list of imported and exported symbols
166
    void matchSymbols();                         // match lists of imported and exported symbols
167
    void librarySearch();                        // search libraries for imported symbols
168
    void checkDuplicateSymbols();                // check for duplicate symbols
169
    void readLibraryModules();                   // get imported library modules into modules2 buffer
170
    void makeSectionList();                      // make list of all sections
171
    void sortSections();                         // sort sections in the order in which they should occur in the executable file
172
    void joinCommunalSections();                 // join communal sections with same name
173
    void makeDummySections();                    // make dummy segments for unresolved weak externals
174
    void makeEventList();                        // make sorted list of events
175
    void makeProgramHeaders();                   // make program headers and assign addresses to sections
176
    void specialSymbolsOverride();               // check if automatic symbols have been overridden
177
    int32_t findModule(uint32_t library, uint32_t memberos);// find a module from a record in symbolExports    
178
    void relocate();                             // put values into all cross references
179
    void checkRegisterUse(ElfFwcSym * sym1, ElfFwcSym * sym2, uint32_t modul);// Check if external function call has compatible register use
180
    ElfFwcSym * findSymbolAddress(uint64_t * a, uint32_t * targetModule, ElfFwcSym * sym, uint32_t modul); // find a symbol and its address
181
    uint64_t findSymbolAddress(const char * name); // find the address of a symbol from its name
182
    void copySections();                         // copy sections to output file
183
    void copySymbols();                          // copy symbols to output file
184
    void copyRelocations();                      // copy relocation records to output file if needed
185
    uint32_t resolveRelocationTarget(uint32_t modul, uint32_t symi);// resolve relocation target for executable file record
186
    void makeFileHeader();                       // make file header
187
    CELF inputFile;                              // input file if relinking
188
    CELF outFile;                                // output file
189
    CMetaBuffer<CELF> modules1;                  // object files and modules from input exe file
190
    CMetaBuffer<CELF> modules2;                  // same + object files from libraries
191
    CMetaBuffer<CLibrary> libraries;             // library files
192
    CDynamicArray<SSymbolEntry> symbolExports;   // list of exported symbols
193
    CDynamicArray<SSymbolEntry> symbolImports;   // list of imported symbols
194
    CDynamicArray<SLinkSection> sections;        // list of sections, sorted in memory order
195
    CDynamicArray<SLinkSection> communalSections;// list of communal sections
196
    CDynamicArray<SLinkSection2> sections2;      // list of sections, sorted by module and section index
197
    CDynamicArray<SLibraryModule> libmodules;    // list of imported library modules
198
    CDynamicArray<SReloc2> relocations2;         // extended relocation records to be copied to executable file
199
    CDynamicArray<SSymbolXref> symbolXref;       // symbol index cross reference
200
    CDynamicArray<SSymbolXref2> unresWeakSym;    // list of unresolved weak symbols
201
    CDynamicArray<SRelinkModule> relinkModules;  // list of modules and libraries in input file to relink
202
    CDynamicArray<SLCommand> rnames;             // List of modules and libraries to delete or replace
203
    CDynamicArray<ElfFwcEvent> eventData;        // container for all event records
204
    CELF memberBuffer;                           // buffer containing temporary copy of single library member
205
    ElfFwcEhdr fileHeader;                       // file header for executable file
206
    bool relinkable;                             // output file is relinkable
207
    bool relinking;                              // relinking existing file
208
};
209
 
210
const uint32_t fillerInstruction = 0x7FFFFFFF;   // binary representation of filler instruction

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.