[PATCH] D82883: [LLD][COFF] Deduplicate .pdata entries
Alexandre Ganea via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 15:42:12 PDT 2020
aganea added subscribers: ruiu, majnemer, rnk.
aganea added a comment.
I've digged a bit more. The issue is that the ICF improperly folds `.text$x` sections (catch funclets) but not always the "associated" `.pdata` and `.xdata` records, in part because those additional sections are attached to `.text$mn` not to `.text$x`. This occurs only with MSVC-cl built OBJs, Clang does not create separate `.text$x` sections for catch functlets (rather, they are merged into the function `.text`). I'm seeing the bug when linking with the FBX SDK 2016.1 VS2015 <https://www.autodesk.com/developer-network/platform-technologies/fbx-sdk-2016-1> (`lib\vs2015\x64\release\libfbxsdk-mt.lib`).
The COFF table for `fbxmesh.obj` in the archive above looks like this:
11C 00000000 SECT88 notype Static | .text$mn
Section length 52, #relocs 2, #linenums 0, checksum 270664C2, selection 2 (pick any)
11E 00000000 SECT89 notype Static | .text$x <<<< ----- this is de-duplicated, probably it shouldn't be ----- >>>>
Section length 20, #relocs 2, #linenums 0, checksum 7C6EA17D, selection 5 (pick associative Section 0x88)
...
817 00000000 SECT160 notype Static | .xdata
Section length 10, #relocs 2, #linenums 0, checksum DFA6EA80, selection 5 (pick associative Section 0x88)
819 00000000 SECT160 notype Static | $unwind$?_Buyheadnode@?$_Tree_comp_alloc at V?$_Tmap_traits at HHU?$less at H@std@@V?$allocator at U?$pair@$$CBHH at std@@@2@$00 at std@@@std@@QEAAPEAU?$_Tree_node at U?$pair@$$CBHH at std@@PEAX at 2@XZ
81A 00000000 SECT161 notype Static | .pdata
Section length C, #relocs 3, #linenums 0, checksum 1703F4BB, selection 5 (pick associative Section 0x88)
81C 00000000 SECT161 notype Static | $pdata$?_Buyheadnode@?$_Tree_comp_alloc at V?$_Tmap_traits at HHU?$less at H@std@@V?$allocator at U?$pair@$$CBHH at std@@@2@$00 at std@@@std@@QEAAPEAU?$_Tree_node at U?$pair@$$CBHH at std@@PEAX at 2@XZ
81D 00000000 SECT162 notype Static | .rdata
Section length 28, #relocs 3, #linenums 0, checksum 849A3B3, selection 5 (pick associative Section 0x88)
81F 00000000 SECT162 notype Static | $cppxdata$?_Buyheadnode@?$_Tree_comp_alloc at V?$_Tmap_traits at HHU?$less at H@std@@V?$allocator at U?$pair@$$CBHH at std@@@2@$00 at std@@@std@@QEAAPEAU?$_Tree_node at U?$pair@$$CBHH at std@@PEAX at 2@XZ
820 00000000 SECT163 notype Static | .xdata
Section length 10, #relocs 0, #linenums 0, checksum 8999943C, selection 5 (pick associative Section 0x88)
822 00000000 SECT163 notype Static | $stateUnwindMap$?_Buyheadnode@?$_Tree_comp_alloc at V?$_Tmap_traits at HHU?$less at H@std@@V?$allocator at U?$pair@$$CBHH at std@@@2@$00 at std@@@std@@QEAAPEAU?$_Tree_node at U?$pair@$$CBHH at std@@PEAX at 2@XZ
823 00000000 SECT164 notype Static | .xdata
Section length 14, #relocs 1, #linenums 0, checksum 570F4CF1, selection 5 (pick associative Section 0x88)
825 00000000 SECT164 notype Static | $tryMap$?_Buyheadnode@?$_Tree_comp_alloc at V?$_Tmap_traits at HHU?$less at H@std@@V?$allocator at U?$pair@$$CBHH at std@@@2@$00 at std@@@std@@QEAAPEAU?$_Tree_node at U?$pair@$$CBHH at std@@PEAX at 2@XZ
826 00000000 SECT165 notype Static | .xdata
Section length 14, #relocs 1, #linenums 0, checksum 677058, selection 5 (pick associative Section 0x88)
828 00000000 SECT165 notype Static | $handlerMap$0$?_Buyheadnode@?$_Tree_comp_alloc at V?$_Tmap_traits at HHU?$less at H@std@@V?$allocator at U?$pair@$$CBHH at std@@@2@$00 at std@@@std@@QEAAPEAU?$_Tree_node at U?$pair@$$CBHH at std@@PEAX at 2@XZ
829 00000000 SECT166 notype Static | .xdata
Section length 28, #relocs 5, #linenums 0, checksum F9326582, selection 5 (pick associative Section 0x88)
82B 00000000 SECT166 notype Static | $ip2state$?_Buyheadnode@?$_Tree_comp_alloc at V?$_Tmap_traits at HHU?$less at H@std@@V?$allocator at U?$pair@$$CBHH at std@@@2@$00 at std@@@std@@QEAAPEAU?$_Tree_node at U?$pair@$$CBHH at std@@PEAX at 2@XZ
82C 00000000 SECT167 notype Static | .xdata
Section length 10, #relocs 2, #linenums 0, checksum 5840A276, selection 5 (pick associative Section 0x88)
82E 00000000 SECT167 notype Static | $unwind$?catch$0@?0??_Buyheadnode@?$_Tree_comp_alloc at V?$_Tmap_traits at HHU?$less at H@std@@V?$allocator at U?$pair@$$CBHH at std@@@2@$00 at std@@@std@@QEAAPEAU?$_Tree_node at U?$pair@$$CBHH at std@@PEAX at 2@XZ at 4HA
82F 00000000 SECT168 notype Static | .pdata <<<< ----- but this is not de-duplicated ----- >>>>
Section length C, #relocs 3, #linenums 0, checksum F9766256, selection 5 (pick associative Section 0x88)
831 00000000 SECT168 notype Static | $pdata$?catch$0@?0??_Buyheadnode@?$_Tree_comp_alloc at V?$_Tmap_traits at HHU?$less at H@std@@V?$allocator at U?$pair@$$CBHH at std@@@2@$00 at std@@@std@@QEAAPEAU?$_Tree_node at U?$pair@$$CBHH at std@@PEAX at 2@XZ at 4HA
Note how all associative COMDATs are attached to `.text$mn`, none to `.text$x`, this seems to be by design.
This gives this non-trivial graph: https://miro.com/app/board/o9J_klyfWoY=/
F12911723: image.png <https://reviews.llvm.org/F12911723>
In essence, we end up with several `.pdata` entries in the PE pointing to the same `.text$x` address.
I think there should be a rule in the ICF to prevent `.text$x` (SECT89) from being folded if its pointee .xdata and .pdata cannot be folded as well, like here. Although the ICF algorithm seems to work based only on forward dependencies.
I can't find a repro, something else could be involved (the counter for the equivalence classes?).
I've tried the following:
// --- foo.h
void bar(int);
void bar(unsigned);
template <typename T> struct A {
template <typename X> void foo(X a) {
try {
bar(a);
} catch (...) {
throw;
}
}
};
// --- a.cpp
#include "foo.h"
void test(int a) {
A<int> val;
val.foo(a);
}
// --- b.cpp
#include "foo.h"
template <> struct A<unsigned> {
void foo(unsigned a) {
try {
bar(a);
bar(a);
} catch (...) {
throw;
}
}
};
void alttest(unsigned a) {
A<unsigned> val;
val.foo(a);
}
But that doesn't trigger the bug. The issue seems to be occuring on the MS-STL `std::_Tree::_Insert_nohint` function, although from MS-STL VS2015.
There are many other libraries linked in, compiled with VS2019 or VS2017, so the issue could be from elsewhere.
I'm a bit stuck at the point. Would you go with the current patch, or something different in `lld/COFF/ICF.cpp`?
Ideas? @majnemer @rnk @ruiu
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D82883/new/
https://reviews.llvm.org/D82883
More information about the llvm-commits
mailing list