|
| 1 | +diff --git a/rts/Linker.c b/rts/Linker.c |
| 2 | +index 1f229f8173..7f954702a3 100644 |
| 3 | +--- a/rts/Linker.c |
| 4 | ++++ b/rts/Linker.c |
| 5 | +@@ -273,7 +273,7 @@ int ghciInsertSymbolTable( |
| 6 | + RtsSymbolInfo *pinfo = lookupStrHashTable(table, key); |
| 7 | + if (!pinfo) /* new entry */ |
| 8 | + { |
| 9 | +- pinfo = stgMallocBytes(sizeof (*pinfo), "ghciInsertToSymbolTable"); |
| 10 | ++ pinfo = stgCallocBytes(1, sizeof (*pinfo), "ghciInsertToSymbolTable"); |
| 11 | + pinfo->value = data; |
| 12 | + pinfo->owner = owner; |
| 13 | + pinfo->strength = strength; |
| 14 | +@@ -1203,7 +1203,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize, |
| 15 | + |
| 16 | + |
| 17 | + IF_DEBUG(linker, debugBelch("mkOc: %" PATH_FMT "\n", path)); |
| 18 | +- oc = stgMallocBytes(sizeof(ObjectCode), "mkOc(oc)"); |
| 19 | ++ oc = stgCallocBytes(1, sizeof(ObjectCode), "mkOc(oc)"); |
| 20 | + |
| 21 | + oc->info = NULL; |
| 22 | + oc->type = type; |
| 23 | +@@ -1223,7 +1223,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize, |
| 24 | + oc->fileName = pathdup(path); |
| 25 | + |
| 26 | + if (archiveMemberName) { |
| 27 | +- oc->archiveMemberName = stgMallocBytes( (pathlen(archiveMemberName)+1) * pathsize, |
| 28 | ++ oc->archiveMemberName = stgCallocBytes(1, (pathlen(archiveMemberName)+1) * pathsize, |
| 29 | + "loadObj" ); |
| 30 | + pathcopy(oc->archiveMemberName, archiveMemberName); |
| 31 | + } else { |
| 32 | +@@ -1380,12 +1380,12 @@ preloadObjectFile (pathchar *path) |
| 33 | + // reading the file, and then we misalign image on purpose so |
| 34 | + // that the actual sections end up aligned again. |
| 35 | + misalignment = machoGetMisalignment(f); |
| 36 | +- image = stgMallocBytes(fileSize + misalignment, "loadObj(image)"); |
| 37 | ++ image = stgCallocBytes(1, fileSize + misalignment, "loadObj(image)"); |
| 38 | + image += misalignment; |
| 39 | + |
| 40 | + # else /* !defined(darwin_HOST_OS) */ |
| 41 | + |
| 42 | +- image = stgMallocBytes(fileSize, "loadObj(image)"); |
| 43 | ++ image = stgCallocBytes(1, fileSize, "loadObj(image)"); |
| 44 | + |
| 45 | + #endif /* !defined(darwin_HOST_OS) */ |
| 46 | + |
| 47 | +@@ -1678,6 +1678,8 @@ static HsInt resolveObjs_ (void) |
| 48 | + IF_DEBUG(linker, debugBelch("resolveObjs: start\n")); |
| 49 | + |
| 50 | + for (ObjectCode *oc = objects; oc; oc = oc->next) { |
| 51 | ++ if(oc->status == OBJECT_RESOLVED) |
| 52 | ++ continue; |
| 53 | + int r = ocTryLoad(oc); |
| 54 | + if (!r) { |
| 55 | + errorBelch("Could not load Object Code %" PATH_FMT ".\n", OC_INFORMATIVE_FILENAME(oc)); |
| 56 | +@@ -1806,7 +1808,7 @@ void |
| 57 | + addProddableBlock ( ObjectCode* oc, void* start, int size ) |
| 58 | + { |
| 59 | + ProddableBlock* pb |
| 60 | +- = stgMallocBytes(sizeof(ProddableBlock), "addProddableBlock"); |
| 61 | ++ = stgCallocBytes(1,sizeof(ProddableBlock), "addProddableBlock"); |
| 62 | + |
| 63 | + IF_DEBUG(linker, debugBelch("addProddableBlock: %p %p %d\n", oc, start, size)); |
| 64 | + ASSERT(size > 0); |
| 65 | +diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h |
| 66 | +index e6098aa2b0..4b8992e817 100644 |
| 67 | +--- a/rts/LinkerInternals.h |
| 68 | ++++ b/rts/LinkerInternals.h |
| 69 | +@@ -299,6 +299,10 @@ struct _ObjectCode { |
| 70 | + int n_segments; |
| 71 | + Segment *segments; |
| 72 | + |
| 73 | ++ // COMMON section |
| 74 | ++ void * common_mem; |
| 75 | ++ unsigned long common_size; |
| 76 | ++ |
| 77 | + // |
| 78 | + // Garbage collection fields |
| 79 | + // |
| 80 | +diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c |
| 81 | +index 4cac10ba15..fe0d8ca40e 100644 |
| 82 | +--- a/rts/RtsUtils.c |
| 83 | ++++ b/rts/RtsUtils.c |
| 84 | +@@ -104,6 +104,11 @@ stgCallocBytes (size_t count, size_t size, char *msg) |
| 85 | + rtsConfig.mallocFailHook((W_) count*size, msg); |
| 86 | + stg_exit(EXIT_INTERNAL_ERROR); |
| 87 | + } |
| 88 | ++ // If we run under qemu with jemalloc, calloc is not guaranteed |
| 89 | ++ // to zero memory. |
| 90 | ++ // - https://giters.com/jemalloc/jemalloc/issues/1844 |
| 91 | ++ // - https://lists.nongnu.org/archive/html/qemu-devel/2020-05/msg03119.html |
| 92 | ++ memset(space, 0, count*size); |
| 93 | + return space; |
| 94 | + } |
| 95 | + |
| 96 | +diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c |
| 97 | +index d181450190..1ad05fc286 100644 |
| 98 | +--- a/rts/linker/Elf.c |
| 99 | ++++ b/rts/linker/Elf.c |
| 100 | +@@ -307,6 +307,15 @@ ocInit_ELF(ObjectCode * oc) |
| 101 | + } |
| 102 | + } |
| 103 | + } |
| 104 | ++ if(NULL != oc->common_mem) { |
| 105 | ++#if RTS_LINKER_USE_MMAP |
| 106 | ++ munmap(oc->common_mem, oc->common_size); |
| 107 | ++#else |
| 108 | ++ stgFree(oc->common_mem); |
| 109 | ++#endif |
| 110 | ++ } |
| 111 | ++ oc->common_mem = NULL; |
| 112 | ++ oc->common_size = 0; |
| 113 | + } |
| 114 | + |
| 115 | + void |
| 116 | +@@ -963,14 +972,17 @@ ocGetNames_ELF ( ObjectCode* oc ) |
| 117 | + for (size_t j = 0; j < symTab->n_symbols; j++) { |
| 118 | + ElfSymbol *symbol = &symTab->symbols[j]; |
| 119 | + if (SHN_COMMON == symTab->symbols[j].elf_sym->st_shndx) { |
| 120 | +- common_size += symbol->elf_sym->st_size; |
| 121 | ++ // st_value holds the alignment. Adding alignment always |
| 122 | ++ // should give us some wiggle room to get alignment right. |
| 123 | ++ common_size += symbol->elf_sym->st_size + symbol->elf_sym->st_value; |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | +- void * common_mem = NULL; |
| 128 | ++ oc->common_mem = NULL; |
| 129 | ++ oc->common_size = common_size; |
| 130 | + if(common_size > 0) { |
| 131 | +- common_mem = mmapAnonForLinker(common_size); |
| 132 | +- if (common_mem == NULL) { |
| 133 | ++ oc->common_mem = mmapAnonForLinker(common_size); |
| 134 | ++ if (oc->common_mem == NULL) { |
| 135 | + barf("ocGetNames_ELF: Failed to allocate memory for SHN_COMMONs"); |
| 136 | + } |
| 137 | + } |
| 138 | +@@ -1011,9 +1023,10 @@ ocGetNames_ELF ( ObjectCode* oc ) |
| 139 | + if (shndx == SHN_COMMON) { |
| 140 | + isLocal = false; |
| 141 | + CHECK(common_used < common_size); |
| 142 | +- CHECK(common_mem); |
| 143 | +- symbol->addr = (void*)((uintptr_t)common_mem + common_used); |
| 144 | +- common_used += symbol->elf_sym->st_size; |
| 145 | ++ CHECK(oc->common_mem); |
| 146 | ++ int alignment = symbol->elf_sym->st_value-1; |
| 147 | ++ symbol->addr = (void*)(((uintptr_t)oc->common_mem + common_used + alignment) & ~alignment); |
| 148 | ++ common_used = (uintptr_t)symbol->addr - (uintptr_t)oc->common_mem + symbol->elf_sym->st_size; |
| 149 | + CHECK(common_used <= common_size); |
| 150 | + |
| 151 | + IF_DEBUG(linker_verbose, |
| 152 | +@@ -1027,7 +1040,9 @@ ocGetNames_ELF ( ObjectCode* oc ) |
| 153 | + || ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK |
| 154 | + ) |
| 155 | + /* and not an undefined symbol */ |
| 156 | +- && shndx != SHN_UNDEF |
| 157 | ++ && (shndx != SHN_UNDEF |
| 158 | ++ /* unless it's weak */ |
| 159 | ++ || (shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK)) |
| 160 | + /* and not in a "special section" */ |
| 161 | + && (shndx < SHN_LORESERVE |
| 162 | + #if defined(SHN_XINDEX) |
| 163 | +@@ -1054,6 +1069,14 @@ ocGetNames_ELF ( ObjectCode* oc ) |
| 164 | + (intptr_t) oc->sections[secno].start + |
| 165 | + (intptr_t) symbol->elf_sym->st_value); |
| 166 | + CHECK(symbol->addr != 0x0); |
| 167 | ++ if(shndx == SHN_UNDEF && ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK) { |
| 168 | ++ symbol->addr = NULL; |
| 169 | ++ } else { |
| 170 | ++ symbol->addr = (SymbolAddr*)( |
| 171 | ++ (intptr_t) oc->sections[secno].start + |
| 172 | ++ (intptr_t) symbol->elf_sym->st_value); |
| 173 | ++ CHECK(symbol->addr != 0x0); |
| 174 | ++ } |
| 175 | + if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_LOCAL) { |
| 176 | + isLocal = true; |
| 177 | + isWeak = false; |
| 178 | +@@ -1065,42 +1088,20 @@ ocGetNames_ELF ( ObjectCode* oc ) |
| 179 | + isWeak = ELF_ST_BIND(symbol->elf_sym->st_info) |
| 180 | + == STB_WEAK; |
| 181 | + } |
| 182 | +- } |
| 183 | +- |
| 184 | +- SymType sym_type; |
| 185 | +- if (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC) { |
| 186 | +- sym_type = SYM_TYPE_CODE; |
| 187 | ++ } else if (ELF_ST_BIND(symbol->elf_sym->st_info) == STB_WEAK |
| 188 | ++ && shndx == SHN_UNDEF |
| 189 | ++ && (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC |
| 190 | ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_OBJECT |
| 191 | ++ || ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_NOTYPE)) { |
| 192 | ++ symbol->addr = NULL; |
| 193 | ++ isLocal = false; |
| 194 | ++ isWeak = true; |
| 195 | + } else { |
| 196 | +- sym_type = SYM_TYPE_DATA; |
| 197 | +- } |
| 198 | +- |
| 199 | +- /* And the decision is ... */ |
| 200 | +- |
| 201 | +- if (symbol->addr != NULL) { |
| 202 | +- CHECK(nm != NULL); |
| 203 | +- /* Acquire! */ |
| 204 | +- if (!isLocal) { |
| 205 | +- |
| 206 | +- if (isWeak == HS_BOOL_TRUE) { |
| 207 | +- setWeakSymbol(oc, nm); |
| 208 | +- } |
| 209 | +- if (!ghciInsertSymbolTable(oc->fileName, symhash, |
| 210 | +- nm, symbol->addr, isWeak, sym_type, oc) |
| 211 | +- ) { |
| 212 | +- goto fail; |
| 213 | +- } |
| 214 | +- oc->symbols[curSymbol].name = nm; |
| 215 | +- oc->symbols[curSymbol].addr = symbol->addr; |
| 216 | +- oc->symbols[curSymbol].type = sym_type; |
| 217 | +- curSymbol++; |
| 218 | +- } |
| 219 | +- } else { |
| 220 | +- /* Skip. */ |
| 221 | ++ /* Skip. */ |
| 222 | + IF_DEBUG(linker_verbose, |
| 223 | + debugBelch("skipping `%s'\n", |
| 224 | + nm) |
| 225 | + ); |
| 226 | +- |
| 227 | + /* |
| 228 | + debugBelch( |
| 229 | + "skipping bind = %d, type = %d, secno = %d `%s'\n", |
| 230 | +@@ -1110,7 +1111,34 @@ ocGetNames_ELF ( ObjectCode* oc ) |
| 231 | + nm |
| 232 | + ); |
| 233 | + */ |
| 234 | ++ continue; |
| 235 | + } |
| 236 | ++ |
| 237 | ++ SymType sym_type; |
| 238 | ++ if (ELF_ST_TYPE(symbol->elf_sym->st_info) == STT_FUNC) { |
| 239 | ++ sym_type = SYM_TYPE_CODE; |
| 240 | ++ } else { |
| 241 | ++ sym_type = SYM_TYPE_DATA; |
| 242 | ++ } |
| 243 | ++ |
| 244 | ++ /* And the decision is ... */ |
| 245 | ++ CHECK(nm != NULL); |
| 246 | ++ /* Acquire! */ |
| 247 | ++ if (!isLocal) { |
| 248 | ++ |
| 249 | ++ if (isWeak == HS_BOOL_TRUE) { |
| 250 | ++ setWeakSymbol(oc, nm); |
| 251 | ++ } |
| 252 | ++ if (!ghciInsertSymbolTable(oc->fileName, symhash, |
| 253 | ++ nm, symbol->addr, isWeak, sym_type, oc) |
| 254 | ++ ) { |
| 255 | ++ goto fail; |
| 256 | ++ } |
| 257 | ++ oc->symbols[curSymbol].name = nm; |
| 258 | ++ oc->symbols[curSymbol].addr = symbol->addr; |
| 259 | ++ oc->symbols[curSymbol].type = sym_type; |
| 260 | ++ curSymbol++; |
| 261 | ++ } |
| 262 | + } |
| 263 | + } |
| 264 | + } |
| 265 | +diff --git a/rts/linker/elf_plt.c b/rts/linker/elf_plt.c |
| 266 | +index 5c6ef8ed44..314d49cbc6 100644 |
| 267 | +--- a/rts/linker/elf_plt.c |
| 268 | ++++ b/rts/linker/elf_plt.c |
| 269 | +@@ -1,4 +1,5 @@ |
| 270 | + #include "Rts.h" |
| 271 | ++#include "RtsUtils.h" |
| 272 | + #include "elf_plt.h" |
| 273 | + |
| 274 | + #include <stdbool.h> |
| 275 | +@@ -51,7 +52,7 @@ makeStub(Section * section, |
| 276 | + void* * addr, |
| 277 | + uint8_t flags) { |
| 278 | + |
| 279 | +- Stub * s = calloc(1, sizeof(Stub)); |
| 280 | ++ Stub * s = stgCallocBytes(1, sizeof(Stub), "makeStub"); |
| 281 | + ASSERT(s != NULL); |
| 282 | + s->target = *addr; |
| 283 | + s->flags = flags; |
| 284 | +diff --git a/rts/linker/elf_plt_aarch64.c b/rts/linker/elf_plt_aarch64.c |
| 285 | +index 11354a63db..6b27a2c73d 100644 |
| 286 | +--- a/rts/linker/elf_plt_aarch64.c |
| 287 | ++++ b/rts/linker/elf_plt_aarch64.c |
| 288 | +@@ -25,6 +25,7 @@ const size_t stubSizeAarch64 = 5 * 4; |
| 289 | + */ |
| 290 | + bool needStubForRelAarch64(Elf_Rel * rel) { |
| 291 | + switch(ELF64_R_TYPE(rel->r_info)) { |
| 292 | ++ case COMPAT_R_AARCH64_CONDBR19: |
| 293 | + case COMPAT_R_AARCH64_CALL26: |
| 294 | + case COMPAT_R_AARCH64_JUMP26: |
| 295 | + return true; |
| 296 | +@@ -34,6 +35,7 @@ bool needStubForRelAarch64(Elf_Rel * rel) { |
| 297 | + } |
| 298 | + bool needStubForRelaAarch64(Elf_Rela * rela) { |
| 299 | + switch(ELF64_R_TYPE(rela->r_info)) { |
| 300 | ++ case COMPAT_R_AARCH64_CONDBR19: |
| 301 | + case COMPAT_R_AARCH64_CALL26: |
| 302 | + case COMPAT_R_AARCH64_JUMP26: |
| 303 | + return true; |
| 304 | +diff --git a/rts/linker/elf_reloc_aarch64.c b/rts/linker/elf_reloc_aarch64.c |
| 305 | +index 51d7178094..dc0724c4f1 100644 |
| 306 | +--- a/rts/linker/elf_reloc_aarch64.c |
| 307 | ++++ b/rts/linker/elf_reloc_aarch64.c |
| 308 | +@@ -105,8 +105,24 @@ encodeAddendAarch64(Section * section, Elf_Rel * rel, int64_t addend) { |
| 309 | + break; |
| 310 | + } |
| 311 | + /* - control flow relocations */ |
| 312 | ++ case COMPAT_R_AARCH64_CONDBR19: { /* relocate b.* ... */ |
| 313 | ++ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 |
| 314 | ++ // 0 1 0 1 0 1 0 0 [ imm19 ... |
| 315 | ++ // |
| 316 | ++ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
| 317 | ++ // ... imm19 ] 0 [ cond ] |
| 318 | ++ CHECK(isInt64(19+2, addend)); /* X in range */ |
| 319 | ++ *(inst_t *)P = (*(inst_t *)P & 0xff00001f) |
| 320 | ++ | ((uint32_t)(addend << (5-2)) & 0x00ffffe0); |
| 321 | ++ break; |
| 322 | ++ } |
| 323 | + case COMPAT_R_AARCH64_JUMP26: /* relocate b ... */ |
| 324 | + case COMPAT_R_AARCH64_CALL26: { /* relocate bl ... */ |
| 325 | ++ // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 |
| 326 | ++ // 0|1 0 0 1 0 1 [ imm26 ... |
| 327 | ++ |
| 328 | ++ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
| 329 | ++ // ... imm26 ] |
| 330 | + CHECK(isInt64(26+2, addend)); /* X in range */ |
| 331 | + *(inst_t *)P = (*(inst_t *)P & 0xfc000000) /* keep upper 6 (32-6) |
| 332 | + * bits */ |
| 333 | +@@ -222,6 +238,23 @@ computeAddend(Section * section, Elf_Rel * rel, |
| 334 | + case COMPAT_R_AARCH64_ADD_ABS_LO12_NC: |
| 335 | + /* type: static, class: aarch64, op: S + A */ |
| 336 | + return (S + A) & 0xfff; |
| 337 | ++ case COMPAT_R_AARCH64_CONDBR19: { |
| 338 | ++ int64_t V = S + A - P; |
| 339 | ++ if(!isInt64(19+2, V)) { |
| 340 | ++ /* need a stub */ |
| 341 | ++ /* check if we already have that stub */ |
| 342 | ++ if(findStub(section, (void**)&S, 0)) { |
| 343 | ++ /* did not find it. Crete a new stub. */ |
| 344 | ++ if(makeStub(section, (void**)&S, 0)) { |
| 345 | ++ abort(/* could not find or make stub */); |
| 346 | ++ } |
| 347 | ++ } |
| 348 | ++ |
| 349 | ++ V = S + A -P; |
| 350 | ++ assert(isInt64(19+2, V)); |
| 351 | ++ } |
| 352 | ++ return V; |
| 353 | ++ } |
| 354 | + case COMPAT_R_AARCH64_JUMP26: |
| 355 | + case COMPAT_R_AARCH64_CALL26: { |
| 356 | + // S+A-P |
0 commit comments