summaryrefslogtreecommitdiff
path: root/rts/CheckUnload.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2015-10-15 16:17:06 +0100
committerSimon Marlow <marlowsd@gmail.com>2015-10-15 16:19:45 +0100
commit04e8366608fee4f5e3358acc855bc6f556c3f508 (patch)
tree3b198e2dd38cc4587c679f6ada00031318406be6 /rts/CheckUnload.c
parent20e30d5f3d932d6393369ed56e4a1518f0ffe60b (diff)
downloadhaskell-04e8366608fee4f5e3358acc855bc6f556c3f508.tar.gz
ELF/x86_64: map object file sections separately into the low 2GB
On 64-bit ELF we need to link object files into the low 2GB due to the small memory model. Previously we would map the entire object file using MAP_32BIT, but the object file can consist of 75% or more symbols, which only need to be present during linking, so this is wasteful. In our particular application, we're already running out of space here. This patch changes the way we load object files on ELF platforms so that the object is first mapped above the 2GB boundary, parsed, and then the important sections are re-mapped into the low 2GB area. Test Plan: validate (also needs testing on OS X & Windows, preferably 32 & 64 bit) Reviewers: Phyx, trommler, bgamari, austin Subscribers: hsyl20, thomie, bgamari Differential Revision: https://phabricator.haskell.org/D975
Diffstat (limited to 'rts/CheckUnload.c')
-rw-r--r--rts/CheckUnload.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/rts/CheckUnload.c b/rts/CheckUnload.c
index 7802754445..c75673847e 100644
--- a/rts/CheckUnload.c
+++ b/rts/CheckUnload.c
@@ -40,15 +40,21 @@
static void checkAddress (HashTable *addrs, void *addr)
{
ObjectCode *oc;
+ int i;
if (!lookupHashTable(addrs, (W_)addr)) {
insertHashTable(addrs, (W_)addr, addr);
for (oc = unloaded_objects; oc; oc = oc->next) {
- if ((W_)addr >= (W_)oc->image &&
- (W_)addr < (W_)oc->image + oc->fileSize) {
- oc->referenced = 1;
- break;
+ for (i = 0; i < oc->n_sections; i++) {
+ if (oc->sections[i].kind != SECTIONKIND_OTHER) {
+ if ((W_)addr >= (W_)oc->sections[i].start &&
+ (W_)addr < (W_)oc->sections[i].start
+ + oc->sections[i].size) {
+ oc->referenced = 1;
+ return;
+ }
+ }
}
}
}