Home | History | Annotate | Download | only in unittests
      1 //===- NamePoolTest.cpp ---------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include "NamePoolTest.h"
     10 #include "mcld/LD/NamePool.h"
     11 #include "mcld/LD/Resolver.h"
     12 #include "mcld/LD/StaticResolver.h"
     13 #include "mcld/LD/ResolveInfo.h"
     14 #include "mcld/LD/LDSymbol.h"
     15 #include <llvm/ADT/StringRef.h>
     16 #include <string>
     17 #include <cstdio>
     18 
     19 using namespace mcld;
     20 using namespace mcldtest;
     21 
     22 // Constructor can do set-up work for all test here.
     23 NamePoolTest::NamePoolTest() {
     24   // create testee. modify it if need
     25   StaticResolver resolver;
     26   m_pTestee = new NamePool(resolver, 10);
     27 }
     28 
     29 // Destructor can do clean-up work that doesn't throw exceptions here.
     30 NamePoolTest::~NamePoolTest() {
     31   delete m_pTestee;
     32 }
     33 
     34 // SetUp() will be called immediately before each test.
     35 void NamePoolTest::SetUp() {
     36 }
     37 
     38 // TearDown() will be called immediately after each test.
     39 void NamePoolTest::TearDown() {
     40 }
     41 
     42 //==========================================================================//
     43 // Testcases
     44 //
     45 
     46 TEST_F(NamePoolTest, insertString) {
     47   const char* s1 = "Hello MCLinker";
     48   llvm::StringRef result1 = m_pTestee->insertString(s1);
     49   EXPECT_NE(s1, result1.data());
     50   EXPECT_STREQ(s1, result1.data());
     51 }
     52 
     53 TEST_F(NamePoolTest, insertSameString) {
     54   const char* s1 = "Hello MCLinker";
     55   std::string s2(s1);
     56   llvm::StringRef result1 = m_pTestee->insertString(s1);
     57   llvm::StringRef result2 = m_pTestee->insertString(s2.c_str());
     58   EXPECT_STREQ(s1, result1.data());
     59   EXPECT_STREQ(s2.c_str(), result2.data());
     60   EXPECT_EQ(result1.data(), result2.data());
     61 }
     62 
     63 TEST_F(NamePoolTest, insert_local_defined_Symbol) {
     64   const char* name = "Hello MCLinker";
     65   bool isDyn = false;
     66   ResolveInfo::Type type = ResolveInfo::Function;
     67   ResolveInfo::Desc desc = ResolveInfo::Define;
     68   ResolveInfo::Binding binding = ResolveInfo::Local;
     69   uint64_t value = 0;
     70   uint64_t size = 0;
     71   ResolveInfo::Visibility other = ResolveInfo::Default;
     72   Resolver::Result result1;
     73   m_pTestee->insertSymbol(
     74       name, isDyn, type, desc, binding, size, other, NULL, result1);
     75 
     76   EXPECT_NE(name, result1.info->name());
     77   EXPECT_STREQ(name, result1.info->name());
     78   EXPECT_EQ(isDyn, result1.info->isDyn());
     79   EXPECT_EQ(type, result1.info->type());
     80   EXPECT_EQ(desc, result1.info->desc());
     81   EXPECT_EQ(binding, result1.info->binding());
     82   EXPECT_EQ(size, result1.info->size());
     83   EXPECT_EQ(other, result1.info->visibility());
     84 
     85   Resolver::Result result2;
     86   m_pTestee->insertSymbol(
     87       name, isDyn, type, desc, binding, size, other, NULL, result2);
     88 
     89   EXPECT_NE(name, result1.info->name());
     90   EXPECT_STREQ(name, result1.info->name());
     91   EXPECT_EQ(isDyn, result1.info->isDyn());
     92   EXPECT_EQ(type, result1.info->type());
     93   EXPECT_EQ(desc, result1.info->desc());
     94   EXPECT_EQ(binding, result1.info->binding());
     95   EXPECT_EQ(size, result1.info->size());
     96   EXPECT_EQ(other, result1.info->visibility());
     97 
     98   EXPECT_NE(result1.existent, result2.existent);
     99 }
    100 
    101 TEST_F(NamePoolTest, insert_global_reference_Symbol) {
    102   const char* name = "Hello MCLinker";
    103   bool isDyn = false;
    104   ResolveInfo::Type type = ResolveInfo::NoType;
    105   ResolveInfo::Desc desc = ResolveInfo::Undefined;
    106   ResolveInfo::Binding binding = ResolveInfo::Global;
    107   uint64_t size = 0;
    108   ResolveInfo::Visibility other = ResolveInfo::Default;
    109   Resolver::Result result1;
    110   m_pTestee->insertSymbol(
    111       name, isDyn, type, desc, binding, size, other, NULL, result1);
    112 
    113   EXPECT_NE(name, result1.info->name());
    114   EXPECT_STREQ(name, result1.info->name());
    115   EXPECT_EQ(isDyn, result1.info->isDyn());
    116   EXPECT_EQ(type, result1.info->type());
    117   EXPECT_EQ(desc, result1.info->desc());
    118   EXPECT_EQ(binding, result1.info->binding());
    119   EXPECT_EQ(size, result1.info->size());
    120   EXPECT_EQ(other, result1.info->visibility());
    121 
    122   Resolver::Result result2;
    123   m_pTestee->insertSymbol(
    124       name, isDyn, type, desc, binding, size, other, NULL, result2);
    125 
    126   EXPECT_EQ(result1.info, result2.info);
    127 
    128   Resolver::Result result3;
    129   m_pTestee->insertSymbol("Different Symbol",
    130                           isDyn,
    131                           type,
    132                           desc,
    133                           binding,
    134                           size,
    135                           other,
    136                           NULL,
    137                           result3);
    138 
    139   EXPECT_NE(result1.info, result3.info);
    140 }
    141 
    142 TEST_F(NamePoolTest, insertSymbol_after_insert_same_string) {
    143   const char* name = "Hello MCLinker";
    144   bool isDyn = false;
    145   LDSymbol::Type type = LDSymbol::Defined;
    146   LDSymbol::Binding binding = LDSymbol::Global;
    147   const llvm::MCSectionData* section = 0;
    148   uint64_t value = 0;
    149   uint64_t size = 0;
    150   uint8_t other = 0;
    151 
    152   const char* result1 = m_pTestee->insertString(name);
    153   LDSymbol* sym = m_pTestee->insertSymbol(
    154       name, isDyn, type, binding, section, value, size, other);
    155 
    156   EXPECT_STREQ(name, sym->name());
    157   EXPECT_EQ(result1, sym->name());
    158 
    159   char s[16];
    160   strcpy(s, result1);
    161   const char* result2 = m_pTestee->insertString(result1);
    162   const char* result3 = m_pTestee->insertString(s);
    163 
    164   EXPECT_EQ(result1, result2);
    165   EXPECT_EQ(result1, result3);
    166 }
    167 
    168 TEST_F(NamePoolTest, insert_16384_weak_reference_symbols) {
    169   char name[16];
    170   bool isDyn = false;
    171   LDSymbol::Type type = LDSymbol::Reference;
    172   LDSymbol::Binding binding = LDSymbol::Weak;
    173   const llvm::MCSectionData* section = 0;
    174   uint64_t value = 0;
    175   uint64_t size = 0;
    176   uint8_t other = 0;
    177   strcpy(name, "Hello MCLinker");
    178   LDSymbol* syms[128][128];
    179   for (int i = 0; i < 128; ++i) {
    180     name[0] = i;
    181     for (int j = 0; j < 128; ++j) {
    182       name[1] = j;
    183       syms[i][j] = m_pTestee->insertSymbol(
    184           name, isDyn, type, binding, section, value, size, other);
    185 
    186       ASSERT_STREQ(name, syms[i][j]->name());
    187     }
    188   }
    189   for (int i = 127; i >= 0; --i) {
    190     name[0] = i;
    191     for (int j = 0; j < 128; ++j) {
    192       name[1] = j;
    193       LDSymbol* sym = m_pTestee->insertSymbol(
    194           name, isDyn, type, binding, section, value, size, other);
    195       ASSERT_EQ(sym, syms[i][j]);
    196     }
    197   }
    198   for (int i = 0; i < 128; ++i) {
    199     name[0] = i;
    200     for (int j = 0; j < 128; ++j) {
    201       name[1] = j;
    202       LDSymbol* sym = m_pTestee->insertSymbol(
    203           name, isDyn, type, binding, section, value, size, other);
    204       ASSERT_EQ(sym, syms[i][j]);
    205     }
    206   }
    207 }
    208