[PATCH] D86701: [LLD] [COFF] Error out if creating a DLL with too many exported symbols

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 27 05:00:29 PDT 2020


mstorsjo created this revision.
mstorsjo added reviewers: amccarth, MaskRay, ruiu.
Herald added a reviewer: alexshap.
Herald added a project: LLVM.
mstorsjo requested review of this revision.

The PE/DLL format has a limit on 64k exported symbols per DLL; make sure to check this.

TODO: What's a neat way of testing this? The test object file I used for testing it weighs in at 3.8 MB (generated from a C source file at around 3.0 MB), so checking in that is a bit unwieldy. It can be gzipped, but even then it's >500 KB. There's a test helper script for unzipping test inputs in llvm/test/tools/llvm-objcopy/Inputs/ungzip.py, that would have to be moved to a more central location if we'd use it in a lld test. Or can we generate inputs for this within a test reasonably quickly?

My test input was generated with `i=0; while [ $i -lt 65536 ]; do echo "__declspec(dllexport) void func$i(void) { }" >> dllexport65536.c; i=$(($i+1)); done` and compiling that. I guess it could be possible to do the same by just having one func and having 64k export directives, for exporting the one function under a number of different names, but the issue of neatly passing those 64k export directives remains.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86701

Files:
  lld/COFF/DriverUtils.cpp


Index: lld/COFF/DriverUtils.cpp
===================================================================
--- lld/COFF/DriverUtils.cpp
+++ lld/COFF/DriverUtils.cpp
@@ -32,6 +32,7 @@
 #include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/WindowsManifest/WindowsManifestMerger.h"
+#include <limits>
 #include <memory>
 
 using namespace llvm::COFF;
@@ -673,12 +674,15 @@
 
 void assignExportOrdinals() {
   // Assign unique ordinals if default (= 0).
-  uint16_t max = 0;
+  uint32_t max = 0;
   for (Export &e : config->exports)
-    max = std::max(max, e.ordinal);
+    max = std::max(max, (uint32_t)e.ordinal);
   for (Export &e : config->exports)
     if (e.ordinal == 0)
       e.ordinal = ++max;
+  if (max > std::numeric_limits<uint16_t>::max())
+    fatal("too many exported symbols (max " +
+          Twine(std::numeric_limits<uint16_t>::max()) + ")");
 }
 
 // Parses a string in the form of "key=value" and check


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D86701.288286.patch
Type: text/x-patch
Size: 952 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200827/9c93dec2/attachment.bin>


More information about the llvm-commits mailing list