| //===- NamePoolTest.cpp ---------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "NamePoolTest.h" |
| #include "mcld/LD/NamePool.h" |
| #include "mcld/LD/Resolver.h" |
| #include "mcld/LD/StaticResolver.h" |
| #include "mcld/LD/ResolveInfo.h" |
| #include "mcld/LD/LDSymbol.h" |
| #include <llvm/ADT/StringRef.h> |
| #include <string> |
| #include <cstdio> |
| |
| using namespace mcld; |
| using namespace mcldtest; |
| |
| // Constructor can do set-up work for all test here. |
| NamePoolTest::NamePoolTest() { |
| // create testee. modify it if need |
| StaticResolver resolver; |
| m_pTestee = new NamePool(resolver, 10); |
| } |
| |
| // Destructor can do clean-up work that doesn't throw exceptions here. |
| NamePoolTest::~NamePoolTest() { |
| delete m_pTestee; |
| } |
| |
| // SetUp() will be called immediately before each test. |
| void NamePoolTest::SetUp() { |
| } |
| |
| // TearDown() will be called immediately after each test. |
| void NamePoolTest::TearDown() { |
| } |
| |
| //==========================================================================// |
| // Testcases |
| // |
| |
| TEST_F(NamePoolTest, insertString) { |
| const char* s1 = "Hello MCLinker"; |
| llvm::StringRef result1 = m_pTestee->insertString(s1); |
| EXPECT_NE(s1, result1.data()); |
| EXPECT_STREQ(s1, result1.data()); |
| } |
| |
| TEST_F(NamePoolTest, insertSameString) { |
| const char* s1 = "Hello MCLinker"; |
| std::string s2(s1); |
| llvm::StringRef result1 = m_pTestee->insertString(s1); |
| llvm::StringRef result2 = m_pTestee->insertString(s2.c_str()); |
| EXPECT_STREQ(s1, result1.data()); |
| EXPECT_STREQ(s2.c_str(), result2.data()); |
| EXPECT_EQ(result1.data(), result2.data()); |
| } |
| |
| TEST_F(NamePoolTest, insert_local_defined_Symbol) { |
| const char* name = "Hello MCLinker"; |
| bool isDyn = false; |
| ResolveInfo::Type type = ResolveInfo::Function; |
| ResolveInfo::Desc desc = ResolveInfo::Define; |
| ResolveInfo::Binding binding = ResolveInfo::Local; |
| uint64_t value = 0; |
| uint64_t size = 0; |
| ResolveInfo::Visibility other = ResolveInfo::Default; |
| Resolver::Result result1; |
| m_pTestee->insertSymbol( |
| name, isDyn, type, desc, binding, size, other, NULL, result1); |
| |
| EXPECT_NE(name, result1.info->name()); |
| EXPECT_STREQ(name, result1.info->name()); |
| EXPECT_EQ(isDyn, result1.info->isDyn()); |
| EXPECT_EQ(type, result1.info->type()); |
| EXPECT_EQ(desc, result1.info->desc()); |
| EXPECT_EQ(binding, result1.info->binding()); |
| EXPECT_EQ(size, result1.info->size()); |
| EXPECT_EQ(other, result1.info->visibility()); |
| |
| Resolver::Result result2; |
| m_pTestee->insertSymbol( |
| name, isDyn, type, desc, binding, size, other, NULL, result2); |
| |
| EXPECT_NE(name, result1.info->name()); |
| EXPECT_STREQ(name, result1.info->name()); |
| EXPECT_EQ(isDyn, result1.info->isDyn()); |
| EXPECT_EQ(type, result1.info->type()); |
| EXPECT_EQ(desc, result1.info->desc()); |
| EXPECT_EQ(binding, result1.info->binding()); |
| EXPECT_EQ(size, result1.info->size()); |
| EXPECT_EQ(other, result1.info->visibility()); |
| |
| EXPECT_NE(result1.existent, result2.existent); |
| } |
| |
| TEST_F(NamePoolTest, insert_global_reference_Symbol) { |
| const char* name = "Hello MCLinker"; |
| bool isDyn = false; |
| ResolveInfo::Type type = ResolveInfo::NoType; |
| ResolveInfo::Desc desc = ResolveInfo::Undefined; |
| ResolveInfo::Binding binding = ResolveInfo::Global; |
| uint64_t size = 0; |
| ResolveInfo::Visibility other = ResolveInfo::Default; |
| Resolver::Result result1; |
| m_pTestee->insertSymbol( |
| name, isDyn, type, desc, binding, size, other, NULL, result1); |
| |
| EXPECT_NE(name, result1.info->name()); |
| EXPECT_STREQ(name, result1.info->name()); |
| EXPECT_EQ(isDyn, result1.info->isDyn()); |
| EXPECT_EQ(type, result1.info->type()); |
| EXPECT_EQ(desc, result1.info->desc()); |
| EXPECT_EQ(binding, result1.info->binding()); |
| EXPECT_EQ(size, result1.info->size()); |
| EXPECT_EQ(other, result1.info->visibility()); |
| |
| Resolver::Result result2; |
| m_pTestee->insertSymbol( |
| name, isDyn, type, desc, binding, size, other, NULL, result2); |
| |
| EXPECT_EQ(result1.info, result2.info); |
| |
| Resolver::Result result3; |
| m_pTestee->insertSymbol("Different Symbol", |
| isDyn, |
| type, |
| desc, |
| binding, |
| size, |
| other, |
| NULL, |
| result3); |
| |
| EXPECT_NE(result1.info, result3.info); |
| } |
| |
| TEST_F(NamePoolTest, insertSymbol_after_insert_same_string) { |
| const char* name = "Hello MCLinker"; |
| bool isDyn = false; |
| LDSymbol::Type type = LDSymbol::Defined; |
| LDSymbol::Binding binding = LDSymbol::Global; |
| const llvm::MCSectionData* section = 0; |
| uint64_t value = 0; |
| uint64_t size = 0; |
| uint8_t other = 0; |
| |
| const char* result1 = m_pTestee->insertString(name); |
| LDSymbol* sym = m_pTestee->insertSymbol( |
| name, isDyn, type, binding, section, value, size, other); |
| |
| EXPECT_STREQ(name, sym->name()); |
| EXPECT_EQ(result1, sym->name()); |
| |
| char s[16]; |
| strcpy(s, result1); |
| const char* result2 = m_pTestee->insertString(result1); |
| const char* result3 = m_pTestee->insertString(s); |
| |
| EXPECT_EQ(result1, result2); |
| EXPECT_EQ(result1, result3); |
| } |
| |
| TEST_F(NamePoolTest, insert_16384_weak_reference_symbols) { |
| char name[16]; |
| bool isDyn = false; |
| LDSymbol::Type type = LDSymbol::Reference; |
| LDSymbol::Binding binding = LDSymbol::Weak; |
| const llvm::MCSectionData* section = 0; |
| uint64_t value = 0; |
| uint64_t size = 0; |
| uint8_t other = 0; |
| strcpy(name, "Hello MCLinker"); |
| LDSymbol* syms[128][128]; |
| for (int i = 0; i < 128; ++i) { |
| name[0] = i; |
| for (int j = 0; j < 128; ++j) { |
| name[1] = j; |
| syms[i][j] = m_pTestee->insertSymbol( |
| name, isDyn, type, binding, section, value, size, other); |
| |
| ASSERT_STREQ(name, syms[i][j]->name()); |
| } |
| } |
| for (int i = 127; i >= 0; --i) { |
| name[0] = i; |
| for (int j = 0; j < 128; ++j) { |
| name[1] = j; |
| LDSymbol* sym = m_pTestee->insertSymbol( |
| name, isDyn, type, binding, section, value, size, other); |
| ASSERT_EQ(sym, syms[i][j]); |
| } |
| } |
| for (int i = 0; i < 128; ++i) { |
| name[0] = i; |
| for (int j = 0; j < 128; ++j) { |
| name[1] = j; |
| LDSymbol* sym = m_pTestee->insertSymbol( |
| name, isDyn, type, binding, section, value, size, other); |
| ASSERT_EQ(sym, syms[i][j]); |
| } |
| } |
| } |