From 553d4d08d2bee53d2cc19ea5160a0dfbffe12fa9 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 20 Dec 2020 21:04:12 -0800 Subject: [PATCH] [MC] Report locations for .symver errors --- llvm/include/llvm/MC/MCAssembler.h | 7 ++++++- llvm/lib/MC/ELFObjectWriter.cpp | 16 +++++++--------- llvm/lib/MC/MCELFStreamer.cpp | 3 ++- llvm/test/MC/ELF/invalid-symver.s | 7 ------- llvm/test/MC/ELF/multiple-different-symver.s | 6 ------ llvm/test/MC/ELF/multiple-equiv-symver.s | 6 ------ llvm/test/MC/ELF/symver-err.s | 12 ++++++++++++ 7 files changed, 27 insertions(+), 30 deletions(-) delete mode 100644 llvm/test/MC/ELF/invalid-symver.s delete mode 100644 llvm/test/MC/ELF/multiple-different-symver.s delete mode 100644 llvm/test/MC/ELF/multiple-equiv-symver.s create mode 100644 llvm/test/MC/ELF/symver-err.s diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h index 15c0be436fd8..1b76559d33b3 100644 --- a/llvm/include/llvm/MC/MCAssembler.h +++ b/llvm/include/llvm/MC/MCAssembler.h @@ -211,7 +211,12 @@ private: handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup); public: - std::vector> Symvers; + struct Symver { + StringRef Name; + const MCSymbol *Sym; + SMLoc Loc; + }; + std::vector Symvers; /// Construct a new assembler instance. // diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 9cf29ba0a232..d5da8deab0f0 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -1258,9 +1258,9 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { // The presence of symbol versions causes undefined symbols and // versions declared with @@@ to be renamed. - for (const std::pair &P : Asm.Symvers) { - StringRef AliasName = P.first; - const auto &Symbol = cast(*P.second); + for (const MCAssembler::Symver &S : Asm.Symvers) { + StringRef AliasName = S.Name; + const auto &Symbol = cast(*S.Sym); size_t Pos = AliasName.find('@'); assert(Pos != StringRef::npos); @@ -1286,18 +1286,16 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, if (!Symbol.isUndefined() && !Rest.startswith("@@@")) continue; - // FIXME: Get source locations for these errors or diagnose them earlier. if (Symbol.isUndefined() && Rest.startswith("@@") && !Rest.startswith("@@@")) { - Asm.getContext().reportError(SMLoc(), "versioned symbol " + AliasName + - " must be defined"); + Asm.getContext().reportError(S.Loc, "default version symbol " + + AliasName + " must be defined"); continue; } if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) { - Asm.getContext().reportError( - SMLoc(), llvm::Twine("multiple symbol versions defined for ") + - Symbol.getName()); + Asm.getContext().reportError(S.Loc, Twine("multiple versions for ") + + Symbol.getName()); continue; } diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index acd8af13c6aa..17beca1c3556 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -342,7 +342,8 @@ void MCELFStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) { void MCELFStreamer::emitELFSymverDirective(StringRef AliasName, const MCSymbol *Aliasee) { - getAssembler().Symvers.push_back({AliasName, Aliasee}); + getAssembler().Symvers.push_back( + MCAssembler::Symver{AliasName, Aliasee, getStartTokLoc()}); } void MCELFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size, diff --git a/llvm/test/MC/ELF/invalid-symver.s b/llvm/test/MC/ELF/invalid-symver.s deleted file mode 100644 index d9f97b102b57..000000000000 --- a/llvm/test/MC/ELF/invalid-symver.s +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t 2> %t.out -// RUN: FileCheck --input-file=%t.out %s - -// CHECK: error: versioned symbol foo@@bar must be defined - - .symver undefined, foo@@bar - .long undefined diff --git a/llvm/test/MC/ELF/multiple-different-symver.s b/llvm/test/MC/ELF/multiple-different-symver.s deleted file mode 100644 index c34626c08173..000000000000 --- a/llvm/test/MC/ELF/multiple-different-symver.s +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t 2>&1 | FileCheck %s - -// CHECK: error: multiple symbol versions defined for foo - -.symver foo, foo@1 -.symver foo, foo@2 diff --git a/llvm/test/MC/ELF/multiple-equiv-symver.s b/llvm/test/MC/ELF/multiple-equiv-symver.s deleted file mode 100644 index 0ab48f0992d0..000000000000 --- a/llvm/test/MC/ELF/multiple-equiv-symver.s +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s - -// CHECK-NOT: Multiple symbol versions defined for foo - -.symver foo, foo@1 -.symver foo, foo@1 diff --git a/llvm/test/MC/ELF/symver-err.s b/llvm/test/MC/ELF/symver-err.s new file mode 100644 index 000000000000..66640bedba62 --- /dev/null +++ b/llvm/test/MC/ELF/symver-err.s @@ -0,0 +1,12 @@ +# RUN: not llvm-mc -filetype=obj -triple=x86_64 %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: + +# CHECK: {{.*}}.s:[[#@LINE+2]]:1: error: multiple versions for multi +.symver multi, multi@1 +.symver multi, multi@2 + +.symver equiv, equiv@1 +.symver equiv, equiv@1 + +# CHECK: {{.*}}.s:[[#@LINE+1]]:1: error: default version symbol undefined@@v1 must be defined +.symver undefined_2, undefined@@v1 +.long undefined_2