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
|
/* -----------------------------------------------------------------------------
*
* (c) The GHC Team, 2000
*
* RTS Object Linker
*
* ---------------------------------------------------------------------------*/
#ifndef LINKERINTERNALS_H
#define LINKERINTERNALS_H
typedef enum {
OBJECT_LOADED,
OBJECT_RESOLVED,
OBJECT_UNLOADED
} 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
struct _Section {
void* start;
void* end;
SectionKind kind;
struct _Section* next;
}
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;
/* 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;
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 malloc'd lump of memory holding the obj file */
char* image;
/* flag used when deciding whether to unload an object file */
int referenced;
#ifdef darwin_HOST_OS
/* record by how much image has been deliberately misaligned
after allocation, so that we can use realloc */
int misalignment;
#endif
/* The section-kind entries for this object module. Linked
list. */
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 powerpc_HOST_ARCH || x86_64_HOST_ARCH || arm_HOST_ARCH
SymbolExtra *symbol_extras;
unsigned long first_symbol_extra;
unsigned long n_symbol_extras;
#endif
ForeignExportStablePtr *stable_ptrs;
} 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);
#endif /* LINKERINTERNALS_H */
|