Use fully-qualified names for linking, too

Using libraries leaves behind a library link reference in the binary
which the linker must later resolve.  These link references were still
being generated by name and not by fully-qualified name.  This would
lead to a link-time collision between two libraries having the same
name but in different source units.

This change changes linker symbols over to fully-qualified names,
which resolves that issue.  This does potentially introduce a new
problem, which is that linker symbols appear to be limited to 36
characters and are truncated.  Storing paths extends the average
symbol size, and it would be great if truncation was from the tail
rather than the head.
This commit is contained in:
Rhett Aultman 2016-12-21 11:26:22 -08:00 committed by Rhett Aultman
parent 85c55c796a
commit 1f30982ab5
3 changed files with 15 additions and 15 deletions

View File

@ -575,7 +575,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
else if (auto contract = dynamic_cast<ContractDefinition const*>(decl)) else if (auto contract = dynamic_cast<ContractDefinition const*>(decl))
{ {
solAssert(contract->isLibrary(), ""); solAssert(contract->isLibrary(), "");
_assembly.appendLibraryAddress(contract->name()); _assembly.appendLibraryAddress(contract->fullyQualifiedName());
} }
else else
solAssert(false, "Invalid declaration type."); solAssert(false, "Invalid declaration type.");

View File

@ -892,7 +892,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
solAssert(funType->location() == FunctionType::Location::DelegateCall, ""); solAssert(funType->location() == FunctionType::Location::DelegateCall, "");
auto contract = dynamic_cast<ContractDefinition const*>(funType->declaration().scope()); auto contract = dynamic_cast<ContractDefinition const*>(funType->declaration().scope());
solAssert(contract && contract->isLibrary(), ""); solAssert(contract && contract->isLibrary(), "");
m_context.appendLibraryAddress(contract->name()); m_context.appendLibraryAddress(contract->fullyQualifiedName());
m_context << funType->externalIdentifier(); m_context << funType->externalIdentifier();
utils().moveIntoStack(funType->selfType()->sizeOnStack(), 2); utils().moveIntoStack(funType->selfType()->sizeOnStack(), 2);
} }
@ -1270,7 +1270,7 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
else if (auto contract = dynamic_cast<ContractDefinition const*>(declaration)) else if (auto contract = dynamic_cast<ContractDefinition const*>(declaration))
{ {
if (contract->isLibrary()) if (contract->isLibrary())
m_context.appendLibraryAddress(contract->name()); m_context.appendLibraryAddress(contract->fullyQualifiedName());
} }
else if (dynamic_cast<EventDefinition const*>(declaration)) else if (dynamic_cast<EventDefinition const*>(declaration))
{ {

View File

@ -3192,7 +3192,7 @@ BOOST_AUTO_TEST_CASE(library_call_in_homestead)
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}}); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{":Lib", m_contractAddress}});
BOOST_CHECK(callContractFunction("f()") == encodeArgs()); BOOST_CHECK(callContractFunction("f()") == encodeArgs());
BOOST_CHECK(callContractFunction("sender()") == encodeArgs(u160(m_sender))); BOOST_CHECK(callContractFunction("sender()") == encodeArgs(u160(m_sender)));
} }
@ -6191,7 +6191,7 @@ BOOST_AUTO_TEST_CASE(library_call)
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}}); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{":Lib", m_contractAddress}});
BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(33) * 9)); BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(33) * 9));
} }
@ -6208,7 +6208,7 @@ BOOST_AUTO_TEST_CASE(library_stray_values)
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}}); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{":Lib", m_contractAddress}});
BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(42))); BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(42)));
} }
@ -6341,7 +6341,7 @@ BOOST_AUTO_TEST_CASE(internal_types_in_library)
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}}); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{":Lib", m_contractAddress}});
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(4), u256(17))); BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(4), u256(17)));
} }
@ -6368,7 +6368,7 @@ BOOST_AUTO_TEST_CASE(using_library_structs)
} }
)"; )";
compileAndRun(sourceCode, 0, "Lib"); compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}}); compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{":Lib", m_contractAddress}});
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7), u256(8))); BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7), u256(8)));
} }
@ -6902,7 +6902,7 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_int)
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{"D", m_contractAddress}}); compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{":D", m_contractAddress}});
BOOST_CHECK(callContractFunction("f(uint256)", u256(9)) == encodeArgs(u256(2 * 9))); BOOST_CHECK(callContractFunction("f(uint256)", u256(9)) == encodeArgs(u256(2 * 9)));
} }
@ -6920,7 +6920,7 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_struct)
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{"D", m_contractAddress}}); compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{":D", m_contractAddress}});
BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(3 * 7))); BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(3 * 7)));
BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(3 * 7))); BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(3 * 7)));
} }
@ -6943,7 +6943,7 @@ BOOST_AUTO_TEST_CASE(using_for_overload)
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{"D", m_contractAddress}}); compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{":D", m_contractAddress}});
BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(6 * 7))); BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(6 * 7)));
BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(6 * 7))); BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(6 * 7)));
} }
@ -6962,7 +6962,7 @@ BOOST_AUTO_TEST_CASE(using_for_by_name)
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{"D", m_contractAddress}}); compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{":D", m_contractAddress}});
BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(6 * 7))); BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(6 * 7)));
BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(6 * 7))); BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(6 * 7)));
} }
@ -6982,7 +6982,7 @@ BOOST_AUTO_TEST_CASE(bound_function_in_var)
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{"D", m_contractAddress}}); compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{":D", m_contractAddress}});
BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(6 * 7))); BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(6 * 7)));
BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(6 * 7))); BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(6 * 7)));
} }
@ -7005,7 +7005,7 @@ BOOST_AUTO_TEST_CASE(bound_function_to_string)
} }
)"; )";
compileAndRun(sourceCode, 0, "D"); compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{"D", m_contractAddress}}); compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{":D", m_contractAddress}});
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(3))); BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(3)));
BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(3))); BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(3)));
} }
@ -7751,7 +7751,7 @@ BOOST_AUTO_TEST_CASE(payable_function_calls_library)
} }
)"; )";
compileAndRun(sourceCode, 0, "L"); compileAndRun(sourceCode, 0, "L");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{"L", m_contractAddress}}); compileAndRun(sourceCode, 0, "C", bytes(), map<string, Address>{{":L", m_contractAddress}});
BOOST_CHECK(callContractFunctionWithValue("f()", 27) == encodeArgs(u256(7))); BOOST_CHECK(callContractFunctionWithValue("f()", 27) == encodeArgs(u256(7)));
} }