Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

11 changed files:

Changes:

  • rts/Linker.c
    ... ... @@ -268,6 +268,7 @@ int ghciInsertSymbolTable(
    268 268
        SymbolAddr* data,
    
    269 269
        SymStrength strength,
    
    270 270
        SymType type,
    
    271
    +   unsigned long size,
    
    271 272
        ObjectCode *owner)
    
    272 273
     {
    
    273 274
        RtsSymbolInfo *pinfo = lookupStrHashTable(table, key);
    
    ... ... @@ -278,6 +279,7 @@ int ghciInsertSymbolTable(
    278 279
           pinfo->owner = owner;
    
    279 280
           pinfo->strength = strength;
    
    280 281
           pinfo->type = type;
    
    282
    +      pinfo->size = size;
    
    281 283
           insertStrHashTable(table, key, pinfo);
    
    282 284
           return 1;
    
    283 285
        }
    
    ... ... @@ -290,6 +292,7 @@ int ghciInsertSymbolTable(
    290 292
                 pinfo->owner = owner;
    
    291 293
                 pinfo->strength = strength;
    
    292 294
                 pinfo->type = type;
    
    295
    +            pinfo->size = size;
    
    293 296
                 return 1;
    
    294 297
            }
    
    295 298
            /* We were asked to discard the symbol on duplicates, do so quietly.  */
    
    ... ... @@ -318,6 +321,7 @@ int ghciInsertSymbolTable(
    318 321
            /* The existing symbol is weak with a zero value; replace it with the new symbol. */
    
    319 322
            pinfo->value = data;
    
    320 323
            pinfo->owner = owner;
    
    324
    +       pinfo->size = size;
    
    321 325
            return 1;
    
    322 326
        }
    
    323 327
        else if (strength == STRENGTH_WEAK)
    
    ... ... @@ -336,6 +340,7 @@ int ghciInsertSymbolTable(
    336 340
           pinfo->value = data;
    
    337 341
           pinfo->owner = owner;
    
    338 342
           pinfo->strength = strength;
    
    343
    +      pinfo->size = size;
    
    339 344
           return 1;
    
    340 345
        }
    
    341 346
        else if (  pinfo->owner
    
    ... ... @@ -360,6 +365,7 @@ int ghciInsertSymbolTable(
    360 365
                pinfo->value = data;
    
    361 366
                pinfo->owner = owner;
    
    362 367
                pinfo->strength = strength;
    
    368
    +           pinfo->size = size;
    
    363 369
            }
    
    364 370
     
    
    365 371
            return 1;
    
    ... ... @@ -477,7 +483,7 @@ initLinker_ (int retain_cafs)
    477 483
             IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
    
    478 484
             if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
    
    479 485
                                         symhash, sym->lbl, sym->addr,
    
    480
    -                                    sym->strength, sym->type, NULL)) {
    
    486
    +                                    sym->strength, sym->type, 0, NULL)) {
    
    481 487
                 barf("ghciInsertSymbolTable failed");
    
    482 488
             }
    
    483 489
         }
    
    ... ... @@ -495,7 +501,7 @@ initLinker_ (int retain_cafs)
    495 501
                 IF_DEBUG(linker, debugBelch("initLinker: inserting extra rts symbol %s, %p\n", sym->lbl, sym->addr));
    
    496 502
                 if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
    
    497 503
                                             symhash, sym->lbl, sym->addr,
    
    498
    -                                        sym->strength, sym->type, NULL)) {
    
    504
    +                                        sym->strength, sym->type, 0, NULL)) {
    
    499 505
                     barf("ghciInsertSymbolTable failed");
    
    500 506
                 }
    
    501 507
             }
    
    ... ... @@ -506,7 +512,7 @@ initLinker_ (int retain_cafs)
    506 512
         if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"), symhash,
    
    507 513
                                     MAYBE_LEADING_UNDERSCORE_STR("newCAF"),
    
    508 514
                                     retain_cafs ? newRetainedCAF : newGCdCAF,
    
    509
    -                                HS_BOOL_FALSE, SYM_TYPE_CODE, NULL)) {
    
    515
    +                                HS_BOOL_FALSE, SYM_TYPE_CODE, 0, NULL)) {
    
    510 516
             barf("ghciInsertSymbolTable failed");
    
    511 517
         }
    
    512 518
     
    
    ... ... @@ -778,7 +784,7 @@ HsBool removeLibrarySearchPath(HsPtr dll_path_index)
    778 784
     HsInt insertSymbol(pathchar* obj_name, SymbolName* key, SymbolAddr* data)
    
    779 785
     {
    
    780 786
         return ghciInsertSymbolTable(obj_name, symhash, key, data, HS_BOOL_FALSE,
    
    781
    -                                 SYM_TYPE_CODE, NULL);
    
    787
    +                                 SYM_TYPE_CODE, 0, NULL);
    
    782 788
     }
    
    783 789
     
    
    784 790
     /* -----------------------------------------------------------------------------
    
    ... ... @@ -1623,7 +1629,7 @@ int ocTryLoad (ObjectCode* oc) {
    1623 1629
                 && !ghciInsertSymbolTable(oc->fileName, symhash, symbol.name,
    
    1624 1630
                                           symbol.addr,
    
    1625 1631
                                           isSymbolWeak(oc, symbol.name),
    
    1626
    -                                      symbol.type, oc)) {
    
    1632
    +                                      symbol.type, 0, oc)) {
    
    1627 1633
                 return 0;
    
    1628 1634
             }
    
    1629 1635
         }
    

  • rts/LinkerInternals.h
    ... ... @@ -418,6 +418,7 @@ typedef struct _RtsSymbolInfo {
    418 418
         ObjectCode *owner;
    
    419 419
         SymStrength strength;
    
    420 420
         SymType type;
    
    421
    +    unsigned long size; // symbol size: only used for COMMON symbols
    
    421 422
     } RtsSymbolInfo;
    
    422 423
     
    
    423 424
     #include "BeginPrivate.h"
    
    ... ... @@ -441,6 +442,7 @@ int ghciInsertSymbolTable(
    441 442
         SymbolAddr* data,
    
    442 443
         SymStrength weak,
    
    443 444
         SymType type,
    
    445
    +    unsigned long size,
    
    444 446
         ObjectCode *owner);
    
    445 447
     
    
    446 448
     /* Lock-free version of lookupSymbol. When 'dependent' is not NULL, adds it as a
    

  • rts/linker/Elf.c
    ... ... @@ -961,7 +961,11 @@ ocGetNames_ELF ( ObjectCode* oc )
    961 961
                for (size_t j = 0; j < symTab->n_symbols; j++) {
    
    962 962
                    ElfSymbol *symbol = &symTab->symbols[j];
    
    963 963
                    if (SHN_COMMON == symTab->symbols[j].elf_sym->st_shndx) {
    
    964
    -                   common_size += symbol->elf_sym->st_size;
    
    964
    +                   /* Skip COMMON symbols already defined by a previously-loaded
    
    965
    +                    * object; we will reuse the existing allocation. */
    
    966
    +                   if (!lookupStrHashTable(symhash, symTab->symbols[j].name)) {
    
    967
    +                       common_size += symbol->elf_sym->st_size;
    
    968
    +                   }
    
    965 969
                    }
    
    966 970
                }
    
    967 971
           }
    
    ... ... @@ -1006,17 +1010,35 @@ ocGetNames_ELF ( ObjectCode* oc )
    1006 1010
                    /* Figure out if we want to add it; if so, set ad to its
    
    1007 1011
                       address.  Otherwise leave ad == NULL. */
    
    1008 1012
     
    
    1013
    +               bool common_already_defined = false;
    
    1009 1014
                    if (shndx == SHN_COMMON) {
    
    1010 1015
                        isLocal = false;
    
    1011
    -                   CHECK(common_used < common_size);
    
    1012
    -                   CHECK(common_mem);
    
    1013
    -                   symbol->addr = (void*)((uintptr_t)common_mem + common_used);
    
    1014
    -                   common_used += symbol->elf_sym->st_size;
    
    1015
    -                   CHECK(common_used <= common_size);
    
    1016
    -
    
    1017
    -                   IF_DEBUG(linker_verbose,
    
    1018
    -                            debugBelch("COMMON symbol, size %llu name %s allocated at %p\n",
    
    1019
    -                                       (long long unsigned int) symbol->elf_sym->st_size, nm, symbol->addr));
    
    1016
    +                   RtsSymbolInfo *existing = lookupStrHashTable(symhash, nm);
    
    1017
    +                   if (existing != NULL) {
    
    1018
    +                       /* COMMON symbol already allocated by a previously-loaded
    
    1019
    +                        * object; reuse that address so relocations resolve to
    
    1020
    +                        * the same storage. */
    
    1021
    +                       if(symbol->elf_sym->st_size > existing->size) {
    
    1022
    +                           barf("linker: trying to link COMMON symbols %s with incompatible sizes: previous size %llu, new size %llu\n",
    
    1023
    +                                   nm,
    
    1024
    +                                   (long long unsigned int) existing->size,
    
    1025
    +                                   (long long unsigned int) symbol->elf_sym->st_size);
    
    1026
    +                       }
    
    1027
    +                       symbol->addr = existing->value;
    
    1028
    +                       common_already_defined = true;
    
    1029
    +                       IF_DEBUG(linker_verbose,
    
    1030
    +                                debugBelch("COMMON symbol, size %llu name %s reusing address %p\n",
    
    1031
    +                                           (long long unsigned int) symbol->elf_sym->st_size, nm, symbol->addr));
    
    1032
    +                   } else {
    
    1033
    +                       CHECK(common_used < common_size);
    
    1034
    +                       CHECK(common_mem);
    
    1035
    +                       symbol->addr = (void*)((uintptr_t)common_mem + common_used);
    
    1036
    +                       common_used += symbol->elf_sym->st_size;
    
    1037
    +                       CHECK(common_used <= common_size);
    
    1038
    +                       IF_DEBUG(linker_verbose,
    
    1039
    +                                debugBelch("COMMON symbol, size %llu name %s allocated at %p\n",
    
    1040
    +                                           (long long unsigned int) symbol->elf_sym->st_size, nm, symbol->addr));
    
    1041
    +                   }
    
    1020 1042
     
    
    1021 1043
                        /* Pointless to do addProddableBlock() for this area,
    
    1022 1044
                           since the linker should never poke around in it. */
    
    ... ... @@ -1080,13 +1102,13 @@ ocGetNames_ELF ( ObjectCode* oc )
    1080 1102
                    if (symbol->addr != NULL) {
    
    1081 1103
                        CHECK(nm != NULL);
    
    1082 1104
                        /* Acquire! */
    
    1083
    -                   if (!isLocal) {
    
    1105
    +                   if (!isLocal && !common_already_defined) {
    
    1084 1106
     
    
    1085 1107
                            if (isWeak == HS_BOOL_TRUE) {
    
    1086 1108
                                setWeakSymbol(oc, nm);
    
    1087 1109
                            }
    
    1088 1110
                            if (!ghciInsertSymbolTable(oc->fileName, symhash,
    
    1089
    -                                                  nm, symbol->addr, isWeak, sym_type, oc)
    
    1111
    +                                                  nm, symbol->addr, isWeak, sym_type, symbol->elf_sym->st_size, oc)
    
    1090 1112
                                ) {
    
    1091 1113
                                goto fail;
    
    1092 1114
                            }
    

  • rts/linker/MachO.c
    ... ... @@ -1421,8 +1421,13 @@ ocGetNames_MachO(ObjectCode* oc)
    1421 1421
                     if((oc->info->nlist[i].n_type & N_TYPE) == N_UNDF
    
    1422 1422
                         && (oc->info->nlist[i].n_value != 0))
    
    1423 1423
                     {
    
    1424
    -                    commonSize += oc->info->nlist[i].n_value;
    
    1425 1424
                         oc->n_symbols++;
    
    1425
    +                    /* Only allocate space for COMMON symbols not already
    
    1426
    +                     * defined by a previously-loaded object. */
    
    1427
    +                    SymbolName *nm_c = oc->info->macho_symbols[i].name;
    
    1428
    +                    if (!lookupStrHashTable(symhash, nm_c)) {
    
    1429
    +                        commonSize += oc->info->nlist[i].n_value;
    
    1430
    +                    }
    
    1426 1431
                     }
    
    1427 1432
                     else if((oc->info->nlist[i].n_type & N_TYPE) == N_SECT)
    
    1428 1433
                         oc->n_symbols++;
    
    ... ... @@ -1436,7 +1441,7 @@ ocGetNames_MachO(ObjectCode* oc)
    1436 1441
          */
    
    1437 1442
         IF_DEBUG(linker, debugBelch("ocGetNames_MachO: %d external symbols\n",
    
    1438 1443
                                     oc->n_symbols));
    
    1439
    -    oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(Symbol_t),
    
    1444
    +    oc->symbols = stgCallocBytes(oc->n_symbols, sizeof(Symbol_t),
    
    1440 1445
                                        "ocGetNames_MachO(oc->symbols)");
    
    1441 1446
     
    
    1442 1447
         if (oc->info->symCmd) {
    
    ... ... @@ -1467,6 +1472,7 @@ ocGetNames_MachO(ObjectCode* oc)
    1467 1472
                                                      , addr
    
    1468 1473
                                                      , HS_BOOL_FALSE
    
    1469 1474
                                                      , sym_type
    
    1475
    +                                                 , 0
    
    1470 1476
                                                      , oc);
    
    1471 1477
     
    
    1472 1478
                                 oc->symbols[curSymbol].name = nm;
    
    ... ... @@ -1488,8 +1494,10 @@ ocGetNames_MachO(ObjectCode* oc)
    1488 1494
         }
    
    1489 1495
     
    
    1490 1496
         /* setup the common storage */
    
    1491
    -    commonStorage = stgCallocBytes(1,commonSize,"ocGetNames_MachO(common symbols)");
    
    1492
    -    commonCounter = (unsigned long)commonStorage;
    
    1497
    +    if (commonSize > 0) {
    
    1498
    +        commonStorage = stgCallocBytes(1, commonSize, "ocGetNames_MachO(common symbols)");
    
    1499
    +        commonCounter = (unsigned long)commonStorage;
    
    1500
    +    }
    
    1493 1501
     
    
    1494 1502
         if (oc->info->symCmd) {
    
    1495 1503
             for (size_t i = 0; i < oc->info->n_macho_symbols; i++) {
    
    ... ... @@ -1499,22 +1507,47 @@ ocGetNames_MachO(ObjectCode* oc)
    1499 1507
                  && (nlist->n_type & N_EXT)
    
    1500 1508
                  && (nlist->n_value != 0)) {
    
    1501 1509
                     unsigned long sz = nlist->n_value;
    
    1502
    -
    
    1503
    -                nlist->n_value = commonCounter;
    
    1504
    -
    
    1505
    -                /* also set the final address to the macho_symbol */
    
    1506
    -                oc->info->macho_symbols[i].addr = (void*)commonCounter;
    
    1507 1510
                     /* TODO: Figure out how to determine this from object */
    
    1508 1511
                     SymType sym_type = SYM_TYPE_CODE;
    
    1509 1512
     
    
    1510
    -                IF_DEBUG(linker_verbose, debugBelch("ocGetNames_MachO: inserting common symbol: %s\n", nm));
    
    1511
    -                ghciInsertSymbolTable(oc->fileName, symhash, nm,
    
    1512
    -                                       (void*)commonCounter, HS_BOOL_FALSE, sym_type, oc);
    
    1513
    -                oc->symbols[curSymbol].name = nm;
    
    1514
    -                oc->symbols[curSymbol].addr = oc->info->macho_symbols[i].addr;
    
    1515
    -                curSymbol++;
    
    1513
    +                RtsSymbolInfo *existing = lookupStrHashTable(symhash, nm);
    
    1514
    +                if (existing != NULL) {
    
    1515
    +                    /* COMMON symbol already allocated by a previously-loaded
    
    1516
    +                     * object; reuse that address so relocations resolve to
    
    1517
    +                     * the same storage. */
    
    1518
    +                    if (sz > existing->size) {
    
    1519
    +                        barf("linker: trying to link COMMON symbols %s with"
    
    1520
    +                             " incompatible sizes: previous size %llu,"
    
    1521
    +                             " new size %lu\n",
    
    1522
    +                             nm,
    
    1523
    +                             (long long unsigned int) existing->size,
    
    1524
    +                             sz);
    
    1525
    +                    }
    
    1526
    +                    nlist->n_value = (unsigned long)existing->value;
    
    1527
    +                    oc->info->macho_symbols[i].addr = existing->value;
    
    1528
    +                    IF_DEBUG(linker_verbose,
    
    1529
    +                             debugBelch("ocGetNames_MachO: COMMON symbol %s"
    
    1530
    +                                        " reusing address %p\n",
    
    1531
    +                                        nm, existing->value));
    
    1532
    +                    /* Don't add to oc->symbols: not the owner */
    
    1533
    +                } else {
    
    1534
    +                    nlist->n_value = commonCounter;
    
    1535
    +                    /* also set the final address to the macho_symbol */
    
    1536
    +                    oc->info->macho_symbols[i].addr = (void*)commonCounter;
    
    1516 1537
     
    
    1517
    -                commonCounter += sz;
    
    1538
    +                    IF_DEBUG(linker_verbose,
    
    1539
    +                             debugBelch("ocGetNames_MachO: inserting common symbol: %s\n", nm));
    
    1540
    +                    ghciInsertSymbolTable(oc->fileName, symhash, nm,
    
    1541
    +                                         (void*)commonCounter, HS_BOOL_FALSE,
    
    1542
    +                                         sym_type,
    
    1543
    +                                         sz, oc);
    
    1544
    +                    oc->symbols[curSymbol].name = nm;
    
    1545
    +                    oc->symbols[curSymbol].addr = oc->info->macho_symbols[i].addr;
    
    1546
    +                    oc->symbols[curSymbol].type = sym_type;
    
    1547
    +                    curSymbol++;
    
    1548
    +
    
    1549
    +                    commonCounter += sz;
    
    1550
    +                }
    
    1518 1551
                 }
    
    1519 1552
             }
    
    1520 1553
         }
    

  • rts/linker/PEi386.c
    ... ... @@ -573,7 +573,7 @@ void initLinker_PEi386(void)
    573 573
         if (!ghciInsertSymbolTable(WSTR("(GHCi/Ld special symbols)"),
    
    574 574
                                    symhash, "__image_base__",
    
    575 575
                                    GetModuleHandleW (NULL), HS_BOOL_TRUE,
    
    576
    -                               SYM_TYPE_CODE, NULL)) {
    
    576
    +                               SYM_TYPE_CODE, 0, NULL)) {
    
    577 577
             barf("ghciInsertSymbolTable failed");
    
    578 578
         }
    
    579 579
     
    
    ... ... @@ -1186,7 +1186,7 @@ bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f
    1186 1186
         SymType symType = SYM_TYPE_DUP_DISCARD | SYM_TYPE_HIDDEN;
    
    1187 1187
         symType |= hdr.Type == IMPORT_OBJECT_CODE ? SYM_TYPE_CODE : SYM_TYPE_DATA;
    
    1188 1188
     
    
    1189
    -    if (!ghciInsertSymbolTable(dll, symhash, symbol, sym, false, symType, NULL))
    
    1189
    +    if (!ghciInsertSymbolTable(dll, symhash, symbol, sym, false, symType, 0, NULL))
    
    1190 1190
           return false;
    
    1191 1191
     
    
    1192 1192
         return true;
    
    ... ... @@ -1825,7 +1825,12 @@ ocGetNames_PEi386 ( ObjectCode* oc )
    1825 1825
           if (getSymSectionNumber (info, sym) == PE_SECTION_UNDEFINED
    
    1826 1826
                && getSymValue (info, sym) > 0
    
    1827 1827
                && getSymStorageClass (info, sym) != IMAGE_SYM_CLASS_SECTION) {
    
    1828
    -           globalBssSize += getSymValue (info, sym);
    
    1828
    +           /* Only count COMMON symbols not already defined by a
    
    1829
    +            * previously-loaded object; we will reuse their allocation. */
    
    1830
    +           SymbolName *nm = get_sym_name (getSymShortName (info, sym), oc);
    
    1831
    +           if (!lookupStrHashTable(symhash, nm)) {
    
    1832
    +               globalBssSize += getSymValue (info, sym);
    
    1833
    +           }
    
    1829 1834
           }
    
    1830 1835
           i += getSymNumberOfAuxSymbols (info, sym);
    
    1831 1836
        }
    
    ... ... @@ -1859,6 +1864,8 @@ ocGetNames_PEi386 ( ObjectCode* oc )
    1859 1864
           uint8_t symStorageClass = getSymStorageClass (info, sym);
    
    1860 1865
           SymbolAddr *addr = NULL;
    
    1861 1866
           bool isWeak = false;
    
    1867
    +      bool common_already_defined = false;
    
    1868
    +      unsigned long symSize = 0;
    
    1862 1869
           SymbolName *sname = get_sym_name (getSymShortName (info, sym), oc);
    
    1863 1870
     
    
    1864 1871
           uint32_t secNumber = getSymSectionNumber (info, sym);
    
    ... ... @@ -1959,10 +1966,31 @@ ocGetNames_PEi386 ( ObjectCode* oc )
    1959 1966
           }
    
    1960 1967
           else if (  secNumber == IMAGE_SYM_UNDEFINED && symValue > 0) {
    
    1961 1968
              /* This symbol isn't in any section at all, ie, global bss.
    
    1962
    -            Allocate zeroed space for it from the BSS section */
    
    1963
    -          addr = bss;
    
    1964
    -          bss = (SymbolAddr*)((StgWord)bss + (StgWord)symValue);
    
    1965
    -          IF_DEBUG(linker_verbose, debugBelch("bss symbol @ %p %u\n", addr, symValue));
    
    1969
    +            Allocate zeroed space for it from the BSS section, unless a
    
    1970
    +            previously-loaded object already allocated storage for it. */
    
    1971
    +          RtsSymbolInfo *existing = lookupStrHashTable(symhash, sname);
    
    1972
    +          if (existing != NULL) {
    
    1973
    +              /* COMMON symbol already allocated by a previously-loaded
    
    1974
    +               * object; reuse that address so relocations resolve to
    
    1975
    +               * the same storage. */
    
    1976
    +              if (symValue > existing->size) {
    
    1977
    +                  barf("linker: trying to link COMMON symbols %s with"
    
    1978
    +                       " incompatible sizes: previous size %llu,"
    
    1979
    +                       " new size %u\n",
    
    1980
    +                       sname,
    
    1981
    +                       (long long unsigned int) existing->size,
    
    1982
    +                       symValue);
    
    1983
    +              }
    
    1984
    +              addr = existing->value;
    
    1985
    +              common_already_defined = true;
    
    1986
    +              IF_DEBUG(linker_verbose,
    
    1987
    +                       debugBelch("bss symbol reusing @ %p %u\n", addr, symValue));
    
    1988
    +          } else {
    
    1989
    +              addr = bss;
    
    1990
    +              bss = (SymbolAddr*)((StgWord)bss + (StgWord)symValue);
    
    1991
    +              symSize = (unsigned long)symValue;
    
    1992
    +              IF_DEBUG(linker_verbose, debugBelch("bss symbol @ %p %u\n", addr, symValue));
    
    1993
    +          }
    
    1966 1994
           }
    
    1967 1995
           else if (section && section->kind == SECTIONKIND_BFD_IMPORT_LIBRARY) {
    
    1968 1996
               /* Disassembly of section .idata$5:
    
    ... ... @@ -1990,7 +2018,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
    1990 2018
               type = has_code_section ? SYM_TYPE_CODE : SYM_TYPE_DATA;
    
    1991 2019
               type |= SYM_TYPE_DUP_DISCARD;
    
    1992 2020
               if (!ghciInsertSymbolTable(oc->fileName, symhash, sname,
    
    1993
    -                                     addr, false, type, oc)) {
    
    2021
    +                                     addr, false, type, 0, oc)) {
    
    1994 2022
                  releaseOcInfo (oc);
    
    1995 2023
                  stgFree (oc->image);
    
    1996 2024
                  oc->image = NULL;
    
    ... ... @@ -2073,7 +2101,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
    2073 2101
                 type |= SYM_TYPE_HIDDEN;
    
    2074 2102
     
    
    2075 2103
               if (!ghciInsertSymbolTable(oc->fileName, symhash, sname,
    
    2076
    -                                     addr, false, type, oc))
    
    2104
    +                                     addr, false, type, 0, oc))
    
    2077 2105
                    return false;
    
    2078 2106
     
    
    2079 2107
               break;
    
    ... ... @@ -2083,6 +2111,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
    2083 2111
           }
    
    2084 2112
     
    
    2085 2113
           if ((addr != NULL || isWeak)
    
    2114
    +         && !common_already_defined
    
    2086 2115
              && (!section || (section && section->kind != SECTIONKIND_IMPORT))) {
    
    2087 2116
              /* debugBelch("addSymbol %p `%s' Weak:%lld \n", addr, sname, isWeak); */
    
    2088 2117
              sname = strdup (sname);
    
    ... ... @@ -2098,7 +2127,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
    2098 2127
              }
    
    2099 2128
     
    
    2100 2129
              if (! ghciInsertSymbolTable(oc->fileName, symhash, sname, addr,
    
    2101
    -                                     isWeak, type, oc))
    
    2130
    +                                     isWeak, type, symSize, oc))
    
    2102 2131
                  return false;
    
    2103 2132
           } else {
    
    2104 2133
               /* We're skipping the symbol, but if we ever load this
    

  • testsuite/tests/rts/linker/Makefile
    ... ... @@ -152,3 +152,10 @@ T25191:
    152 152
     	"$(TEST_HC)" -c T25191_foo2.c -o foo2.o -v0
    
    153 153
     	"$(TEST_HC)" T25191.hs -v0
    
    154 154
     	./T25191
    
    155
    +
    
    156
    +.PHONY: T6107
    
    157
    +T6107:
    
    158
    +	"$(TEST_HC)" -c T6107_sym1.s -o T6107_sym1.o -v0
    
    159
    +	"$(TEST_HC)" -c T6107_sym2.s -o T6107_sym2.o -v0
    
    160
    +	"$(TEST_HC)" $(TEST_HC_OPTS) T6107.hs -o T6107 -v0
    
    161
    +	./T6107

  • testsuite/tests/rts/linker/T6107.hs
    1
    +{-# LANGUAGE ForeignFunctionInterface, CPP #-}
    
    2
    +-- Test that the RTS linker merges COMMON symbols from multiple object files.
    
    3
    +-- Without the fix, loadObj of the second .o fails with a duplicate symbol error.
    
    4
    +import Foreign.C.String
    
    5
    +import Control.Monad
    
    6
    +
    
    7
    +-- Type of paths is different on Windows
    
    8
    +#if defined(mingw32_HOST_OS)
    
    9
    +type PathString = CWString
    
    10
    +withPathString = withCWString
    
    11
    +#else
    
    12
    +type PathString = CString
    
    13
    +withPathString = withCString
    
    14
    +#endif
    
    15
    +
    
    16
    +main :: IO ()
    
    17
    +main = do
    
    18
    +    initLinker
    
    19
    +    r1 <- withPathString "T6107_sym1.o" loadObj
    
    20
    +    when (r1 /= 1) $ error "loadObj T6107_sym1.o failed"
    
    21
    +    r2 <- withPathString "T6107_sym2.o" loadObj
    
    22
    +    when (r2 /= 1) $ error "loadObj T6107_sym2.o failed"
    
    23
    +    r <- resolveObjs
    
    24
    +    when (r /= 1) $ error "resolveObjs failed"
    
    25
    +    putStrLn "OK"
    
    26
    +
    
    27
    +foreign import ccall "initLinker" initLinker :: IO ()
    
    28
    +foreign import ccall "loadObj"    loadObj    :: PathString -> IO Int
    
    29
    +foreign import ccall "resolveObjs" resolveObjs :: IO Int

  • testsuite/tests/rts/linker/T6107.stdout
    1
    +OK

  • testsuite/tests/rts/linker/T6107_sym1.s
    1
    +.comm shared_var, 4

  • testsuite/tests/rts/linker/T6107_sym2.s
    1
    +.comm shared_var, 4

  • testsuite/tests/rts/linker/all.T
    ... ... @@ -181,3 +181,11 @@ test('T25191',
    181 181
           when(opsys('mingw32'), expect_broken(25191)) # not supported in the PE linker yet
    
    182 182
          ],
    
    183 183
          makefile_test, ['T25191'])
    
    184
    +
    
    185
    +
    
    186
    +# Test that COMMON symbols from multiple object files are merged correctly
    
    187
    +test('T6107',
    
    188
    +     [req_rts_linker,
    
    189
    +      extra_files(['T6107_sym1.s', 'T6107_sym2.s'])
    
    190
    +     ],
    
    191
    +     makefile_test, ['T6107'])