the same general comments as before: <div>1. we need to notify the mach_override authors/maintainers </div><div>2. I'd like to get rid of mach_override completely. Any MacOS expert's advice is welcome! </div><div><br>
</div><div>--kcc <br><br><div class="gmail_quote">On Thu, Mar 22, 2012 at 4:29 AM, Alexander Potapenko <span dir="ltr"><<a href="mailto:glider@google.com">glider@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: glider<br>
Date: Thu Mar 22 06:29:53 2012<br>
New Revision: 153249<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=153249&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=153249&view=rev</a><br>
Log:<br>
Handle two-byte short jumps in the relocated code.<br>
After the instructions are moved to the branch island, fixupInstructions() expands every 2-byte ja/je instruction with a 1-byte offset into a 6-byte ja/je with 32-bit offset. The offset is fixed to point to the original function.<br>

<br>
<br>
Modified:<br>
    compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c<br>
<br>
Modified: compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c?rev=153249&r1=153248&r2=153249&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c?rev=153249&r1=153248&r2=153249&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c (original)<br>
+++ compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c Thu Mar 22 06:29:53 2012<br>
@@ -157,6 +157,12 @@<br>
     void               *instructionsToFix,<br>
        int                     instructionCount,<br>
        uint8_t         *instructionSizes ) __attribute__((visibility("hidden")));<br>
+<br>
+#ifdef DEBUG_DISASM<br>
+       static void<br>
+dump16Bytes(<br>
+       void    *ptr);<br>
+#endif  // DEBUG_DISASM<br>
 #endif<br>
<br>
 /*******************************************************************************<br>
@@ -830,9 +836,21 @@<br>
        int                     instructionCount,<br>
        uint8_t         *instructionSizes )<br>
 {<br>
-       int     index;<br>
+       void *initialOriginalFunction = originalFunction;<br>
+       int     index, fixed_size, code_size = 0;<br>
+       for (index = 0;index < instructionCount;index += 1)<br>
+               code_size += instructionSizes[index];<br>
+<br>
+#ifdef DEBUG_DISASM<br>
+       void *initialInstructionsToFix = instructionsToFix;<br>
+       fprintf(stderr, "BEFORE FIXING:\n");<br>
+       dump16Bytes(initialOriginalFunction);<br>
+       dump16Bytes(initialInstructionsToFix);<br>
+#endif  // DEBUG_DISASM<br>
+<br>
        for (index = 0;index < instructionCount;index += 1)<br>
        {<br>
+                fixed_size = instructionSizes[index];<br>
                if ((*(uint8_t*)instructionsToFix == 0xE9) || // 32-bit jump relative<br>
                    (*(uint8_t*)instructionsToFix == 0xE8))   // 32-bit call relative<br>
                {<br>
@@ -840,13 +858,56 @@<br>
                        uint32_t *jumpOffsetPtr = (uint32_t*)((uintptr_t)instructionsToFix + 1);<br>
                        *jumpOffsetPtr += offset;<br>
                }<br>
-<br>
+               if ((*(uint8_t*)instructionsToFix == 0x74) ||  // Near jump if equal (je), 2 bytes.<br>
+                   (*(uint8_t*)instructionsToFix == 0x77))    // Near jump if above (ja), 2 bytes.<br>
+               {<br>
+                       // We replace a near je/ja instruction, "7P JJ", with a 32-bit je/ja, "0F 8P WW XX YY ZZ".<br>
+                       // This is critical, otherwise a near jump will likely fall outside the original function.<br>
+                       uint32_t offset = (uintptr_t)initialOriginalFunction - (uintptr_t)escapeIsland;<br>
+                       uint32_t jumpOffset = *(uint8_t*)((uintptr_t)instructionsToFix + 1);<br>
+                       *(uint8_t*)(instructionsToFix + 1) = *(uint8_t*)instructionsToFix + 0x10;<br>
+                       *(uint8_t*)instructionsToFix = 0x0F;<br>
+                       uint32_t *jumpOffsetPtr = (uint32_t*)((uintptr_t)instructionsToFix + 2 );<br>
+                       *jumpOffsetPtr = offset + jumpOffset;<br>
+                       fixed_size = 6;<br>
+                }<br>
<br>
                originalFunction = (void*)((uintptr_t)originalFunction + instructionSizes[index]);<br>
                escapeIsland = (void*)((uintptr_t)escapeIsland + instructionSizes[index]);<br>
-               instructionsToFix = (void*)((uintptr_t)instructionsToFix + instructionSizes[index]);<br>
-    }<br>
+               instructionsToFix = (void*)((uintptr_t)instructionsToFix + fixed_size);<br>
+<br>
+               // Expanding short instructions into longer ones may overwrite the next instructions,<br>
+               // so we must restore them.<br>
+               code_size -= fixed_size;<br>
+               if ((code_size > 0) && (fixed_size != instructionSizes[index])) {<br>
+                       bcopy(originalFunction, instructionsToFix, code_size);<br>
+               }<br>
+       }<br>
+#ifdef DEBUG_DISASM<br>
+       fprintf(stderr, "AFTER_FIXING:\n");<br>
+       dump16Bytes(initialOriginalFunction);<br>
+       dump16Bytes(initialInstructionsToFix);<br>
+#endif  // DEBUG_DISASM<br>
+}<br>
+<br>
+#ifdef DEBUG_DISASM<br>
+#define HEX_DIGIT(x) ((((x) % 16) < 10) ? ('0' + ((x) % 16)) : ('A' + ((x) % 16 - 10)))<br>
+<br>
+       static void<br>
+dump16Bytes(<br>
+       void    *ptr) {<br>
+       int i;<br>
+       char buf[3];<br>
+       uint8_t *bytes = (uint8_t*)ptr;<br>
+       for (i = 0; i < 16; i++) {<br>
+               buf[0] = HEX_DIGIT(bytes[i] / 16);<br>
+               buf[1] = HEX_DIGIT(bytes[i] % 16);<br>
+               buf[2] = ' ';<br>
+               write(2, buf, 3);<br>
+       }<br>
+       write(2, "\n", 1);<br>
 }<br>
+#endif  // DEBUG_DISASM<br>
 #endif<br>
<br>
 #if defined(__i386__)<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>