|
| 1 | +From bcce4db821abe826673c247d673274db5d219949 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Moritz Angermann < [email protected]> |
| 3 | +Date: Wed, 21 Feb 2024 08:13:32 +0000 |
| 4 | +Subject: [PATCH 6/7] Adds support for Hidden symbols |
| 5 | + |
| 6 | +There migth be hidden and Global symbols. Global symbols should have precedence over Hidden ones. |
| 7 | +--- |
| 8 | + rts/Linker.c | 19 +++++++++++++++---- |
| 9 | + rts/LinkerInternals.h | 2 ++ |
| 10 | + rts/linker/Elf.c | 3 +++ |
| 11 | + rts/linker/ElfTypes.h | 6 ++++++ |
| 12 | + rts/linker/PEi386.c | 2 +- |
| 13 | + 5 files changed, 27 insertions(+), 5 deletions(-) |
| 14 | + |
| 15 | +diff --git a/rts/Linker.c b/rts/Linker.c |
| 16 | +index c3a5b5d..b826af8 100644 |
| 17 | +--- a/rts/Linker.c |
| 18 | ++++ b/rts/Linker.c |
| 19 | +@@ -226,11 +226,11 @@ static void ghciRemoveSymbolTable(StrHashTable *table, const SymbolName* key, |
| 20 | + static const char * |
| 21 | + symbolTypeString (SymType type) |
| 22 | + { |
| 23 | +- switch (type & ~SYM_TYPE_DUP_DISCARD) { |
| 24 | ++ switch (type & ~(SYM_TYPE_DUP_DISCARD | SYM_TYPE_HIDDEN)) { |
| 25 | + case SYM_TYPE_CODE: return "code"; |
| 26 | + case SYM_TYPE_DATA: return "data"; |
| 27 | + case SYM_TYPE_INDIRECT_DATA: return "indirect-data"; |
| 28 | +- default: barf("symbolTypeString: unknown symbol type"); |
| 29 | ++ default: barf("symbolTypeString: unknown symbol type (%d)", type); |
| 30 | + } |
| 31 | + } |
| 32 | + |
| 33 | +@@ -277,10 +277,19 @@ int ghciInsertSymbolTable( |
| 34 | + } |
| 35 | + else if (pinfo->type ^ type) |
| 36 | + { |
| 37 | ++ if(pinfo->type & SYM_TYPE_HIDDEN) |
| 38 | ++ { |
| 39 | ++ /* The existing symbol is hidden, let's replace it */ |
| 40 | ++ pinfo->value = data; |
| 41 | ++ pinfo->owner = owner; |
| 42 | ++ pinfo->strength = strength; |
| 43 | ++ pinfo->type = type; |
| 44 | ++ return 1; |
| 45 | ++ } |
| 46 | + /* We were asked to discard the symbol on duplicates, do so quietly. */ |
| 47 | +- if (!(type & SYM_TYPE_DUP_DISCARD)) |
| 48 | ++ if (!(type & (SYM_TYPE_DUP_DISCARD | SYM_TYPE_HIDDEN))) |
| 49 | + { |
| 50 | +- debugBelch("Symbol type mismatch.\n"); |
| 51 | ++ debugBelch("Symbol type mismatch (existing %d, new %d).\n", pinfo->type, type); |
| 52 | + debugBelch("Symbol %s was defined by %" PATH_FMT " to be a %s symbol.\n", |
| 53 | + key, obj_name, symbolTypeString(type)); |
| 54 | + debugBelch(" yet was defined by %" PATH_FMT " to be a %s symbol.\n", |
| 55 | +@@ -380,6 +389,8 @@ int ghciInsertSymbolTable( |
| 56 | + pinfo->owner->archiveMemberName ? pinfo->owner->archiveMemberName |
| 57 | + : pinfo->owner->fileName |
| 58 | + ); |
| 59 | ++ debugBelch("Address of new symbol: %p, old symbol: %p\n", data, pinfo->value); |
| 60 | ++ debugBelch("Type of symbol; new: %d, existing: %d\n", type, pinfo->type); |
| 61 | + |
| 62 | + return 0; |
| 63 | + } |
| 64 | +diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h |
| 65 | +index 6cadaa8..3beac1d 100644 |
| 66 | +--- a/rts/LinkerInternals.h |
| 67 | ++++ b/rts/LinkerInternals.h |
| 68 | +@@ -64,6 +64,8 @@ typedef enum _SymType { |
| 69 | + SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library |
| 70 | + however if a duplicate is found with a mismatching |
| 71 | + SymType then discard this one. */ |
| 72 | ++ SYM_TYPE_HIDDEN = 1 << 4, /* the symbol is hidden and should not be exported */ |
| 73 | ++ |
| 74 | + } SymType; |
| 75 | + |
| 76 | + |
| 77 | +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c |
| 78 | +index 9f56812..05db9b3 100644 |
| 79 | +--- a/rts/linker/Elf.c |
| 80 | ++++ b/rts/linker/Elf.c |
| 81 | +@@ -1139,6 +1139,9 @@ ocGetNames_ELF ( ObjectCode* oc ) |
| 82 | + } else { |
| 83 | + sym_type = SYM_TYPE_DATA; |
| 84 | + } |
| 85 | ++ if(ELF_ST_VISIBILITY(symbol->elf_sym->st_other) == STV_HIDDEN) { |
| 86 | ++ sym_type |= SYM_TYPE_HIDDEN; |
| 87 | ++ } |
| 88 | + |
| 89 | + /* And the decision is ... */ |
| 90 | + |
| 91 | +diff --git a/rts/linker/ElfTypes.h b/rts/linker/ElfTypes.h |
| 92 | +index 24e29a1..d3524e1 100644 |
| 93 | +--- a/rts/linker/ElfTypes.h |
| 94 | ++++ b/rts/linker/ElfTypes.h |
| 95 | +@@ -33,6 +33,9 @@ |
| 96 | + #define Elf_Sym Elf64_Sym |
| 97 | + #define Elf_Rel Elf64_Rel |
| 98 | + #define Elf_Rela Elf64_Rela |
| 99 | ++#if !defined(ELF_ST_VISIBILITY) |
| 100 | ++#define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY |
| 101 | ++#endif |
| 102 | + #if !defined(ELF_ST_TYPE) |
| 103 | + #define ELF_ST_TYPE ELF64_ST_TYPE |
| 104 | + #endif |
| 105 | +@@ -57,6 +60,9 @@ |
| 106 | + #define Elf_Sym Elf32_Sym |
| 107 | + #define Elf_Rel Elf32_Rel |
| 108 | + #define Elf_Rela Elf32_Rela |
| 109 | ++#if !defined(ELF_ST_VISIBILITY) |
| 110 | ++#define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY |
| 111 | ++#endif /* ELF_ST_VISIBILITY */ |
| 112 | + #if !defined(ELF_ST_TYPE) |
| 113 | + #define ELF_ST_TYPE ELF32_ST_TYPE |
| 114 | + #endif /* ELF_ST_TYPE */ |
| 115 | +diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c |
| 116 | +index 010dc8f..c6f82b7 100644 |
| 117 | +--- a/rts/linker/PEi386.c |
| 118 | ++++ b/rts/linker/PEi386.c |
| 119 | +@@ -1942,7 +1942,7 @@ static size_t |
| 120 | + makeSymbolExtra_PEi386( ObjectCode* oc, uint64_t index STG_UNUSED, size_t s, char* symbol STG_UNUSED, SymType type ) |
| 121 | + { |
| 122 | + SymbolExtra *extra; |
| 123 | +- switch(type & ~SYM_TYPE_DUP_DISCARD) { |
| 124 | ++ switch(type & ~(SYM_TYPE_DUP_DISCARD | SYM_TYPE_HIDDEN)) { |
| 125 | + case SYM_TYPE_CODE: { |
| 126 | + // jmp *-14(%rip) |
| 127 | + extra = m32_alloc(oc->rx_m32, sizeof(SymbolExtra), 8); |
| 128 | +-- |
| 129 | +2.33.0 |
| 130 | + |
0 commit comments