| //===- 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]); |
| } |
| } |
| } |