summaryrefslogtreecommitdiff
path: root/rts/LinkerInternals.h
blob: 729cf1d79240139a377aa2bea75635d8e980e858 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
/* -----------------------------------------------------------------------------
 *
 * (c) The GHC Team, 2000
 *
 * RTS Object Linker
 *
 * ---------------------------------------------------------------------------*/

#ifndef LINKERINTERNALS_H
#define LINKERINTERNALS_H

#include "Rts.h"
#include "Hash.h"

/* See Linker.c Note [runtime-linker-phases] */
typedef enum {
    OBJECT_LOADED,
    OBJECT_NEEDED,
    OBJECT_RESOLVED,
    OBJECT_UNLOADED,
    OBJECT_DONT_RESOLVE
} OStatus;

/* Indication of section kinds for loaded objects.  Needed by
   the GC for deciding whether or not a pointer on the stack
   is a code pointer.
*/
typedef
   enum { SECTIONKIND_CODE_OR_RODATA,
          SECTIONKIND_RWDATA,
          SECTIONKIND_INIT_ARRAY,
          SECTIONKIND_OTHER,
          SECTIONKIND_NOINFOAVAIL }
   SectionKind;

typedef
   enum { SECTION_NOMEM,
          SECTION_M32,
          SECTION_MMAP,
          SECTION_MALLOC,
        }
   SectionAlloc;

typedef
   struct _Section {
      void*    start;              /* actual start of section in memory */
      StgWord  size;               /* actual size of section in memory */
      SectionKind kind;
      SectionAlloc alloc;

      /*
       * The following fields are relevant for SECTION_MMAP sections only
       */
      StgWord mapped_offset;      /* offset from the image of mapped_start */
      void* mapped_start;         /* start of mmap() block */
      StgWord mapped_size;        /* size of mmap() block */
   }
   Section;

typedef
   struct _ProddableBlock {
      void* start;
      int   size;
      struct _ProddableBlock* next;
   }
   ProddableBlock;

/*
 * We must keep track of the StablePtrs that are created for foreign
 * exports by constructor functions when the module is loaded, so that
 * we can free them again when the module is unloaded.  If we don't do
 * this, then the StablePtr will keep the module alive indefinitely.
 */
typedef struct ForeignExportStablePtr_ {
    StgStablePtr stable_ptr;
    struct ForeignExportStablePtr_ *next;
} ForeignExportStablePtr;

#if powerpc_HOST_ARCH || x86_64_HOST_ARCH || arm_HOST_ARCH
#define NEED_SYMBOL_EXTRAS 1
#endif

/* Jump Islands are sniplets of machine code required for relative
 * address relocations on the PowerPC, x86_64 and ARM.
 */
typedef struct {
#ifdef powerpc_HOST_ARCH
    struct {
        short lis_r12, hi_addr;
        short ori_r12_r12, lo_addr;
        long mtctr_r12;
        long bctr;
    } jumpIsland;
#elif x86_64_HOST_ARCH
    uint64_t    addr;
    uint8_t     jumpIsland[6];
#elif arm_HOST_ARCH
    uint8_t     jumpIsland[16];
#endif
} SymbolExtra;


/* Top-level structure for an object module.  One of these is allocated
 * for each object file in use.
 */
typedef struct _ObjectCode {
    OStatus    status;
    pathchar  *fileName;
    int        fileSize;     /* also mapped image size when using mmap() */
    char*      formatName;            /* eg "ELF32", "DLL", "COFF", etc. */

    /* If this object is a member of an archive, archiveMemberName is
     * like "libarchive.a(object.o)". Otherwise it's NULL.
     */
    char*      archiveMemberName;

    /* An array containing ptrs to all the symbol names copied from
       this object into the global symbol hash table.  This is so that
       we know which parts of the latter mapping to nuke when this
       object is removed from the system. */
    char** symbols;
    int    n_symbols;

    /* ptr to mem containing the object file image */
    char*      image;
    /* non-zero if the object file was mmap'd, otherwise malloc'd */
    int        imageMapped;

    /* flag used when deciding whether to unload an object file */
    int        referenced;

    /* record by how much image has been deliberately misaligned
       after allocation, so that we can use realloc */
    int        misalignment;

    /* The section-kind entries for this object module.  Linked
       list. */
    int n_sections;
    Section* sections;

    /* Allow a chain of these things */
    struct _ObjectCode * next;

    /* SANITY CHECK ONLY: a list of the only memory regions which may
       safely be prodded during relocation.  Any attempt to prod
       outside one of these is an error in the linker. */
    ProddableBlock* proddables;

#ifdef ia64_HOST_ARCH
    /* Procedure Linkage Table for this object */
    void *plt;
    unsigned int pltIndex;
#endif

#if NEED_SYMBOL_EXTRAS
    SymbolExtra    *symbol_extras;
    unsigned long   first_symbol_extra;
    unsigned long   n_symbol_extras;
#endif

    ForeignExportStablePtr *stable_ptrs;

    /* Holds the list of symbols in the .o file which
       require extra information.*/
    HashTable *extraInfos;

} ObjectCode;

