Ticket #5062: 5062-2.patch

File 5062-2.patch, 52.0 KB (added by igloo, 2 years ago)
  • rts/Linker.c

    diff -rN -u old-ghc//rts/Linker.c new-ghc//rts/Linker.c
    old new  
    45694642    return 1; 
    45704643} 
    45714644 
    4572 static unsigned long relocateAddress( 
     4645 
     4646#ifndef x86_64_HOST_ARCH 
     4647 
     4648static unsigned long 
     4649relocateAddress( 
    45734650    ObjectCode* oc, 
    45744651    int nSections, 
    45754652    struct section* sections, 
    45764653    unsigned long address) 
    45774654{ 
    45784655    int i; 
     4656    unsigned long relocated; 
     4657 
    45794658    IF_DEBUG(linker, debugBelch("relocateAddress: start\n")); 
    45804659    for (i = 0; i < nSections; i++) 
    45814660    { 
    4582             IF_DEBUG(linker, debugBelch("    relocating address in section %d\n", i)); 
     4661        IF_DEBUG(linker, debugBelch("relocateAddress: \ttrying to relocate address %#lx in section %d\n", address, i)); 
     4662 
     4663        // check if the address to be relocated is in section i 
    45834664        if (sections[i].addr <= address 
    45844665            && address < sections[i].addr + sections[i].size) 
    45854666        { 
    4586             return (unsigned long)oc->image 
    4587                     + sections[i].offset + address - sections[i].addr; 
     4667            relocated = (unsigned long)oc->image + sections[i].offset + address - sections[i].addr; 
     4668 
     4669            IF_DEBUG(linker, debugBelch("relocateAddress: \tin section %d, relocated address is %#lx\n", i, relocated)); 
     4670            IF_DEBUG(linker, debugBelch("relocateAddress: \toc->image = %lu (%#lx)\n", (unsigned long)oc->image, 
     4671                                        (unsigned long)oc->image)); 
     4672            IF_DEBUG(linker, debugBelch("relocateAddress: \tsections[%d].offset = %u (%#x)\n", i, sections[i].offset, 
     4673                                        sections[i].offset)); 
     4674            IF_DEBUG(linker, debugBelch("relocateAddress: \taddress = %ld (%#lx)\n", address, address)); 
     4675 
     4676            IF_DEBUG(linker, debugBelch("relocateAddress: \tsections[%d].addr = %llu (%#llx)\n", i, sections[i].addr, 
     4677                                        sections[i].addr)); 
     4678            IF_DEBUG(linker, debugBelch("relocateAddress: done\n")); 
     4679            return relocated; 
    45884680        } 
    45894681    } 
    45904682    barf("Invalid Mach-O file:" 
     
    45924684    return 0; 
    45934685} 
    45944686 
    4595 static int relocateSection( 
     4687#endif 
     4688 
     4689 
     4690static void 
     4691checkProddableBlock_MachO (ObjectCode *oc, void *addr, int ll) 
     4692{ 
     4693    ProddableBlock* pb; 
     4694    int len; 
     4695 
     4696    // For x86_64, ll is the base 2 logarithm of the relocation 
     4697    // length. 
     4698    // 
     4699    // We need to check the actual relocation length instead of 
     4700    // the maximum length, otherwise we might incorrectly conclude 
     4701    // that the last relocation in a ProddableBlock runs off the end. 
     4702 
     4703    if (ll >= 0 && ll <= 3) { 
     4704        len = 2^ll; 
     4705    } else { 
     4706        barf("checkProddableBlock_MachO: invalid relocation length, %d\n", ll); 
     4707    } 
     4708 
     4709    for (pb = oc->proddables; pb != NULL; pb = pb->next) { 
     4710        char *s = (char *)(pb->start); 
     4711        char *e = s + pb->size - 1; 
     4712        char *a = (char *)addr; 
     4713 
     4714        if (a >= s && (a + (len - 1)) <= e) { 
     4715            return; 
     4716        } 
     4717    } 
     4718 
     4719    barf("checkProddableBlock_MachO: invalid fixup in runtime linker at %p, length %d", addr, len); 
     4720} 
     4721 
     4722 
     4723// Look up a symbol, either defined in the symbol table as an exportable 
     4724// reference in the current image. 
     4725 
     4726static uint64_t 
     4727findExternalSymbol( 
     4728    struct nlist *symbol, 
     4729    char *symbolName, 
     4730    ObjectCode *oc, 
     4731    struct section *sections) 
     4732{ 
     4733    uint64_t addr; 
     4734 
     4735    // If this is an exported external symbol, i.e., one that is 
     4736    // defined in this object file, then the N_SECT bit is set.  
     4737    // We just look up its address in the nlist. If not, look 
     4738    // up the address in the symbol table. 
     4739 
     4740    IF_DEBUG(linker, debugBelch("findSymbolAddress: looking for symbol %s\n", symbolName)); 
     4741    if ((symbol->n_type & N_TYPE) == N_SECT) { 
     4742        IF_DEBUG(linker, debugBelch("findSymbolAddress: \t%s is defined in this object file\n", symbolName)); 
     4743 
     4744        int sect = symbol->n_sect - 1; 
     4745        addr = (uint64_t) (oc->image + sections[sect].offset - sections[sect].addr + symbol->n_value); 
     4746 
     4747        IF_DEBUG(linker, debugBelch("findSymbolAddress: \toc->image = %p\n", oc->image)); 
     4748        IF_DEBUG(linker, debugBelch("findSymbolAddress: \tsection[%d].offset = %#0x\n", sect, sections[sect].offset)); 
     4749        IF_DEBUG(linker, debugBelch("findSymbolAddress: \tsection[%d].addr = %#0llx\n", sect, (unsigned long long)sections[sect].addr)); 
     4750        IF_DEBUG(linker, debugBelch("findSymbolAddress: \tsymbol->n_value = %#0llx\n", (unsigned long long)symbol->n_value)); 
     4751    } else { 
     4752        IF_DEBUG(linker, debugBelch("findSymbolAddress: \tsearching for %s in symbol table\n", symbolName)); 
     4753 
     4754        addr = (uint64_t) lookupSymbol(symbolName); 
     4755        if (!addr) { 
     4756            barf("findExternalSymbol: failed to find %s in the symbol table", symbolName); 
     4757        } else { 
     4758            IF_DEBUG(linker, debugBelch("findExternalSymbol: symbol %s is at %p\n", symbolName, (void *) addr)); 
     4759        } 
     4760    } 
     4761 
     4762    return addr; 
     4763} 
     4764 
     4765 
     4766// Look up an internal reference.  In this case, the fixup value initially 
     4767// read from the relocation entry contains the offset into the target section. 
     4768// We just need to find the installed memory address of the start of the 
     4769// target section. 
     4770 
     4771static uint64_t 
     4772findInternalReference( 
     4773    struct relocation_info *reloc, 
     4774    ObjectCode *oc, 
     4775    struct section *sections) 
     4776{ 
     4777    uint64_t addr; 
     4778 
     4779    // If reloc->r_symbolnum equals R_ABS (which is numerically zero), 
     4780    // the symbol is not relocatable and zero is returned, indicating that the 
     4781    // fixup should be written back unchanged.  Othewise, look up the 
     4782    // file offset of section number (reloc->r_symbolnum - 1) and add it 
     4783    // to the base address of the memory image. 
     4784 
     4785    if (reloc->r_symbolnum == R_ABS) { 
     4786        addr = 0; 
     4787        IF_DEBUG(linker, debugBelch("relocateSection: internal symbol is absolute (no relocation)\n")); 
     4788    } else { 
     4789        int sect = reloc->r_symbolnum - 1; 
     4790        addr = (uint64_t) (oc->image + sections[sect].offset); 
     4791        IF_DEBUG(linker, debugBelch("relocateSection: internal symbol is in section %d at %0llx\n", sect, addr)); 
     4792    } 
     4793 
     4794    return addr; 
     4795} 
     4796 
     4797 
     4798// Limits for pc relative offsets: 
     4799 
     4800#define MAX_8_BIT_FORWARD_DISPL 127 
     4801#define MIN_8_BIT_BACKWARD_DISPL -128 
     4802#define MAX_32_BIT_FORWARD_DISPL 2147483647 
     4803#define MIN_32_BIT_BACKWARD_DISPL -2147483648 
     4804 
     4805 
     4806// Perform all of the relocations in a section.  This is the core 
     4807// of the relocation operation. 
     4808 
     4809static int 
     4810relocateSection( 
    45964811    ObjectCode* oc, 
    45974812    char *image, 
    4598     struct symtab_command *symLC, struct nlist *nlist, 
    4599     int nSections, struct section* sections, struct section *sect) 
     4813    struct symtab_command *symLC, 
     4814    struct nlist *nlist, 
     4815    int nSections, 
     4816    struct section *sections, 
     4817    struct section *sect) 
    46004818{ 
    46014819    struct relocation_info *relocs; 
    46024820    int i, n; 
    46034821 
    46044822    IF_DEBUG(linker, debugBelch("relocateSection: start\n")); 
    46054823 
    4606     if(!strcmp(sect->sectname,"__la_symbol_ptr")) 
     4824    // Certain sections are only used for external references (references 
     4825    // to symbols defined in other files).  Symbols in these sections 
     4826    // have to be resolved to the installed address, but don't contain 
     4827    // relocations, so they are skipped. 
     4828 
     4829    if (strcmp(sect->sectname,"__la_symbol_ptr") == 0) { 
     4830        IF_DEBUG(linker, debugBelch("relocateSection: __la_symbol_ptr section, skipping\n"));  
    46074831        return 1; 
    4608     else if(!strcmp(sect->sectname,"__nl_symbol_ptr")) 
     4832    } 
     4833    else if (strcmp(sect->sectname,"__nl_symbol_ptr") == 0) { 
     4834        IF_DEBUG(linker, debugBelch("relocateSection: __nl_symbol_ptr section, skipping\n"));  
    46094835        return 1; 
    4610     else if(!strcmp(sect->sectname,"__la_sym_ptr2")) 
     4836    } 
     4837    else if (strcmp(sect->sectname,"__la_sym_ptr2") == 0) { 
     4838        IF_DEBUG(linker, debugBelch("relocateSection: __la_sym_ptr2 section, skipping\n"));  
    46114839        return 1; 
    4612     else if(!strcmp(sect->sectname,"__la_sym_ptr3")) 
     4840    } 
     4841    else if (strcmp(sect->sectname,"__la_sym_ptr3") == 0) { 
     4842        IF_DEBUG(linker, debugBelch("relocateSection: __la_sym_ptr3 section, skipping\n"));  
    46134843        return 1; 
     4844    } 
     4845 
     4846    // If we reach this point, we have a section that may need relocations. 
    46144847 
    46154848    n = sect->nreloc; 
    4616     IF_DEBUG(linker, debugBelch("relocateSection: number of relocations: %d\n", n)); 
     4849    relocs = (struct relocation_info *) (image + sect->reloff); 
    46174850 
    4618     relocs = (struct relocation_info*) (image + sect->reloff); 
     4851    IF_DEBUG(linker, debugBelch("relocateSection: section %s has %d relocations\n", sect->sectname, n)); 
     4852 
     4853    for (i = 0; i < n; i++) { 
    46194854 
    4620     for(i=0;i<n;i++) 
    4621     { 
    46224855#ifdef x86_64_HOST_ARCH 
     4856 
    46234857        struct relocation_info *reloc = &relocs[i]; 
    46244858 
    4625         char    *thingPtr = image + sect->offset + reloc->r_address; 
    4626         uint64_t thing; 
    4627         /* We shouldn't need to initialise this, but gcc on OS X 64 bit 
    4628            complains that it may be used uninitialized if we don't */ 
    4629         uint64_t value = 0; 
    4630         uint64_t baseValue; 
     4859        // The object that may require relocation (commonly, a "fixup") is 
     4860        // located at offset reloc->r_address from the start of the section. 
     4861        // The start of the section is at memory address image + sect->offset. 
     4862        // The location of the fixup is therefore given by the expression 
     4863        // for fixupPtr below. 
     4864        // 
     4865        // The variable fixup will contain the final fixed-up value written 
     4866        // to the location given by fixupPtr. 
     4867 
     4868        void    *fixupPtr = image + sect->offset + reloc->r_address; 
     4869        uint64_t fixup; 
     4870 
     4871        uint64_t addr; 
     4872        uint64_t pc; 
     4873 
     4874        struct nlist *symbol = NULL; 
     4875        char *symbolName     = NULL; 
     4876         
    46314877        int type = reloc->r_type; 
    46324878 
    4633         checkProddableBlock(oc,thingPtr); 
     4879        if (nSections > 255) { 
     4880                barf("relocateSection: nSections > 255"); 
     4881        } 
     4882 
     4883        // Check that we can write to the location that fixupPtr points to. 
     4884        // If we can't, checkProddableBlock_MachO will barf. 
     4885         
     4886        checkProddableBlock_MachO(oc, fixupPtr, reloc->r_length); 
     4887 
     4888        // Read the object to be relocated (the "fixup") from the fixupPtr. 
     4889        // Then calculate the notional program counter ("pc") used for 
     4890        // relative relocations. The notional pc is address of the next 
     4891        // instruction after the one containing the relocation. 
     4892 
    46344893        switch(reloc->r_length) 
    46354894        { 
    46364895            case 0: 
    4637                 thing = *(uint8_t*)thingPtr; 
    4638                 baseValue = (uint64_t)thingPtr + 1; 
     4896                fixup = *(uint8_t *)fixupPtr; 
     4897                pc    = (uint64_t)fixupPtr + 1; 
    46394898                break; 
    46404899            case 1: 
    4641                 thing = *(uint16_t*)thingPtr; 
    4642                 baseValue = (uint64_t)thingPtr + 2; 
     4900                fixup = *(uint16_t *)fixupPtr; 
     4901                pc    = (uint64_t)fixupPtr + 2; 
    46434902                break; 
    46444903            case 2: 
    4645                 thing = *(uint32_t*)thingPtr; 
    4646                 baseValue = (uint64_t)thingPtr + 4; 
     4904                fixup = *(uint32_t *)fixupPtr; 
     4905                pc    = (uint64_t)fixupPtr + 4; 
    46474906                break; 
    46484907            case 3: 
    4649                 thing = *(uint64_t*)thingPtr; 
    4650                 baseValue = (uint64_t)thingPtr + 8; 
     4908                fixup = *(uint64_t *)fixupPtr; 
     4909                pc    = (uint64_t)fixupPtr + 8; 
    46514910                break; 
    46524911            default: 
    4653                 barf("Unknown size."); 
     4912                barf("relocateSection: Unknown relocation length %d", reloc->r_length); 
    46544913        } 
    46554914 
    4656         IF_DEBUG(linker, 
    4657                  debugBelch("relocateSection: length = %d, thing = %" PRId64 ", baseValue = %p\n", 
    4658                             reloc->r_length, thing, (char *)baseValue)); 
     4915        IF_DEBUG(linker, debugBelch("relocateSection: relocation %d has\n", i)); 
     4916        IF_DEBUG(linker, debugBelch("relocateSection: \tr_address   = %d (%#x)\n", 
     4917                                    reloc->r_address, 
     4918                                    reloc->r_address)); 
     4919        IF_DEBUG(linker, debugBelch("relocateSection: \tr_symbolnum = %u (%#x)\n", 
     4920                                    reloc->r_symbolnum, 
     4921                                    reloc->r_symbolnum)); 
     4922        IF_DEBUG(linker, debugBelch("relocateSection: \tr_pcrel     = %d\n", 
     4923                                    reloc->r_pcrel)); 
     4924        IF_DEBUG(linker, debugBelch("relocateSection: \tr_length    = %d\n", 
     4925                                    reloc->r_length)); 
     4926        IF_DEBUG(linker, debugBelch("relocateSection: \tr_extern    = %d\n", 
     4927                                    reloc->r_extern)); 
     4928        IF_DEBUG(linker, debugBelch("relocateSection: \tr_type      = %d (%#x)\n", 
     4929                                    reloc->r_type, reloc->r_type)); 
     4930        IF_DEBUG(linker, debugBelch("relocateSection: \tfixupPtr = %p, fixup = 0x%lx, pc = %p\n", 
     4931                                    fixupPtr, 
     4932                                    (unsigned long)fixup, 
     4933                                    (void *)pc)); 
     4934 
     4935        // For external relocations, get the symbol table entry and the 
     4936        // symbol name. 
     4937 
     4938        if (reloc->r_extern) { 
     4939            symbol     = &nlist[reloc->r_symbolnum]; 
     4940            symbolName = image + symLC->stroff + symbol->n_un.n_strx; 
     4941        } 
     4942 
     4943        // Do the relocation.  This is not the shortest possible way 
     4944        // to do this, but by considering each type of relocation and 
     4945        // whether the relocation is external and the length of the relocated 
     4946        // object, all invalid cases can be caught. 
    46594947 
    4660         if (type == X86_64_RELOC_GOT 
    4661            || type == X86_64_RELOC_GOT_LOAD) 
     4948        switch (type) 
    46624949        { 
    4663             struct nlist *symbol = &nlist[reloc->r_symbolnum]; 
    4664             char *nm = image + symLC->stroff + symbol->n_un.n_strx; 
     4950        case X86_64_RELOC_GOT: 
     4951        case X86_64_RELOC_GOT_LOAD: 
     4952 
     4953            ASSERT(reloc->r_pcrel);          // GOT and GOT_LOAD are always pc-relative, 
     4954            ASSERT(reloc->r_extern);         // always external, 
     4955            ASSERT(reloc->r_length == 2);    // and always 32 bit. 
     4956 
     4957            // Create a Global Offset Table (GOT) entry and install the 
     4958            // address of the symbol in the table.  The address of the 
     4959            // GOT entry is target of the final pc relative relocation. 
     4960 
     4961            addr = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, (unsigned long)lookupSymbol(symbolName))->addr; 
     4962 
     4963            IF_DEBUG(linker, debugBelch("relocateSection: type is X64_64_RELOC_GOT or X86_64_RELOC_GOT_LOAD\n")); 
     4964            IF_DEBUG(linker, debugBelch("relocateSection: GOT entry for %s is at %0llx\n", symbolName, addr)); 
     4965 
     4966            fixup += (addr - pc); 
     4967            break; 
     4968 
     4969        case X86_64_RELOC_UNSIGNED: 
    46654970 
    4666             IF_DEBUG(linker, debugBelch("relocateSection: making jump island for %s, extern = %d, X86_64_RELOC_GOT\n", nm, reloc->r_extern)); 
    4667             ASSERT(reloc->r_extern); 
    4668             value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, (unsigned long)lookupSymbol(nm))->addr; 
     4971            ASSERT(!reloc->r_pcrel);          // UNSIGNED relocs are always absolute addresses 
     4972            ASSERT(reloc->r_length >= 2);     // and always 32 or 64 bits. 
    46694973 
    4670             type = X86_64_RELOC_SIGNED; 
     4974            IF_DEBUG(linker, debugBelch("relocateSection: type is X86_64_RELOC_UNSIGNED\n")); 
     4975 
     4976            if (reloc->r_extern) { 
     4977                addr = findExternalSymbol(symbol, symbolName, oc, sections); 
     4978                IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s found at %0llx\n", symbolName, addr)); 
     4979            } 
     4980            else { 
     4981                // Non-external, UNSIGNED relocation: the fixup contains the address 
     4982                // of the target from the start of the memory image.  So just add 
     4983                // the memory address of the begining of the mmap'ed object code. 
     4984 
     4985                int s = reloc->r_symbolnum - 1; 
     4986                addr = (uint64_t)(oc->image + sections[s].offset - sections[s].addr); 
     4987                IF_DEBUG(linker, debugBelch("relocateSection: start target section is at %0llx\n", addr)); 
     4988            } 
     4989 
     4990            fixup += addr; 
     4991 
     4992            break; 
     4993 
     4994        case X86_64_RELOC_BRANCH: 
     4995 
     4996            ASSERT(reloc->r_pcrel);           // BRANCH relocs are always pc-relative, 
     4997            ASSERT(reloc->r_length == 0 ||    // and either 8 or 32 bits. 
     4998                   reloc->r_length == 2); 
     4999 
     5000            IF_DEBUG(linker, debugBelch("relocateSection: type is X86_64_RELOC_BRANCH\n")); 
     5001 
     5002            int64_t displ; 
     5003 
     5004            if (reloc->r_length == 0) { 
     5005                if (reloc->r_extern) { 
     5006                    addr = findExternalSymbol(symbol, symbolName, oc, sections); 
     5007                    IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s found at %0llx\n", symbolName, addr)); 
     5008                } 
     5009                else { 
     5010                    addr = findInternalReference(reloc, oc, sections); 
     5011                    IF_DEBUG(linker, debugBelch("relocateSection: internal reference found at %0llx\n", addr)); 
     5012                } 
     5013 
     5014                if (addr == 0) { 
     5015                    barf("relocateSection: non-relocatable symbol found in 8 bit BRANCH relocation\n"); 
     5016                }  
     5017 
     5018                displ = addr - pc; 
     5019 
     5020                if (displ > 0) { 
     5021                    if (displ > MAX_8_BIT_FORWARD_DISPL) { 
     5022                        barf("relocateSection: required 8 bit displacement too far forward"); 
     5023                    } 
     5024                } else { 
     5025                    if (displ < MIN_8_BIT_BACKWARD_DISPL) { 
     5026                        barf("relocateSection: required 8 bit displacement too far backward"); 
    46715027        } 
    4672         else if(reloc->r_extern) 
    4673         { 
    4674             struct nlist *symbol = &nlist[reloc->r_symbolnum]; 
    4675             char *nm = image + symLC->stroff + symbol->n_un.n_strx; 
     5028                } 
     5029 
     5030                IF_DEBUG(linker, debugBelch("relocateSection: 8 bit BRANCH displacement = %lld (%#0llx)\n", displ, (unsigned long long) displ)); 
    46765031 
    4677             IF_DEBUG(linker, debugBelch("relocateSection: looking up external symbol %s\n", nm)); 
    4678             IF_DEBUG(linker, debugBelch("               : type  = %d\n", symbol->n_type)); 
    4679             IF_DEBUG(linker, debugBelch("               : sect  = %d\n", symbol->n_sect)); 
    4680             IF_DEBUG(linker, debugBelch("               : desc  = %d\n", symbol->n_desc)); 
    4681             IF_DEBUG(linker, debugBelch("               : value = %p\n", (void *)symbol->n_value)); 
    4682             if ((symbol->n_type & N_TYPE) == N_SECT) { 
    4683                 value = relocateAddress(oc, nSections, sections, 
    4684                                         symbol->n_value); 
    4685                 IF_DEBUG(linker, debugBelch("relocateSection, defined external symbol %s, relocated address %p\n", nm, (void *)value)); 
     5032            } else { 
     5033                if (reloc->r_extern) { 
     5034                    addr = findExternalSymbol(symbol, symbolName, oc, sections); 
     5035                    IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s found at %0llx\n", symbolName, addr)); 
    46865036            } 
    46875037            else { 
    4688                 value = (uint64_t) lookupSymbol(nm); 
    4689                 IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s, address %p\n", nm, (void *)value)); 
     5038                    addr = findInternalReference(reloc, oc, sections); 
     5039                    IF_DEBUG(linker, debugBelch("relocateSection: internal reference found at %0llx\n", addr)); 
     5040                } 
     5041 
     5042                if (addr == 0) { 
     5043                    barf("relocateSection: non-relocatable symbol found in 32 bit BRANCH relocation\n"); 
     5044                }  
     5045 
     5046                displ = addr - pc; 
     5047 
     5048                IF_DEBUG(linker, debugBelch("relocateSection: 32 bit BRANCH displacement = %lld (%#0llx)\n", displ, (unsigned long long) displ)); 
     5049                 
     5050                if (((displ > 0) && (displ > MAX_32_BIT_FORWARD_DISPL)) 
     5051                 || ((displ < 0) && (displ < MIN_32_BIT_BACKWARD_DISPL))) { 
     5052                    addr = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, addr)->jumpIsland; 
     5053                    IF_DEBUG(linker, debugBelch("relocateSection: making jump island for 32 bit BRANCH relocation: %#0llx\n", addr)); 
     5054                    displ = addr - pc; 
     5055 
     5056                    IF_DEBUG(linker, debugBelch("relocateSection: 32 bit BRANCH displacement to jump island= %lld (%#0llx)\n", displ, (unsigned long long) displ)); 
     5057                } 
    46905058            } 
     5059 
     5060            fixup += displ; 
     5061 
     5062            break; 
     5063 
     5064        case X86_64_RELOC_SUBTRACTOR: 
     5065 
     5066            IF_DEBUG(linker, debugBelch("relocateSection: type is X86_64_RELOC_SUBTRACTOR\n")); 
     5067 
     5068            // An X86_64_RELOC_SUBTRACTOR can never be the last relocation 
     5069            // in a section, since it must be followed by an X86_64_RELOC_UNSIGNED. 
     5070            // Barf if this isn't true. 
     5071 
     5072            if (i == (n - 1)) { 
     5073                barf("X86_64_RELOC_SUBTRACTOR is the last relocation in section %s", sect->sectname); 
     5074            } 
     5075 
     5076            struct relocation_info *nextReloc =  &relocs[i + 1]; 
     5077 
     5078            ASSERT(!reloc->r_pcrel);                              // SUBTRACTOR relocs must not be pc relative, 
     5079            ASSERT(reloc->r_length == 2 ||                        // must be 32 or 64 bits, 
     5080                   reloc->r_length == 3);                         // 
     5081            ASSERT(reloc->r_extern);                              // must be external, 
     5082            ASSERT(nextReloc->r_type == X86_64_RELOC_UNSIGNED);   // must be followed by a X86_64_RELOC_UNSIGNED, 
     5083            ASSERT(nextReloc->r_length == nextReloc->r_length);   // with the same length as the SUBTRACTOR reloc, 
     5084            ASSERT(!nextReloc->r_pcrel);                          // and must also not be pc relative. Got it? 
     5085 
     5086            if (nextReloc->r_type != X86_64_RELOC_UNSIGNED) { 
     5087                barf("relocateSection: SUBTRACTOR must be followed by UNSIGNED"); 
    46915088        } 
    4692         else 
    4693         { 
    4694             // If the relocation is not through the global offset table 
    4695             // or external, then set the value to the baseValue.  This 
    4696             // will leave displacements into the __const section 
    4697             // unchanged (as they ought to be). 
    46985089 
    4699             value = baseValue; 
     5090            if (reloc->r_length == 2) { 
     5091                    addr = findExternalSymbol(symbol, symbolName, oc, sections); 
     5092                    IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s found at %0llx\n", symbolName, addr)); 
    47005093        } 
     5094            else { 
     5095                    addr = findExternalSymbol(symbol, symbolName, oc, sections); 
     5096                    IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s found at %0llx\n", symbolName, addr)); 
     5097            } 
     5098 
     5099            // Subtract the symbol address from the fixup.  The subsequent 
     5100            // UNSIGNED relocation will add the address of another external 
     5101            // symbol, so the final relocation will be the difference of the 
     5102            // symbol addresses, plus any offset originally saved in the 
     5103            // fixup location. 
     5104 
     5105            fixup -= addr; 
     5106 
     5107            break; 
     5108 
     5109        case X86_64_RELOC_SIGNED: 
     5110        case X86_64_RELOC_SIGNED_1: 
     5111        case X86_64_RELOC_SIGNED_2: 
     5112        case X86_64_RELOC_SIGNED_4: 
     5113 
     5114            IF_DEBUG(linker, debugBelch("relocateSection: type is X86_64_RELOC_SIGNED/1/2/4\n")); 
    47015115 
    4702         IF_DEBUG(linker, debugBelch("relocateSection: value = %p\n", (void *)value)); 
     5116            uint64_t addend = 0; 
    47035117 
    4704         if (type == X86_64_RELOC_BRANCH) 
     5118            ASSERT(reloc->r_pcrel);           // SIGNED relocs are always pc relative 
     5119            ASSERT(reloc->r_length == 2);     // and 32 bits long. 
     5120 
     5121            if (reloc->r_extern) { 
     5122                switch (reloc->r_type) 
    47055123        { 
    4706             if((int32_t)(value - baseValue) != (int64_t)(value - baseValue)) 
    4707             { 
    4708                 ASSERT(reloc->r_extern); 
    4709                 value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, value) 
    4710                                         -> jumpIsland; 
     5124                case X86_64_RELOC_SIGNED: 
     5125                    addend = 0; 
     5126                    break; 
     5127                case X86_64_RELOC_SIGNED_1: 
     5128                    addend = 1; 
     5129                    break; 
     5130                case X86_64_RELOC_SIGNED_2: 
     5131                    addend = 2; 
     5132                    break; 
     5133                case X86_64_RELOC_SIGNED_4: 
     5134                    addend = 4; 
     5135                    break; 
    47115136            } 
    4712             ASSERT((int32_t)(value - baseValue) == (int64_t)(value - baseValue)); 
    4713             type = X86_64_RELOC_SIGNED; 
     5137 
     5138                addr = findExternalSymbol(symbol, symbolName, oc, sections); 
     5139                IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s found at %0llx\n", symbolName, addr)); 
    47145140        } 
     5141            else { 
     5142 
     5143                // Relocations that are both SIGNED and not external 
     5144                // have compiler computed offsets to the target address 
     5145                // in the object file. We needn't do anything at all with these. 
    47155146 
    4716         switch(type) 
     5147                switch (reloc->r_type) 
    47175148        { 
    4718             case X86_64_RELOC_UNSIGNED: 
    4719                 ASSERT(!reloc->r_pcrel); 
    4720                 thing += value; 
     5149                case X86_64_RELOC_SIGNED: 
     5150                    addend = 0; 
    47215151                break; 
    4722             case X86_64_RELOC_SIGNED: 
    47235152            case X86_64_RELOC_SIGNED_1: 
     5153                    addend = 1; 
     5154                    break; 
    47245155            case X86_64_RELOC_SIGNED_2: 
     5156                    addend = 2; 
     5157                    break; 
    47255158            case X86_64_RELOC_SIGNED_4: 
    4726                 ASSERT(reloc->r_pcrel); 
    4727                 thing += value - baseValue; 
     5159                    addend = 4; 
    47285160                break; 
    4729             case X86_64_RELOC_SUBTRACTOR: 
    4730                 ASSERT(!reloc->r_pcrel); 
    4731                 thing -= value; 
     5161                } 
     5162 
     5163                addr = pc; 
     5164                IF_DEBUG(linker, debugBelch("relocateSection: not external, leaving fixup unchanged.\n")); 
     5165            } 
     5166 
     5167            fixup += (addr - pc) + addend; 
     5168 
    47325169                break; 
     5170 
    47335171            default: 
    4734                 barf("unkown relocation"); 
     5172            barf("relocateSection: unknown relocation type"); 
     5173 
    47355174        } 
    47365175 
     5176        IF_DEBUG(linker, debugBelch("relocateSection: FINAL: reloc = %d, addr = %0lx, fixup = %0llx\n", i, (unsigned long)reloc->r_address, fixup)); 
     5177        // Write the fixed-up value back to the image. 
     5178 
    47375179        switch(reloc->r_length) 
    47385180        { 
    47395181            case 0: 
    4740                 *(uint8_t*)thingPtr = thing; 
     5182                IF_DEBUG(linker, debugBelch("relocateSection: 8 bit reloc, fixup %#0x written to %p\n", 
     5183                                            (uint8_t)fixup, fixupPtr)); 
     5184                *(uint8_t *)fixupPtr = fixup; 
    47415185                break; 
    47425186            case 1: 
    4743                 *(uint16_t*)thingPtr = thing; 
     5187                IF_DEBUG(linker, debugBelch("relocateSection: 16 bit reloc, fixup %#0x written to %p\n", 
     5188                                            (uint16_t)fixup, fixupPtr)); 
     5189                *(uint16_t *)fixupPtr = fixup; 
    47445190                break; 
    47455191            case 2: 
    4746                 *(uint32_t*)thingPtr = thing; 
     5192                IF_DEBUG(linker, debugBelch("relocateSection: 32 bit reloc, fixup %#0x written to %p\n", 
     5193                                            (uint32_t)fixup, fixupPtr)); 
     5194                *(uint32_t *)fixupPtr = fixup; 
    47475195                break; 
    47485196            case 3: 
    4749                 *(uint64_t*)thingPtr = thing; 
     5197                IF_DEBUG(linker, debugBelch("relocateSection: 64 bit reloc, fixup %#0llx written to %p\n", 
     5198                                            (uint64_t)fixup, fixupPtr)); 
     5199                *(uint64_t *)fixupPtr = fixup; 
    47505200                break; 
    47515201        } 
    4752 #else 
    4753         if(relocs[i].r_address & R_SCATTERED) 
    4754         { 
     5202 
     5203#else // x86 and powerpc architectures start here 
     5204 
     5205        if (relocs[i].r_address & R_SCATTERED) { 
    47555206            struct scattered_relocation_info *scat = 
    47565207                (struct scattered_relocation_info*) &relocs[i]; 
    47575208 
    4758             if(!scat->r_pcrel) 
    4759             { 
    4760                 if(scat->r_length == 2) 
    4761                 { 
     5209            if (!scat->r_pcrel) { 
     5210                if (scat->r_length == 2) { 
     5211 
    47625212                    unsigned long word = 0; 
    47635213                    unsigned long* wordPtr = (unsigned long*) (image + sect->offset + scat->r_address); 
     5214 
    47645215                    checkProddableBlock(oc,wordPtr); 
    47655216 
    47665217                    // Note on relocation types: 
     
    47735224                    // and use #ifdefs for the other types. 
    47745225 
    47755226                    // Step 1: Figure out what the relocated value should be 
    4776                     if(scat->r_type == GENERIC_RELOC_VANILLA) 
    4777                     { 
    4778                         word = *wordPtr + (unsigned long) relocateAddress( 
    4779                                                                 oc, 
     5227                    if (scat->r_type == GENERIC_RELOC_VANILLA) { 
     5228                        word = *wordPtr 
     5229                             + (unsigned long) relocateAddress(oc, 
    47805230                                                                nSections, 
    47815231                                                                sections, 
    47825232                                                                scat->r_value) 
     
    47965246                        struct scattered_relocation_info *pair = 
    47975247                                (struct scattered_relocation_info*) &relocs[i+1]; 
    47985248 
    4799                         if(!pair->r_scattered || pair->r_type != GENERIC_RELOC_PAIR) 
     5249                        if (!pair->r_scattered || pair->r_type != GENERIC_RELOC_PAIR) { 
    48005250                            barf("Invalid Mach-O file: " 
    48015251                                 "RELOC_*_SECTDIFF not followed by RELOC_PAIR"); 
     5252                        } 
    48025253 
    48035254                        word = (unsigned long) 
    48045255                               (relocateAddress(oc, nSections, sections, scat->r_value) 
     
    48125263                         || scat->r_type == PPC_RELOC_LO14) 
    48135264                    {   // these are generated by label+offset things 
    48145265                        struct relocation_info *pair = &relocs[i+1]; 
    4815                         if((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR) 
     5266 
     5267                        if ((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR) { 
    48165268                            barf("Invalid Mach-O file: " 
    48175269                                 "PPC_RELOC_* not followed by PPC_RELOC_PAIR"); 
     5270                        } 
    48185271 
    48195272                        if(scat->r_type == PPC_RELOC_LO16) 
    48205273                        { 
     
    48455298                        i++; 
    48465299                    } 
    48475300 #endif 
    4848                     else 
    4849                     { 
     5301                    else { 
    48505302                        barf ("Don't know how to handle this Mach-O " 
    48515303                              "scattered relocation entry: " 
    48525304                              "object file %s; entry type %ld; " 
     
    48695321                        *wordPtr = word; 
    48705322                    } 
    48715323#ifdef powerpc_HOST_ARCH 
    4872                     else if(scat->r_type == PPC_RELOC_LO16_SECTDIFF || scat->r_type == PPC_RELOC_LO16) 
     5324                    else if (scat->r_type == PPC_RELOC_LO16_SECTDIFF 
     5325                          || scat->r_type == PPC_RELOC_LO16) 
    48735326                    { 
    48745327                        ((unsigned short*) wordPtr)[1] = word & 0xFFFF; 
    48755328                    } 
    4876                     else if(scat->r_type == PPC_RELOC_HI16_SECTDIFF || scat->r_type == PPC_RELOC_HI16) 
     5329                    else if (scat->r_type == PPC_RELOC_HI16_SECTDIFF 
     5330                          || scat->r_type == PPC_RELOC_HI16) 
    48775331                    { 
    48785332                        ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF; 
    48795333                    } 
    4880                     else if(scat->r_type == PPC_RELOC_HA16_SECTDIFF || scat->r_type == PPC_RELOC_HA16) 
     5334                    else if (scat->r_type == PPC_RELOC_HA16_SECTDIFF 
     5335                          || scat->r_type == PPC_RELOC_HA16) 
    48815336                    { 
    48825337                        ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF) 
    48835338                            + ((word & (1<<15)) ? 1 : 0); 
     
    49125367        else /* !(relocs[i].r_address & R_SCATTERED) */ 
    49135368        { 
    49145369            struct relocation_info *reloc = &relocs[i]; 
    4915             if(reloc->r_pcrel && !reloc->r_extern) 
     5370            if (reloc->r_pcrel && !reloc->r_extern) { 
     5371                IF_DEBUG(linker, debugBelch("relocateSection: pc relative but not external, skipping\n")); 
    49165372                continue; 
     5373            } 
    49175374 
    4918             if(reloc->r_length == 2) 
    4919             { 
     5375            if (reloc->r_length == 2) { 
    49205376                unsigned long word = 0; 
    49215377#ifdef powerpc_HOST_ARCH 
    49225378                unsigned long jumpIsland = 0; 
     
    49285384                unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address); 
    49295385                checkProddableBlock(oc,wordPtr); 
    49305386 
    4931                 if(reloc->r_type == GENERIC_RELOC_VANILLA) 
    4932                 { 
     5387                if (reloc->r_type == GENERIC_RELOC_VANILLA) { 
    49335388                    word = *wordPtr; 
    49345389                } 
    49355390#ifdef powerpc_HOST_ARCH 
    4936                 else if(reloc->r_type == PPC_RELOC_LO16) 
    4937                 { 
     5391                else if (reloc->r_type == PPC_RELOC_LO16) { 
    49385392                    word = ((unsigned short*) wordPtr)[1]; 
    49395393                    word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16; 
    49405394                } 
    4941                 else if(reloc->r_type == PPC_RELOC_HI16) 
    4942                 { 
     5395                else if (reloc->r_type == PPC_RELOC_HI16) { 
    49435396                    word = ((unsigned short*) wordPtr)[1] << 16; 
    49445397                    word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF); 
    49455398                } 
    4946                 else if(reloc->r_type == PPC_RELOC_HA16) 
    4947                 { 
     5399                else if (reloc->r_type == PPC_RELOC_HA16) { 
    49485400                    word = ((unsigned short*) wordPtr)[1] << 16; 
    49495401                    word += ((short)relocs[i+1].r_address & (short)0xFFFF); 
    49505402                } 
    4951                 else if(reloc->r_type == PPC_RELOC_BR24) 
    4952                 { 
     5403                else if (reloc->r_type == PPC_RELOC_BR24) { 
    49535404                    word = *wordPtr; 
    49545405                    word = (word & 0x03FFFFFC) | ((word & 0x02000000) ? 0xFC000000 : 0); 
    49555406                } 
    49565407#endif 
    4957                 else 
    4958                 { 
     5408                else { 
    49595409                    barf("Can't handle this Mach-O relocation entry " 
    49605410                         "(not scattered): " 
    49615411                         "object file %s; entry type %ld; address %#lx\n", 
     
    49655415                    return 0; 
    49665416                } 
    49675417 
    4968                 if(!reloc->r_extern) 
    4969                 { 
    4970                     long delta = 
    4971                         sections[reloc->r_symbolnum-1].offset 
     5418                if (!reloc->r_extern) { 
     5419                    long delta = sections[reloc->r_symbolnum-1].offset 
    49725420                        - sections[reloc->r_symbolnum-1].addr 
    49735421                        + ((long) image); 
    49745422 
    49755423                    word += delta; 
    49765424                } 
    4977                 else 
    4978                 { 
     5425                else { 
    49795426                    struct nlist *symbol = &nlist[reloc->r_symbolnum]; 
    49805427                    char *nm = image + symLC->stroff + symbol->n_un.n_strx; 
    49815428                    void *symbolAddress = lookupSymbol(nm); 
    4982                     if(!symbolAddress) 
    4983                     { 
     5429 
     5430                    if (!symbolAddress) { 
    49845431                        errorBelch("\nunknown symbol `%s'", nm); 
    49855432                        return 0; 
    49865433                    } 
    49875434 
    4988                     if(reloc->r_pcrel) 
    4989                     { 
     5435                    if (reloc->r_pcrel) {   
    49905436#ifdef powerpc_HOST_ARCH 
    49915437                            // In the .o file, this should be a relative jump to NULL 
    49925438                            // and we'll change it to a relative jump to the symbol 
     
    49965442                                                         reloc->r_symbolnum, 
    49975443                                                         (unsigned long) symbolAddress) 
    49985444                                         -> jumpIsland; 
    4999                         if(jumpIsland != 0) 
    5000                         { 
     5445                        if (jumpIsland != 0) { 
    50015446                            offsetToJumpIsland = word + jumpIsland 
    50025447                                - (((long)image) + sect->offset - sect->addr); 
    50035448                        } 
     
    50055450                        word += (unsigned long) symbolAddress 
    50065451                                - (((long)image) + sect->offset - sect->addr); 
    50075452                    } 
    5008                     else 
    5009                     { 
     5453                    else { 
    50105454                        word += (unsigned long) symbolAddress; 
    50115455                    } 
    50125456                } 
    50135457 
    5014                 if(reloc->r_type == GENERIC_RELOC_VANILLA) 
    5015                 { 
     5458                if (reloc->r_type == GENERIC_RELOC_VANILLA) { 
    50165459                    *wordPtr = word; 
    50175460                    continue; 
    50185461                } 
     
    50205463                else if(reloc->r_type == PPC_RELOC_LO16) 
    50215464                { 
    50225465                    ((unsigned short*) wordPtr)[1] = word & 0xFFFF; 
    5023                     i++; continue; 
     5466                    i++; 
     5467                    continue; 
    50245468                } 
    50255469                else if(reloc->r_type == PPC_RELOC_HI16) 
    50265470                { 
    50275471                    ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF; 
    5028                     i++; continue; 
     5472                    i++; 
     5473                    continue; 
    50295474                } 
    50305475                else if(reloc->r_type == PPC_RELOC_HA16) 
    50315476                { 
    50325477                    ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF) 
    50335478                        + ((word & (1<<15)) ? 1 : 0); 
    5034                     i++; continue; 
     5479                    i++; 
     5480                    continue; 
    50355481                } 
    50365482                else if(reloc->r_type == PPC_RELOC_BR24) 
    50375483                { 
    5038                     if((word & 0x03) != 0) 
     5484                    if ((word & 0x03) != 0) { 
    50395485                        barf("%s: unconditional relative branch with a displacement " 
    50405486                             "which isn't a multiple of 4 bytes: %#lx", 
    50415487                             OC_INFORMATIVE_FILENAME(oc), 
    50425488                             word); 
     5489                    } 
    50435490 
    50445491                    if((word & 0xFE000000) != 0xFE000000 && 
    5045                        (word & 0xFE000000) != 0x00000000) 
    5046                     { 
     5492                        (word & 0xFE000000) != 0x00000000) { 
    50475493                        // The branch offset is too large. 
    50485494                        // Therefore, we try to use a jump island. 
    5049                         if(jumpIsland == 0) 
    5050                         { 
     5495                        if (jumpIsland == 0) { 
    50515496                            barf("%s: unconditional relative branch out of range: " 
    50525497                                 "no jump island available: %#lx", 
    50535498                                 OC_INFORMATIVE_FILENAME(oc), 
     
    50555500                        } 
    50565501 
    50575502                        word = offsetToJumpIsland; 
     5503 
    50585504                        if((word & 0xFE000000) != 0xFE000000 && 
    5059                            (word & 0xFE000000) != 0x00000000) 
     5505                            (word & 0xFE000000) != 0x00000000) { 
    50605506                            barf("%s: unconditional relative branch out of range: " 
    50615507                                 "jump island out of range: %#lx", 
    50625508                                 OC_INFORMATIVE_FILENAME(oc), 
    50635509                                 word); 
    50645510                    } 
     5511                    } 
    50655512                    *wordPtr = (*wordPtr & 0xFC000003) | (word & 0x03FFFFFC); 
    50665513                    continue; 
    50675514                } 
     
    50825529        } 
    50835530#endif 
    50845531    } 
     5532 
    50855533    IF_DEBUG(linker, debugBelch("relocateSection: done\n")); 
    50865534    return 1; 
    50875535} 
    50885536 
    5089 static int ocGetNames_MachO(ObjectCode* oc) 
     5537static int 
     5538ocGetNames_MachO(ObjectCode* oc) 
    50905539{ 
    50915540    char *image = (char*) oc->image; 
    50925541    struct mach_header *header = (struct mach_header*) image; 
     
    51045553 
    51055554    for(i=0;i<header->ncmds;i++) 
    51065555    { 
    5107         if(lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) 
     5556        if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) { 
    51085557            segLC = (struct segment_command*) lc; 
    5109         else if(lc->cmd == LC_SYMTAB) 
     5558        } 
     5559        else if (lc->cmd == LC_SYMTAB) { 
    51105560            symLC = (struct symtab_command*) lc; 
     5561        } 
     5562 
    51115563        lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize ); 
    51125564    } 
    51135565 
     
    51155567    nlist = symLC ? (struct nlist*) (image + symLC->symoff) 
    51165568                  : NULL; 
    51175569 
    5118     if(!segLC) 
     5570    if (!segLC) { 
    51195571        barf("ocGetNames_MachO: no segment load command"); 
     5572    } 
    51205573 
     5574    IF_DEBUG(linker, debugBelch("ocGetNames_MachO: will load %d sections\n", segLC->nsects)); 
    51215575    for(i=0;i<segLC->nsects;i++) 
    51225576    { 
    5123         IF_DEBUG(linker, debugBelch("ocGetNames_MachO: segment %d\n", i)); 
    5124         if (sections[i].size == 0) 
     5577        IF_DEBUG(linker, debugBelch("ocGetNames_MachO: section %d\n", i)); 
     5578 
     5579        if (sections[i].size == 0) { 
     5580            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: found a zero length section, skipping\n")); 
    51255581            continue; 
     5582        } 
    51265583 
    51275584        if((sections[i].flags & SECTION_TYPE) == S_ZEROFILL) 
    51285585        { 
     
    51315588            sections[i].offset = zeroFillArea - image; 
    51325589        } 
    51335590 
    5134         if(!strcmp(sections[i].sectname,"__text")) 
     5591        if (!strcmp(sections[i].sectname,"__text")) { 
     5592 
     5593            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __text section\n")); 
    51355594            addSection(oc, SECTIONKIND_CODE_OR_RODATA, 
    51365595                (void*) (image + sections[i].offset), 
    51375596                (void*) (image + sections[i].offset + sections[i].size)); 
    5138         else if(!strcmp(sections[i].sectname,"__const")) 
     5597        } 
     5598        else if (!strcmp(sections[i].sectname,"__const")) { 
     5599 
     5600            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __const section\n")); 
    51395601            addSection(oc, SECTIONKIND_RWDATA, 
    51405602                (void*) (image + sections[i].offset), 
    51415603                (void*) (image + sections[i].offset + sections[i].size)); 
    5142         else if(!strcmp(sections[i].sectname,"__data")) 
     5604        }     
     5605        else if (!strcmp(sections[i].sectname,"__data")) { 
     5606 
     5607            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __data section\n")); 
    51435608            addSection(oc, SECTIONKIND_RWDATA, 
    51445609                (void*) (image + sections[i].offset), 
    51455610                (void*) (image + sections[i].offset + sections[i].size)); 
     5611        } 
    51465612        else if(!strcmp(sections[i].sectname,"__bss") 
    5147                 || !strcmp(sections[i].sectname,"__common")) 
     5613                || !strcmp(sections[i].sectname,"__common")) { 
     5614 
     5615            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __bss section\n")); 
    51485616            addSection(oc, SECTIONKIND_RWDATA, 
    51495617                (void*) (image + sections[i].offset), 
    51505618                (void*) (image + sections[i].offset + sections[i].size)); 
    5151  
    5152         addProddableBlock(oc, (void*) (image + sections[i].offset), 
     5619        } 
     5620        addProddableBlock(oc, 
     5621                          (void *) (image + sections[i].offset), 
    51535622                                        sections[i].size); 
    51545623    } 
    51555624 
    51565625        // count external symbols defined here 
    51575626    oc->n_symbols = 0; 
    5158     if(symLC) 
    5159     { 
    5160         for(i=0;i<symLC->nsyms;i++) 
    5161         { 
    5162             if(nlist[i].n_type & N_STAB) 
     5627    if (symLC) { 
     5628        for (i = 0; i < symLC->nsyms; i++) { 
     5629            if (nlist[i].n_type & N_STAB) { 
    51635630                ; 
     5631            } 
    51645632            else if(nlist[i].n_type & N_EXT) 
    51655633            { 
    51665634                if((nlist[i].n_type & N_TYPE) == N_UNDF 
     
    51695637                    commonSize += nlist[i].n_value; 
    51705638                    oc->n_symbols++; 
    51715639                } 
    5172                 else if((nlist[i].n_type & N_TYPE) == N_SECT) 
     5640                else if ((nlist[i].n_type & N_TYPE) == N_SECT) { 
    51735641                    oc->n_symbols++; 
    51745642            } 
    51755643        } 
    51765644    } 
     5645    } 
     5646 
    51775647    IF_DEBUG(linker, debugBelch("ocGetNames_MachO: %d external symbols\n", oc->n_symbols)); 
    51785648    oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*), 
    51795649                                   "ocGetNames_MachO(oc->symbols)"); 
    51805650 
    5181     if(symLC) 
    5182     { 
    5183         for(i=0;i<symLC->nsyms;i++) 
    5184         { 
    5185             if(nlist[i].n_type & N_STAB) 
     5651    if (symLC) { 
     5652        for (i = 0; i < symLC->nsyms; i++) { 
     5653            IF_DEBUG(linker, debugBelch("ocGetNames_MachO: symbol type is %#04x\n", nlist[i].n_type)); 
     5654            if (nlist[i].n_type & N_STAB) { 
    51865655                ; 
     5656            } 
    51875657            else if((nlist[i].n_type & N_TYPE) == N_SECT) 
    51885658            { 
    5189                 if(nlist[i].n_type & N_EXT) 
     5659                if ((nlist[i].n_type & N_EXT) && !(nlist[i].n_type & N_PEXT)) 
    51905660                { 
    51915661                    char *nm = image + symLC->stroff + nlist[i].n_un.n_strx; 
     5662 
    51925663                    if ((nlist[i].n_desc & N_WEAK_DEF) && lookupSymbol(nm)) { 
    51935664                        // weak definition, and we already have a definition 
    5194                         IF_DEBUG(linker, debugBelch("    weak: %s\n", nm)); 
     5665                        IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \tweak: %s\n", nm)); 
    51955666                    } 
    51965667                    else 
    51975668                    { 
     
    52045675                            oc->symbols[curSymbol++] = nm; 
    52055676                    } 
    52065677                } 
     5678                else 
     5679                { 
     5680                    IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not external, skipping\n")); 
     5681                } 
     5682            } 
     5683            else 
     5684            { 
     5685                IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not defined in this section, skipping\n")); 
    52075686            } 
    52085687        } 
    52095688    } 
    52105689 
    52115690    commonStorage = stgCallocBytes(1,commonSize,"ocGetNames_MachO(common symbols)"); 
    52125691    commonCounter = (unsigned long)commonStorage; 
    5213     if(symLC) 
    5214     { 
    5215         for(i=0;i<symLC->nsyms;i++) 
    5216         { 
     5692 
     5693    if (symLC) { 
     5694        for (i = 0; i < symLC->nsyms; i++) { 
    52175695            if((nlist[i].n_type & N_TYPE) == N_UNDF 
    5218                     && (nlist[i].n_type & N_EXT) && (nlist[i].n_value != 0)) 
    5219             { 
     5696             && (nlist[i].n_type & N_EXT) 
     5697             && (nlist[i].n_value != 0)) { 
     5698 
    52205699                char *nm = image + symLC->stroff + nlist[i].n_un.n_strx; 
    52215700                unsigned long sz = nlist[i].n_value; 
    52225701 
     
    52315710            } 
    52325711        } 
    52335712    } 
     5713 
     5714    IF_DEBUG(linker, debugBelch("ocGetNames_MachO: done\n")); 
    52345715    return 1; 
    52355716} 
    52365717 
    5237 static int ocResolve_MachO(ObjectCode* oc) 
     5718static int 
     5719ocResolve_MachO(ObjectCode* oc) 
    52385720{ 
    52395721    char *image = (char*) oc->image; 
    52405722    struct mach_header *header = (struct mach_header*) image; 
     
    52495731    IF_DEBUG(linker, debugBelch("ocResolve_MachO: start\n")); 
    52505732    for (i = 0; i < header->ncmds; i++) 
    52515733    { 
    5252         if(lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) 
     5734        if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) { 
    52535735            segLC = (struct segment_command*) lc; 
    5254         else if(lc->cmd == LC_SYMTAB) 
     5736            IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a 32 or 64 bit segment load command\n")); 
     5737        } 
     5738        else if (lc->cmd == LC_SYMTAB) { 
    52555739            symLC = (struct symtab_command*) lc; 
    5256         else if(lc->cmd == LC_DYSYMTAB) 
     5740            IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a symbol table load command\n")); 
     5741        } 
     5742        else if (lc->cmd == LC_DYSYMTAB) { 
    52575743            dsymLC = (struct dysymtab_command*) lc; 
     5744            IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a dynamic symbol table load command\n")); 
     5745        } 
     5746 
    52585747        lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize ); 
    52595748    } 
    52605749 
     
    52625751    nlist = symLC ? (struct nlist*) (image + symLC->symoff) 
    52635752                  : NULL; 
    52645753 
    5265     if(dsymLC) 
    5266     { 
     5754    if (dsymLC) { 
    52675755        unsigned long *indirectSyms 
    52685756            = (unsigned long*) (image + dsymLC->indirectsymoff); 
    52695757 
    5270         IF_DEBUG(linker, debugBelch("ocResolve_MachO: resolving dsymLC\n")); 
    5271         for (i = 0; i < segLC->nsects; i++) 
    5272         { 
    5273             if(    !strcmp(sections[i].sectname,"__la_symbol_ptr") 
    5274                 || !strcmp(sections[i].sectname,"__la_sym_ptr2") 
    5275                 || !strcmp(sections[i].sectname,"__la_sym_ptr3")) 
     5758        IF_DEBUG(linker, debugBelch("ocResolve_MachO: trying to resolve dynamic symbols\n")); 
     5759        for (i = 0; i < segLC->nsects; i++) { 
     5760            if (    strcmp(sections[i].sectname,"__la_symbol_ptr") == 0 
     5761                 || strcmp(sections[i].sectname,"__la_sym_ptr2")   == 0 
     5762                 || strcmp(sections[i].sectname,"__la_sym_ptr3")   == 0) 
    52765763            { 
     5764                IF_DEBUG(linker, debugBelch("ocResolve_machO: resolving __la_symbol_ptr, __la_sym_ptr2 or __la_sym_ptr3 section\n")); 
    52775765                if(!resolveImports(oc,image,symLC,&sections[i],indirectSyms,nlist)) 
    52785766                    return 0; 
    52795767            } 
    5280             else if(!strcmp(sections[i].sectname,"__nl_symbol_ptr") 
    5281                 ||  !strcmp(sections[i].sectname,"__pointers")) 
     5768            else if (strcmp(sections[i].sectname,"__nl_symbol_ptr") == 0 
     5769                 ||  strcmp(sections[i].sectname,"__pointers")      == 0) 
    52825770            { 
     5771                IF_DEBUG(linker, debugBelch("ocResolve_machO: resolving __nl_symbol_ptr or __pointers section\n")); 
    52835772                if(!resolveImports(oc,image,symLC,&sections[i],indirectSyms,nlist)) 
    52845773                    return 0; 
    52855774            } 
    5286             else if(!strcmp(sections[i].sectname,"__jump_table")) 
     5775            else if (strcmp(sections[i].sectname,"__jump_table") == 0) 
    52875776            { 
     5777                IF_DEBUG(linker, debugBelch("ocResolve_MachO: resolving jump table\n")); 
    52885778                if(!resolveImports(oc,image,symLC,&sections[i],indirectSyms,nlist)) 
    52895779                    return 0; 
    52905780            } 
    52915781            else 
    52925782            { 
    5293                 IF_DEBUG(linker, debugBelch("ocResolve_MachO: unknown section\n")); 
     5783                    IF_DEBUG(linker, debugBelch("ocResolve_MachO: %s is not used by the dynamic linker, skipping\n", sections[i].sectname)); 
    52945784            } 
    52955785        } 
     5786        IF_DEBUG(linker, debugBelch("ocResolve_MachO: done resolving dynamic symbols\n")); 
    52965787    } 
    52975788 
    5298     for(i=0;i<segLC->nsects;i++) 
    5299     { 
    5300             IF_DEBUG(linker, debugBelch("ocResolve_MachO: relocating section %d\n", i)); 
     5789    IF_DEBUG(linker, debugBelch("ocResolve_MachO: beginning relocations\n")); 
     5790 
     5791    IF_DEBUG(linker,  
     5792    for (i = 0; i < segLC->nsects; i++) { 
     5793        debugBelch("ocResolve_MachO: \tsection[%d].sectname = %s\n", i, sections[i].sectname); 
     5794        debugBelch("ocResolve_MachO: \tsection[%d].segname  = %s\n", i, sections[i].segname); 
     5795        debugBelch("ocResolve_MachO: \tsection[%d].addr     = %#0llx\n", i, (unsigned long long)sections[i].addr); 
     5796        debugBelch("ocResolve_MachO: \tsection[%d].size     = %#0llx\n", i, (unsigned long long)sections[i].size); 
     5797        debugBelch("ocResolve_MachO: \tsection[%d].offset   = %#0lx\n", i, (unsigned long)sections[i].offset); 
     5798        debugBelch("ocResolve_MachO: \tsection[%d].align    = %#0lx\n", i, (unsigned long)sections[i].align); 
     5799        debugBelch("ocResolve_MachO: \tsection[%d].reloff   = %#0lx\n", i, (unsigned long)sections[i].reloff); 
     5800        debugBelch("ocResolve_MachO: \tsection[%d].nreloc   = %#0lx\n", i, (unsigned long)sections[i].nreloc); 
     5801        debugBelch("ocResolve_MachO: \tsection[%d].flags    = %#0lx\n", i, (unsigned long)sections[i].flags); 
     5802        debugBelch("ocResolve_MachO: \n"); 
     5803    }); 
     5804 
     5805    for (i = 0; i < segLC->nsects; i++) { 
     5806 
     5807        IF_DEBUG(linker, debugBelch("ocResolve_MachO: relocating section %d (%s)\n", i, sections[i].sectname)); 
    53015808 
    53025809        if (!relocateSection(oc,image,symLC,nlist,segLC->nsects,sections,&sections[i])) 
    53035810            return 0; 
    53045811    } 
    53055812 
     5813    IF_DEBUG(linker, debugBelch("ocResolve_MachO: finished relocating\n")); 
     5814 
    53065815#if defined (powerpc_HOST_ARCH) 
    53075816    ocFlushInstructionCache( oc ); 
    53085817#endif 
    53095818 
     5819    IF_DEBUG(linker, debugBelch("ocResolve_MachO: done\n")); 
    53105820    return 1; 
    53115821} 
    53125822 
     
    53225832 
    53235833extern void* symbolsWithoutUnderscore[]; 
    53245834 
    5325 static void machoInitSymbolsWithoutUnderscore() 
     5835static void 
     5836machoInitSymbolsWithoutUnderscore(void) 
    53265837{ 
    53275838    void **p = symbolsWithoutUnderscore; 
    53285839    __asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:"); 
     
    53505861 * Figure out by how much to shift the entire Mach-O file in memory 
    53515862 * when loading so that its single segment ends up 16-byte-aligned 
    53525863 */ 
    5353 static int machoGetMisalignment( FILE * f ) 
     5864static int 
     5865machoGetMisalignment( FILE * f ) 
    53545866{ 
    53555867    struct mach_header header; 
    53565868    int misalignment;