From e525ca0a4d60ba8612aef911470f957667c3913a Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 9 Jan 2006 02:47:18 +0000 Subject: [PATCH] Fixed relocation of negative 14, 16, or 24 bit values. In case of 14 and 24 bits the set upper bits were overwriting the upper bits of the word at the target location (usually something like a branch instruction). This is the kind of bug that easily take six hours to find, especially when working with interrupt code and being convinced that the problem must be related. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15879 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/boot/arch/ppc/elf.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/system/boot/arch/ppc/elf.cpp b/src/system/boot/arch/ppc/elf.cpp index 02d14074ce..7a3e37678d 100644 --- a/src/system/boot/arch/ppc/elf.cpp +++ b/src/system/boot/arch/ppc/elf.cpp @@ -46,10 +46,10 @@ static inline bool write_low24_check(addr_t P, Elf32_Word value) { // bits 6:29 -// TODO: This check doesn't work, since negative values are allowed, too. -// if (value & 0xff000000) -// return false; - *(Elf32_Word*)P = (*(Elf32_Word*)P & 0xfc000003) | (value << 2); + if ((value & 0x3f000000) && (~value & 0x3f800000)) + return false; + *(Elf32_Word*)P = (*(Elf32_Word*)P & 0xfc000003) + | ((value & 0x00ffffff) << 2); return true; } @@ -58,9 +58,10 @@ static inline bool write_low14_check(addr_t P, Elf32_Word value) { // bits 16:29 -// if (value & 0xffffc000) -// return false; - *(Elf32_Word*)P = (*(Elf32_Word*)P & 0xffff0003) | (value << 2); + if ((value & 0x3fffc000) && (~value & 0x3fffe000)) + return false; + *(Elf32_Word*)P = (*(Elf32_Word*)P & 0xffff0003) + | ((value & 0x00003fff) << 2); return true; } @@ -77,8 +78,8 @@ static inline bool write_half16_check(addr_t P, Elf32_Word value) { // bits 16:29 -// if (value & 0xffff0000) -// return false; + if ((value & 0xffff0000) && (~value & 0xffff8000)) + return false; *(Elf32_Half*)P = (Elf32_Half)value; return true; }