diff options
Diffstat (limited to 'wasm/SymbolTable.cpp')
| -rw-r--r-- | wasm/SymbolTable.cpp | 147 | 
1 files changed, 88 insertions, 59 deletions
diff --git a/wasm/SymbolTable.cpp b/wasm/SymbolTable.cpp index e1ba23769738..c7983196db36 100644 --- a/wasm/SymbolTable.cpp +++ b/wasm/SymbolTable.cpp @@ -10,6 +10,7 @@  #include "SymbolTable.h"  #include "Config.h"  #include "InputChunks.h" +#include "InputEvent.h"  #include "InputGlobal.h"  #include "WriterUtils.h"  #include "lld/Common/ErrorHandler.h" @@ -20,6 +21,7 @@  using namespace llvm;  using namespace llvm::wasm; +using namespace llvm::object;  using namespace lld;  using namespace lld::wasm; @@ -60,7 +62,6 @@ void SymbolTable::addCombinedLTOObject() {  }  void SymbolTable::reportRemainingUndefines() { -  SetVector<Symbol *> Undefs;    for (Symbol *Sym : SymVector) {      if (!Sym->isUndefined() || Sym->isWeak())        continue; @@ -68,34 +69,26 @@ void SymbolTable::reportRemainingUndefines() {        continue;      if (!Sym->IsUsedInRegularObj)        continue; -    Undefs.insert(Sym); +    error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym));    } - -  if (Undefs.empty()) -    return; - -  for (ObjFile *File : ObjectFiles) -    for (Symbol *Sym : File->getSymbols()) -      if (Undefs.count(Sym)) -        error(toString(File) + ": undefined symbol: " + toString(*Sym)); - -  for (Symbol *Sym : Undefs) -    if (!Sym->getFile()) -      error("undefined symbol: " + toString(*Sym));  }  Symbol *SymbolTable::find(StringRef Name) {    return SymMap.lookup(CachedHashStringRef(Name));  } -std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { +std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) { +  bool Inserted = false;    Symbol *&Sym = SymMap[CachedHashStringRef(Name)]; -  if (Sym) -    return {Sym, false}; -  Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); -  Sym->IsUsedInRegularObj = false; -  SymVector.emplace_back(Sym); -  return {Sym, true}; +  if (!Sym) { +    Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); +    Sym->IsUsedInRegularObj = false; +    SymVector.emplace_back(Sym); +    Inserted = true; +  } +  if (!File || File->kind() == InputFile::ObjectKind) +    Sym->IsUsedInRegularObj = true; +  return {Sym, Inserted};  }  static void reportTypeError(const Symbol *Existing, const InputFile *File, @@ -106,6 +99,8 @@ static void reportTypeError(const Symbol *Existing, const InputFile *File,          " in " + toString(File));  } +// Check the type of new symbol matches that of the symbol is replacing. +// For functions this can also involve verifying that the signatures match.  static void checkFunctionType(Symbol *Existing, const InputFile *File,                                const WasmSignature *NewSig) {    auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing); @@ -117,9 +112,9 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File,    if (!NewSig)      return; -  const WasmSignature *OldSig = ExistingFunction->FunctionType; +  const WasmSignature *OldSig = ExistingFunction->Signature;    if (!OldSig) { -    ExistingFunction->FunctionType = NewSig; +    ExistingFunction->Signature = NewSig;      return;    } @@ -130,8 +125,6 @@ static void checkFunctionType(Symbol *Existing, const InputFile *File,           toString(*NewSig) + " in " + toString(File));  } -// Check the type of new symbol matches that of the symbol is replacing. -// For functions this can also involve verifying that the signatures match.  static void checkGlobalType(const Symbol *Existing, const InputFile *File,                              const WasmGlobalType *NewType) {    if (!isa<GlobalSymbol>(Existing)) { @@ -147,6 +140,28 @@ static void checkGlobalType(const Symbol *Existing, const InputFile *File,    }  } +static void checkEventType(const Symbol *Existing, const InputFile *File, +                           const WasmEventType *NewType, +                           const WasmSignature *NewSig) { +  auto ExistingEvent = dyn_cast<EventSymbol>(Existing); +  if (!isa<EventSymbol>(Existing)) { +    reportTypeError(Existing, File, WASM_SYMBOL_TYPE_EVENT); +    return; +  } + +  const WasmEventType *OldType = cast<EventSymbol>(Existing)->getEventType(); +  const WasmSignature *OldSig = ExistingEvent->Signature; +  if (NewType->Attribute != OldType->Attribute) +    error("Event type mismatch: " + Existing->getName() + "\n>>> defined as " + +          toString(*OldType) + " in " + toString(Existing->getFile()) + +          "\n>>> defined as " + toString(*NewType) + " in " + toString(File)); +  if (*NewSig != *OldSig) +    warn("Event signature mismatch: " + Existing->getName() + +         "\n>>> defined as " + toString(*OldSig) + " in " + +         toString(Existing->getFile()) + "\n>>> defined as " + +         toString(*NewSig) + " in " + toString(File)); +} +  static void checkDataType(const Symbol *Existing, const InputFile *File) {    if (!isa<DataSymbol>(Existing))      reportTypeError(Existing, File, WASM_SYMBOL_TYPE_DATA); @@ -158,15 +173,15 @@ DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,    LLVM_DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");    assert(!find(Name));    SyntheticFunctions.emplace_back(Function); -  return replaceSymbol<DefinedFunction>(insert(Name).first, Name, Flags, -                                        nullptr, Function); +  return replaceSymbol<DefinedFunction>(insert(Name, nullptr).first, Name, +                                        Flags, nullptr, Function);  }  DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name,                                                   uint32_t Flags) {    LLVM_DEBUG(dbgs() << "addSyntheticDataSymbol: " << Name << "\n");    assert(!find(Name)); -  return replaceSymbol<DefinedData>(insert(Name).first, Name, Flags); +  return replaceSymbol<DefinedData>(insert(Name, nullptr).first, Name, Flags);  }  DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags, @@ -175,8 +190,8 @@ DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t Flags,                      << "\n");    assert(!find(Name));    SyntheticGlobals.emplace_back(Global); -  return replaceSymbol<DefinedGlobal>(insert(Name).first, Name, Flags, nullptr, -                                      Global); +  return replaceSymbol<DefinedGlobal>(insert(Name, nullptr).first, Name, Flags, +                                      nullptr, Global);  }  static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, @@ -210,13 +225,12 @@ static bool shouldReplace(const Symbol *Existing, InputFile *NewFile,  Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,                                          InputFile *File,                                          InputFunction *Function) { -  LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n"); +  LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " [" +                    << (Function ? toString(Function->Signature) : "none") +                    << "]\n");    Symbol *S;    bool WasInserted; -  std::tie(S, WasInserted) = insert(Name); - -  if (!File || File->kind() == InputFile::ObjectKind) -    S->IsUsedInRegularObj = true; +  std::tie(S, WasInserted) = insert(Name, File);    if (WasInserted || S->isLazy()) {      replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); @@ -226,8 +240,16 @@ Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags,    if (Function)      checkFunctionType(S, File, &Function->Signature); -  if (shouldReplace(S, File, Flags)) -    replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); +  if (shouldReplace(S, File, Flags)) { +    // If the new defined function doesn't have signture (i.e. bitcode +    // functions) but the old symbols does then preserve the old signature +    const WasmSignature *OldSig = nullptr; +    if (auto* F = dyn_cast<FunctionSymbol>(S)) +      OldSig = F->Signature; +    auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); +    if (!NewSym->Signature) +      NewSym->Signature = OldSig; +  }    return S;  } @@ -238,10 +260,7 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,                      << "\n");    Symbol *S;    bool WasInserted; -  std::tie(S, WasInserted) = insert(Name); - -  if (!File || File->kind() == InputFile::ObjectKind) -    S->IsUsedInRegularObj = true; +  std::tie(S, WasInserted) = insert(Name, File);    if (WasInserted || S->isLazy()) {      replaceSymbol<DefinedData>(S, Name, Flags, File, Segment, Address, Size); @@ -258,12 +277,10 @@ Symbol *SymbolTable::addDefinedData(StringRef Name, uint32_t Flags,  Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,                                        InputFile *File, InputGlobal *Global) {    LLVM_DEBUG(dbgs() << "addDefinedGlobal:" << Name << "\n"); +    Symbol *S;    bool WasInserted; -  std::tie(S, WasInserted) = insert(Name); - -  if (!File || File->kind() == InputFile::ObjectKind) -    S->IsUsedInRegularObj = true; +  std::tie(S, WasInserted) = insert(Name, File);    if (WasInserted || S->isLazy()) {      replaceSymbol<DefinedGlobal>(S, Name, Flags, File, Global); @@ -277,17 +294,35 @@ Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags,    return S;  } +Symbol *SymbolTable::addDefinedEvent(StringRef Name, uint32_t Flags, +                                     InputFile *File, InputEvent *Event) { +  LLVM_DEBUG(dbgs() << "addDefinedEvent:" << Name << "\n"); + +  Symbol *S; +  bool WasInserted; +  std::tie(S, WasInserted) = insert(Name, File); + +  if (WasInserted || S->isLazy()) { +    replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event); +    return S; +  } + +  checkEventType(S, File, &Event->getType(), &Event->Signature); + +  if (shouldReplace(S, File, Flags)) +    replaceSymbol<DefinedEvent>(S, Name, Flags, File, Event); +  return S; +} +  Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags,                                            InputFile *File,                                            const WasmSignature *Sig) { -  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n"); +  LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << +             " [" << (Sig ? toString(*Sig) : "none") << "]\n");    Symbol *S;    bool WasInserted; -  std::tie(S, WasInserted) = insert(Name); - -  if (!File || File->kind() == InputFile::ObjectKind) -    S->IsUsedInRegularObj = true; +  std::tie(S, WasInserted) = insert(Name, File);    if (WasInserted)      replaceSymbol<UndefinedFunction>(S, Name, Flags, File, Sig); @@ -305,10 +340,7 @@ Symbol *SymbolTable::addUndefinedData(StringRef Name, uint32_t Flags,    Symbol *S;    bool WasInserted; -  std::tie(S, WasInserted) = insert(Name); - -  if (!File || File->kind() == InputFile::ObjectKind) -    S->IsUsedInRegularObj = true; +  std::tie(S, WasInserted) = insert(Name, File);    if (WasInserted)      replaceSymbol<UndefinedData>(S, Name, Flags, File); @@ -326,10 +358,7 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef Name, uint32_t Flags,    Symbol *S;    bool WasInserted; -  std::tie(S, WasInserted) = insert(Name); - -  if (!File || File->kind() == InputFile::ObjectKind) -    S->IsUsedInRegularObj = true; +  std::tie(S, WasInserted) = insert(Name, File);    if (WasInserted)      replaceSymbol<UndefinedGlobal>(S, Name, Flags, File, Type); @@ -346,7 +375,7 @@ void SymbolTable::addLazy(ArchiveFile *File, const Archive::Symbol *Sym) {    Symbol *S;    bool WasInserted; -  std::tie(S, WasInserted) = insert(Name); +  std::tie(S, WasInserted) = insert(Name, nullptr);    if (WasInserted) {      replaceSymbol<LazySymbol>(S, Name, File, *Sym);  | 
