runtime_loader: Add support for DT_GNU_HASH.

This is an alternative to DT_HASH (SystemV/SVR4 hash tables.) Notably,
it uses a Bloom filter to allow an entire image to be skipped
at once rather than searching the actual symbol hash.

We don't currently build anything with DT_GNU_HASH support.
You can test this by adding -Wl,--hash-style=both to HAIKU_LINKFLAGS.
(It seems to increase image sizes by not too much: libroot goes
from 1347139 to 1367691 bytes (20.55 KB) in my build.)

Change-Id: I4a91276490fcd136db175833ee48b36e06ceed47
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7855
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2024-07-23 23:24:36 +00:00
committed by waddlesplash
parent 90a0982dcb
commit ffc1a5219d
5 changed files with 110 additions and 12 deletions
+2
View File
@@ -544,6 +544,8 @@ typedef struct {
#define DT_PREINIT_ARRAY 32 /* preinitialization array */
#define DT_PREINIT_ARRAYSZ 33 /* preinitialization array size */
#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table */
#define DT_VERSYM 0x6ffffff0 /* symbol version table */
#define DT_VERDEF 0x6ffffffc /* version definition table */
#define DT_VERDEFNUM 0x6ffffffd /* number of version definitions */
@@ -107,16 +107,32 @@ typedef struct image_t {
addr_t term_routine;
addr_t dynamic_ptr; // pointer to the dynamic section
// pointer to symbol participation data structures
// needed images
uint32 num_needed;
struct image_t **needed;
// symbol participation data structures
uint32 *symhash;
elf_sym *syms;
char *strtab;
struct {
uint32 mask_words_count_mask;
uint32 shift2;
uint32 bucket_count;
elf_addr *bloom;
uint32 *buckets;
uint32 *chain0;
} gnuhash;
// relocation information
elf_rel *rel;
int rel_len;
elf_rela *rela;
int rela_len;
elf_rel *pltrel;
int pltrel_len;
// init/term functions
addr_t *init_array;
int init_array_len;
addr_t *preinit_array;
@@ -124,11 +140,6 @@ typedef struct image_t {
addr_t *term_array;
int term_array_len;
unsigned dso_tls_id;
uint32 num_needed;
struct image_t **needed;
// versioning related structures
uint32 num_version_definitions;
elf_verdef *version_definitions;
@@ -138,6 +149,9 @@ typedef struct image_t {
elf_version_info *versions;
uint32 num_versions;
// thread-local storage
unsigned dso_tls_id;
#ifdef __cplusplus
elf_sym* (*find_undefined_symbol)(struct image_t* rootImage,
struct image_t* image,