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
23// Constructor can do set-up work for all test here.
24NamePoolTest::NamePoolTest()
25{
26  // create testee. modify it if need
27  StaticResolver resolver;
28  m_pTestee = new NamePool(resolver, 10);
29}
30
31// Destructor can do clean-up work that doesn't throw exceptions here.
32NamePoolTest::~NamePoolTest()
33{
34  delete m_pTestee;
35}
36
37// SetUp() will be called immediately before each test.
38void NamePoolTest::SetUp()
39{
40}
41
42// TearDown() will be called immediately after each test.
43void NamePoolTest::TearDown()
44{
45}
46
47//==========================================================================//
48// Testcases
49//
50
51
52TEST_F( NamePoolTest, insertString ) {
53  const char *s1 = "Hello MCLinker";
54  llvm::StringRef result1 = m_pTestee->insertString(s1);
55  EXPECT_NE(s1, result1.data());
56  EXPECT_STREQ(s1, result1.data());
57}
58
59TEST_F( NamePoolTest, insertSameString ) {
60  const char *s1 = "Hello MCLinker";
61  std::string s2(s1);
62  llvm::StringRef result1 = m_pTestee->insertString(s1);
63  llvm::StringRef result2 = m_pTestee->insertString(s2.c_str());
64  EXPECT_STREQ(s1, result1.data());
65  EXPECT_STREQ(s2.c_str(), result2.data());
66  EXPECT_EQ(result1.data(), result2.data());
67}
68
69TEST_F( NamePoolTest, insert_local_defined_Symbol ) {
70  const char *name = "Hello MCLinker";
71  bool isDyn = false;
72  ResolveInfo::Type type = ResolveInfo::Function;
73  ResolveInfo::Desc desc = ResolveInfo::Define;
74  ResolveInfo::Binding binding = ResolveInfo::Local;
75  uint64_t value = 0;
76  uint64_t size = 0;
77  ResolveInfo::Visibility other = ResolveInfo::Default;
78  Resolver::Result result1;
79  m_pTestee->insertSymbol(name,
80                          isDyn,
81                          type,
82                          desc,
83                          binding,
84                          size,
85                          other,
86                          NULL,
87                          result1);
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  Resolver::Result result2;
99  m_pTestee->insertSymbol(name,
100                          isDyn,
101                          type,
102                          desc,
103                          binding,
104                          size,
105                          other,
106                          NULL,
107                          result2);
108
109  EXPECT_NE(name, result1.info->name());
110  EXPECT_STREQ(name, result1.info->name());
111  EXPECT_EQ(isDyn, result1.info->isDyn());
112  EXPECT_EQ(type, result1.info->type());
113  EXPECT_EQ(desc, result1.info->desc());
114  EXPECT_EQ(binding, result1.info->binding());
115  EXPECT_EQ(size, result1.info->size());
116  EXPECT_EQ(other, result1.info->visibility());
117
118  EXPECT_NE(result1.existent, result2.existent);
119}
120
121TEST_F( NamePoolTest, insert_global_reference_Symbol ) {
122  const char *name = "Hello MCLinker";
123  bool isDyn = false;
124  ResolveInfo::Type type = ResolveInfo::NoType;
125  ResolveInfo::Desc desc = ResolveInfo::Undefined;
126  ResolveInfo::Binding binding = ResolveInfo::Global;
127  uint64_t size = 0;
128  ResolveInfo::Visibility other = ResolveInfo::Default;
129  Resolver::Result result1;
130  m_pTestee->insertSymbol(name,
131                          isDyn,
132                          type,
133                          desc,
134                          binding,
135                          size,
136                          other,
137                          NULL,
138                          result1);
139
140  EXPECT_NE(name, result1.info->name());
141  EXPECT_STREQ(name, result1.info->name());
142  EXPECT_EQ(isDyn, result1.info->isDyn());
143  EXPECT_EQ(type, result1.info->type());
144  EXPECT_EQ(desc, result1.info->desc());
145  EXPECT_EQ(binding, result1.info->binding());
146  EXPECT_EQ(size, result1.info->size());
147  EXPECT_EQ(other, result1.info->visibility());
148
149  Resolver::Result result2;
150  m_pTestee->insertSymbol(name,
151                          isDyn,
152                          type,
153                          desc,
154                          binding,
155                          size,
156                          other,
157                          NULL,
158                          result2);
159
160  EXPECT_EQ(result1.info, result2.info);
161
162  Resolver::Result result3;
163  m_pTestee->insertSymbol("Different Symbol",
164                          isDyn,
165                          type,
166                          desc,
167                          binding,
168                          size,
169                          other,
170                          NULL,
171                          result3);
172
173
174  EXPECT_NE(result1.info, result3.info);
175}
176
177
178TEST_F( NamePoolTest, insertSymbol_after_insert_same_string ) {
179  const char *name = "Hello MCLinker";
180  bool isDyn = false;
181  LDSymbol::Type type = LDSymbol::Defined;
182  LDSymbol::Binding binding = LDSymbol::Global;
183  const llvm::MCSectionData *section = 0;
184  uint64_t value = 0;
185  uint64_t size = 0;
186  uint8_t other = 0;
187
188  const char *result1 =  m_pTestee->insertString(name);
189  LDSymbol *sym =  m_pTestee->insertSymbol(name,
190                                           isDyn,
191                                           type,
192                                           binding,
193                                           section,
194                                           value,
195                                           size,
196                                           other);
197
198  EXPECT_STREQ(name, sym->name());
199  EXPECT_EQ(result1, sym->name());
200
201  char s[16];
202  strcpy(s, result1);
203  const char *result2 = m_pTestee->insertString(result1);
204  const char *result3 = m_pTestee->insertString(s);
205
206  EXPECT_EQ(result1, result2);
207  EXPECT_EQ(result1, result3);
208}
209
210
211TEST_F( NamePoolTest, insert_16384_weak_reference_symbols ) {
212  char name[16];
213  bool isDyn = false;
214  LDSymbol::Type type = LDSymbol::Reference;
215  LDSymbol::Binding binding = LDSymbol::Weak;
216  const llvm::MCSectionData *section = 0;
217  uint64_t value = 0;
218  uint64_t size = 0;
219  uint8_t other = 0;
220  strcpy(name, "Hello MCLinker");
221  LDSymbol *syms[128][128];
222  for(int i=0; i<128 ;++i) {
223    name[0] = i;
224    for(int j=0; j<128 ;++j) {
225      name[1] = j;
226      syms[i][j] =  m_pTestee->insertSymbol(name,
227                                            isDyn,
228                                            type,
229                                            binding,
230                                            section,
231                                            value,
232                                            size,
233                                            other);
234
235      ASSERT_STREQ(name, syms[i][j]->name());
236    }
237  }
238  for(int i=127; i>=0 ;--i) {
239    name[0] = i;
240    for(int j=0; j<128 ;++j) {
241      name[1] = j;
242      LDSymbol *sym =  m_pTestee->insertSymbol(name,
243                                               isDyn,
244                                               type,
245                                               binding,
246                                               section,
247                                               value,
248                                               size,
249                                               other);
250      ASSERT_EQ(sym, syms[i][j]);
251    }
252  }
253  for(int i=0; i<128 ;++i) {
254    name[0] = i;
255    for(int j=0; j<128 ;++j) {
256      name[1] = j;
257      LDSymbol *sym =  m_pTestee->insertSymbol(name,
258                                               isDyn,
259                                               type,
260                                               binding,
261                                               section,
262                                               value,
263                                               size,
264                                               other);
265      ASSERT_EQ(sym, syms[i][j]);
266    }
267  }
268}
269