[lld] r358394 - [COFF] Link crtend.o as the last object file
Martin Storsjo via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 15 03:57:45 PDT 2019
Author: mstorsjo
Date: Mon Apr 15 03:57:44 2019
New Revision: 358394
URL: http://llvm.org/viewvc/llvm-project?rev=358394&view=rev
Log:
[COFF] Link crtend.o as the last object file
When faced with command line options such as "crtbegin.o appmain.o
-lsomelib crtend.o", GNU ld pulls in all necessary object files from
somelib before proceeding to crtend.o.
LLD operates differently, only loading object files from any
referenced static libraries after processing all input object files.
This uses a similar hack as in the ELF linker. Here, it moves crtend.o
to the end of the vector of object files. This makes sure that
terminator chunks for sections such as .eh_frame gets ordered last,
fixing DWARF exception handling for libgcc and gcc's crtend.o.
Differential Revision: https://reviews.llvm.org/D60628
Added:
lld/trunk/test/COFF/Inputs/eh_frame_terminator-crtend.s
lld/trunk/test/COFF/Inputs/eh_frame_terminator-otherfunc.s
lld/trunk/test/COFF/eh_frame_terminator.s
Modified:
lld/trunk/COFF/Driver.cpp
lld/trunk/docs/ReleaseNotes.rst
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=358394&r1=358393&r2=358394&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Mon Apr 15 03:57:44 2019
@@ -91,6 +91,16 @@ static std::string getOutputPath(StringR
return (S.substr(0, S.rfind('.')) + E).str();
}
+// Returns true if S matches /crtend.?\.o$/.
+static bool isCrtend(StringRef S) {
+ if (!S.endswith(".o"))
+ return false;
+ S = S.drop_back(2);
+ if (S.endswith("crtend"))
+ return true;
+ return !S.empty() && S.drop_back().endswith("crtend");
+}
+
// ErrorOr is not default constructible, so it cannot be used as the type
// parameter of a future.
// FIXME: We could open the file in createFutureForFile and avoid needing to
@@ -1665,11 +1675,28 @@ void LinkerDriver::link(ArrayRef<const c
return;
}
- // In MinGW, all symbols are automatically exported if no symbols
- // are chosen to be exported.
- if (Config->MinGW)
+ if (Config->MinGW) {
+ // In MinGW, all symbols are automatically exported if no symbols
+ // are chosen to be exported.
maybeExportMinGWSymbols(Args);
+ // Make sure the crtend.o object is the last object file. This object
+ // file can contain terminating section chunks that need to be placed
+ // last. GNU ld processes files and static libraries explicitly in the
+ // order provided on the command line, while lld will pull in needed
+ // files from static libraries only after the last object file on the
+ // command line.
+ for (auto I = ObjFile::Instances.begin(), E = ObjFile::Instances.end();
+ I != E; I++) {
+ ObjFile *File = *I;
+ if (isCrtend(File->getName())) {
+ ObjFile::Instances.erase(I);
+ ObjFile::Instances.push_back(File);
+ break;
+ }
+ }
+ }
+
// Windows specific -- when we are creating a .dll file, we also
// need to create a .lib file.
if (!Config->Exports.empty() || Config->DLL) {
Modified: lld/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/docs/ReleaseNotes.rst?rev=358394&r1=358393&r2=358394&view=diff
==============================================================================
--- lld/trunk/docs/ReleaseNotes.rst (original)
+++ lld/trunk/docs/ReleaseNotes.rst Mon Apr 15 03:57:44 2019
@@ -37,7 +37,9 @@ COFF Improvements
MinGW Improvements
------------------
-* ...
+* lld now correctly links crtend.o as the last object file, handling
+ terminators for the sections such as .eh_frame properly, fixing
+ DWARF exception handling with libgcc and gcc's crtend.o.
MachO Improvements
------------------
Added: lld/trunk/test/COFF/Inputs/eh_frame_terminator-crtend.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/eh_frame_terminator-crtend.s?rev=358394&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/eh_frame_terminator-crtend.s (added)
+++ lld/trunk/test/COFF/Inputs/eh_frame_terminator-crtend.s Mon Apr 15 03:57:44 2019
@@ -0,0 +1,3 @@
+ .section .eh_frame,"dr"
+__FRAME_END__:
+ .byte 3
Added: lld/trunk/test/COFF/Inputs/eh_frame_terminator-otherfunc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/eh_frame_terminator-otherfunc.s?rev=358394&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/eh_frame_terminator-otherfunc.s (added)
+++ lld/trunk/test/COFF/Inputs/eh_frame_terminator-otherfunc.s Mon Apr 15 03:57:44 2019
@@ -0,0 +1,7 @@
+ .text
+ .globl otherfunc
+otherfunc:
+ ret
+
+ .section .eh_frame,"dr"
+ .byte 2
Added: lld/trunk/test/COFF/eh_frame_terminator.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/eh_frame_terminator.s?rev=358394&view=auto
==============================================================================
--- lld/trunk/test/COFF/eh_frame_terminator.s (added)
+++ lld/trunk/test/COFF/eh_frame_terminator.s Mon Apr 15 03:57:44 2019
@@ -0,0 +1,26 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows-gnu %s -o %t.main.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows-gnu \
+// RUN: %p/Inputs/eh_frame_terminator-otherfunc.s -o %t.otherfunc.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows-gnu \
+// RUN: %p/Inputs/eh_frame_terminator-crtend.s -o %t.crtend.o
+// RUN: rm -f %t.otherfunc.lib
+// RUN: llvm-ar rcs %t.otherfunc.lib %t.otherfunc.o
+// RUN: lld-link -lldmingw %t.main.o %t.otherfunc.lib %t.crtend.o -out:%t.exe
+// RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+ .text
+ .globl main
+main:
+ call otherfunc
+ ret
+
+ .globl mainCRTStartup
+mainCRTStartup:
+ call main
+
+ .section .eh_frame,"dr"
+ .byte 1
+
+// CHECK: Contents of section .eh_fram:
+// CHECK-NEXT: 140003000 010203
More information about the llvm-commits
mailing list