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
19using namespace mcld;
20using namespace mcldtest;
21
22// Constructor can do set-up work for all test here.
23NamePoolTest::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.
30NamePoolTest::~NamePoolTest() {
31  delete m_pTestee;
32}
33
34// SetUp() will be called immediately before each test.
35void NamePoolTest::SetUp() {
36}
37
38// TearDown() will be called immediately after each test.
39void NamePoolTest::TearDown() {
40}
41
42//==========================================================================//
43// Testcases
44//
45
46TEST_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
53TEST_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
63TEST_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
101TEST_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
142TEST_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
168TEST_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