[lld] 4e5a59a - [LLD][COFF] Fix writing a map file when range extension thunks are inserted

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 6 23:35:03 PDT 2022


Author: Jan Ole Hüser
Date: 2022-09-07T09:26:41+03:00
New Revision: 4e5a59a3839f54d928d37d49d4c4ddbb3f339b76

URL: https://github.com/llvm/llvm-project/commit/4e5a59a3839f54d928d37d49d4c4ddbb3f339b76
DIFF: https://github.com/llvm/llvm-project/commit/4e5a59a3839f54d928d37d49d4c4ddbb3f339b76.diff

LOG: [LLD][COFF] Fix writing a map file when range extension thunks are inserted

Bug: An assertion fails:

    Assertion failed: isa<To>(Val) && "cast<Ty>() argument of incompatible type!",
    file C:\Users\<user>\prog\llvm\llvm-git-lld-bug\llvm\include\llvm/Support/Casting.h, line 578

Bug is triggered, if

    - a map file is requested with /MAP, and
    - Architecture is ARMv7, Thumb, and
    - a relative jump (branch instruction) is greater than 16 MiB (2^24)

The reason for the Bug is:

    - a Thunk is created for the jump
    - a Symbol for the Thunk is created
        - of type `DefinedSynthetic`
        - in file `Writer.cpp`
        - in function `getThunk`
    - the Symbol has no name
    - when creating the map file, the name of the Symbol is queried
    - the function `Symbol::computeName` of the base class `Symbol`
      casts the `this` pointer to type `DefinedCOFF` (a derived type),
      but the acutal type is `DefinedSynthetic`
    - The in the llvm::cast an assertion fails

Changes:

- Modify regression test to trigger this bug
- Give the symbol pointing to the thunk a name, to fix the bug
- Add assertion, that only DefinedCOFF symbols are allowed to have an
  empty name, when the constructor of the base class Symbol is executed

Reviewed By: rnk

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

Added: 
    

Modified: 
    lld/COFF/Symbols.h
    lld/COFF/Writer.cpp
    lld/test/COFF/arm-thumb-thunks.s
    lld/test/COFF/arm64-thunks.s

Removed: 
    


################################################################################
diff  --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h
index c8865d128fb84..a4c6f893f10cf 100644
--- a/lld/COFF/Symbols.h
+++ b/lld/COFF/Symbols.h
@@ -106,7 +106,10 @@ class Symbol {
       : symbolKind(k), isExternal(true), isCOMDAT(false),
         writtenToSymtab(false), pendingArchiveLoad(false), isGCRoot(false),
         isRuntimePseudoReloc(false), deferUndefined(false), canInline(true),
-        nameSize(n.size()), nameData(n.empty() ? nullptr : n.data()) {}
+        nameSize(n.size()), nameData(n.empty() ? nullptr : n.data()) {
+    assert((!n.empty() || k <= LastDefinedCOFFKind) &&
+           "If the name is empty, the Symbol must be a DefinedCOFF.");
+  }
 
   const unsigned symbolKind : 8;
   unsigned isExternal : 1;

diff  --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index c530b21b46865..93521bc1956c4 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -396,7 +396,7 @@ getThunk(DenseMap<uint64_t, Defined *> &lastThunks, Defined *target, uint64_t p,
   default:
     llvm_unreachable("Unexpected architecture");
   }
-  Defined *d = make<DefinedSynthetic>("", c);
+  Defined *d = make<DefinedSynthetic>("range_extension_thunk", c);
   lastThunk = d;
   return {d, true};
 }

diff  --git a/lld/test/COFF/arm-thumb-thunks.s b/lld/test/COFF/arm-thumb-thunks.s
index 2a176b00c6a99..9f01981fefb93 100644
--- a/lld/test/COFF/arm-thumb-thunks.s
+++ b/lld/test/COFF/arm-thumb-thunks.s
@@ -1,6 +1,6 @@
 // REQUIRES: arm
 // RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
-// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -map -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
 // RUN: llvm-objdump -d %t.exe --start-address=0x401000 --stop-address=0x401022 | FileCheck --check-prefix=MAIN %s
 // RUN: llvm-objdump -d %t.exe --start-address=0x501022 --stop-address=0x501032 | FileCheck --check-prefix=FUNC1 %s
 // RUN: llvm-objdump -d %t.exe --start-address=0x601032 | FileCheck --check-prefix=FUNC2 %s

diff  --git a/lld/test/COFF/arm64-thunks.s b/lld/test/COFF/arm64-thunks.s
index 86760ed08c3ad..240af765a1933 100644
--- a/lld/test/COFF/arm64-thunks.s
+++ b/lld/test/COFF/arm64-thunks.s
@@ -1,6 +1,6 @@
 // REQUIRES: aarch64
 // RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj
-// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -map -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
 // RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASM %s
 
 // VERBOSE: Added 2 thunks with margin {{.*}} in 1 passes


        


More information about the llvm-commits mailing list