[ELF] Don't suggest an alternative spelling for a symbol in a discarded section
authorFangrui Song <maskray@google.com>
Fri, 20 Dec 2019 00:04:45 +0000 (16:04 -0800)
committerFangrui Song <maskray@google.com>
Mon, 23 Dec 2019 17:10:29 +0000 (09:10 -0800)
For undef-not-suggest.test, we currently make redundant alternative
spelling suggestions:

```
ld.lld: error: relocation refers to a discarded section: .text.foo
>>> defined in a.o
>>> section group signature: foo
>>> prevailing definition is in a.o
>>> referenced by a.o:(.rodata+0x0)
>>> did you mean:
>>> defined in: a.o

ld.lld: error: relocation refers to a symbol in a discarded section: foo
>>> defined in a.o
>>> section group signature: foo
>>> prevailing definition is in a.o
>>> referenced by a.o:(.rodata+0x8)
>>> did you mean: for
>>> defined in: a.o
```

Reviewed By: grimar, ruiu

Differential Revision: https://reviews.llvm.org/D71735

lld/ELF/Relocations.cpp
lld/test/ELF/undef-not-suggest.test [new file with mode: 0644]

index c5aa801..c57585e 100644 (file)
@@ -714,12 +714,19 @@ static bool canSuggestExternCForCXX(StringRef ref, StringRef def) {
 // Suggest an alternative spelling of an "undefined symbol" diagnostic. Returns
 // the suggested symbol, which is either in the symbol table, or in the same
 // file of sym.
+template <class ELFT>
 static const Symbol *getAlternativeSpelling(const Undefined &sym,
                                             std::string &pre_hint,
                                             std::string &post_hint) {
-  // Build a map of local defined symbols.
   DenseMap<StringRef, const Symbol *> map;
-  if (sym.file && !isa<SharedFile>(sym.file)) {
+  if (auto *file = dyn_cast_or_null<ObjFile<ELFT>>(sym.file)) {
+    // If sym is a symbol defined in a discarded section, maybeReportDiscarded()
+    // will give an error. Don't suggest an alternative spelling.
+    if (file && sym.discardedSecIdx != 0 &&
+        file->getSections()[sym.discardedSecIdx] == &InputSection::discarded)
+      return nullptr;
+
+    // Build a map of local defined symbols.
     for (const Symbol *s : sym.file->getSymbols())
       if (s->isLocal() && s->isDefined())
         map.try_emplace(s->getName(), s);
@@ -865,8 +872,8 @@ static void reportUndefinedSymbol(const UndefinedDiag &undef,
 
   if (correctSpelling) {
     std::string pre_hint = ": ", post_hint;
-    if (const Symbol *corrected =
-            getAlternativeSpelling(cast<Undefined>(sym), pre_hint, post_hint)) {
+    if (const Symbol *corrected = getAlternativeSpelling<ELFT>(
+            cast<Undefined>(sym), pre_hint, post_hint)) {
       msg += "\n>>> did you mean" + pre_hint + toString(*corrected) + post_hint;
       if (corrected->file)
         msg += "\n>>> defined in: " + toString(corrected->file);
diff --git a/lld/test/ELF/undef-not-suggest.test b/lld/test/ELF/undef-not-suggest.test
new file mode 100644 (file)
index 0000000..0055aaa
--- /dev/null
@@ -0,0 +1,56 @@
+## Check we don't suggest alternative spelling for relocations to symbols
+## defined in discarded sections.
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld %t.o %t.o -o /dev/null 2>&1 | FileCheck %s
+
+# CHECK-NOT: did you mean:
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .group
+    Type: SHT_GROUP
+    Link: .symtab
+    Info: foo
+    Members:
+      - SectionOrType: GRP_COMDAT
+      - SectionOrType: .text.foo
+  - Name:  .text.foo
+    Type:  SHT_PROGBITS
+    Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+  - Name:  .rodata
+    Type:  SHT_PROGBITS
+    Flags: [ SHF_ALLOC ]
+  - Name: .rela.rodata
+    Type: SHT_RELA
+    Link: .symtab
+    Info: .rodata
+    Relocations:
+      ## Relocation which references ".text.foo". Check we don't suggest the
+      ## section symbol for ".data", which has an empty name.
+      - Offset: 0x0
+        ## .text.foo
+        Symbol: 1
+        Type:   R_X86_64_64
+      ## Relocation which references "foo". Check we don't suggest "for".
+      - Offset: 0x8
+        Symbol: foo
+        Type:   R_X86_64_64
+  - Name: .data
+    Type: SHT_PROGBITS
+Symbols:
+  - Name:    ""
+    Type:    STT_SECTION
+    Section: .text.foo
+  - Name:    ""
+    Type:    STT_SECTION
+    Section: .data
+  - Name:    foo
+    Section: .text.foo
+  - Name:    for
+    Section: .data