[lld] [LLD] [COFF] Preserve directives and export names from LTO objects (PR #78802)

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 19 14:36:33 PST 2024


https://github.com/mstorsjo created https://github.com/llvm/llvm-project/pull/78802

The export names are saved as StringRefs pointing into the COFF directives. In the case of LTO objects, this can be memory allocated that is owned by the LTO InputFile, which gets destructed when doing the compilation.

In the case of LTO objects from an older version of LLVM, which require being upgraded when loaded, the directives string gets destructed, while when using LTO objects of a matching version (the common case), the directives string points into memory that doesn't get destructed on LTO compilation.

Test this by linking a bundled binary LTO object file, from an older version of LLVM.

This fixes issue #78591, and downstream issue https://github.com/mstorsjo/llvm-mingw/issues/392.

>From c8f8f29456bbee9b3712f50e58d8feae3618c162 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Sat, 20 Jan 2024 00:28:24 +0200
Subject: [PATCH] [LLD] [COFF] Preserve directives and export names from LTO
 objects

The export names are saved as StringRefs pointing into the
COFF directives. In the case of LTO objects, this can be
memory allocated that is owned by the LTO InputFile, which
gets destructed when doing the compilation.

In the case of LTO objects from an older version of LLVM, which
require being upgraded when loaded, the directives string gets
destructed, while when using LTO objects of a matching
version (the common case), the directives string points into
memory that doesn't get destructed on LTO compilation.

Test this by linking a bundled binary LTO object file, from
an older version of LLVM.

This fixes issue #78591.
---
 lld/COFF/InputFiles.cpp                 |   2 +-
 lld/test/COFF/Inputs/lto-directives.obj | Bin 0 -> 2316 bytes
 lld/test/COFF/lto-directives.test       |  15 +++++++++++++++
 3 files changed, 16 insertions(+), 1 deletion(-)
 create mode 100644 lld/test/COFF/Inputs/lto-directives.obj
 create mode 100644 lld/test/COFF/lto-directives.test

diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index cd744800cb0dec4..22cc0e3e5dbaf73 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -1081,7 +1081,7 @@ void BitcodeFile::parse() {
     if (objSym.isUsed())
       ctx.config.gcroot.push_back(sym);
   }
-  directives = obj->getCOFFLinkerOpts();
+  directives = saver.save(obj->getCOFFLinkerOpts());
 }
 
 void BitcodeFile::parseLazy() {
diff --git a/lld/test/COFF/Inputs/lto-directives.obj b/lld/test/COFF/Inputs/lto-directives.obj
new file mode 100644
index 0000000000000000000000000000000000000000..a413b0ab92f4e43833627109e869a402ad98d5b7
GIT binary patch
literal 2316
zcma)8e{2)i9e<8P&Jc4pkhMv3cibgmO<74UPDt$7k!&Bdri)ZV*_2I8_;;N)n2TfL
zBt?~vb9Y7!EFk~kKbT~%Okz_z1u1_p2~Bp+P2J2zDXJ=zS&>Zw7!+94vI%L`w(lAC
z|DN=H at B4lC-uHcfe7;}X&SlpQHX*bPA>`4r9dG^OFM-egweXw9qp at KX>@iw|o&nQX
z$DlfpUjo8}_Di-x{gDQ}!E{*_*Y4Y<X`$*r_QbS@>+F{s?LNJs$*5`m=?;S-;o$R3
z`=Q;^tloCH&R5V}Z=$(367-iUgCX9$zjOaw&)NACmuR^Fde77F4y=Z at f`<0Ifta6k
zq_oUFm|9-desp!tW$>M#JG|%8*LI;jKH7B=Y0=SUgsgC<^={j<|G-f3XnUtfYwLeU
z-p-M$F><*=EDGdmmRfcb)e5<h+4+Pa3j(#Gim79~6b-6p<|ICbO*ycrQR)v$d>V_O
zs*QS-A&`fvGQ^UbTt(DIg{)?XC4pMAQL9$sQI05P2+($)A)mrY3)0MJuxX<dPD}mG
z*wi%)?cK`at698?Xi&0IA(jPdHA^frL^VTgWQhB!5pg_=SzO{l7CW25rhy4clUb~P
zM4V1ZVGvW&bSGv429DiO$I{XaFNK5Rcubl>w=zTt3}DD5B~9oE#6e;9oCC_&-u^I$
zSJOKm<;ZVy<XVL))jTf=1n~DWJ6GM*rkl7+>q=I<oZVS=iLWKO)&-F&ajjXAD5;2Q
zj(|871!6&EDdfm}jaN2pwF3fC704BVx}zc&Y=bZ>qOCQhrm_N+7l^X0^@f_N+K4;P
zFV?;m?L<LE1>@}19CEBTa{JSIgfxl+R)lD@!|D;ONB at mb>~+}3VB0`J_IC}>&2Ink
zn at jbaXM2;)mXvEZ&~@<n&v2$!6C?5!BG9B7N^r)wJZq0((^J?)YFv9C=^pFxr!l-&
zYo``-Bt$L1ZmS&=TZ`(U0yi|P9x6`FMtJN4$e%;vd2EJPPfkfZEwvPP;hS at Kh1G>v
z-TD^3<-~jSd2)>*?l9z{n+mY!%{N8!3TIkSTW*S$xY}IYYMOLm9|W<1AfyT#h)F!a
z%Y{vLVw2Cdf!b(HI;oMyo24*hHzmCOWD9>%#{ZGUH(9l(pg`(5u!xdd!Af2rm)#BD
z&T*y!XG+!P8?rIU853%AQtpOFe>i9UMs1##wO@=%{D>6h#YhmFa!HY9DUz02ZoQ*>
zf^^?G at r^lr-Kwk5_$GKkcao(XwP>SmGek+CN at V~j`A9_tnvWXixxp)<x#;Y8;fPC$
zPGM82qr*?<bV>xM_iDAokZU>eLzM#MB13Mu8;*Y at 8jG@do*ROI{IF=*;LHgS<=M}7
zfTvOv?9pH|ome;}oLJZ6n_2vx6aSuV&)v2`b-jG2Lau=Uju!L0IJ6+P#%1FyXDZ5;
z8#z-!1|Ka&$HKS<1FOa%fFn}N-<I%Am+o=7VT;z?V|Djv-9MdpNRO|xIEdeu8y=SN
z4JZDLZNCdphc0lZ^71A_LdE785;9n2_6F$Rns0JLH`J!2Xey4}gzST}P{}h6DauPN
ze|>=eoz+#!_(QAiVH#eMRqBar82EBB1yE5U99e->3UQmMEJNsqAX7zaK20uX$g+)E
z%MpPNFN;@{{OUl-J(gp{GtJn9Lpqt3&c@*G^`y!&D_fGXafKTMI29pcS_ktZyPE=2
zZ{^5iLKB*%5qcA_9;O^Lm(aFs4;vhGyD)p{($|O5`c9vv$6&uW$9xi`y{fmu#O^^j
z8}$a=;gb`iGk)h0jvn?;`p3>hBW}-_|9EgTG<^K+!y!d at haVe_fb_G_Xv90_4!uiH
z`oj~Wr$cm4e;3=;M|TDz5q at H@yZhbINbroO%X|7%_t at Cv^XUK|KK-8G8|i|NwA<fj
z=rQ$synUwLK)`Pt7;q2xdwqd`(c|wmu)PO;es`ab9e543YYwsJteSRB9u_ at FJu+Wk
z&~j~buXZ_BWQn{%=9|9I3QW7OeK~RAt3Q49`^OhPz4%%2^VtKNW1*zS{mO$QA1V9$
zE__<N5K5xDKR`ct75r}85$=RK!)8YK6y#P(i)lqZcb{0w?1aV+Z2;n0t>O2jzI7M=
zzzJoc+fa%__rQriosS9FbZ4z<rzAj}g4q%Nifmj^nXigNNxANQXaGd1LX>D?!>!C!
zfm(DED;c8j9BA&GO81o3Rh&BLJ&lQ4!j*Q0zJ|Wm04r9sTouh%porB&Y0&}&Jtr&u
z+fBdd<Ml#a4){F?p-<|+bgJ6^h!{gWp=a!Q&G}cX2`$rhD53AMAH(%+-gy2dedyPT
zUAw=F>09i_eyMNs#pB=5zPPW%+P9%b)io8$x@@3p9CWH-HNdqv+ECcq at Wb!?Uf_1C
zlUvG$@<I7e&<!*Uq}VnBqzq+MWL^<q^Z~U2{TxW~?F0}G^uO=G*3K)dG8DbaP*&wP
z8+Ft~^eeD|0v2p|r0n=Zk?`~j4F12!nlkpE?C(2pCiH&jbTo7zIvVnwj!qmnH8JV!
eF?AW(F7}jrG}Ps#yAO{z-#&JHu=dFF_x}sNRUJ_P

literal 0
HcmV?d00001

diff --git a/lld/test/COFF/lto-directives.test b/lld/test/COFF/lto-directives.test
new file mode 100644
index 000000000000000..5890d426764c4e9
--- /dev/null
+++ b/lld/test/COFF/lto-directives.test
@@ -0,0 +1,15 @@
+; REQUIRES: x86
+
+;; Test linking an LTO object file that contains directives. The
+;; LTO object file is built with an older toolchain, to force it
+;; to be upgraded when loaded.
+
+;; The input file is compiled from source that looks like this:
+;;   void __declspec(dllexport) entry(void) { }
+;; with this command:
+;;   clang -target x86_64-windows-msvc -c main.c -flto
+
+; RUN: lld-link /entry:entry /subsystem:console %p/Inputs/lto-directives.obj /dll /out:%t.dll
+; RUN: llvm-readobj --coff-exports %t.dll | FileCheck %s
+
+; CHECK: Name: entry



More information about the llvm-commits mailing list