Repository : ssh://darcs.haskell.org//srv/darcs/ghc On branch : master
http://hackage.haskell.org/trac/ghc/changeset/bf21999aad97b96b0318013d16c846730a27f41b >--------------------------------------------------------------- commit bf21999aad97b96b0318013d16c846730a27f41b Author: Ian Lynagh <[email protected]> Date: Tue May 1 14:00:57 2012 +0100 Tell checkProddableBlock how many bytes we want to write It doesn't suffice for checkProddableBlock to just check whether the largest possible write could be made at the address we are writing, as if we are making a smaller write then checkProddableBlock may conservatively think we will write off the end of the block. Thus we now tell checkProddableBlock how many bytes we will write. >--------------------------------------------------------------- rts/Linker.c | 41 +++++++++++++++++++++++------------------ 1 files changed, 23 insertions(+), 18 deletions(-) diff --git a/rts/Linker.c b/rts/Linker.c index f4faa5d..48667b4 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -2493,23 +2493,15 @@ addProddableBlock ( ObjectCode* oc, void* start, int size ) } static void -checkProddableBlock (ObjectCode *oc, void *addr ) +checkProddableBlock (ObjectCode *oc, void *addr, size_t size ) { ProddableBlock* pb; for (pb = oc->proddables; pb != NULL; pb = pb->next) { char* s = (char*)(pb->start); - char* e = s + pb->size - 1; + char* e = s + pb->size; char* a = (char*)addr; -#if WORD_SIZE_IN_BITS == 32 - /* Assumes that the biggest fixup involves a 4-byte write */ - if (a >= s && (a+3) <= e) return; -#elif WORD_SIZE_IN_BITS == 64 - /* Assumes that the biggest fixup involves a 4-byte write */ - if (a >= s && (a+7) <= e) return; -#else -#error -#endif + if (a >= s && (a+size) <= e) return; } barf("checkProddableBlock: invalid fixup in runtime linker: %p", addr); } @@ -3670,7 +3662,8 @@ ocResolve_PEi386 ( ObjectCode* oc ) return 0; foundit:; } - checkProddableBlock(oc, pP); + /* All supported relocations write at least 4 bytes */ + checkProddableBlock(oc, pP, 4); switch (reltab_j->Type) { #if defined(i386_HOST_ARCH) case MYIMAGE_REL_I386_DIR32: @@ -3715,6 +3708,7 @@ ocResolve_PEi386 ( ObjectCode* oc ) case 1: /* R_X86_64_64 */ { UInt64 A; + checkProddableBlock(oc, pP, 8); A = *(UInt64*)pP; *(UInt64 *)pP = ((UInt64)S) + ((UInt64)A); break; @@ -4466,7 +4460,7 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC, IF_DEBUG(linker,debugBelch( "Reloc: P = %p S = %p A = %p\n", (void*)P, (void*)S, (void*)A )); - checkProddableBlock ( oc, pP ); + checkProddableBlock ( oc, pP, sizeof(Elf_Word) ); #ifdef i386_HOST_ARCH value = S + A; @@ -5233,7 +5227,7 @@ resolveImports( #if i386_HOST_ARCH if (isJumpTable) { - checkProddableBlock(oc,image + sect->offset + i*itemSize); + checkProddableBlock(oc,image + sect->offset + i*itemSize, 5); *(image + sect->offset + i * itemSize) = 0xe9; // jmp opcode *(unsigned*)(image + sect->offset + i*itemSize + 1) @@ -5242,7 +5236,9 @@ resolveImports( else #endif { - checkProddableBlock(oc,((void**)(image + sect->offset)) + i); + checkProddableBlock(oc, + ((void**)(image + sect->offset)) + i, + sizeof(void *)); ((void**)(image + sect->offset))[i] = addr; } } @@ -5323,22 +5319,25 @@ relocateSection( IF_DEBUG(linker, debugBelch(" : extern = %d\n", reloc->r_extern)); IF_DEBUG(linker, debugBelch(" : type = %d\n", reloc->r_type)); - checkProddableBlock(oc,thingPtr); switch(reloc->r_length) { case 0: + checkProddableBlock(oc,thingPtr,1); thing = *(uint8_t*)thingPtr; baseValue = (uint64_t)thingPtr + 1; break; case 1: + checkProddableBlock(oc,thingPtr,2); thing = *(uint16_t*)thingPtr; baseValue = (uint64_t)thingPtr + 2; break; case 2: + checkProddableBlock(oc,thingPtr,4); thing = *(uint32_t*)thingPtr; baseValue = (uint64_t)thingPtr + 4; break; case 3: + checkProddableBlock(oc,thingPtr,8); thing = *(uint64_t*)thingPtr; baseValue = (uint64_t)thingPtr + 8; break; @@ -5506,7 +5505,10 @@ relocateSection( { unsigned long word = 0; unsigned long* wordPtr = (unsigned long*) (image + sect->offset + scat->r_address); - checkProddableBlock(oc,wordPtr); + + /* In this check we assume that sizeof(unsigned long) = 2 * sizeof(unsigned short) + on powerpc_HOST_ARCH */ + checkProddableBlock(oc,wordPtr,sizeof(unsigned long)); // Note on relocation types: // i386 uses the GENERIC_RELOC_* types, @@ -5676,7 +5678,10 @@ relocateSection( #endif unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address); - checkProddableBlock(oc,wordPtr); + + /* In this check we assume that sizeof(unsigned long) = 2 * sizeof(unsigned short) + on powerpc_HOST_ARCH */ + checkProddableBlock(oc,wordPtr, sizeof(unsigned long)); if (reloc->r_type == GENERIC_RELOC_VANILLA) { word = *wordPtr; _______________________________________________ Cvs-ghc mailing list [email protected] http://www.haskell.org/mailman/listinfo/cvs-ghc
