summaryrefslogtreecommitdiff
path: root/rts/LinkerInternals.h
diff options
context:
space:
mode:
authorRay Shih <rayshih@fb.com>2020-07-09 06:48:55 -0700
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-11-11 03:20:35 -0500
commit2782487f5f6ad9df4dc8725226a47f07fec77f9f (patch)
treec0605f2cfd8228586eb108598d021ce0c40d9976 /rts/LinkerInternals.h
parentc34a4b98b1f09ea3096d39a839a86f2d7185c796 (diff)
downloadhaskell-2782487f5f6ad9df4dc8725226a47f07fec77f9f.tar.gz
Add loadNativeObj and unloadNativeObj
(This change is originally written by niteria) This adds two functions: * `loadNativeObj` * `unloadNativeObj` and implements them for Linux. They are useful if you want to load a shared object with Haskell code using the system linker and have GHC call dlclose() after the code is no longer referenced from the heap. Using the system linker allows you to load the shared object above outside the low-mem region. It also loads the DWARF sections in a way that `perf` understands. `dl_iterate_phdr` is what makes this implementation Linux specific.
Diffstat (limited to 'rts/LinkerInternals.h')
-rw-r--r--rts/LinkerInternals.h33
1 files changed, 31 insertions, 2 deletions
diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h
index 6b726f7a27..93e949f2f2 100644
--- a/rts/LinkerInternals.h
+++ b/rts/LinkerInternals.h
@@ -31,6 +31,13 @@ typedef struct _Symbol
SymbolAddr *addr;
} Symbol_t;
+typedef struct NativeCodeRange_ {
+ void *start, *end;
+
+ /* Allow a chain of these things */
+ struct NativeCodeRange_ *next;
+} NativeCodeRange;
+
/* 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.
@@ -157,6 +164,13 @@ typedef struct {
#endif
} SymbolExtra;
+typedef enum {
+ /* Objects that were loaded by this linker */
+ STATIC_OBJECT,
+
+ /* Objects that were loaded by dlopen */
+ DYNAMIC_OBJECT,
+} ObjectType;
/* Top-level structure for an object module. One of these is allocated
* for each object file in use.
@@ -165,7 +179,8 @@ typedef struct _ObjectCode {
OStatus status;
pathchar *fileName;
int fileSize; /* also mapped image size when using mmap() */
- char* formatName; /* eg "ELF32", "DLL", "COFF", etc. */
+ char* formatName; /* e.g. "ELF32", "DLL", "COFF", etc. */
+ ObjectType type; /* who loaded this object? */
/* If this object is a member of an archive, archiveMemberName is
* like "libarchive.a(object.o)". Otherwise it's NULL.
@@ -267,6 +282,19 @@ typedef struct _ObjectCode {
* (read-only/executable) code. */
m32_allocator *rw_m32, *rx_m32;
#endif
+
+ /*
+ * The following are only valid if .type == DYNAMIC_OBJECT
+ */
+
+ /* handle returned from dlopen */
+ void *dlopen_handle;
+
+ /* base virtual address of the loaded code */
+ void *l_addr;
+
+ /* virtual memory ranges of loaded code */
+ NativeCodeRange *nc_ranges;
} ObjectCode;
#define OC_INFORMATIVE_FILENAME(OC) \
@@ -275,6 +303,7 @@ typedef struct _ObjectCode {
(OC)->fileName \
)
+
#if defined(THREADED_RTS)
extern Mutex linker_mutex;
#endif
@@ -360,7 +389,7 @@ resolveSymbolAddr (pathchar* buffer, int size,
HsInt isAlreadyLoaded( pathchar *path );
HsInt loadOc( ObjectCode* oc );
-ObjectCode* mkOc( pathchar *path, char *image, int imageSize,
+ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
bool mapped, pathchar *archiveMemberName,
int misalignment
);