[llvm-dlltool] Implement the --no-leading-underscore option
authorMartin Storsjö <martin@martin.st>
Wed, 7 Jun 2023 11:11:30 +0000 (14:11 +0300)
committerMartin Storsjö <martin@martin.st>
Fri, 9 Jun 2023 18:29:05 +0000 (21:29 +0300)
This requires being able to opt out from adding the leading underscores
in COFFModuleDefinition. Normally it is added automatically for I386
type targets. We could either move the decision entirely to all
callers, letting the caller check the machine type and decide whether
underscores should be added, or keep the logic mostly as is, but allowing
opting out from the behaviour on I386.

I went with keeping the interface as is for now.

Differential Revision: https://reviews.llvm.org/D152363

llvm/include/llvm/Object/COFFModuleDefinition.h
llvm/lib/Object/COFFModuleDefinition.cpp
llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
llvm/lib/ToolDrivers/llvm-dlltool/Options.td
llvm/test/tools/llvm-dlltool/no-leading-underscore.def [new file with mode: 0644]

index c9d8f42..a4ed997 100644 (file)
@@ -41,7 +41,7 @@ struct COFFModuleDefinition {
 
 Expected<COFFModuleDefinition>
 parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine,
-                          bool MingwDef = false);
+                          bool MingwDef = false, bool AddUnderscores = true);
 
 } // End namespace object.
 } // End namespace llvm.
index 0666970..a339497 100644 (file)
@@ -138,8 +138,11 @@ private:
 
 class Parser {
 public:
-  explicit Parser(StringRef S, MachineTypes M, bool B)
-      : Lex(S), Machine(M), MingwDef(B) {}
+  explicit Parser(StringRef S, MachineTypes M, bool B, bool AU)
+      : Lex(S), Machine(M), MingwDef(B), AddUnderscores(AU) {
+    if (Machine != IMAGE_FILE_MACHINE_I386)
+      AddUnderscores = false;
+  }
 
   Expected<COFFModuleDefinition> parse() {
     do {
@@ -234,7 +237,7 @@ private:
       unget();
     }
 
-    if (Machine == IMAGE_FILE_MACHINE_I386) {
+    if (AddUnderscores) {
       if (!isDecorated(E.Name, MingwDef))
         E.Name = (std::string("_").append(E.Name));
       if (!E.ExtName.empty() && !isDecorated(E.ExtName, MingwDef))
@@ -279,7 +282,7 @@ private:
       if (Tok.K == EqualEqual) {
         read();
         E.AliasTarget = std::string(Tok.Value);
-        if (Machine == IMAGE_FILE_MACHINE_I386 && !isDecorated(E.AliasTarget, MingwDef))
+        if (AddUnderscores && !isDecorated(E.AliasTarget, MingwDef))
           E.AliasTarget = std::string("_").append(E.AliasTarget);
         continue;
       }
@@ -349,12 +352,14 @@ private:
   MachineTypes Machine;
   COFFModuleDefinition Info;
   bool MingwDef;
+  bool AddUnderscores;
 };
 
 Expected<COFFModuleDefinition> parseCOFFModuleDefinition(MemoryBufferRef MB,
                                                          MachineTypes Machine,
-                                                         bool MingwDef) {
-  return Parser(MB.getBuffer(), Machine, MingwDef).parse();
+                                                         bool MingwDef,
+                                                         bool AddUnderscores) {
+  return Parser(MB.getBuffer(), Machine, MingwDef, AddUnderscores).parse();
 }
 
 } // namespace object
index a5dcf6c..39bb8dd 100644 (file)
@@ -165,8 +165,9 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> ArgsArr) {
     return 1;
   }
 
-  Expected<COFFModuleDefinition> Def =
-      parseCOFFModuleDefinition(*MB, Machine, /*MingwDef=*/true);
+  bool AddUnderscores = !Args.hasArg(OPT_no_leading_underscore);
+  Expected<COFFModuleDefinition> Def = parseCOFFModuleDefinition(
+      *MB, Machine, /*MingwDef=*/true, AddUnderscores);
 
   if (!Def) {
     llvm::errs() << "error parsing definition\n"
index 6da5dc8..fee408f 100644 (file)
@@ -15,6 +15,9 @@ def d_long : JoinedOrSeparate<["--"], "input-def">, Alias<d>;
 def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">;
 def k_alias: Flag<["--"], "kill-at">, Alias<k>;
 
+def no_leading_underscore: Flag<["--"], "no-leading-underscore">,
+    HelpText<"Don't add leading underscores on symbols">;
+
 //==============================================================================
 // The flags below do nothing. They are defined only for dlltool compatibility.
 //==============================================================================
diff --git a/llvm/test/tools/llvm-dlltool/no-leading-underscore.def b/llvm/test/tools/llvm-dlltool/no-leading-underscore.def
new file mode 100644 (file)
index 0000000..6b78e15
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: llvm-dlltool -k -m i386 --input-def %s --output-lib %t.a --no-leading-underscore --kill-at
+; RUN: llvm-readobj %t.a | FileCheck %s
+; RUN: llvm-nm %t.a | FileCheck %s -check-prefix=CHECK-NM
+
+LIBRARY test.dll
+EXPORTS
+func
+alias == func
+DecoratedFunction@4
+
+; CHECK:      Name type: name
+; CHECK-NEXT: Symbol: __imp_func
+; CHECK-NEXT: Symbol: func
+; CHECK:      Name type: undecorate
+; CHECK-NEXT: Symbol: __imp_DecoratedFunction@4
+; CHECK-NEXT: Symbol: DecoratedFunction@4
+
+; CHECK-NM: W alias
+; CHECK-NM: U func