brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · ff3a1a4 Raw
136 lines · c
1// REQUIRES: x86-registered-target2 3// This verifies that global variable redirection works correctly when using hotpatching.4//5// RUN: %clang_cl -c --target=x86_64-windows-msvc -O2 /Z7 \6// RUN:   -fms-secure-hotpatch-functions-list=hp1,hp2,hp3,hp4,hp5_phi_ptr_mixed,hp_phi_ptr_both,hp_const_ptr_sub \7// RUN:   /clang:-S /clang:-o- -- %s | FileCheck %s8 9#ifdef __clang__10#define NO_TAIL __attribute__((disable_tail_calls))11#else12#define NO_TAIL13#endif14 15extern int g_data[10];16 17struct SomeData {18    int x;19    int y;20};21 22const struct SomeData g_this_is_const = { 100, 200 };23 24struct HasPointers {25    int* ptr;26    int x;27};28 29extern struct HasPointers g_has_pointers;30 31void take_data(const void* p);32 33void do_side_effects();34void do_other_side_effects();35 36void hp1() NO_TAIL {37    take_data(&g_data[5]);38}39 40// CHECK: hp1:41// CHECK: mov rcx, qword ptr [rip + __ref_g_data]42// CHECK: add rcx, 2043// CHECK: call take_data44// CHECK: .seh_endproc45 46void hp2() NO_TAIL {47    // We do not expect string literals to be redirected.48    take_data("hello, world!");49}50 51// CHECK: hp2:52// CHECK: lea rcx, [rip + "??_C@_0O@KJBLMJCB@hello?0?5world?$CB?$AA@"]53// CHECK: call take_data54// CHECK: .seh_endproc55 56void hp3() NO_TAIL {57    // We do not expect g_this_is_const to be redirected because it is const58    // and contains no pointers.59    take_data(&g_this_is_const);60}61 62// CHECK: hp3:63// CHECK: lea rcx, [rip + g_this_is_const]64// CHECK: call take_data65// CHECK-NOT: __ref_g_this_is_const66// CHECK: .seh_endproc67 68void hp4() NO_TAIL {69    take_data(&g_has_pointers);70    // We expect &g_has_pointers to be redirected.71}72 73// CHECK: hp4:74// CHECK: mov rcx, qword ptr [rip + __ref_g_has_pointers]75// CHECK: call take_data76// CHECK: .seh_endproc77 78// This case checks that global variable redirection interacts correctly with PHI nodes.79// The IR for this generates a "phi ptr g_has_pointers, g_this_is_const" node.80// We expect g_has_pointers to be redirected, but not g_this_is_const.81void hp5_phi_ptr_mixed(int x) NO_TAIL {82    const void* y;83    if (x) {84        y = &g_has_pointers;85        do_side_effects();86    } else {87        y = &g_this_is_const;88        do_other_side_effects();89    }90    take_data(y);91}92 93// CHECK: hp5_phi_ptr_mixed94// CHECK: .seh_endprologue95// CHECK: test ecx, ecx96// CHECK: mov rsi, qword ptr [rip + __ref_g_has_pointers]97// CHECK: call do_side_effects98// CHECK: jmp99// CHECK: call do_other_side_effects100// CHECK: lea rsi, [rip + g_this_is_const]101// CHECK: mov rcx, rsi102// CHECK: call take_data103// CHECK: .seh_endproc104 105// This case tests that global variable redirection interacts correctly with PHI nodes,106// where two (all) operands of a given PHI node are globabl variables that redirect.107void hp_phi_ptr_both(int x) NO_TAIL {108    const void* y;109    if (x) {110        y = &g_has_pointers;111        do_side_effects();112    } else {113        y = &g_data[5];114        do_other_side_effects();115    }116    take_data(y);117}118 119// CHECK: hp_phi_ptr_both:120// CHECK: .seh_endprologue121// CHECK: test ecx, ecx122// CHECK: mov rsi, qword ptr [rip + __ref_g_has_pointers]123// CHECK: mov rsi, qword ptr [rip + __ref_g_data]124// CHECK: take_data125// CHECK: .seh_endproc126 127// Test a constant expression which references global variable addresses.128size_t hp_const_ptr_sub() NO_TAIL {129    return (unsigned char*)&g_has_pointers - (unsigned char*)&g_data;130}131 132// CHECK: hp_const_ptr_sub:133// CHECK: mov rax, qword ptr [rip + __ref_g_has_pointers]134// CHECK: sub rax, qword ptr [rip + __ref_g_data]135// CHECK: ret136