Andreas Klebinger pushed to branch wip/andreask/linker_fix at Glasgow Haskell Compiler / GHC

Commits:

8 changed files:

Changes:

  • rts/Linker.c
    ... ... @@ -1240,7 +1240,7 @@ void freeObjectCode (ObjectCode *oc)
    1240 1240
     
    
    1241 1241
     ObjectCode*
    
    1242 1242
     mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
    
    1243
    -      bool mapped, pathchar *archiveMemberName, int misalignment ) {
    
    1243
    +      bool mapped, pathchar *archiveMemberName ) {
    
    1244 1244
        ObjectCode* oc;
    
    1245 1245
     
    
    1246 1246
     
    
    ... ... @@ -1294,7 +1294,6 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
    1294 1294
        oc->bssEnd            = NULL;
    
    1295 1295
        oc->imageMapped       = mapped;
    
    1296 1296
     
    
    1297
    -   oc->misalignment      = misalignment;
    
    1298 1297
        oc->cxa_finalize      = NULL;
    
    1299 1298
        oc->extraInfos        = NULL;
    
    1300 1299
     
    
    ... ... @@ -1352,7 +1351,6 @@ preloadObjectFile (pathchar *path)
    1352 1351
        int r;
    
    1353 1352
        void *image;
    
    1354 1353
        ObjectCode *oc;
    
    1355
    -   int misalignment = 0;
    
    1356 1354
     
    
    1357 1355
        r = pathstat(path, &st);
    
    1358 1356
        if (r == -1) {
    
    ... ... @@ -1410,27 +1408,8 @@ preloadObjectFile (pathchar *path)
    1410 1408
            return NULL;
    
    1411 1409
        }
    
    1412 1410
     
    
    1413
    -#  if defined(darwin_HOST_OS)
    
    1414
    -
    
    1415
    -    // In a Mach-O .o file, all sections can and will be misaligned
    
    1416
    -    // if the total size of the headers is not a multiple of the
    
    1417
    -    // desired alignment. This is fine for .o files that only serve
    
    1418
    -    // as input for the static linker, but it's not fine for us,
    
    1419
    -    // as SSE (used by gcc for floating point) and Altivec require
    
    1420
    -    // 16-byte alignment.
    
    1421
    -    // We calculate the correct alignment from the header before
    
    1422
    -    // reading the file, and then we misalign image on purpose so
    
    1423
    -    // that the actual sections end up aligned again.
    
    1424
    -   misalignment = machoGetMisalignment(f);
    
    1425
    -   image = stgMallocBytes(fileSize + misalignment, "loadObj(image)");
    
    1426
    -   image += misalignment;
    
    1427
    -
    
    1428
    -# else /* !defined(darwin_HOST_OS) */
    
    1429
    -
    
    1430 1411
        image = stgMallocBytes(fileSize, "loadObj(image)");
    
    1431 1412
     
    
    1432
    -#endif /* !defined(darwin_HOST_OS) */
    
    1433
    -
    
    1434 1413
        int n;
    
    1435 1414
        n = fread ( image, 1, fileSize, f );
    
    1436 1415
        fclose(f);
    
    ... ... @@ -1445,16 +1424,13 @@ preloadObjectFile (pathchar *path)
    1445 1424
        IF_DEBUG(linker, debugBelch("loadObj: preloaded image at %p\n", (void *) image));
    
    1446 1425
     
    
    1447 1426
        /* FIXME (AP): =mapped= parameter unconditionally set to true */
    
    1448
    -   oc = mkOc(STATIC_OBJECT, path, image, fileSize, true, NULL, misalignment);
    
    1427
    +   oc = mkOc(STATIC_OBJECT, path, image, fileSize, true, NULL);
    
    1449 1428
     
    
    1450
    -#if defined(OBJFORMAT_MACHO)
    
    1451
    -   if (ocVerifyImage_MachO( oc ))
    
    1452
    -       ocInit_MachO( oc );
    
    1453
    -#endif
    
    1454
    -#if defined(OBJFORMAT_ELF)
    
    1455
    -   if(ocVerifyImage_ELF( oc ))
    
    1456
    -       ocInit_ELF( oc );
    
    1457
    -#endif
    
    1429
    +   if (!verifyAndInitOc(oc)) {
    
    1430
    +       ocDebugBelch(oc, "loadObj: Failed to verify oc.\n");
    
    1431
    +       freeObjectCode(oc);
    
    1432
    +       return NULL;
    
    1433
    +   }
    
    1458 1434
        return oc;
    
    1459 1435
     }
    
    1460 1436
     
    
    ... ... @@ -1511,27 +1487,42 @@ HsInt loadObj (pathchar *path)
    1511 1487
        return r;
    
    1512 1488
     }
    
    1513 1489
     
    
    1490
    +// Call the relevant VerifyImage_* and ocInit_* functions.
    
    1491
    +// Return 1 on success.
    
    1492
    +HsInt verifyAndInitOc (ObjectCode* oc)
    
    1493
    +{
    
    1494
    +    int r;
    
    1495
    +
    
    1496
    +    /* verify the in-memory image */
    
    1497
    +#if defined(OBJFORMAT_ELF)
    
    1498
    +    r = ocVerifyImage_ELF ( oc );
    
    1499
    +    if(r) {
    
    1500
    +        ocInit_ELF( oc );
    
    1501
    +    }
    
    1502
    +#elif defined(OBJFORMAT_PEi386)
    
    1503
    +    r = ocVerifyImage_PEi386 ( oc );
    
    1504
    +#elif defined(OBJFORMAT_MACHO)
    
    1505
    +    r = ocVerifyImage_MachO ( oc );
    
    1506
    +    if(r) {
    
    1507
    +        ocInit_MachO( oc );
    
    1508
    +    }
    
    1509
    +#else
    
    1510
    +    barf("loadObj: no verify method");
    
    1511
    +#endif
    
    1512
    +    if (!r) {
    
    1513
    +        IF_DEBUG(linker, ocDebugBelch(oc, "ocVerifyImage_* failed\n"));
    
    1514
    +        return r;
    
    1515
    +    }
    
    1516
    +    return 1;
    
    1517
    +}
    
    1518
    +
    
    1519
    +// Precondition: oc already verified.
    
    1514 1520
     HsInt loadOc (ObjectCode* oc)
    
    1515 1521
     {
    
    1516 1522
        int r;
    
    1517 1523
     
    
    1518 1524
        IF_DEBUG(linker, ocDebugBelch(oc, "start\n"));
    
    1519 1525
     
    
    1520
    -   /* verify the in-memory image */
    
    1521
    -#  if defined(OBJFORMAT_ELF)
    
    1522
    -   r = ocVerifyImage_ELF ( oc );
    
    1523
    -#  elif defined(OBJFORMAT_PEi386)
    
    1524
    -   r = ocVerifyImage_PEi386 ( oc );
    
    1525
    -#  elif defined(OBJFORMAT_MACHO)
    
    1526
    -   r = ocVerifyImage_MachO ( oc );
    
    1527
    -#  else
    
    1528
    -   barf("loadObj: no verify method");
    
    1529
    -#  endif
    
    1530
    -   if (!r) {
    
    1531
    -       IF_DEBUG(linker, ocDebugBelch(oc, "ocVerifyImage_* failed\n"));
    
    1532
    -       return r;
    
    1533
    -   }
    
    1534
    -
    
    1535 1526
        /* Note [loadOc orderings]
    
    1536 1527
           ~~~~~~~~~~~~~~~~~~~~~~~
    
    1537 1528
           The order of `ocAllocateExtras` and `ocGetNames` matters. For MachO
    
    ... ... @@ -1593,7 +1584,7 @@ HsInt loadOc (ObjectCode* oc)
    1593 1584
                oc->status = OBJECT_LOADED;
    
    1594 1585
            }
    
    1595 1586
        }
    
    1596
    -   IF_DEBUG(linker, ocDebugBelch(oc, "done\n"));
    
    1587
    +   IF_DEBUG(linker, ocDebugBelch(oc, "loadOc:done\n"));
    
    1597 1588
     
    
    1598 1589
        return 1;
    
    1599 1590
     }
    

  • rts/LinkerInternals.h
    ... ... @@ -264,10 +264,6 @@ struct _ObjectCode {
    264 264
         /* non-zero if the object file was mmap'd, otherwise malloc'd */
    
    265 265
         int        imageMapped;
    
    266 266
     
    
    267
    -    /* record by how much image has been deliberately misaligned
    
    268
    -       after allocation, so that we can use realloc */
    
    269
    -    int        misalignment;
    
    270
    -
    
    271 267
         /* The address of __cxa_finalize; set when at least one finalizer was
    
    272 268
          * register and therefore we must call __cxa_finalize before unloading.
    
    273 269
          * See Note [Resolving __dso_handle]. */
    
    ... ... @@ -390,6 +386,11 @@ extern Elf_Word shndx_table_uninit_label;
    390 386
                    OC_INFORMATIVE_FILENAME(oc), \
    
    391 387
                    ##__VA_ARGS__)
    
    392 388
     
    
    389
    +#define ocBelch(oc, s, ...) \
    
    390
    +    errorBelch("%s(%" PATH_FMT ": " s, \
    
    391
    +               __func__, \
    
    392
    +               OC_INFORMATIVE_FILENAME(oc), \
    
    393
    +               ##__VA_ARGS__)
    
    393 394
     
    
    394 395
     #if defined(THREADED_RTS)
    
    395 396
     extern Mutex linker_mutex;
    
    ... ... @@ -487,12 +488,17 @@ HsInt loadArchive_ (pathchar *path);
    487 488
     HsInt isAlreadyLoaded( pathchar *path );
    
    488 489
     OStatus getObjectLoadStatus_ (pathchar *path);
    
    489 490
     ObjectCode *lookupObjectByPath(pathchar *path);
    
    491
    +
    
    492
    +/* Verify an objects is an a format that can be loaded and initialize the oc struct if required. */
    
    493
    +HsInt verifyAndInitOc( ObjectCode *oc );
    
    494
    +
    
    495
    +//Expects the oc to be verified already.
    
    490 496
     HsInt loadOc( ObjectCode* oc );
    
    491 497
     ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
    
    492
    -                  bool mapped, pathchar *archiveMemberName,
    
    493
    -                  int misalignment
    
    498
    +                  bool mapped, pathchar *archiveMemberName
    
    494 499
                       );
    
    495 500
     
    
    501
    +
    
    496 502
     void initSegment(Segment *s, void *start, size_t size, SegmentProt prot, int n_sections);
    
    497 503
     void freeSegments(ObjectCode *oc);
    
    498 504
     
    

  • rts/linker/LoadArchive.c
    ... ... @@ -24,7 +24,9 @@
    24 24
     #include <string.h>
    
    25 25
     #include <stddef.h>
    
    26 26
     #include <ctype.h>
    
    27
    +#include <sys/types.h>
    
    27 28
     #include <fs_rts.h>
    
    29
    +#include <stdio.h>
    
    28 30
     
    
    29 31
     #define FAIL(...) do {\
    
    30 32
        errorBelch("loadArchive: "__VA_ARGS__); \
    
    ... ... @@ -33,7 +35,6 @@
    33 35
     
    
    34 36
     #define DEBUG_LOG(...) IF_DEBUG(linker, debugBelch("loadArchive: " __VA_ARGS__))
    
    35 37
     
    
    36
    -
    
    37 38
     #if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
    
    38 39
     /* Read 4 bytes and convert to host byte order */
    
    39 40
     static uint32_t read4Bytes(const char buf[static 4])
    
    ... ... @@ -110,56 +111,8 @@ static bool loadFatArchive(char input[static 20], FILE* f, pathchar* path)
    110 111
     }
    
    111 112
     #endif
    
    112 113
     
    
    113
    -enum ObjectFileFormat {
    
    114
    -    NotObject,
    
    115
    -    COFFAmd64,
    
    116
    -    COFFI386,
    
    117
    -    COFFAArch64,
    
    118
    -    ELF,
    
    119
    -    MachO32,
    
    120
    -    MachO64,
    
    121
    -};
    
    122
    -
    
    123
    -static enum ObjectFileFormat identifyObjectFile_(char* buf, size_t sz)
    
    124
    -{
    
    125
    -    if (sz > 2 && ((uint16_t*)buf)[0] == 0x8664) {
    
    126
    -        return COFFAmd64;
    
    127
    -    }
    
    128
    -    if (sz > 2 && ((uint16_t*)buf)[0] == 0x014c) {
    
    129
    -        return COFFI386;
    
    130
    -    }
    
    131
    -    if (sz > 2 && ((uint16_t*)buf)[0] == 0xaa64) {
    
    132
    -        return COFFAArch64;
    
    133
    -    }
    
    134
    -    if (sz > 4 && memcmp(buf, "\x7f" "ELF", 4) == 0) {
    
    135
    -        return ELF;
    
    136
    -    }
    
    137
    -    if (sz > 4 && ((uint32_t*)buf)[0] == 0xfeedface) {
    
    138
    -        return MachO32;
    
    139
    -    }
    
    140
    -    if (sz > 4 && ((uint32_t*)buf)[0] == 0xfeedfacf) {
    
    141
    -        return MachO64;
    
    142
    -    }
    
    143
    -    // BigObj COFF files ...
    
    144
    -    if (sz > 8 && ((uint64_t*)buf)[0] == 0x86640002ffff0000) {
    
    145
    -        return COFFAmd64;
    
    146
    -    }
    
    147
    -    return NotObject;
    
    148
    -}
    
    149
    -
    
    150
    -static enum ObjectFileFormat identifyObjectFile(FILE *f)
    
    114
    +static pathchar* thinArchiveMemberPath(pathchar* path, char* fileName)
    
    151 115
     {
    
    152
    -    char buf[32];
    
    153
    -    ssize_t sz = fread(buf, 1, 32, f);
    
    154
    -    CHECK(fseek(f, -sz, SEEK_CUR) == 0);
    
    155
    -    return identifyObjectFile_(buf, sz);
    
    156
    -}
    
    157
    -
    
    158
    -static bool readThinArchiveMember(int n, int memberSize, pathchar* path,
    
    159
    -        char* fileName, char* image)
    
    160
    -{
    
    161
    -    bool has_succeeded = false;
    
    162
    -    FILE* member = NULL;
    
    163 116
         pathchar *pathCopy, *dirName, *memberPath, *objFileName;
    
    164 117
         memberPath = NULL;
    
    165 118
         /* Allocate and setup the dirname of the archive.  We'll need
    
    ... ... @@ -173,15 +126,29 @@ static bool readThinArchiveMember(int n, int memberSize, pathchar* path,
    173 126
         objFileName = mkPath(fileName);
    
    174 127
         pathprintf(memberPath, memberLen, WSTR("%" PATH_FMT "%" PATH_FMT), dirName,
    
    175 128
                 objFileName);
    
    176
    -    stgFree(objFileName);
    
    129
    +
    
    130
    +    stgFree(pathCopy);
    
    177 131
         stgFree(dirName);
    
    132
    +    stgFree(objFileName);
    
    133
    +    return memberPath;
    
    134
    +}
    
    135
    +
    
    136
    +static bool readThinArchiveMember(int memberSize, pathchar* path,
    
    137
    +        char* fileName, char* image)
    
    138
    +{
    
    139
    +    bool has_succeeded = false;
    
    140
    +    FILE* member = NULL;
    
    141
    +    pathchar *memberPath;
    
    142
    +    //Fully resolved path.
    
    143
    +    memberPath = thinArchiveMemberPath(path, fileName);
    
    144
    +
    
    178 145
         member = pathopen(memberPath, WSTR("rb"));
    
    179 146
         if (!member) {
    
    180 147
             errorBelch("loadObj: can't read thin archive `%" PATH_FMT "'",
    
    181 148
                        memberPath);
    
    182 149
             goto inner_fail;
    
    183 150
         }
    
    184
    -    n = fread(image, 1, memberSize, member);
    
    151
    +    int n = fread(image, 1, memberSize, member);
    
    185 152
         if (n != memberSize) {
    
    186 153
             errorBelch("loadArchive: error whilst reading `%s'",
    
    187 154
                        fileName);
    
    ... ... @@ -192,7 +159,6 @@ static bool readThinArchiveMember(int n, int memberSize, pathchar* path,
    192 159
     inner_fail:
    
    193 160
         fclose(member);
    
    194 161
         stgFree(memberPath);
    
    195
    -    stgFree(pathCopy);
    
    196 162
         return has_succeeded;
    
    197 163
     }
    
    198 164
     
    
    ... ... @@ -379,7 +345,6 @@ HsInt loadArchive_ (pathchar *path)
    379 345
         int memberIdx = 0;
    
    380 346
         FILE *f = NULL;
    
    381 347
         size_t thisFileNameSize = (size_t) -1; /* shut up bogus GCC warning */
    
    382
    -    int misalignment = 0;
    
    383 348
     
    
    384 349
         DEBUG_LOG("start\n");
    
    385 350
         DEBUG_LOG("Loading archive `%" PATH_FMT "'\n", path);
    
    ... ... @@ -387,8 +352,7 @@ HsInt loadArchive_ (pathchar *path)
    387 352
         /* Check that we haven't already loaded this archive.
    
    388 353
            Ignore requests to load multiple times */
    
    389 354
         if (isAlreadyLoaded(path)) {
    
    390
    -        IF_DEBUG(linker,
    
    391
    -                 debugBelch("ignoring repeated load of %" PATH_FMT "\n", path));
    
    355
    +        DEBUG_LOG("ignoring repeated load of %" PATH_FMT "\n", path);
    
    392 356
             return 1; /* success */
    
    393 357
         }
    
    394 358
     
    
    ... ... @@ -407,6 +371,9 @@ HsInt loadArchive_ (pathchar *path)
    407 371
             FAIL("failed to identify archive format of %" PATH_FMT ".", path);
    
    408 372
         }
    
    409 373
         bool isThin = archive_fmt == ThinArchive;
    
    374
    +    if(isThin) {
    
    375
    +        DEBUG_LOG("Found thin archive.\n");
    
    376
    +    }
    
    410 377
     
    
    411 378
         DEBUG_LOG("loading archive contents\n");
    
    412 379
     
    
    ... ... @@ -547,9 +514,25 @@ HsInt loadArchive_ (pathchar *path)
    547 514
             }
    
    548 515
     
    
    549 516
             DEBUG_LOG("Found member file `%s'\n", fileName);
    
    550
    -
    
    551 517
             bool is_symbol_table = strcmp("", fileName) == 0;
    
    552
    -        enum ObjectFileFormat object_fmt = is_symbol_table ? NotObject : identifyObjectFile(f);
    
    518
    +#if defined(OBJFORMAT_MACHO)
    
    519
    +        if (!is_symbol_table) {
    
    520
    +            /* Darwin ranlib symbol tables are named __.SYMDEF*
    
    521
    +             * There is no good documentation for this. Your best bets are
    
    522
    +             * probably the LLVM and Apple cctools sources.
    
    523
    +            */
    
    524
    +            if (strncmp(fileName, "__.SYMDEF", sizeof("__.SYMDEF")) == 0 ||
    
    525
    +                strncmp(fileName, "__.SYMDEF SORTED", sizeof("__.SYMDEF SORTED")) == 0 ||
    
    526
    +                strncmp(fileName, "__.SYMDEF_64", sizeof("__.SYMDEF_64")) == 0 ||
    
    527
    +                strncmp(fileName, "__.SYMDEF_64 SORTED", sizeof("__.SYMDEF_64 SORTED")) == 0) {
    
    528
    +                is_symbol_table = true;
    
    529
    +            }
    
    530
    +        }
    
    531
    +#endif
    
    532
    +
    
    533
    +/////////////////////////////////////////////////
    
    534
    +// We found the member file. Load it into memory.
    
    535
    +/////////////////////////////////////////////////
    
    553 536
     
    
    554 537
     #if defined(OBJFORMAT_PEi386)
    
    555 538
             /*
    
    ... ... @@ -562,39 +545,70 @@ HsInt loadArchive_ (pathchar *path)
    562 545
             * for sections. So on windows, just try to load it all.
    
    563 546
             *
    
    564 547
             * Linker members (e.g. filename / are skipped since they are not needed)
    
    548
    +        *
    
    549
    +        * AK: The gist of it is really that we need to:
    
    550
    +        * + Load .dll members as objects if they are *not* an import lib.
    
    551
    +        * + Load .dll members as import libs if they are ... import libs.
    
    552
    +        *
    
    553
    +        * There seems to be no good place to make this decision so i've put the
    
    554
    +        * ugly import lib detection code here, keeping the rest of the verification/loading
    
    555
    +        * logic relatively tidy. We basically read parts of the member file to get
    
    556
    +        * the header and then reuse the PE linkers type detection logic.
    
    557
    +        *
    
    558
    +        * We read at least sizeof(ANON_OBJECT_HEADER) bytes, but at most
    
    559
    +        * sizeof(ANON_OBJECT_HEADER_BIGOBJ). Members might be megabytes in size
    
    560
    +        * and we really only need at most the size of the largest header to determine
    
    561
    +        * the type.
    
    565 562
             */
    
    566
    -        bool isImportLib = thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".dll", 4) == 0;
    
    567
    -#else
    
    568
    -        bool isImportLib = false;
    
    569
    -#endif // windows
    
    563
    +        bool mb_peImportLib = thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".dll", 4) == 0;
    
    564
    +        bool importLib = false;
    
    565
    +        if (mb_peImportLib) {
    
    566
    +
    
    567
    +            char buf[sizeof(ANON_OBJECT_HEADER_BIGOBJ)];
    
    568
    +            // Too small to be a import lib
    
    569
    +            if(memberSize < sizeof(ANON_OBJECT_HEADER)) { importLib = false;}
    
    570
    +            // Read & Check the header
    
    571
    +            else {
    
    572
    +                if (isThin)
    
    573
    +                {   if (!readThinArchiveMember(
    
    574
    +                            stg_min(sizeof(ANON_OBJECT_HEADER_BIGOBJ), memberSize),
    
    575
    +                            path, fileName, buf))
    
    576
    +                    { goto fail; }
    
    577
    +                }
    
    578
    +                else {
    
    579
    +                    ssize_t sz = fread(buf, 1, sizeof(ANON_OBJECT_HEADER_BIGOBJ), f);
    
    580
    +                    CHECK(fseek(f, -sz, SEEK_CUR) == 0);
    
    581
    +                }
    
    582
    +                importLib = getObjectType(buf, path) == COFF_IMPORT_LIB;
    
    583
    +            }
    
    584
    +            IF_DEBUG(linker, if(importLib) { DEBUG_LOG("\tfound import lib.\n") })
    
    585
    +        }
    
    570 586
     
    
    587
    +#endif // windows
    
    571 588
             DEBUG_LOG("\tthisFileNameSize = %d\n", (int)thisFileNameSize);
    
    572
    -        DEBUG_LOG("\tisObject = %d\n", object_fmt);
    
    573
    -
    
    574
    -        if ((!is_symbol_table && isThin) || object_fmt != NotObject) {
    
    575
    -            DEBUG_LOG("Member is an object file...loading...\n");
    
    576 589
     
    
    590
    +        if (!is_symbol_table
    
    591
    +#if defined(OBJFORMAT_PEi386)
    
    592
    +            && !importLib
    
    593
    +#endif
    
    594
    +        )
    
    595
    +        {
    
    596
    +            ASSERT(!isGnuIndex);
    
    597
    +            DEBUG_LOG("Member might be an object file...loading...\n");
    
    577 598
     #if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
    
    578
    -            if (RTS_LINKER_USE_MMAP)
    
    579
    -                image = mmapAnonForLinker(memberSize);
    
    580
    -            else {
    
    581
    -                /* See loadObj() */
    
    582
    -                misalignment = machoGetMisalignment(f);
    
    583
    -                image = stgMallocBytes(memberSize + misalignment,
    
    584
    -                                        "loadArchive(image)");
    
    585
    -                image += misalignment;
    
    586
    -            }
    
    599
    +#if defined(RTS_LINKER_USE_MMAP)
    
    600
    +            image = mmapAnonForLinker(memberSize);
    
    601
    +#else
    
    602
    +#error "Only MMAP based loading supported on Apple platforms"
    
    603
    +#endif // defined(RTS_LINKER_USE_MMAP)
    
    587 604
     
    
    588 605
     #else // not darwin
    
    589 606
                 image = stgMallocBytes(memberSize, "loadArchive(image)");
    
    590 607
     #endif
    
    591 608
                 if (isThin) {
    
    592
    -                if (!readThinArchiveMember(n, memberSize, path, fileName, image)) {
    
    593
    -                    goto fail;
    
    609
    +                if (!readThinArchiveMember(memberSize, path, fileName, image)) {
    
    610
    +                    FAIL("Failed to read thin member %" PATH_FMT"\n", path);
    
    594 611
                     }
    
    595
    -                // Unlike for regular archives for thin archives we can only identify the object format
    
    596
    -                // after having read the file pointed to.
    
    597
    -                object_fmt = identifyObjectFile_(image, memberSize);
    
    598 612
                 }
    
    599 613
                 else
    
    600 614
                 {
    
    ... ... @@ -613,21 +627,26 @@ HsInt loadArchive_ (pathchar *path)
    613 627
                 pathprintf(archiveMemberName, size+1, WSTR("%" PATH_FMT "(#%d:%.*s)"),
    
    614 628
                            path, memberIdx, (int)thisFileNameSize, fileName);
    
    615 629
     
    
    616
    -            ObjectCode *oc = mkOc(STATIC_OBJECT, path, image, memberSize, false, archiveMemberName,
    
    617
    -                                  misalignment);
    
    618
    -#if defined(OBJFORMAT_MACHO)
    
    619
    -            ASSERT(object_fmt == MachO32 || object_fmt == MachO64);
    
    620
    -            ocInit_MachO( oc );
    
    621
    -#endif
    
    622
    -#if defined(OBJFORMAT_ELF)
    
    623
    -            ASSERT(object_fmt == ELF);
    
    624
    -            ocInit_ELF( oc );
    
    625
    -#endif
    
    630
    +///////////////////////////////////////////////////////////////
    
    631
    +// Verfiy the object file is valid, and load it if appropriate.
    
    632
    +///////////////////////////////////////////////////////////////
    
    626 633
     
    
    634
    +            // Prepare headers, doesn't load any data yet.
    
    635
    +            ObjectCode *oc = mkOc(STATIC_OBJECT, path, image, memberSize, false, archiveMemberName);
    
    627 636
                 stgFree(archiveMemberName);
    
    628 637
     
    
    638
    +            if(!verifyAndInitOc( oc ))
    
    639
    +            {
    
    640
    +                errorBelch("Failed to verify %" PATH_FMT " , aborting.\n", path);
    
    641
    +                freeObjectCode( oc );
    
    642
    +                continue;
    
    643
    +            }
    
    644
    +
    
    645
    +
    
    629 646
                 if (0 == loadOc(oc)) {
    
    647
    +                ocBelch(oc, "Failed to load OC %" PATH_FMT " , aborting.\n", path);
    
    630 648
                     stgFree(fileName);
    
    649
    +                freeObjectCode( oc );
    
    631 650
                     fclose(f);
    
    632 651
                     return 0;
    
    633 652
                 } else {
    
    ... ... @@ -654,8 +673,8 @@ while reading filename from `%" PATH_FMT "'", path);
    654 673
                 gnuFileIndex[memberSize] = '/';
    
    655 674
                 gnuFileIndexSize = memberSize;
    
    656 675
             }
    
    657
    -        else if (isImportLib) {
    
    658 676
     #if defined(OBJFORMAT_PEi386)
    
    677
    +        else if (importLib) {
    
    659 678
                 if (checkAndLoadImportLibrary(path, fileName, f)) {
    
    660 679
                     DEBUG_LOG("Member is an import file section... "
    
    661 680
                               "Corresponding DLL has been loaded...\n");
    
    ... ... @@ -668,8 +687,8 @@ while reading filename from `%" PATH_FMT "'", path);
    668 687
                         FAIL("error whilst seeking by %zd in `%" PATH_FMT "'",
    
    669 688
                         memberSize, path);
    
    670 689
                 }
    
    671
    -#endif
    
    672 690
             }
    
    691
    +#endif
    
    673 692
             else {
    
    674 693
                 DEBUG_LOG("`%s' does not appear to be an object file\n",
    
    675 694
                           fileName);
    
    ... ... @@ -698,7 +717,7 @@ while reading filename from `%" PATH_FMT "'", path);
    698 717
             }
    
    699 718
             memberIdx ++;
    
    700 719
             DEBUG_LOG("reached end of archive loading while loop\n");
    
    701
    -    }
    
    720
    +    } // while(1)
    
    702 721
         retcode = 1;
    
    703 722
     fail:
    
    704 723
         if (f != NULL)
    
    ... ... @@ -742,4 +761,3 @@ bool isArchive (pathchar *path)
    742 761
         }
    
    743 762
         return strncmp(ARCHIVE_HEADER, buffer, sizeof(ARCHIVE_HEADER)-1) == 0;
    
    744 763
     }
    745
    -

  • rts/linker/LoadNativeObjPosix.c
    ... ... @@ -134,7 +134,7 @@ void * loadNativeObj_POSIX (pathchar *path, char **errmsg)
    134 134
          goto dlopen_fail;
    
    135 135
        }
    
    136 136
     
    
    137
    -   nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL, 0);
    
    137
    +   nc = mkOc(DYNAMIC_OBJECT, path, NULL, 0, false, NULL);
    
    138 138
     
    
    139 139
        // If we HAVE_DLINFO, we use RTLD_NOW rather than RTLD_LAZY because we want
    
    140 140
        // to learn eagerly about all external functions. Otherwise, there is no
    

  • rts/linker/MachO.c
    1 1
     #include "Rts.h"
    
    2
    +#include "rts/Linker.h"
    
    2 3
     
    
    3 4
     #if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
    
    4 5
     
    
    ... ... @@ -199,11 +200,14 @@ ocAllocateExtras_MachO(ObjectCode* oc)
    199 200
     int
    
    200 201
     ocVerifyImage_MachO(ObjectCode * oc)
    
    201 202
     {
    
    203
    +    IF_DEBUG(linker, debugBelch("ocVerifyImage_MachO: start\n"));
    
    202 204
         char *image = (char*) oc->image;
    
    205
    +    if (oc->fileSize < (int) sizeof(MachOHeader)) {
    
    206
    +        IF_DEBUG(linker, errorBelch("Tried loading machO smaller than header size.\n"));
    
    207
    +        return 0;
    
    208
    +    }
    
    203 209
         MachOHeader *header = (MachOHeader*) image;
    
    204 210
     
    
    205
    -    IF_DEBUG(linker, debugBelch("ocVerifyImage_MachO: start\n"));
    
    206
    -
    
    207 211
         if(header->magic != MH_MAGIC_64) {
    
    208 212
             errorBelch("Could not load image %s: bad magic!\n"
    
    209 213
                        "  Expected %08x (64bit), got %08x%s\n",
    
    ... ... @@ -1774,34 +1778,4 @@ ocRunFini_MachO ( ObjectCode *oc )
    1774 1778
         return 1;
    
    1775 1779
     }
    
    1776 1780
     
    
    1777
    -/*
    
    1778
    - * Figure out by how much to shift the entire Mach-O file in memory
    
    1779
    - * when loading so that its single segment ends up 16-byte-aligned
    
    1780
    - */
    
    1781
    -int
    
    1782
    -machoGetMisalignment( FILE * f )
    
    1783
    -{
    
    1784
    -    MachOHeader header;
    
    1785
    -    int misalignment;
    
    1786
    -
    
    1787
    -    {
    
    1788
    -        size_t n = fread(&header, sizeof(header), 1, f);
    
    1789
    -        if (n != 1) {
    
    1790
    -            barf("machoGetMisalignment: can't read the Mach-O header");
    
    1791
    -        }
    
    1792
    -    }
    
    1793
    -    fseek(f, -sizeof(header), SEEK_CUR);
    
    1794
    -
    
    1795
    -    if(header.magic != MH_MAGIC_64) {
    
    1796
    -        barf("Bad magic. Expected: %08x, got: %08x.",
    
    1797
    -             MH_MAGIC_64, header.magic);
    
    1798
    -    }
    
    1799
    -
    
    1800
    -    misalignment = (header.sizeofcmds + sizeof(header))
    
    1801
    -                    & 0xF;
    
    1802
    -
    
    1803
    -    IF_DEBUG(linker, debugBelch("mach-o misalignment %d\n", misalignment));
    
    1804
    -    return misalignment ? (16 - misalignment) : 0;
    
    1805
    -}
    
    1806
    -
    
    1807 1781
     #endif /* darwin_HOST_OS || ios_HOST_OS */

  • rts/linker/MachO.h
    ... ... @@ -13,7 +13,6 @@ int ocGetNames_MachO ( ObjectCode* oc );
    13 13
     int    ocResolve_MachO              ( ObjectCode* oc );
    
    14 14
     int    ocRunInit_MachO              ( ObjectCode* oc );
    
    15 15
     int    ocRunFini_MachO              ( ObjectCode* oc );
    
    16
    -int    machoGetMisalignment         ( FILE * );
    
    17 16
     int    ocAllocateExtras_MachO       ( ObjectCode* oc );
    
    18 17
     
    
    19 18
     SectionKind getSectionKind_MachO    ( MachOSection *macho );
    

  • rts/linker/PEi386.c
    ... ... @@ -780,6 +780,12 @@ COFF_OBJ_TYPE getObjectType ( char* image, pathchar* fileName )
    780 780
      *************/
    
    781 781
     COFF_HEADER_INFO* getHeaderInfo ( ObjectCode* oc )
    
    782 782
     {
    
    783
    +   //No guarantee it's a valid file/oc at this point as we call
    
    784
    +   //getHeaderInfo during verify.
    
    785
    +   if((size_t) oc->fileSize < sizeof(IMAGE_FILE_HEADER)) {
    
    786
    +      IF_DEBUG(linker, ocErrorBelch ("Supposed COFF file smaller than minimum header size.\n"));
    
    787
    +      return NULL;
    
    788
    +   }
    
    783 789
        COFF_OBJ_TYPE coff_type = getObjectType (oc->image, OC_INFORMATIVE_FILENAME(oc));
    
    784 790
     
    
    785 791
        COFF_HEADER_INFO* info
    
    ... ... @@ -808,11 +814,23 @@ COFF_HEADER_INFO* getHeaderInfo ( ObjectCode* oc )
    808 814
              info->numberOfSections     = hdr->NumberOfSections;
    
    809 815
             }
    
    810 816
             break;
    
    817
    +       case COFF_IMPORT_LIB:
    
    818
    +        {
    
    819
    +         errorBelch ("Unexpected COFF_IMPORT_LIB in getHeaderInfo.\n");
    
    820
    +         stgFree(info);
    
    821
    +         info = NULL;
    
    822
    +         break;
    
    823
    +        }
    
    811 824
            default:
    
    812 825
             {
    
    813 826
              stgFree (info);
    
    814 827
              info = NULL;
    
    815 828
              errorBelch ("Unknown COFF %d type in getHeaderInfo.", coff_type);
    
    829
    +         if(oc->archiveMemberName) {
    
    830
    +             errorBelch ("Archive %" PATH_FMT ".\n", oc->archiveMemberName);
    
    831
    +         }
    
    832
    +        errorBelch ("In %" PATH_FMT ".\n", oc->fileName);
    
    833
    +
    
    816 834
             }
    
    817 835
             break;
    
    818 836
        }
    

  • rts/linker/SymbolExtras.c
    ... ... @@ -63,14 +63,10 @@ int ocAllocateExtras(ObjectCode* oc, int count, int first, int bssSize)
    63 63
     
    
    64 64
           // round up to the nearest 4
    
    65 65
           int aligned = (oc->fileSize + 3) & ~3;
    
    66
    -      int misalignment = oc->misalignment;
    
    67 66
     
    
    68
    -      oc->image -= misalignment;
    
    69 67
           oc->image = stgReallocBytes( oc->image,
    
    70
    -                               misalignment +
    
    71 68
                                    aligned + extras_size,
    
    72 69
                                    "ocAllocateExtras" );
    
    73
    -      oc->image += misalignment;
    
    74 70
     
    
    75 71
           oc->symbol_extras = (SymbolExtra *) (oc->image + aligned);
    
    76 72
         } else if (USE_CONTIGUOUS_MMAP || RtsFlags.MiscFlags.linkerAlwaysPic) {