eb5bec8b781188e0a4eb7712ab9b80385c967a06
[ghc.git] / rts / linker / PEi386.h
1 #pragma once
2
3 #include "Rts.h"
4 #include "LinkerInternals.h"
5 #include "PathUtils.h"
6 #include <windows.h>
7 #include <stdbool.h>
8
9 #include "BeginPrivate.h"
10
11 #if defined(x86_64_HOST_ARCH)
12 #define PEi386_IMAGE_OFFSET 4
13 #else
14 #define PEi386_IMAGE_OFFSET 0
15 #endif
16
17 #define PEi386_STRTAB_OFFSET 4
18
19 /********************************************
20 * COFF/PE types
21 ********************************************/
22
23 typedef enum _COFF_OBJ_TYPE {
24 COFF_IMAGE,
25 COFF_ANON_OBJ,
26 COFF_IMPORT_LIB,
27 COFF_ANON_BIG_OBJ,
28 COFF_UNKNOWN
29 } COFF_OBJ_TYPE;
30
31 typedef struct _COFF_HEADER_INFO {
32 COFF_OBJ_TYPE type;
33 uint16_t sizeOfOptionalHeader;
34 uint16_t sizeOfHeader;
35 uint32_t pointerToSymbolTable;
36 uint32_t numberOfSymbols;
37 uint32_t numberOfSections;
38 } COFF_HEADER_INFO;
39
40 /********************************************
41 * COFF/PE prototypes
42 ********************************************/
43
44 void initLinker_PEi386( void );
45 void exitLinker_PEi386( void );
46 const char * addDLL_PEi386( pathchar *dll_name, HINSTANCE *instance );
47 void freePreloadObjectFile_PEi386( ObjectCode *oc );
48
49 bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f);
50
51 pathchar* findSystemLibrary_PEi386( pathchar* dll_name );
52 HsPtr addLibrarySearchPath_PEi386( pathchar* dll_path );
53 bool removeLibrarySearchPath_PEi386( HsPtr dll_path_index );
54
55 bool ocResolve_PEi386 ( ObjectCode* oc );
56 bool ocRunInit_PEi386 ( ObjectCode *oc );
57 bool ocGetNames_PEi386 ( ObjectCode* oc );
58 bool ocVerifyImage_PEi386 ( ObjectCode* oc );
59 SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl);
60 bool ocAllocateSymbolExtras_PEi386 ( ObjectCode* oc );
61 SymbolAddr *lookupSymbolInDLLs ( const SymbolName* lbl );
62 /* See Note [mingw-w64 name decoration scheme] */
63 /* We use myindex to calculate array addresses, rather than
64 simply doing the normal subscript thing. That's because
65 some of the above structs have sizes which are not
66 a whole number of words. GCC rounds their sizes up to a
67 whole number of words, which means that the address calcs
68 arising from using normal C indexing or pointer arithmetic
69 are just plain wrong. Sigh.
70 */
71 INLINE_HEADER unsigned char *
72 myindex ( int scale, void* base, int index )
73 {
74 return
75 ((unsigned char*)base) + scale * index;
76 }
77 pathchar* resolveSymbolAddr_PEi386 ( pathchar* buffer, int size,
78 SymbolAddr* symbol, uintptr_t* top );
79
80 char *get_name_string(
81 unsigned char* name,
82 ObjectCode* oc);
83
84 char* get_sym_name(
85 uint8_t* name,
86 ObjectCode* oc);
87
88 /********************************************
89 * COFF/PE headers
90 ********************************************/
91 /* Section 7.1 PE Specification */
92 typedef IMPORT_OBJECT_HEADER COFF_import_header;
93 #define sizeof_COFF_import_Header sizeof(COFF_import_header)
94
95 typedef IMAGE_SECTION_HEADER COFF_section;
96 #define sizeof_COFF_section sizeof(COFF_section)
97
98
99 typedef IMAGE_SYMBOL COFF_symbol_og;
100 #define sizeof_COFF_symbol_og sizeof(COFF_symbol_og)
101
102 typedef IMAGE_SYMBOL_EX COFF_symbol_ex;
103 #define sizeof_COFF_symbol_ex sizeof(COFF_symbol_ex)
104
105 typedef IMAGE_RELOCATION COFF_reloc;
106 #define sizeof_COFF_reloc sizeof(COFF_reloc)
107
108 // MingW-w64 is missing these from the implementation. So we have to look them up
109 typedef DLL_DIRECTORY_COOKIE(WINAPI *LPAddDLLDirectory)(PCWSTR NewDirectory);
110 typedef WINBOOL(WINAPI *LPRemoveDLLDirectory)(DLL_DIRECTORY_COOKIE Cookie);
111
112 /* Combine union of possible symbol types. */
113 typedef
114 union _COFF_symbol {
115 COFF_symbol_og og;
116 COFF_symbol_ex ex;
117 } COFF_symbol;
118
119 /* A record for storing handles into DLLs. */
120 typedef
121 struct _OpenedDLL {
122 pathchar* name;
123 struct _OpenedDLL* next;
124 HINSTANCE instance;
125 } OpenedDLL;
126
127 /* A record for storing indirectly linked functions from DLLs. */
128 typedef
129 struct _IndirectAddr {
130 SymbolAddr* addr;
131 struct _IndirectAddr* next;
132 } IndirectAddr;
133
134 /* Some alignment information. */
135 typedef
136 struct _Alignments {
137 uint32_t mask;
138 uint32_t value;
139 } Alignments;
140
141 /* Util symbol handling functions. */
142 COFF_OBJ_TYPE getObjectType ( char* image, pathchar* fileName );
143 COFF_HEADER_INFO* getHeaderInfo ( ObjectCode* oc );
144 size_t getSymbolSize ( COFF_HEADER_INFO *info );
145 int32_t getSymSectionNumber ( COFF_HEADER_INFO *info, COFF_symbol* sym );
146 uint32_t getSymValue ( COFF_HEADER_INFO *info, COFF_symbol* sym );
147 uint8_t getSymStorageClass ( COFF_HEADER_INFO *info, COFF_symbol* sym );
148 uint8_t getSymNumberOfAuxSymbols ( COFF_HEADER_INFO *info, COFF_symbol* sym );
149 uint16_t getSymType ( COFF_HEADER_INFO *info, COFF_symbol* sym );
150 uint8_t* getSymShortName ( COFF_HEADER_INFO *info, COFF_symbol* sym );
151
152 /* See Note [mingw-w64 name decoration scheme] */
153 #if !defined(x86_64_HOST_ARCH)
154 #define STRIP_LEADING_UNDERSCORE 1
155 #else
156 #define STRIP_LEADING_UNDERSCORE 0
157 #endif
158
159 /*
160 Note [mingw-w64 name decoration scheme]
161
162 What's going on with name decoration? Well, original code
163 have some crufty and ad-hocish paths related mostly to very old
164 mingw gcc/binutils/runtime combinations. Now mingw-w64 offers pretty
165 uniform and MS-compatible decoration scheme across its tools and runtime.
166
167 The scheme is pretty straightforward: on 32 bit objects symbols are exported
168 with underscore prepended (and @ + stack size suffix appended for stdcall
169 functions), on 64 bits no underscore is prepended and no suffix is appended
170 because we have no stdcall convention on 64 bits.
171
172 See #9218
173 */
174
175
176 #include "EndPrivate.h"