From a909ce21592702606dfe18728bca553adbc8a380 Mon Sep 17 00:00:00 2001 From: wolfgang Date: Wed, 2 Oct 2002 09:36:00 +0000 Subject: [PATCH] [project @ 2002-10-02 09:36:00 by wolfgang] PowerPC Mach-O: Handle more kinds of relocations, so that non-PIC-code can be loaded --- ghc/rts/Linker.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/ghc/rts/Linker.c b/ghc/rts/Linker.c index 74e7093..a465dc7 100644 --- a/ghc/rts/Linker.c +++ b/ghc/rts/Linker.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: Linker.c,v 1.103 2002/09/13 15:02:50 simonpj Exp $ + * $Id: Linker.c,v 1.104 2002/10/02 09:36:00 wolfgang Exp $ * * (c) The GHC Team, 2000, 2001 * @@ -64,6 +64,7 @@ # include # include #elif defined(darwin_TARGET_OS) +# include # define OBJFORMAT_MACHO # include # include @@ -2963,12 +2964,32 @@ static void relocateSection(char *image, if(reloc->r_pcrel && !reloc->r_extern) continue; - if(!reloc->r_pcrel - && reloc->r_length == 2 - && reloc->r_type == GENERIC_RELOC_VANILLA) + if(!reloc->r_pcrel && reloc->r_length == 2) { - unsigned long* word = (unsigned long*) (image + sect->offset + reloc->r_address); + unsigned long word; + + unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address); + if(reloc->r_type == GENERIC_RELOC_VANILLA) + { + word = *wordPtr; + } + else if(reloc->r_type == PPC_RELOC_LO16) + { + word = ((unsigned short*) wordPtr)[1]; + word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16; + } + else if(reloc->r_type == PPC_RELOC_HI16) + { + word = ((unsigned short*) wordPtr)[1] << 16; + word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF); + } + else if(reloc->r_type == PPC_RELOC_HA16) + { + word = ((unsigned short*) wordPtr)[1] << 16; + word += ((short)relocs[i+1].r_address & (short)0xFFFF); + } + if(!reloc->r_extern) { long delta = @@ -2976,14 +2997,36 @@ static void relocateSection(char *image, - sections[reloc->r_symbolnum-1].addr + ((long) image); - *word += delta; + word += delta; } else { struct nlist *symbol = &nlist[reloc->r_symbolnum]; char *nm = image + symLC->stroff + symbol->n_un.n_strx; - *word = (unsigned long) (lookupSymbol(nm)); - ASSERT(*word); + word = (unsigned long) (lookupSymbol(nm)); + ASSERT(word); + } + + if(reloc->r_type == GENERIC_RELOC_VANILLA) + { + *wordPtr = word; + continue; + } + else if(reloc->r_type == PPC_RELOC_LO16) + { + ((unsigned short*) wordPtr)[1] = word & 0xFFFF; + i++; continue; + } + else if(reloc->r_type == PPC_RELOC_HI16) + { + ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF; + i++; continue; + } + else if(reloc->r_type == PPC_RELOC_HA16) + { + ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF) + + ((word & (1<<15)) ? 1 : 0); + i++; continue; } continue; } -- 1.7.10.4