//===- 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, 0x0);
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, 0x0);
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, 0x0);
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, 0x0);
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, 0x0);
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, 0x0);
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, 0x0);
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, 0x0);
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, 0x0);
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() );
}