/ src / client / mac / handler / testcases / breakpad_nlist_test.cc
breakpad_nlist_test.cc
  1  // Copyright 2008 Google LLC
  2  // Redistribution and use in source and binary forms, with or without
  3  // modification, are permitted provided that the following conditions are
  4  // met:
  5  //
  6  //     * Redistributions of source code must retain the above copyright
  7  // notice, this list of conditions and the following disclaimer.
  8  //     * Redistributions in binary form must reproduce the above
  9  // copyright notice, this list of conditions and the following disclaimer
 10  // in the documentation and/or other materials provided with the
 11  // distribution.
 12  //     * Neither the name of Google LLC nor the names of its
 13  // contributors may be used to endorse or promote products derived from
 14  // this software without specific prior written permission.
 15  //
 16  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 17  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 18  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 19  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 20  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 21  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 22  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 23  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 24  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 26  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27  
 28  //
 29  //  breakpad_nlist_test.cc
 30  //  minidump_test
 31  //
 32  //  Created by Neal Sidhwaney on 4/13/08.
 33  //  Copyright 2008 Google LLC
 34  //
 35  
 36  #ifdef HAVE_CONFIG_H
 37  #include <config.h>  // Must come first
 38  #endif
 39  
 40  #include "client/mac/handler/testcases/breakpad_nlist_test.h"
 41  #include <mach-o/nlist.h>
 42  #include "client/mac/handler/breakpad_nlist_64.h"
 43  
 44  BreakpadNlistTest test1(TEST_INVOCATION(BreakpadNlistTest, CompareToNM));
 45  
 46  BreakpadNlistTest::BreakpadNlistTest(TestInvocation* invocation)
 47      : TestCase(invocation) {
 48  }
 49  
 50  
 51  BreakpadNlistTest::~BreakpadNlistTest() {
 52  }
 53  
 54  void BreakpadNlistTest::CompareToNM() {
 55  #if TARGET_CPU_X86_64
 56    system("/usr/bin/nm -arch x86_64 /usr/lib/dyld > /tmp/dyld-namelist.txt");
 57  #elif TARGET_CPU_PPC64
 58    system("/usr/bin/nm -arch ppc64 /usr/lib/dyld > /tmp/dyld-namelist.txt");
 59  #endif
 60  
 61    FILE* fd = fopen("/tmp/dyld-namelist.txt", "rt");
 62  
 63    char oneNMAddr[30];
 64    char symbolType;
 65    char symbolName[500];
 66    while (!feof(fd)) {
 67      fscanf(fd, "%s %c %s", oneNMAddr, &symbolType, symbolName);
 68      breakpad_nlist symbolList[2];
 69      breakpad_nlist& list = symbolList[0];
 70  
 71      memset(symbolList, 0, sizeof(breakpad_nlist)*2);
 72      const char* symbolNames[2];
 73      symbolNames[0] = (const char*)symbolName;
 74      symbolNames[1] = "\0";
 75      breakpad_nlist_64("/usr/lib/dyld", &list, symbolNames);
 76      uint64_t nmAddr = strtol(oneNMAddr, NULL, 16);
 77      if (!IsSymbolMoreThanOnceInDyld(symbolName)) {
 78        CPTAssert(nmAddr == symbolList[0].n_value);
 79      }
 80    }
 81  
 82    fclose(fd);
 83  }
 84  
 85  bool BreakpadNlistTest::IsSymbolMoreThanOnceInDyld(const char* symbolName) {
 86    // These are the symbols that occur more than once when nm dumps
 87    // the symbol table of /usr/lib/dyld.  Our nlist program returns
 88    // the first address because it's doing a search so we need to exclude
 89    // these from causing the test to fail
 90    const char* multipleSymbols[] = {
 91      "__Z41__static_initialization_and_destruction_0ii",
 92      "___tcf_0",
 93      "___tcf_1",
 94      "_read_encoded_value_with_base",
 95      "_read_sleb128",
 96      "_read_uleb128",
 97      "\0"};
 98  
 99    bool found = false;
100  
101    for (int i = 0; multipleSymbols[i][0]; i++) {
102      if (!strcmp(multipleSymbols[i], symbolName)) {
103        found = true;
104        break;
105      }
106    }
107  
108    return found;
109  }