From 7bcf45933a1b386e7f28c0ee7d09d92bad1ee0e7 Mon Sep 17 00:00:00 2001 From: "Ben.Lippmeier@anu.edu.au" Date: Thu, 28 May 2009 08:05:09 +0000 Subject: [PATCH] Fix handling of R_SPARC_UA32 relocations in linker These refer to unaligned locations that need to be written byte-at-a-time. This fixes the SPARC ghci failures in the current head. --- rts/Linker.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/rts/Linker.c b/rts/Linker.c index d41ede6..b123f78 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -3544,17 +3544,26 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC, w1 |= w2; *pP = w1; break; + /* According to the Sun documentation: R_SPARC_UA32 This relocation type resembles R_SPARC_32, except it refers to an unaligned word. That is, the word to be relocated must be treated as four separate bytes with arbitrary alignment, not as a word aligned according to the architecture requirements. - - (JRS: which means that freeloading on the R_SPARC_32 case - is probably wrong, but hey ...) */ case R_SPARC_UA32: + w2 = (Elf_Word)value; + + // SPARC doesn't do misaligned writes of 32 bit words, + // so we have to do this one byte-at-a-time. + char *pPc = (char*)pP; + pPc[0] = (char) ((Elf_Word)(w2 & 0xff000000) >> 24); + pPc[1] = (char) ((Elf_Word)(w2 & 0x00ff0000) >> 16); + pPc[2] = (char) ((Elf_Word)(w2 & 0x0000ff00) >> 8); + pPc[3] = (char) ((Elf_Word)(w2 & 0x000000ff)); + break; + case R_SPARC_32: w2 = (Elf_Word)value; *pP = w2; -- 1.7.10.4