You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
427 lines
14 KiB
427 lines
14 KiB
//===- 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());
|
|
}
|