Coverage for /Syzygy/pe/test_dll.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%00303.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include <windows.h>  // NOLINT
  16    :  #include <objbase.h>  // NOLINT
  17    :  #include <winnt.h>  // NOLINT
  18    :  
  19    :  #include <math.h>
  20    :  #include <stdio.h>
  21    :  #include <time.h>
  22    :  
  23    :  #include <cstdlib>
  24    :  
  25    :  // A handful of TLS variables, to cause TLS fixups to appear.
  26  m :  __declspec(thread) int tls_int = 42;
  27  m :  __declspec(thread) int tls_array[64] = { 0 };
  28  m :  __declspec(thread) char tls_string_buffer[512] = { 0 };
  29  m :  __declspec(thread) double tls_double = 3.5;
  30    :  
  31    :  // A dummy TLS Initialization callback handler.
  32  m :  VOID NTAPI MyTlsCallback(PVOID instance, DWORD reason, PVOID reserved) {
  33  m :    ::time(NULL);
  34  m :  }
  35    :  
  36    :  // Declare a TLS initializer callback to the linker.
  37    :  #pragma section(".CRT$XLY",long,read)
  38  m :  extern "C" __declspec(allocate(".CRT$XLY"))
  39  m :    PIMAGE_TLS_CALLBACK _xl_y1  = MyTlsCallback;
  40    :  
  41  m :  extern "C" __declspec(allocate(".CRT$XLY"))
  42  m :    PIMAGE_TLS_CALLBACK _xl_y2  = MyTlsCallback;
  43    :  
  44  m :  extern int function1();
  45  m :  extern int function2();
  46  m :  extern int function3();
  47    :  
  48    :  #pragma auto_inline(off)
  49    :  
  50  m :  DWORD WINAPI TestExport(size_t buf_len, char* buf) {
  51  m :    static const char kTestString[] =
  52  m :        "The quick brown fox jumped over the lazy dog";
  53    :  
  54  m :    ::strncpy(buf, kTestString, buf_len);
  55    :  
  56  m :    return 0;
  57  m :  }
  58    :  
  59  m :  DWORD WINAPI BringInOle32DelayLib() {
  60    :    // Reference this from Ole32 to pull in something.
  61  m :    ::CoInitialize(NULL);
  62    :  
  63  m :    return 0;
  64  m :  }
  65    :  
  66  m :  const char* BoolToString(bool value) {
  67  m :    return value ? "true" : "false";
  68  m :  }
  69    :  
  70  m :  int FunctionWithInlineAssembly() {
  71  m :    static int datum = 0;
  72  m :    __asm {
  73  m :      mov eax, [datum];
  74  m :      add eax, 1;
  75  m :      mov [datum], eax;
  76  m :    }
  77  m :    return datum;
  78  m :  }
  79    :  
  80    :  #pragma auto_inline()
  81    :  
  82  m :  BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
  83    :    // The goal of the following weird code is to thwart any optimizations
  84    :    // that the compiler might try.
  85    :  
  86    :    // Put a series of calls in order. In general, expect they'll show up in
  87    :    // the same order when we search for references.
  88  m :    function1();
  89  m :    function1();
  90  m :    function3();
  91  m :    function2();
  92  m :    function2();
  93  m :    function3();
  94  m :    function1();
  95  m :    function1();
  96    :  
  97  m :    int foo = FunctionWithInlineAssembly();
  98    :  
  99    :    // The following odd code and switch statement are to outsmart the
 100    :    // optimizer and coerce it to generate a case and jump table pair.
 101    :    // On decomposition, we expect to find and label the case and jump
 102    :    // tables individually.
 103  m :    wchar_t c = rand() % static_cast<wchar_t>(-1);
 104  m :    bool is_whitespace = false;
 105  m :    bool is_qwerty = false;
 106  m :    bool is_asdfgh = false;
 107  m :    bool is_upper_case = false;
 108  m :    bool is_other = false;
 109    :  
 110    :    // Switch over the UTF16 character space.
 111  m :    switch (c) {
 112  m :     case L'Q':
 113  m :     case L'W':
 114  m :     case L'E':
 115  m :     case L'R':
 116  m :     case L'T':
 117  m :     case L'Y':
 118  m :      is_qwerty = true;
 119  m :      is_upper_case = true;
 120  m :      break;
 121    :  
 122  m :     case L'q':
 123  m :     case L'w':
 124  m :     case L'e':
 125  m :     case L'r':
 126  m :     case L't':
 127  m :     case L'y':
 128  m :      is_qwerty = true;
 129  m :      is_upper_case = false;
 130  m :      break;
 131    :  
 132  m :     case L'A':
 133  m :     case L'S':
 134  m :     case L'D':
 135  m :     case L'F':
 136  m :     case L'G':
 137  m :     case L'H':
 138  m :      is_asdfgh = true;
 139  m :      is_upper_case = true;
 140  m :      break;
 141    :  
 142  m :     case L'a':
 143  m :     case L's':
 144  m :     case L'd':
 145  m :     case L'f':
 146  m :     case L'g':
 147  m :     case L'h':
 148  m :      is_asdfgh = true;
 149  m :      is_upper_case = false;
 150  m :      break;
 151    :  
 152  m :     case ' ':
 153  m :     case '\t':
 154  m :     case '\r':
 155  m :     case '\n':
 156  m :      is_whitespace = true;
 157  m :      break;
 158    :  
 159  m :     default:
 160  m :      is_other = true;
 161  m :      break;
 162  m :    }
 163    :  
 164  m :    char buffer[1024] = {'\0'};
 165  m :    ::memset(buffer, 0, sizeof(buffer));
 166  m :    ::_snprintf(buffer,
 167  m :                sizeof(buffer) - 1,
 168  m :                "is_qwerty=%s\nis_asdfgh=%s\nis_upper_case=%s\nis_whitespace=%s\n"
 169  m :                "is_other=%s",
 170  m :                BoolToString(is_qwerty),
 171  m :                BoolToString(is_asdfgh),
 172  m :                BoolToString(is_upper_case),
 173  m :                BoolToString(is_whitespace),
 174  m :                BoolToString(is_other));
 175    :  
 176  m :    TestExport(sizeof(buffer), buffer);
 177    :  
 178    :    // The following odd code and switch statement are to outsmart the
 179    :    // optimizer and coerce it to generate another case and jump table
 180    :    // pair. On decomposition, we expect to find and label the case
 181    :    // and jump tables individually.
 182  m :    int n = rand();
 183    :  
 184    :    // Access the TLS data so that some TLS FIXUPs are produced.
 185  m :    n += tls_int;
 186  m :    n += tls_array[0];
 187  m :    n += tls_string_buffer[0];
 188  m :    n += static_cast<int>(tls_double);
 189    :  
 190    :    // The case table is a 20X expanded switch on n mod 7.
 191  m :    switch (n % 140) {
 192  m :      case 0:
 193  m :      case 7:
 194  m :      case 14:
 195  m :      case 21:
 196  m :      case 28:
 197  m :      case 35:
 198  m :      case 42:
 199  m :      case 49:
 200  m :      case 56:
 201  m :      case 63:
 202  m :      case 70:
 203  m :      case 77:
 204  m :      case 84:
 205  m :      case 91:
 206  m :      case 98:
 207  m :      case 105:
 208  m :      case 112:
 209  m :      case 119:
 210  m :      case 126:
 211  m :      case 133:
 212  m :        return reinterpret_cast<BOOL>(
 213  m :            function1() + strstr("hello world", "hello"));
 214    :  
 215  m :      case 1:
 216  m :      case 8:
 217  m :      case 15:
 218  m :      case 22:
 219  m :      case 29:
 220  m :      case 36:
 221  m :      case 43:
 222  m :      case 50:
 223  m :      case 57:
 224  m :      case 64:
 225  m :      case 71:
 226  m :      case 78:
 227  m :      case 85:
 228  m :      case 92:
 229  m :      case 99:
 230  m :      case 106:
 231  m :      case 113:
 232  m :      case 120:
 233  m :      case 127:
 234  m :      case 134:
 235  m :        return static_cast<BOOL>(function2() + strlen("foobar"));
 236    :  
 237  m :      case 2:
 238  m :      case 9:
 239  m :      case 16:
 240  m :      case 23:
 241  m :      case 30:
 242  m :      case 37:
 243  m :      case 44:
 244  m :      case 51:
 245  m :      case 58:
 246  m :      case 65:
 247  m :      case 72:
 248  m :      case 79:
 249  m :      case 86:
 250  m :      case 93:
 251  m :      case 100:
 252  m :      case 107:
 253  m :      case 114:
 254  m :      case 121:
 255  m :      case 128:
 256  m :      case 135:
 257  m :        return static_cast<BOOL>(function3() + clock());
 258    :  
 259  m :      case 3:
 260  m :      case 10:
 261  m :      case 17:
 262  m :      case 24:
 263  m :      case 31:
 264  m :      case 38:
 265  m :      case 45:
 266  m :      case 52:
 267  m :      case 59:
 268  m :      case 66:
 269  m :      case 73:
 270  m :      case 80:
 271  m :      case 87:
 272  m :      case 94:
 273  m :      case 101:
 274  m :      case 108:
 275  m :      case 115:
 276  m :      case 122:
 277  m :      case 129:
 278  m :      case 136:
 279  m :        return static_cast<BOOL>(function1() + function2() +
 280  m :            reinterpret_cast<int>(memchr("hello", 'e', 5)));
 281    :  
 282  m :      case 4:
 283  m :      case 11:
 284  m :      case 18:
 285  m :      case 25:
 286  m :      case 32:
 287  m :      case 39:
 288  m :      case 46:
 289  m :      case 53:
 290  m :      case 60:
 291  m :      case 67:
 292  m :      case 74:
 293  m :      case 81:
 294  m :      case 88:
 295  m :      case 95:
 296  m :      case 102:
 297  m :      case 109:
 298  m :      case 116:
 299  m :      case 123:
 300  m :      case 130:
 301  m :      case 137:
 302  m :        return static_cast<BOOL>(function1() + function3() + abs(-3));
 303    :  
 304  m :      case 5:
 305  m :      case 12:
 306  m :      case 19:
 307  m :      case 26:
 308  m :      case 33:
 309  m :      case 40:
 310  m :      case 47:
 311  m :      case 54:
 312  m :      case 61:
 313  m :      case 68:
 314  m :      case 75:
 315  m :      case 82:
 316  m :      case 89:
 317  m :      case 96:
 318  m :      case 103:
 319  m :      case 110:
 320  m :      case 117:
 321  m :      case 124:
 322  m :      case 131:
 323  m :      case 138:
 324  m :        return static_cast<BOOL>(
 325  m :            function2() + function3() + static_cast<int>(floor(1.3)));
 326    :  
 327  m :      case 6:
 328  m :      case 13:
 329  m :      case 20:
 330  m :      case 27:
 331  m :      case 34:
 332  m :      case 41:
 333  m :      case 48:
 334  m :      case 55:
 335  m :      case 62:
 336  m :      case 69:
 337  m :      case 76:
 338  m :      case 83:
 339  m :      case 90:
 340  m :      case 97:
 341  m :      case 104:
 342  m :      case 111:
 343  m :      case 118:
 344  m :      case 125:
 345  m :      case 132:
 346  m :      case 139:
 347  m :        return static_cast<BOOL>(
 348  m :            function1() + function2() + function3() + atoi("7"));
 349  m :    }
 350  m :  }
 351    :  
 352  m :  void used_operation() {
 353  m :    function1();
 354  m :    function2();
 355  m :    function3();
 356  m :  }
 357    :  
 358    :  // This won't be called.
 359  m :  void unused_operation() {
 360  m :    char dummy[512];
 361  m :    TestExport(sizeof(dummy), dummy);
 362  m :  }
 363    :  
 364  m :  class Used {
 365  m :   public:
 366  m :    Used() {}
 367  m :    virtual ~Used() {}
 368  m :    virtual void M() {
 369  m :      used_operation();
 370  m :    }
 371  m :  };
 372    :  
 373    :  // Unused::M() won't be called.
 374  m :  class Unused : public Used {
 375  m :   public:
 376  m :    virtual void M() {
 377  m :      unused_operation();
 378  m :    }
 379  m :  };
 380    :  
 381  m :  void CALLBACK TestUnusedFuncs(HWND unused_window,
 382  m :                                HINSTANCE unused_instance,
 383  m :                                LPSTR unused_cmd_line,
 384  m :                                int unused_show) {
 385  m :    bool call_it = time(NULL) > 10000;  // true unless you play with the clock.
 386    :  
 387  m :    (call_it ? used_operation : unused_operation)();
 388    :  
 389  m :    Used a;
 390  m :    Unused b;
 391  m :    (call_it ? &a : &b)->M();
 392  m :  }

Coverage information generated Thu Sep 06 11:30:46 2012.