| //===- implTest.cpp -------------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "StaticResolverTest.h" |
| #include <mcld/Support/TargetSelect.h> |
| #include <mcld/LD/StaticResolver.h> |
| #include <mcld/LD/ResolveInfo.h> |
| #include <mcld/LinkerConfig.h> |
| |
| #include <mcld/Support/FileSystem.h> |
| |
| using namespace mcld; |
| using namespace mcldtest; |
| |
| //===----------------------------------------------------------------------===// |
| // StaticResolverTest |
| //===----------------------------------------------------------------------===// |
| // Constructor can do set-up work for all test here. |
| StaticResolverTest::StaticResolverTest() |
| : m_pResolver(NULL), m_pConfig(NULL) { |
| // create testee. modify it if need |
| m_pResolver = new StaticResolver(); |
| |
| m_pConfig = new LinkerConfig("arm-none-linux-gnueabi"); |
| } |
| |
| // Destructor can do clean-up work that doesn't throw exceptions here. |
| StaticResolverTest::~StaticResolverTest() |
| { |
| delete m_pResolver; |
| delete m_pConfig; |
| } |
| |
| // SetUp() will be called immediately before each test. |
| void StaticResolverTest::SetUp() |
| { |
| } |
| |
| // TearDown() will be called immediately after each test. |
| void StaticResolverTest::TearDown() |
| { |
| } |
| |
| //==========================================================================// |
| // Testcases |
| // |
| TEST_F( StaticResolverTest, MDEF ) { |
| ResolveInfo* old_sym = ResolveInfo::Create("abc"); |
| ResolveInfo* new_sym = ResolveInfo::Create("abc"); |
| new_sym->setDesc(ResolveInfo::Define); |
| old_sym->setDesc(ResolveInfo::Define); |
| ASSERT_TRUE( mcld::ResolveInfo::Define == new_sym->desc()); |
| ASSERT_TRUE( mcld::ResolveInfo::Define == old_sym->desc()); |
| ASSERT_TRUE( mcld::ResolveInfo::define_flag == new_sym->info()); |
| ASSERT_TRUE( mcld::ResolveInfo::define_flag == old_sym->info()); |
| bool override = true; |
| bool result = m_pResolver->resolve(*old_sym, *new_sym, override); |
| ASSERT_TRUE(result); |
| ASSERT_FALSE( override ); |
| } |
| |
| TEST_F( StaticResolverTest, DynDefAfterDynUndef ) { |
| ResolveInfo* old_sym = ResolveInfo::Create("abc"); |
| ResolveInfo* new_sym = ResolveInfo::Create("abc"); |
| |
| new_sym->setBinding(ResolveInfo::Global); |
| old_sym->setBinding(ResolveInfo::Global); |
| new_sym->setDesc(ResolveInfo::Undefined); |
| old_sym->setDesc(ResolveInfo::Define); |
| new_sym->setSource(true); |
| old_sym->setSource(true); |
| |
| new_sym->setSize(0); |
| |
| old_sym->setSize(1); |
| |
| ASSERT_TRUE( mcld::ResolveInfo::Global == new_sym->binding()); |
| ASSERT_TRUE( mcld::ResolveInfo::Global == old_sym->binding()); |
| ASSERT_TRUE( mcld::ResolveInfo::Undefined == new_sym->desc()); |
| ASSERT_TRUE( mcld::ResolveInfo::Define == old_sym->desc()); |
| |
| bool override = false; |
| bool result = m_pResolver->resolve(*old_sym, *new_sym, override); |
| ASSERT_TRUE(result); |
| ASSERT_FALSE( override ); |
| ASSERT_TRUE(1 == old_sym->size()); |
| } |
| |
| TEST_F( StaticResolverTest, DynDefAfterDynDef ) { |
| ResolveInfo* old_sym = ResolveInfo::Create("abc"); |
| ResolveInfo* new_sym = ResolveInfo::Create("abc"); |
| |
| new_sym->setBinding(ResolveInfo::Global); |
| old_sym->setBinding(ResolveInfo::Global); |
| new_sym->setDesc(ResolveInfo::Define); |
| old_sym->setDesc(ResolveInfo::Define); |
| new_sym->setSource(true); |
| old_sym->setSource(true); |
| |
| new_sym->setSize(0); |
| |
| old_sym->setSize(1); |
| |
| ASSERT_TRUE( mcld::ResolveInfo::Global == new_sym->binding()); |
| ASSERT_TRUE( mcld::ResolveInfo::Global == old_sym->binding()); |
| ASSERT_TRUE( mcld::ResolveInfo::Define == new_sym->desc()); |
| ASSERT_TRUE( mcld::ResolveInfo::Define == old_sym->desc()); |
| |
| bool override = false; |
| bool result = m_pResolver->resolve(*old_sym, *new_sym, override); |
| ASSERT_TRUE(result); |
| ASSERT_FALSE( override ); |
| ASSERT_TRUE(1 == old_sym->size()); |
| } |
| |
| TEST_F( StaticResolverTest, DynUndefAfterDynUndef ) { |
| ResolveInfo* old_sym = ResolveInfo::Create("abc"); |
| ResolveInfo* new_sym = ResolveInfo::Create("abc"); |
| |
| new_sym->setBinding(ResolveInfo::Global); |
| old_sym->setBinding(ResolveInfo::Global); |
| new_sym->setDesc(ResolveInfo::Undefined); |
| old_sym->setDesc(ResolveInfo::Undefined); |
| new_sym->setSource(true); |
| old_sym->setSource(true); |
| |
| new_sym->setSize(0); |
| |
| old_sym->setSize(1); |
| |
| ASSERT_TRUE( mcld::ResolveInfo::Global == new_sym->binding()); |
| ASSERT_TRUE( mcld::ResolveInfo::Global == old_sym->binding()); |
| ASSERT_TRUE( mcld::ResolveInfo::Undefined == new_sym->desc()); |
| ASSERT_TRUE( mcld::ResolveInfo::Undefined == old_sym->desc()); |
| |
| bool override = false; |
| bool result = m_pResolver->resolve(*old_sym, *new_sym, override); |
| ASSERT_TRUE(result); |
| ASSERT_FALSE( override ); |
| ASSERT_TRUE(1 == old_sym->size()); |
| } |
| |
| TEST_F( StaticResolverTest, OverrideWeakByGlobal ) |
| { |
| ResolveInfo* old_sym = ResolveInfo::Create("abc"); |
| ResolveInfo* new_sym = ResolveInfo::Create("abc"); |
| |
| new_sym->setBinding(ResolveInfo::Global); |
| old_sym->setBinding(ResolveInfo::Weak); |
| new_sym->setSize(0); |
| old_sym->setSize(1); |
| |
| ASSERT_TRUE( mcld::ResolveInfo::Global == new_sym->binding()); |
| ASSERT_TRUE( mcld::ResolveInfo::Weak == old_sym->binding()); |
| |
| ASSERT_TRUE( mcld::ResolveInfo::global_flag == new_sym->info()); |
| ASSERT_TRUE( mcld::ResolveInfo::weak_flag == old_sym->info()); |
| bool override = false; |
| bool result = m_pResolver->resolve(*old_sym, *new_sym, override); |
| ASSERT_TRUE(result); |
| ASSERT_TRUE( override ); |
| ASSERT_TRUE(0 == old_sym->size()); |
| } |
| |
| TEST_F( StaticResolverTest, DynWeakAfterDynDef ) { |
| ResolveInfo* old_sym = ResolveInfo::Create("abc"); |
| ResolveInfo* new_sym = ResolveInfo::Create("abc"); |
| |
| old_sym->setBinding(ResolveInfo::Weak); |
| new_sym->setBinding(ResolveInfo::Global); |
| |
| new_sym->setSource(true); |
| old_sym->setSource(true); |
| |
| old_sym->setDesc(ResolveInfo::Define); |
| new_sym->setDesc(ResolveInfo::Define); |
| |
| new_sym->setSize(0); |
| |
| old_sym->setSize(1); |
| |
| ASSERT_TRUE( mcld::ResolveInfo::Weak == old_sym->binding()); |
| ASSERT_TRUE( mcld::ResolveInfo::Global == new_sym->binding()); |
| ASSERT_TRUE( mcld::ResolveInfo::Define == old_sym->desc()); |
| ASSERT_TRUE( mcld::ResolveInfo::Define == new_sym->desc()); |
| |
| bool override = false; |
| bool result = m_pResolver->resolve(*old_sym, *new_sym, override); |
| ASSERT_TRUE(result); |
| ASSERT_FALSE( override ); |
| ASSERT_TRUE(1 == old_sym->size()); |
| } |
| |
| TEST_F( StaticResolverTest, MarkByBiggerCommon ) |
| { |
| ResolveInfo* old_sym = ResolveInfo::Create("abc"); |
| ResolveInfo* new_sym = ResolveInfo::Create("abc"); |
| |
| new_sym->setDesc(ResolveInfo::Common); |
| old_sym->setDesc(ResolveInfo::Common); |
| new_sym->setSize(999); |
| old_sym->setSize(0); |
| |
| ASSERT_TRUE( mcld::ResolveInfo::Common == new_sym->desc()); |
| ASSERT_TRUE( mcld::ResolveInfo::Common == old_sym->desc()); |
| |
| ASSERT_TRUE( mcld::ResolveInfo::common_flag == new_sym->info()); |
| ASSERT_TRUE( mcld::ResolveInfo::common_flag == old_sym->info()); |
| bool override = true; |
| bool result = m_pResolver->resolve(*old_sym, *new_sym, override); |
| ASSERT_TRUE(result); |
| ASSERT_FALSE( override ); |
| ASSERT_TRUE(999 == old_sym->size()); |
| } |
| |
| TEST_F( StaticResolverTest, OverrideByBiggerCommon ) |
| { |
| ResolveInfo* old_sym = ResolveInfo::Create("abc"); |
| ResolveInfo* new_sym = ResolveInfo::Create("abc"); |
| |
| new_sym->setDesc(ResolveInfo::Common); |
| old_sym->setDesc(ResolveInfo::Common); |
| old_sym->setBinding(ResolveInfo::Weak); |
| new_sym->setSize(999); |
| old_sym->setSize(0); |
| |
| ASSERT_TRUE( ResolveInfo::Common == new_sym->desc()); |
| ASSERT_TRUE( ResolveInfo::Common == old_sym->desc()); |
| ASSERT_TRUE( ResolveInfo::Weak == old_sym->binding()); |
| |
| ASSERT_TRUE( ResolveInfo::common_flag == new_sym->info()); |
| ASSERT_TRUE( (ResolveInfo::weak_flag | ResolveInfo::common_flag) == old_sym->info()); |
| |
| bool override = false; |
| bool result = m_pResolver->resolve(*old_sym, *new_sym, override); |
| ASSERT_TRUE(result); |
| ASSERT_TRUE( override ); |
| ASSERT_TRUE(999 == old_sym->size()); |
| } |
| |
| TEST_F( StaticResolverTest, OverrideCommonByDefine) |
| { |
| ResolveInfo* old_sym = ResolveInfo::Create("abc"); |
| ResolveInfo* new_sym = ResolveInfo::Create("abc"); |
| |
| old_sym->setDesc(ResolveInfo::Common); |
| old_sym->setSize(0); |
| |
| new_sym->setDesc(ResolveInfo::Define); |
| new_sym->setSize(999); |
| |
| ASSERT_TRUE( ResolveInfo::Define == new_sym->desc()); |
| ASSERT_TRUE( ResolveInfo::Common == old_sym->desc()); |
| |
| ASSERT_TRUE( ResolveInfo::define_flag == new_sym->info()); |
| ASSERT_TRUE( ResolveInfo::common_flag == old_sym->info()); |
| |
| bool override = false; |
| bool result = m_pResolver->resolve(*old_sym, *new_sym, override); |
| ASSERT_TRUE(result); |
| ASSERT_TRUE( override ); |
| ASSERT_TRUE(999 == old_sym->size()); |
| } |
| |
| TEST_F( StaticResolverTest, SetUpDesc) |
| { |
| ResolveInfo* sym = ResolveInfo::Create("abc"); |
| |
| sym->setIsSymbol(true); |
| |
| // ASSERT_FALSE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isGlobal() ); |
| ASSERT_FALSE( sym->isWeak() ); |
| ASSERT_FALSE( sym->isLocal() ); |
| ASSERT_FALSE( sym->isDefine() ); |
| ASSERT_TRUE( sym->isUndef() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_FALSE( sym->isCommon() ); |
| ASSERT_FALSE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( 0 == sym->desc() ); |
| ASSERT_TRUE( 0 == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| |
| sym->setIsSymbol(false); |
| ASSERT_FALSE( sym->isSymbol() ); |
| // ASSERT_TRUE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isGlobal() ); |
| ASSERT_FALSE( sym->isWeak() ); |
| ASSERT_FALSE( sym->isLocal() ); |
| ASSERT_FALSE( sym->isDefine() ); |
| ASSERT_TRUE( sym->isUndef() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_FALSE( sym->isCommon() ); |
| ASSERT_FALSE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( 0 == sym->desc() ); |
| ASSERT_TRUE( 0 == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| |
| sym->setDesc(ResolveInfo::Define); |
| ASSERT_FALSE( sym->isSymbol() ); |
| // ASSERT_TRUE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isGlobal() ); |
| ASSERT_FALSE( sym->isWeak() ); |
| ASSERT_FALSE( sym->isLocal() ); |
| ASSERT_TRUE( sym->isDefine() ); |
| ASSERT_FALSE( sym->isUndef() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_FALSE( sym->isCommon() ); |
| ASSERT_FALSE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( ResolveInfo::Define == sym->desc() ); |
| ASSERT_TRUE( 0 == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| |
| sym->setDesc(ResolveInfo::Common); |
| ASSERT_FALSE( sym->isSymbol() ); |
| // ASSERT_TRUE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isGlobal() ); |
| ASSERT_FALSE( sym->isWeak() ); |
| ASSERT_FALSE( sym->isLocal() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_FALSE( sym->isDefine() ); |
| ASSERT_FALSE( sym->isUndef() ); |
| ASSERT_TRUE( sym->isCommon() ); |
| ASSERT_FALSE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( ResolveInfo::Common == sym->desc() ); |
| ASSERT_TRUE( 0 == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| |
| sym->setDesc(ResolveInfo::Indirect); |
| ASSERT_FALSE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isGlobal() ); |
| ASSERT_FALSE( sym->isWeak() ); |
| ASSERT_FALSE( sym->isLocal() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_FALSE( sym->isDefine() ); |
| ASSERT_FALSE( sym->isUndef() ); |
| ASSERT_FALSE( sym->isCommon() ); |
| ASSERT_TRUE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( ResolveInfo::Indirect == sym->desc() ); |
| ASSERT_TRUE( 0 == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| |
| sym->setDesc(ResolveInfo::Undefined); |
| ASSERT_FALSE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isGlobal() ); |
| ASSERT_FALSE( sym->isWeak() ); |
| ASSERT_FALSE( sym->isLocal() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_TRUE( sym->isUndef() ); |
| ASSERT_FALSE( sym->isDefine() ); |
| ASSERT_FALSE( sym->isCommon() ); |
| ASSERT_FALSE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( 0 == sym->desc() ); |
| ASSERT_TRUE( 0 == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| } |
| |
| TEST_F( StaticResolverTest, SetUpBinding) |
| { |
| ResolveInfo* sym = ResolveInfo::Create("abc"); |
| |
| sym->setIsSymbol(true); |
| |
| // ASSERT_FALSE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isGlobal() ); |
| ASSERT_FALSE( sym->isWeak() ); |
| ASSERT_FALSE( sym->isLocal() ); |
| ASSERT_FALSE( sym->isDefine() ); |
| ASSERT_TRUE( sym->isUndef() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_FALSE( sym->isCommon() ); |
| ASSERT_FALSE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( 0 == sym->desc() ); |
| ASSERT_TRUE( 0 == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| |
| sym->setBinding(ResolveInfo::Global); |
| ASSERT_TRUE( sym->isSymbol() ); |
| ASSERT_TRUE( sym->isGlobal() ); |
| ASSERT_FALSE( sym->isWeak() ); |
| ASSERT_FALSE( sym->isLocal() ); |
| ASSERT_FALSE( sym->isDefine() ); |
| ASSERT_TRUE( sym->isUndef() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_FALSE( sym->isCommon() ); |
| ASSERT_FALSE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( 0 == sym->desc() ); |
| ASSERT_TRUE( ResolveInfo::Global == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| |
| sym->setBinding(ResolveInfo::Weak); |
| ASSERT_TRUE( sym->isSymbol() ); |
| ASSERT_FALSE( sym->isGlobal() ); |
| ASSERT_TRUE( sym->isWeak() ); |
| ASSERT_FALSE( sym->isLocal() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_FALSE( sym->isDefine() ); |
| ASSERT_TRUE( sym->isUndef() ); |
| ASSERT_FALSE( sym->isCommon() ); |
| ASSERT_FALSE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( 0 == sym->desc() ); |
| ASSERT_TRUE( ResolveInfo::Weak == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| |
| sym->setBinding(ResolveInfo::Local); |
| ASSERT_TRUE( sym->isSymbol() ); |
| ASSERT_FALSE( sym->isGlobal() ); |
| ASSERT_FALSE( sym->isWeak() ); |
| ASSERT_TRUE( sym->isLocal() ); |
| ASSERT_FALSE( sym->isDyn() ); |
| ASSERT_FALSE( sym->isDefine() ); |
| ASSERT_TRUE( sym->isUndef() ); |
| ASSERT_FALSE( sym->isCommon() ); |
| ASSERT_FALSE( sym->isIndirect() ); |
| ASSERT_TRUE( ResolveInfo::NoType == sym->type()); |
| ASSERT_TRUE( 0 == sym->desc() ); |
| ASSERT_TRUE( ResolveInfo::Local == sym->binding() ); |
| ASSERT_TRUE( 0 == sym->other() ); |
| } |
| |