2017-11-18 02:14:09 +08:00
|
|
|
//===- Symbols.cpp --------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "Symbols.h"
|
|
|
|
|
|
|
|
#include "Config.h"
|
|
|
|
#include "InputFiles.h"
|
2018-01-10 07:56:44 +08:00
|
|
|
#include "InputFunction.h"
|
2017-11-18 02:14:09 +08:00
|
|
|
#include "InputSegment.h"
|
|
|
|
#include "lld/Common/ErrorHandler.h"
|
2017-12-06 11:10:39 +08:00
|
|
|
#include "lld/Common/Strings.h"
|
2017-11-18 02:14:09 +08:00
|
|
|
|
|
|
|
#define DEBUG_TYPE "lld"
|
|
|
|
|
|
|
|
using namespace llvm;
|
2018-01-10 08:52:20 +08:00
|
|
|
using namespace llvm::wasm;
|
2017-11-18 02:14:09 +08:00
|
|
|
using namespace lld;
|
|
|
|
using namespace lld::wasm;
|
|
|
|
|
2017-11-30 09:40:08 +08:00
|
|
|
const WasmSignature &Symbol::getFunctionType() const {
|
2018-01-10 07:56:44 +08:00
|
|
|
if (Function != nullptr)
|
|
|
|
return Function->Signature;
|
|
|
|
|
2017-11-30 09:40:08 +08:00
|
|
|
assert(FunctionType != nullptr);
|
|
|
|
return *FunctionType;
|
2017-11-18 02:14:09 +08:00
|
|
|
}
|
|
|
|
|
2018-01-10 07:56:44 +08:00
|
|
|
void Symbol::setFunctionType(const WasmSignature *Type) {
|
|
|
|
assert(FunctionType == nullptr);
|
|
|
|
assert(Function == nullptr);
|
|
|
|
FunctionType = Type;
|
|
|
|
}
|
|
|
|
|
2017-11-18 02:14:09 +08:00
|
|
|
uint32_t Symbol::getVirtualAddress() const {
|
|
|
|
assert(isGlobal());
|
|
|
|
DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
|
2018-01-10 08:52:20 +08:00
|
|
|
return Segment ? Segment->translateVA(VirtualAddress) : VirtualAddress;
|
2017-11-18 02:14:09 +08:00
|
|
|
}
|
|
|
|
|
2018-01-10 07:56:44 +08:00
|
|
|
bool Symbol::hasOutputIndex() const {
|
|
|
|
if (Function)
|
|
|
|
return Function->hasOutputIndex();
|
|
|
|
return OutputIndex.hasValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Symbol::getOutputIndex() const {
|
|
|
|
if (Function)
|
|
|
|
return Function->getOutputIndex();
|
|
|
|
return OutputIndex.getValue();
|
|
|
|
}
|
|
|
|
|
2017-12-06 03:05:45 +08:00
|
|
|
void Symbol::setVirtualAddress(uint32_t Value) {
|
|
|
|
DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
|
2018-01-10 08:52:20 +08:00
|
|
|
assert(isGlobal());
|
2017-12-06 03:05:45 +08:00
|
|
|
VirtualAddress = Value;
|
|
|
|
}
|
|
|
|
|
2017-11-18 02:14:09 +08:00
|
|
|
void Symbol::setOutputIndex(uint32_t Index) {
|
|
|
|
DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n");
|
2018-01-10 07:56:44 +08:00
|
|
|
assert(!Function);
|
2017-12-12 06:00:56 +08:00
|
|
|
assert(!OutputIndex.hasValue());
|
2017-11-18 02:14:09 +08:00
|
|
|
OutputIndex = Index;
|
|
|
|
}
|
2017-12-12 06:00:56 +08:00
|
|
|
|
|
|
|
void Symbol::setTableIndex(uint32_t Index) {
|
|
|
|
DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
|
|
|
|
assert(!TableIndex.hasValue());
|
|
|
|
TableIndex = Index;
|
|
|
|
}
|
2017-11-18 02:14:09 +08:00
|
|
|
|
2018-01-10 08:52:20 +08:00
|
|
|
void Symbol::update(Kind K, InputFile *F, uint32_t Flags_,
|
|
|
|
const InputSegment *Seg, const InputFunction *Func,
|
|
|
|
uint32_t Address) {
|
2017-11-18 02:14:09 +08:00
|
|
|
SymbolKind = K;
|
|
|
|
File = F;
|
2018-01-10 08:52:20 +08:00
|
|
|
Flags = Flags_;
|
2017-11-18 02:14:09 +08:00
|
|
|
Segment = Seg;
|
2018-01-10 07:56:44 +08:00
|
|
|
Function = Func;
|
2018-01-10 08:52:20 +08:00
|
|
|
if (Address != UINT32_MAX)
|
|
|
|
setVirtualAddress(Address);
|
2017-11-18 02:14:09 +08:00
|
|
|
}
|
|
|
|
|
2018-01-10 08:52:20 +08:00
|
|
|
bool Symbol::isWeak() const {
|
|
|
|
return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
|
|
|
|
}
|
2017-11-18 02:14:09 +08:00
|
|
|
|
2018-01-10 08:52:20 +08:00
|
|
|
bool Symbol::isLocal() const {
|
|
|
|
return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Symbol::isHidden() const {
|
|
|
|
return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
|
|
|
|
}
|
2017-12-03 10:38:04 +08:00
|
|
|
|
2017-12-06 00:50:46 +08:00
|
|
|
std::string lld::toString(const wasm::Symbol &Sym) {
|
2017-12-06 11:10:39 +08:00
|
|
|
if (Config->Demangle)
|
|
|
|
if (Optional<std::string> S = demangleItanium(Sym.getName()))
|
|
|
|
return "`" + *S + "'";
|
|
|
|
return Sym.getName();
|
2017-11-18 02:14:09 +08:00
|
|
|
}
|
|
|
|
|
2017-12-06 00:50:46 +08:00
|
|
|
std::string lld::toString(wasm::Symbol::Kind Kind) {
|
2017-11-18 02:14:09 +08:00
|
|
|
switch (Kind) {
|
|
|
|
case wasm::Symbol::DefinedFunctionKind:
|
|
|
|
return "DefinedFunction";
|
|
|
|
case wasm::Symbol::DefinedGlobalKind:
|
|
|
|
return "DefinedGlobal";
|
|
|
|
case wasm::Symbol::UndefinedFunctionKind:
|
|
|
|
return "UndefinedFunction";
|
|
|
|
case wasm::Symbol::UndefinedGlobalKind:
|
|
|
|
return "UndefinedGlobal";
|
|
|
|
case wasm::Symbol::LazyKind:
|
|
|
|
return "LazyKind";
|
|
|
|
}
|
|
|
|
llvm_unreachable("Invalid symbol kind!");
|
|
|
|
}
|