[PATCH] D82883: [LLD][COFF] Deduplicate .pdata entries

Alexandre Ganea via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 30 08:39:50 PDT 2020


aganea created this revision.
aganea added reviewers: pcc, MaskRay, hans, mstorsjo, cdavis5x, compnerd.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
aganea edited the summary of this revision.
aganea edited the summary of this revision.

When targetting x64, before this patch LLD would generate duplicate RUNTIME_FUNCTION <https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-runtime_function> entries. They are not exactly duplicates //stricto sensu//, because the unwind RVA is different. However the two target UNWIND_INFOs would have the same content. An example out of the final EXE before this patch (I used `dumpbin /unwindinfo ...`):

  0049D0DC 0554E9D0 0554E9F7 06ACBCE8   <- RUNTIME_FUNCTION entry (in .pdata)
     Unwind version: 1                  <- pointed UNWIND_INFO entry (in .xdata)
     Unwind flags: EHANDLER UHANDLER
     Size of prologue: 0x0A
     Count of codes: 2
     Unwind codes:
       0A: ALLOC_SMALL, size=0x30
       06: PUSH_NONVOL, register=rbp
     Handler: 05503340 
  0049D0E8 0554E9D0 0554E9F7 06ACB0E8   <- note the last value (the unwind RVA) is different
     Unwind version: 1                  <- different UNWIND_INFO entry, but same content as above
     Unwind flags: EHANDLER UHANDLER
     Size of prologue: 0x0A
     Count of codes: 2
     Unwind codes:
       0A: ALLOC_SMALL, size=0x30
       06: PUSH_NONVOL, register=rbp
     Handler: 05503340

Unfourtunately this prevents us from using some external (commercial) post-processing tools, which assert if the EXE contains duplicate .pdata entries. This behavior is probably wrong anyway, how would the NT loader handle duplicate entries for the same function?

After this patch, we thusly remove any .pdata entries that have the same starting address. We make those changes directly into the final output stream, because the input .pdata streams need to merged, reallocated & sorted first. This has two side-effects: 1. the output PE section that receives the .pdata ends-up a bit larger than needed. 2. the .xdata entries are not stripped currently since they are part of .text sections (same chunks). But all in all we're talking about a few kbytes wasted. In our case, out of 300,000 RUNTIME_FUNCTION entries, this patch removes about 700, so that's about 14 kb wasted out of a 96 MB EXE.

If reviewers would think of a better way to implement this, I would gladly oblige.

Fixes PR45950.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82883

Files:
  lld/COFF/Writer.cpp
  lld/test/COFF/unwind.test

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D82883.274468.patch
Type: text/x-patch
Size: 6074 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200630/fbeb8d97/attachment.bin>


More information about the llvm-commits mailing list