[llvm-commits] [compiler-rt] r153249 - /compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c
Timur Iskhodzhanov
timurrrr at google.com
Fri Mar 23 00:25:15 PDT 2012
On Fri, Mar 23, 2012 at 2:03 AM, Kostya Serebryany <kcc at google.com> wrote:
> the same general comments as before:
> 1. we need to notify the mach_override authors/maintainers
> 2. I'd like to get rid of mach_override completely. Any MacOS expert's
> advice is welcome!
FYI,
an analog of mach_override for Windows took just ~40 LOC
(see OverrideFunction in
http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/interception_win.cc?revision=152557&view=markup
)
This might be harder to achieve on Linux/Mac as the default calling
convention is different though.
> --kcc
>
>
> On Thu, Mar 22, 2012 at 4:29 AM, Alexander Potapenko <glider at google.com>
> wrote:
>>
>> Author: glider
>> Date: Thu Mar 22 06:29:53 2012
>> New Revision: 153249
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=153249&view=rev
>> Log:
>> Handle two-byte short jumps in the relocated code.
>> 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.
>>
>>
>> Modified:
>> compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c
>>
>> Modified:
>> compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c
>> URL:
>> 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
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c
>> (original)
>> +++ compiler-rt/trunk/lib/asan/interception/mach_override/mach_override.c
>> Thu Mar 22 06:29:53 2012
>> @@ -157,6 +157,12 @@
>> void *instructionsToFix,
>> int instructionCount,
>> uint8_t *instructionSizes )
>> __attribute__((visibility("hidden")));
>> +
>> +#ifdef DEBUG_DISASM
>> + static void
>> +dump16Bytes(
>> + void *ptr);
>> +#endif // DEBUG_DISASM
>> #endif
>>
>>
>> /*******************************************************************************
>> @@ -830,9 +836,21 @@
>> int instructionCount,
>> uint8_t *instructionSizes )
>> {
>> - int index;
>> + void *initialOriginalFunction = originalFunction;
>> + int index, fixed_size, code_size = 0;
>> + for (index = 0;index < instructionCount;index += 1)
>> + code_size += instructionSizes[index];
>> +
>> +#ifdef DEBUG_DISASM
>> + void *initialInstructionsToFix = instructionsToFix;
>> + fprintf(stderr, "BEFORE FIXING:\n");
>> + dump16Bytes(initialOriginalFunction);
>> + dump16Bytes(initialInstructionsToFix);
>> +#endif // DEBUG_DISASM
>> +
>> for (index = 0;index < instructionCount;index += 1)
>> {
>> + fixed_size = instructionSizes[index];
>> if ((*(uint8_t*)instructionsToFix == 0xE9) || // 32-bit
>> jump relative
>> (*(uint8_t*)instructionsToFix == 0xE8)) // 32-bit
>> call relative
>> {
>> @@ -840,13 +858,56 @@
>> uint32_t *jumpOffsetPtr =
>> (uint32_t*)((uintptr_t)instructionsToFix + 1);
>> *jumpOffsetPtr += offset;
>> }
>> -
>> + if ((*(uint8_t*)instructionsToFix == 0x74) || // Near
>> jump if equal (je), 2 bytes.
>> + (*(uint8_t*)instructionsToFix == 0x77)) // Near
>> jump if above (ja), 2 bytes.
>> + {
>> + // We replace a near je/ja instruction, "7P JJ",
>> with a 32-bit je/ja, "0F 8P WW XX YY ZZ".
>> + // This is critical, otherwise a near jump will
>> likely fall outside the original function.
>> + uint32_t offset =
>> (uintptr_t)initialOriginalFunction - (uintptr_t)escapeIsland;
>> + uint32_t jumpOffset =
>> *(uint8_t*)((uintptr_t)instructionsToFix + 1);
>> + *(uint8_t*)(instructionsToFix + 1) =
>> *(uint8_t*)instructionsToFix + 0x10;
>> + *(uint8_t*)instructionsToFix = 0x0F;
>> + uint32_t *jumpOffsetPtr =
>> (uint32_t*)((uintptr_t)instructionsToFix + 2 );
>> + *jumpOffsetPtr = offset + jumpOffset;
>> + fixed_size = 6;
>> + }
>>
>> originalFunction = (void*)((uintptr_t)originalFunction +
>> instructionSizes[index]);
>> escapeIsland = (void*)((uintptr_t)escapeIsland +
>> instructionSizes[index]);
>> - instructionsToFix = (void*)((uintptr_t)instructionsToFix +
>> instructionSizes[index]);
>> - }
>> + instructionsToFix = (void*)((uintptr_t)instructionsToFix +
>> fixed_size);
>> +
>> + // Expanding short instructions into longer ones may
>> overwrite the next instructions,
>> + // so we must restore them.
>> + code_size -= fixed_size;
>> + if ((code_size > 0) && (fixed_size !=
>> instructionSizes[index])) {
>> + bcopy(originalFunction, instructionsToFix,
>> code_size);
>> + }
>> + }
>> +#ifdef DEBUG_DISASM
>> + fprintf(stderr, "AFTER_FIXING:\n");
>> + dump16Bytes(initialOriginalFunction);
>> + dump16Bytes(initialInstructionsToFix);
>> +#endif // DEBUG_DISASM
>> +}
>> +
>> +#ifdef DEBUG_DISASM
>> +#define HEX_DIGIT(x) ((((x) % 16) < 10) ? ('0' + ((x) % 16)) : ('A' +
>> ((x) % 16 - 10)))
>> +
>> + static void
>> +dump16Bytes(
>> + void *ptr) {
>> + int i;
>> + char buf[3];
>> + uint8_t *bytes = (uint8_t*)ptr;
>> + for (i = 0; i < 16; i++) {
>> + buf[0] = HEX_DIGIT(bytes[i] / 16);
>> + buf[1] = HEX_DIGIT(bytes[i] % 16);
>> + buf[2] = ' ';
>> + write(2, buf, 3);
>> + }
>> + write(2, "\n", 1);
>> }
>> +#endif // DEBUG_DISASM
>> #endif
>>
>> #if defined(__i386__)
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list