#define OC_INFORMATIVE_FILENAME(OC)             \
    ( (OC)->archiveMemberName ?                 \
      (OC)->archiveMemberName :                 \
      (OC)->fileName                            \
    )

extern ObjectCode *objects;
extern ObjectCode *unloaded_objects;

#ifdef THREADED_RTS
extern Mutex linker_mutex;
extern Mutex linker_unloaded_mutex;
#endif

void exitLinker( void );

void freeObjectCode (ObjectCode *oc);

#if defined(mingw32_HOST_OS)

typedef unsigned char          UChar;
typedef unsigned short         UInt16;
typedef short                  Int16;
typedef unsigned int           UInt32;
typedef          int           Int32;
typedef unsigned long long int UInt64;


typedef
struct {
    UInt16 Machine;
    UInt16 NumberOfSections;
    UInt32 TimeDateStamp;
    UInt32 PointerToSymbolTable;
    UInt32 NumberOfSymbols;
    UInt16 SizeOfOptionalHeader;
    UInt16 Characteristics;
}
COFF_header;

#define sizeof_COFF_header 20

/* Section 7.1 PE Specification */
typedef
struct {
    UInt16 Sig1;
    UInt16 Sig2;
    UInt16 Version;
    UInt16 Machine;
    UInt32 TimeDateStamp;
    UInt32 SizeOfData;
    UInt16 Ordinal;
    UInt16 Type_NameType_Reserved;
}
COFF_import_header;

#define sizeof_COFF_import_Header 20

typedef
struct {
    UChar  Name[8];
    UInt32 VirtualSize;
    UInt32 VirtualAddress;
    UInt32 SizeOfRawData;
    UInt32 PointerToRawData;
    UInt32 PointerToRelocations;
    UInt32 PointerToLinenumbers;
    UInt16 NumberOfRelocations;
    UInt16 NumberOfLineNumbers;
    UInt32 Characteristics;
}
COFF_section;

#define sizeof_COFF_section 40


typedef
struct {
    UChar  Name[8];
    UInt32 Value;
    Int16  SectionNumber;
    UInt16 Type;
    UChar  StorageClass;
    UChar  NumberOfAuxSymbols;
}
COFF_symbol;

#define sizeof_COFF_symbol 18


typedef
struct {
    UInt32 VirtualAddress;
    UInt32 SymbolTableIndex;
    UInt16 Type;
}
COFF_reloc;

#define sizeof_COFF_reloc 10

/* From PE spec doc, section 3.3.2 */
/* Note use of MYIMAGE_* since IMAGE_* are already defined in
windows.h -- for the same purpose, but I want to know what I'm
getting, here. */
#define MYIMAGE_FILE_RELOCS_STRIPPED        0x0001
#define MYIMAGE_FILE_EXECUTABLE_IMAGE       0x0002
#define MYIMAGE_FILE_DLL                    0x2000
#define MYIMAGE_FILE_SYSTEM                 0x1000
#define MYIMAGE_FILE_BYTES_REVERSED_HI      0x8000
#define MYIMAGE_FILE_BYTES_REVERSED_LO      0x0080
#define MYIMAGE_FILE_32BIT_MACHINE          0x0100

/* From PE spec doc, section 5.4.2 and 5.4.4 */
#define MYIMAGE_SYM_CLASS_EXTERNAL          2
#define MYIMAGE_SYM_CLASS_STATIC            3
#define MYIMAGE_SYM_UNDEFINED               0
#define MYIMAGE_SYM_CLASS_SECTION           104
#define MYIMAGE_SYM_CLASS_WEAK_EXTERNAL     105

/* From PE spec doc, section 3.1 */
#define MYIMAGE_SCN_CNT_CODE                0x00000020
#define MYIMAGE_SCN_CNT_INITIALIZED_DATA    0x00000040
#define MYIMAGE_SCN_CNT_UNINITIALIZED_DATA  0x00000080
#define MYIMAGE_SCN_LNK_COMDAT              0x00001000
#define MYIMAGE_SCN_LNK_NRELOC_OVFL         0x01000000
#define MYIMAGE_SCN_LNK_REMOVE              0x00000800
#define MYIMAGE_SCN_MEM_DISCARDABLE         0x02000000

/* From PE spec doc, section 5.2.1 */
#define MYIMAGE_REL_I386_DIR32              0x0006
#define MYIMAGE_REL_I386_DIR32NB            0x0007
#define MYIMAGE_REL_I386_REL32              0x0014

#endif /* OBJFORMAT_PEi386 */

#endif /* LINKERINTERNALS_H */