llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.38k stars 12.15k forks source link

lld creates `.00cfg` and `.voltbl` sections, link.exe doesn't #44456

Open vrubleg opened 4 years ago

vrubleg commented 4 years ago
Bugzilla Link 45111
Version unspecified
OS Windows NT
CC @rnk

Extended Description

The issue is easy to reproduce using the latest clang from https://llvm.org/builds/ (Git commit 2663a25f, 3 February 2020).

  1. Create test.cpp with these contents:

include

int wmain(int argc, wchar_t* argv[]) { printf("Hello, world!"); return 0; }

  1. Compile it and link using lld: clang -std=c++17 -m32 -fuse-ld=lld -Oz -Wl,-subsystem:console,-merge:.rdata=.text,-out:test1.exe test.cpp

  2. Compile it and link using default link.exe: clang -std=c++17 -m32 -Oz -Wl,-subsystem:console,-merge:.rdata=.text,-out:test2.exe test.cpp

  3. Compare section lists of the test1.exe and test2.exe. The test1.exe (linked by lld) does have .00cfg and .voltbl sections; the test2.exe (linked by default linker, link.exe I suppose) doesn't have these sections.

Repro files (with all the libraries) are here: http://veg.by/files/temp/lld_00cfg_repro.7z

It seems that these sections come from standard VC++ and Windows SDK libraries. I guess that it is expected that lld should behave like link.exe. So, probably it is worth to investigate what causes this difference.

vrubleg commented 4 years ago

A comment from YongKang Zhu [MSFT]:

PE-COFF document has been updated with more descriptions on associative COMDAT section, especially on multi-level association case.

As to that symbol for section A (that section B is associated with) has to show up earlier in COFF symbol table before the symbol for section B, there is no mention of this in the original PE-COFF document, so we just keep it that way and don't add this into spec now.

vrubleg commented 4 years ago

The spec has been updated again to clarify the question related to possible loops: https://github.com/MicrosoftDocs/win32/compare/7ddf2ceff076edb3effb6f9326307c3bbf862cfb..d86a62d2a66a033cae105f063f30b9e62ab760c1

vrubleg commented 4 years ago

Microsoft has made this small change to the PE spec which is related to this issue: https://github.com/MicrosoftDocs/win32/commit/ccf71b16e5b50f3c8acf0bba2de13bfa5f513e36

vrubleg commented 4 years ago

These pages are related to .voltbl: https://bugs.chromium.org/p/chromium/issues/detail?id=925943 https://developercommunity.visualstudio.com/content/problem/441151/vc-generatesships-obj-files-with-illegal-associati.html?childToView=470388

rnk commented 4 years ago

It's true, .00cfg has been around for a while, and I've wanted to figure out what VC link does with it. I'm not familiar with .voltbl, but we should look into it.

vrubleg commented 4 years ago

The -merge:.rdata=.text argument can be removed from the command line, it doesn't affect creation of these sections.

The .00cfg section is apparently somehow related to Control Flow Graph.

rnk commented 2 years ago

@aganea shared some info on these sections which I wasn't able to find:

.00cfg is for "Control Flow Guard", there's a pretty good explanation in the answers: [1] (and if you follow the links as well) .voltbl is for "Volatile Metadata" for x86 emulation on ARM64, see [2]. Also thread in [3], and [4] and [5].

[1] https://reverseengineering.stackexchange.com/questions/19593/00cfg-section-in-the-pe-file [2] https://devblogs.microsoft.com/cppblog/msvc-backend-updates-in-visual-studio-2019-version-16-10-preview-2/ [3] https://twitter.com/ericbrumer/status/1422305190414217244 [4] https://github.com/ocaml/ocaml/commit/0ac73587579bb6648dac6aee2b58fb873bd652a6 [5] https://github.com/alainfrisch/flexdll/commit/bd49188b437c60dfdbc7cbed992efac03dc8303f

I think it is important for LLD to support control flow guard. I don't think it makes sense for LLVM to implement the volatile metadata scheme. We already have decent support for targeting Windows ARM64 directly.