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