Coverage for /Syzygy/pe/test_dll.cc

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

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   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 "syzygy/pe/test_dll.h"
  16    :  
  17    :  #include <windows.h>  // NOLINT
  18    :  #include <objbase.h>  // NOLINT
  19    :  #include <winnt.h>  // NOLINT
  20    :  
  21    :  #include <math.h>
  22    :  #include <stdio.h>
  23    :  #include <time.h>
  24    :  
  25    :  #include <cstdlib>
  26    :  
  27    :  #include "base/basictypes.h"
  28    :  
  29    :  // Bring in a data import from export_dll.dll. This will cause a global data
  30    :  // symbol to be emitted pointing to the import entry, but with the type we give
  31    :  // here. If the type is bigger than the entire import table then the data
  32    :  // symbol will be bigger than the block it resolves to. The data must be
  33    :  // explicitly marked dllimport otherwise the linker will treat it as a code
  34    :  // symbol and create a thunk for it.
  35  m :  __declspec(dllimport) extern int kExportedData[1024];
  36    :  
  37    :  // A handful of TLS variables, to cause TLS fixups to appear.
  38  m :  __declspec(thread) int tls_int = 42;
  39  m :  __declspec(thread) int tls_array[64] = { 0 };
  40  m :  __declspec(thread) char tls_string_buffer[512] = { 0 };
  41  m :  __declspec(thread) double tls_double = 3.5;
  42    :  
  43    :  // A dummy TLS Initialization callback handler.
  44  m :  VOID NTAPI MyTlsCallback(PVOID instance, DWORD reason, PVOID reserved) {
  45  m :    ::time(NULL);
  46  m :  }
  47    :  
  48    :  // Declare a TLS initializer callback to the linker.
  49    :  #pragma section(".CRT$XLY",long,read)
  50  m :  extern "C" __declspec(allocate(".CRT$XLY"))
  51  m :    PIMAGE_TLS_CALLBACK _xl_y1  = MyTlsCallback;
  52    :  
  53  m :  extern "C" __declspec(allocate(".CRT$XLY"))
  54  m :    PIMAGE_TLS_CALLBACK _xl_y2  = MyTlsCallback;
  55    :  
  56    :  // Use both mechanisms for importing functions (explicitly hinted with
  57    :  // 'dllimport' and not) so that both code generation mechanisms are present
  58    :  // in the final binary and subsequently tested by our decomposer.
  59  m :  __declspec(dllimport) extern int function1();
  60  m :  extern int function2();
  61  m :  extern int function3();
  62    :  
  63    :  // Import coverage functions.
  64  m :  extern int coverage_func1();
  65  m :  extern int coverage_func2();
  66  m :  extern int coverage_func3();
  67    :  
  68    :  #pragma auto_inline(off)
  69    :  
  70  m :  DWORD WINAPI TestExport(size_t buf_len, char* buf) {
  71  m :    static const char kTestString[] =
  72  m :        "The quick brown fox jumped over the lazy dog";
  73    :  
  74  m :    ::strncpy(buf, kTestString, buf_len);
  75    :  
  76  m :    return 0;
  77  m :  }
  78    :  
  79  m :  DWORD WINAPI BringInOle32DelayLib() {
  80    :    // Reference this from Ole32 to pull in something.
  81  m :    GUID guid = {};
  82  m :    ::CoCreateGuid(&guid);
  83    :  
  84  m :    return 0;
  85  m :  }
  86    :  
  87  m :  const char* BoolToString(bool value) {
  88  m :    return value ? "true" : "false";
  89  m :  }
  90    :  
  91  m :  int FunctionWithInlineAssembly() {
  92  m :    static int datum = 0;
  93  m :    __asm {
  94  m :      mov eax, [datum];
  95  m :      add eax, 1;
  96  m :      mov [datum], eax;
  97  m :    }
  98  m :    return datum;
  99  m :  }
 100    :  
 101    :  #pragma auto_inline()
 102    :  
 103  m :  BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
 104    :    // The goal of the following weird code is to thwart any optimizations
 105    :    // that the compiler might try.
 106    :  
 107    :    // Put a series of calls in order. In general, expect they'll show up in
 108    :    // the same order when we search for references.
 109  m :    function1();
 110  m :    function1();
 111  m :    function3();
 112  m :    function2();
 113  m :    function2();
 114  m :    function3();
 115  m :    function1();
 116  m :    function1();
 117    :  
 118  m :    int foo = FunctionWithInlineAssembly();
 119  m :    foo += kExportedData[0];
 120    :  
 121    :    // We modify the exported data. If imports are improperly thunked this will
 122    :    // cause us to write junk all over any created thunks and should hopefully
 123    :    // cause the instrumented test_dll to explode.
 124  m :    for (size_t i = 0; i < sizeof(kExportedData) / sizeof(kExportedData[0]); ++i)
 125  m :      kExportedData[i] = i;
 126    :  
 127    :    // The following odd code and switch statement are to outsmart the
 128    :    // optimizer and coerce it to generate a case and jump table pair.
 129    :    // On decomposition, we expect to find and label the case and jump
 130    :    // tables individually.
 131  m :    wchar_t c = rand() % static_cast<wchar_t>(-1);
 132    :  
 133    :    // We also need to coerce the optimizer into keeping around kExportedData and
 134    :    // FunctionWithInlineAssembly.
 135  m :    c ^= static_cast<wchar_t>(foo);
 136    :  
 137  m :    bool is_whitespace = false;
 138  m :    bool is_qwerty = false;
 139  m :    bool is_asdfgh = false;
 140  m :    bool is_upper_case = false;
 141  m :    bool is_other = false;
 142    :  
 143    :    // Switch over the UTF16 character space.
 144  m :    switch (c) {
 145  m :     case L'Q':
 146  m :     case L'W':
 147  m :     case L'E':
 148  m :     case L'R':
 149  m :     case L'T':
 150  m :     case L'Y':
 151  m :      is_qwerty = true;
 152  m :      is_upper_case = true;
 153  m :      break;
 154    :  
 155  m :     case L'q':
 156  m :     case L'w':
 157  m :     case L'e':
 158  m :     case L'r':
 159  m :     case L't':
 160  m :     case L'y':
 161  m :      is_qwerty = true;
 162  m :      is_upper_case = false;
 163  m :      break;
 164    :  
 165  m :     case L'A':
 166  m :     case L'S':
 167  m :     case L'D':
 168  m :     case L'F':
 169  m :     case L'G':
 170  m :     case L'H':
 171  m :      is_asdfgh = true;
 172  m :      is_upper_case = true;
 173  m :      break;
 174    :  
 175  m :     case L'a':
 176  m :     case L's':
 177  m :     case L'd':
 178  m :     case L'f':
 179  m :     case L'g':
 180  m :     case L'h':
 181  m :      is_asdfgh = true;
 182  m :      is_upper_case = false;
 183  m :      break;
 184    :  
 185  m :     case ' ':
 186  m :     case '\t':
 187  m :     case '\r':
 188  m :     case '\n':
 189  m :      is_whitespace = true;
 190  m :      break;
 191    :  
 192  m :     default:
 193  m :      is_other = true;
 194  m :      break;
 195  m :    }
 196    :  
 197  m :    char buffer[1024] = {'\0'};
 198  m :    ::memset(buffer, 0, sizeof(buffer));
 199  m :    ::_snprintf(buffer,
 200  m :                sizeof(buffer) - 1,
 201  m :                "is_qwerty=%s\nis_asdfgh=%s\nis_upper_case=%s\nis_whitespace=%s\n"
 202  m :                "is_other=%s",
 203  m :                BoolToString(is_qwerty),
 204  m :                BoolToString(is_asdfgh),
 205  m :                BoolToString(is_upper_case),
 206  m :                BoolToString(is_whitespace),
 207  m :                BoolToString(is_other));
 208    :  
 209  m :    TestExport(sizeof(buffer), buffer);
 210    :  
 211    :    // This code generates a simple jump table with no case table following it.
 212    :  
 213  m :    int n = rand();
 214    :  
 215  m :    switch (n % 3) {
 216  m :      case 0:
 217  m :        n += function1();
 218  m :        break;
 219  m :      case 1:
 220  m :        n += function2();
 221  m :        break;
 222  m :      case 2:
 223  m :        n += function3();
 224  m :        break;
 225  m :      case 3:
 226  m :        n -= function1();
 227  m :        break;
 228  m :      case 4:
 229  m :        n -= function2();
 230  m :        break;
 231  m :      case 5:
 232  m :        n -= function3();
 233  m :        break;
 234  m :    }
 235    :  
 236    :    // The following odd code and switch statement are to outsmart the
 237    :    // optimizer and coerce it to generate another case and jump table
 238    :    // pair. On decomposition, we expect to find and label the case
 239    :    // and jump tables individually.
 240    :  
 241    :    // Access the TLS data so that some TLS FIXUPs are produced.
 242  m :    n += tls_int;
 243  m :    n += tls_array[0];
 244  m :    n += tls_string_buffer[0];
 245  m :    n += static_cast<int>(tls_double);
 246    :  
 247    :    // The case table is a 20X expanded switch on n mod 7.
 248  m :    switch (n % 140) {
 249  m :      case 0:
 250  m :      case 7:
 251  m :      case 14:
 252  m :      case 21:
 253  m :      case 28:
 254  m :      case 35:
 255  m :      case 42:
 256  m :      case 49:
 257  m :      case 56:
 258  m :      case 63:
 259  m :      case 70:
 260  m :      case 77:
 261  m :      case 84:
 262  m :      case 91:
 263  m :      case 98:
 264  m :      case 105:
 265  m :      case 112:
 266  m :      case 119:
 267  m :      case 126:
 268  m :      case 133:
 269  m :        return reinterpret_cast<BOOL>(
 270  m :            function1() + strstr("hello world", "hello"));
 271    :  
 272  m :      case 1:
 273  m :      case 8:
 274  m :      case 15:
 275  m :      case 22:
 276  m :      case 29:
 277  m :      case 36:
 278  m :      case 43:
 279  m :      case 50:
 280  m :      case 57:
 281  m :      case 64:
 282  m :      case 71:
 283  m :      case 78:
 284  m :      case 85:
 285  m :      case 92:
 286  m :      case 99:
 287  m :      case 106:
 288  m :      case 113:
 289  m :      case 120:
 290  m :      case 127:
 291  m :      case 134:
 292  m :        return static_cast<BOOL>(function2() + strlen("foobar"));
 293    :  
 294  m :      case 2:
 295  m :      case 9:
 296  m :      case 16:
 297  m :      case 23:
 298  m :      case 30:
 299  m :      case 37:
 300  m :      case 44:
 301  m :      case 51:
 302  m :      case 58:
 303  m :      case 65:
 304  m :      case 72:
 305  m :      case 79:
 306  m :      case 86:
 307  m :      case 93:
 308  m :      case 100:
 309  m :      case 107:
 310  m :      case 114:
 311  m :      case 121:
 312  m :      case 128:
 313  m :      case 135:
 314  m :        return static_cast<BOOL>(function3() + clock());
 315    :  
 316  m :      case 3:
 317  m :      case 10:
 318  m :      case 17:
 319  m :      case 24:
 320  m :      case 31:
 321  m :      case 38:
 322  m :      case 45:
 323  m :      case 52:
 324  m :      case 59:
 325  m :      case 66:
 326  m :      case 73:
 327  m :      case 80:
 328  m :      case 87:
 329  m :      case 94:
 330  m :      case 101:
 331  m :      case 108:
 332  m :      case 115:
 333  m :      case 122:
 334  m :      case 129:
 335  m :      case 136:
 336  m :        return static_cast<BOOL>(function1() + function2() +
 337  m :            reinterpret_cast<int>(memchr("hello", 'e', 5)));
 338    :  
 339  m :      case 4:
 340  m :      case 11:
 341  m :      case 18:
 342  m :      case 25:
 343  m :      case 32:
 344  m :      case 39:
 345  m :      case 46:
 346  m :      case 53:
 347  m :      case 60:
 348  m :      case 67:
 349  m :      case 74:
 350  m :      case 81:
 351  m :      case 88:
 352  m :      case 95:
 353  m :      case 102:
 354  m :      case 109:
 355  m :      case 116:
 356  m :      case 123:
 357  m :      case 130:
 358  m :      case 137:
 359  m :        return static_cast<BOOL>(function1() + function3() + abs(-3));
 360    :  
 361  m :      case 5:
 362  m :      case 12:
 363  m :      case 19:
 364  m :      case 26:
 365  m :      case 33:
 366  m :      case 40:
 367  m :      case 47:
 368  m :      case 54:
 369  m :      case 61:
 370  m :      case 68:
 371  m :      case 75:
 372  m :      case 82:
 373  m :      case 89:
 374  m :      case 96:
 375  m :      case 103:
 376  m :      case 110:
 377  m :      case 117:
 378  m :      case 124:
 379  m :      case 131:
 380  m :      case 138:
 381  m :        return static_cast<BOOL>(
 382  m :            function2() + function3() + static_cast<int>(floor(1.3)));
 383    :  
 384  m :      case 6:
 385  m :      case 13:
 386  m :      case 20:
 387  m :      case 27:
 388  m :      case 34:
 389  m :      case 41:
 390  m :      case 48:
 391  m :      case 55:
 392  m :      case 62:
 393  m :      case 69:
 394  m :      case 76:
 395  m :      case 83:
 396  m :      case 90:
 397  m :      case 97:
 398  m :      case 104:
 399  m :      case 111:
 400  m :      case 118:
 401  m :      case 125:
 402  m :      case 132:
 403  m :      case 139:
 404  m :        return static_cast<BOOL>(
 405  m :            function1() + function2() + function3() + atoi("7"));
 406  m :    }
 407  m :  }
 408    :  
 409  m :  void used_operation() {
 410  m :    function1();
 411  m :    function2();
 412  m :    function3();
 413  m :  }
 414    :  
 415    :  // This won't be called.
 416  m :  void unused_operation() {
 417  m :    char dummy[512];
 418  m :    TestExport(sizeof(dummy), dummy);
 419  m :  }
 420    :  
 421  m :  class Used {
 422  m :   public:
 423  m :    Used() {}
 424  m :    virtual ~Used() {}
 425  m :    virtual void M() {
 426  m :      used_operation();
 427  m :    }
 428  m :  };
 429    :  
 430    :  // Unused::M() won't be called.
 431  m :  class Unused : public Used {
 432  m :   public:
 433  m :    virtual void M() {
 434  m :      unused_operation();
 435  m :    }
 436  m :  };
 437    :  
 438  m :  void CALLBACK TestUnusedFuncs(HWND unused_window,
 439  m :                                HINSTANCE unused_instance,
 440  m :                                LPSTR unused_cmd_line,
 441  m :                                int unused_show) {
 442  m :    bool call_it = time(NULL) > 10000;  // true unless you play with the clock.
 443    :  
 444  m :    (call_it ? used_operation : unused_operation)();
 445    :  
 446  m :    Used a;
 447  m :    Unused b;
 448  m :    (call_it ? &a : &b)->M();
 449  m :  }
 450    :  
 451  m :  DWORD FuncWithOffsetOutOfImage(int x, int y) {
 452  m :    static const int kArray[4][256] = {};
 453  m :    static const int kBigNum = 0xB0000000;
 454  m :    return kArray[x][y + kBigNum];
 455  m :  }
 456    :  
 457  m :  static unsigned int ArrayComputation1() {
 458    :    // Dummy function to validate end to end instrumentation.
 459  m :    const size_t kBufferLength = 1024;
 460  m :    char A[kBufferLength];
 461  m :    short B[kBufferLength];
 462  m :    int C[kBufferLength];
 463    :  
 464  m :    for (size_t i = 0; i < kBufferLength; ++i) {
 465  m :      if (i == 0)
 466  m :        A[i] = 0;
 467  m :      else
 468  m :        A[i] = 3*A[i-1] + 11;
 469  m :    }
 470    :  
 471  m :    for (size_t i = 0; i < kBufferLength; ++i) {
 472  m :      B[i] = i;
 473  m :      B[i] += A[i];
 474  m :      B[i] = (B[i] << 1) ^ B[i];
 475  m :    }
 476    :  
 477  m :    for (size_t i = 0; i < kBufferLength; ++i) {
 478  m :      C[i] = i;
 479  m :      C[i] += A[i] + B[i];
 480  m :      C[i] = ~C[i];
 481  m :    }
 482    :  
 483  m :    unsigned int sum = 0;
 484  m :    for (int i = 0; i < kBufferLength; ++i) {
 485  m :      sum += C[i] - (A[i] - B[i]);
 486  m :    }
 487    :  
 488  m :    return sum;
 489  m :  }
 490    :  
 491  m :  static unsigned int ArrayComputation2() {
 492    :    // Dummy function to validate end to end instrumentation.
 493  m :    const size_t kBufferLength = 1024;
 494  m :    int A[kBufferLength];
 495    :  
 496  m :    for (size_t i = 0; i < kBufferLength; ++i) {
 497  m :      A[i] = i;
 498  m :    }
 499    :  
 500  m :    int *ptr1 = &A[0];
 501  m :    int *ptr2 = &A[kBufferLength-1];
 502  m :    int result = 0;
 503  m :    while (*ptr1 <= *ptr2) {
 504  m :      ptr1++;
 505  m :      ptr2--;
 506  m :      result++;
 507  m :    }
 508    :  
 509  m :    return result;
 510  m :  }
 511    :  
 512    :  // NOTE: This is used to fool compiler aliasing analysis. Do not make it static
 513    :  //    nor const.
 514  m :  int kOffsetMinusOne = -1;
 515  m :  int kOffetZero = 0;
 516  m :  int kOffetOne = 1;
 517    :  
 518  m :  template<typename type>
 519  m :  static type AsanWriteBufferOverflow() {
 520    :    // Produce an ASAN error by writing one after the buffer.
 521  m :    type* ptr = new type[1];
 522  m :    ptr[kOffetZero] = static_cast<type>(1);
 523  m :    ptr[kOffetOne] = static_cast<type>(2);
 524  m :    type result = ptr[kOffetZero];
 525  m :    delete ptr;
 526  m :    return result;
 527  m :  }
 528    :  
 529  m :  template<typename type>
 530  m :  static type AsanWriteBufferUnderflow() {
 531    :    // Produce an ASAN error by writing one before the buffer.
 532  m :    type* ptr = new type[1];
 533  m :    ptr[kOffsetMinusOne] = static_cast<type>(1);
 534  m :    ptr[kOffetZero] = static_cast<type>(2);
 535  m :    type result = ptr[kOffetZero];
 536  m :    delete ptr;
 537  m :    return result;
 538  m :  }
 539    :  
 540  m :  template<typename type>
 541  m :  static type AsanReadBufferOverflow() {
 542    :    // Produce an ASAN error by reading one after the buffer.
 543  m :    type* ptr = new type[1];
 544  m :    *ptr = static_cast<type>(42);
 545  m :    type result = ptr[kOffetZero] + ptr[kOffetOne];
 546  m :    delete ptr;
 547  m :    return result;
 548  m :  }
 549    :  
 550  m :  template<typename type>
 551  m :  static type AsanReadBufferUnderflow() {
 552    :    // Produce an ASAN error by reading one before the buffer.
 553  m :    type* ptr = new type[1];
 554  m :    *ptr = static_cast<type>(42);
 555  m :    type result = ptr[kOffetZero] + ptr[kOffsetMinusOne];
 556  m :    delete ptr;
 557  m :    return result;
 558  m :  }
 559    :  
 560  m :  template<typename type>
 561  m :  static type AsanReadUseAfterFree() {
 562    :    // Produce an ASAN error by reading memory after deleting it.
 563  m :    type* ptr = new type[1];
 564  m :    *ptr = static_cast<type>(42);
 565  m :    delete ptr;
 566  m :    type result = ptr[kOffetZero];
 567  m :    return result;
 568  m :  }
 569    :  
 570  m :  template<typename type>
 571  m :  static type AsanWriteUseAfterFree() {
 572    :    // Produce an ASAN error by writing memory after deleting it.
 573  m :    type* ptr = new type[1];
 574  m :    *ptr = static_cast<type>(42);
 575  m :    type result = *ptr;
 576  m :    delete ptr;
 577  m :    ptr[kOffetZero] = static_cast<type>(12);
 578  m :    return result;
 579  m :  }
 580    :  
 581    :  
 582    :  // Functions below are used to test basic block counting in the end to end
 583    :  // unittest. We assume the compiler won't simplify any calls.
 584    :  
 585    :  // Avoiding global optimization.
 586    :  #pragma optimize("g", off)
 587    :  
 588  m :  extern "C" unsigned int BBEntryCallOnce() {
 589  m :    return 42;
 590  m :  }
 591    :  
 592  m :  extern "C" unsigned int BBEntryFunction1() {
 593  m :    return 10;
 594  m :  }
 595    :  
 596  m :  extern "C" unsigned int BBEntryFunction2() {
 597  m :    return BBEntryFunction1() + BBEntryFunction1();
 598  m :  }
 599    :  
 600  m :  extern "C" unsigned int BBEntryFunction3() {
 601  m :    return BBEntryFunction2() + BBEntryFunction2();
 602  m :  }
 603    :  
 604  m :  extern "C" unsigned int BBEntryCallTree() {
 605  m :    return BBEntryFunction3() + 2;
 606  m :  }
 607    :  
 608  m :  extern "C" unsigned int BBEntryFunctionRecursive(int n) {
 609  m :    if (n == 1)
 610  m :      return 1;
 611  m :    return BBEntryFunctionRecursive(n - 1) + 1;
 612  m :  }
 613    :  
 614  m :  extern "C" unsigned int BBEntryCallRecursive() {
 615  m :    return BBEntryFunctionRecursive(42);
 616  m :  }
 617    :  
 618  m :  unsigned int CALLBACK EndToEndTest(EndToEndTestId test) {
 619    :    // This function is used to dispatch test id to its corresponding function.
 620  m :    switch (test) {
 621    :      // Behavior tests.
 622  m :      case kArrayComputation1TestId:
 623  m :        return ArrayComputation1();
 624  m :      case kArrayComputation2TestId:
 625  m :        return ArrayComputation2();
 626    :  
 627    :      // Asan Memory Error.
 628  m :      case kAsanRead8BufferOverflowTestId:
 629  m :        return AsanReadBufferOverflow<int8>();
 630  m :      case kAsanRead16BufferOverflowTestId:
 631  m :        return AsanReadBufferOverflow<int16>();
 632  m :      case kAsanRead32BufferOverflowTestId:
 633  m :        return AsanReadBufferOverflow<int32>();
 634  m :      case kAsanRead64BufferOverflowTestId:
 635  m :        return AsanReadBufferOverflow<double>();
 636    :  
 637  m :      case kAsanRead8BufferUnderflowTestId:
 638  m :        return AsanReadBufferUnderflow<int8>();
 639  m :      case kAsanRead16BufferUnderflowTestId:
 640  m :        return AsanReadBufferUnderflow<int16>();
 641  m :      case kAsanRead32BufferUnderflowTestId:
 642  m :        return AsanReadBufferUnderflow<int32>();
 643  m :      case kAsanRead64BufferUnderflowTestId:
 644  m :        return AsanReadBufferUnderflow<double>();
 645    :  
 646  m :      case kAsanWrite8BufferOverflowTestId:
 647  m :        return AsanWriteBufferOverflow<int8>();
 648  m :      case kAsanWrite16BufferOverflowTestId:
 649  m :        return AsanWriteBufferOverflow<int16>();
 650  m :      case kAsanWrite32BufferOverflowTestId:
 651  m :        return AsanWriteBufferOverflow<int32>();
 652  m :      case kAsanWrite64BufferOverflowTestId:
 653  m :        return AsanWriteBufferOverflow<double>();
 654    :  
 655  m :      case kAsanWrite8BufferUnderflowTestId:
 656  m :        return AsanWriteBufferUnderflow<int8>();
 657  m :      case kAsanWrite16BufferUnderflowTestId:
 658  m :        return AsanWriteBufferUnderflow<int16>();
 659  m :      case kAsanWrite32BufferUnderflowTestId:
 660  m :        return AsanWriteBufferUnderflow<int32>();
 661  m :      case kAsanWrite64BufferUnderflowTestId:
 662  m :        return AsanWriteBufferUnderflow<double>();
 663    :  
 664  m :      case kAsanRead8UseAfterFreeTestId:
 665  m :        return AsanReadUseAfterFree<int8>();
 666  m :      case kAsanRead16UseAfterFreeTestId:
 667  m :        return AsanReadUseAfterFree<int16>();
 668  m :      case kAsanRead32UseAfterFreeTestId:
 669  m :        return AsanReadUseAfterFree<int32>();
 670  m :      case kAsanRead64UseAfterFreeTestId:
 671  m :        return AsanReadUseAfterFree<double>();
 672    :  
 673  m :      case kAsanWrite8UseAfterFreeTestId:
 674  m :        return AsanWriteUseAfterFree<int8>();
 675  m :      case kAsanWrite16UseAfterFreeTestId:
 676  m :        return AsanWriteUseAfterFree<int16>();
 677  m :      case kAsanWrite32UseAfterFreeTestId:
 678  m :        return AsanWriteUseAfterFree<int32>();
 679  m :      case kAsanWrite64UseAfterFreeTestId:
 680  m :        return AsanWriteUseAfterFree<double>();
 681    :  
 682  m :      case kBBEntryCallOnce:
 683  m :        return BBEntryCallOnce();
 684  m :      case kBBEntryCallTree:
 685  m :        return BBEntryCallTree();
 686  m :      case kBBEntryCallRecursive:
 687  m :        return BBEntryCallRecursive();
 688    :  
 689  m :      case kCoverage1:
 690  m :        return coverage_func1();
 691  m :      case kCoverage2:
 692  m :        return coverage_func2();
 693  m :      case kCoverage3:
 694  m :        return coverage_func3();
 695  m :    }
 696  m :    return 0;
 697  m :  }

Coverage information generated Thu Jul 04 09:34:53 2013.