Skip to content

Handling of __dso_handle makes little sense

When debugging !6485 (closed) I noticed that the RTS's current handling of the C++ __dso_handle symbol makes very little sense:

    /* GCC defines a special symbol __dso_handle which is resolved to NULL if
       referenced from a statically linked module. We need to mimic this, but
       we cannot use NULL because we use it to mean nonexistent symbols. So we
       use an arbitrary (hopefully unique) address here.
    */
    if (! ghciInsertSymbolTable(WSTR("(GHCi special symbols)"),
                                symhash, "__dso_handle", (void *)0x1234567, HS_BOOL_FALSE, NULL)) {
        barf("ghciInsertSymbolTable failed");
    }

There are a few things wrong here:

  • the comment claims that __dso_handle should be resolved to NULL when statically linking, but I have been unable to find a source to substantiate this claim. Moreover, it appears that real linkers will rather resolve the symbol to another symbol entirely (something relative to memcpy in one case)
  • the logic doesn't even follow the comment but rather resolves the symbol to a random value

The result is that code built as PIC on AArch64 is extremely fragile as the random pointer chosen by the RTS may not sit within 4GB of location of the loaded object, which may contain references to __dso_handle relocated via bounded-displacement relocations (e.g. R_AARCH64_ADR_PREL_PG_HI21).

Edited by Ben Gamari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information