Skip to content

[Driver] Add -Wa, options -mmapsyms={default,implicit} #104542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

MaskRay
Copy link
Member

@MaskRay MaskRay commented Aug 16, 2024

-Wa,-mmapsyms=implicit enables the alternative mapping symbol scheme
discussed at #99718.

While not conforming to the current aaelf64 ABI, the option is
invaluable for those with full control over their toolchain, no reliance
on weird relocatable files, and a strong focus on minimizing both
relocatable and executable sizes.

The option is discouraged when portability of the relocatable objects is
a concern.
https://maskray.me/blog/2024-07-21-mapping-symbols-rethinking-for-efficiency
elaborates the risk.

Created using spr 1.3.5-bogner

[skip ci]
Created using spr 1.3.5-bogner
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:codegen IR generation bugs: mangling, exceptions, etc. labels Aug 16, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 16, 2024

@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Fangrui Song (MaskRay)

Changes

-Wa,-mapsyms=implicit enables the alternative mapping symbol scheme
discussed at #99718.

While not conforming to the current aaelf64 ABI, the option is
invaluable for those with full control over their toolchain, no reliance
on weird relocatable files, and a strong focus on minimizing both
relocatable and executable sizes.

The option is discouraged when portability of the relocatable objects is
a concern.
https://maskray.me/blog/2024-07-21-mapping-symbols-rethinking-for-efficiency
elaborates the risk.


Full diff: https://github.com/llvm/llvm-project/pull/104542.diff

8 Files Affected:

  • (modified) clang/include/clang/Basic/CodeGenOptions.def (+1)
  • (modified) clang/include/clang/Driver/Options.td (+2)
  • (modified) clang/lib/CodeGen/BackendUtil.cpp (+1)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+12)
  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+22-2)
  • (added) clang/test/Driver/mmapsyms.c (+28)
  • (added) clang/test/Misc/cc1as-mmapsyms.c (+9)
  • (modified) clang/tools/driver/cc1as_main.cpp (+5)
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 09e892d6d4defe..aaf419bea8dacc 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -37,6 +37,7 @@ VALUE_CODEGENOPT(Name, Bits, Default)
 
 CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
 CODEGENOPT(Crel, 1, 0) ///< -Wa,--crel
+CODEGENOPT(ImplicitMapSyms, 1, 0) ///< -Wa,-mmapsyms=implicit
 CODEGENOPT(AsmVerbose        , 1, 0) ///< -dA, -fverbose-asm.
 CODEGENOPT(PreserveAsmComments, 1, 1) ///< -dA, -fno-preserve-as-comments.
 CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index c9ed08c20fc04f..d869778e10e6e8 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7131,6 +7131,8 @@ def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">,
 def crel : Flag<["--"], "crel">,
   HelpText<"Enable CREL relocation format (ELF only)">,
   MarshallingInfoFlag<CodeGenOpts<"Crel">>;
+def mmapsyms_implicit : Flag<["-"], "mmapsyms=implicit">,
+    MarshallingInfoFlag<CodeGenOpts<"ImplicitMapSyms">>;
 def mrelax_relocations_no : Flag<["-"], "mrelax-relocations=no">,
     HelpText<"Disable x86 relax relocations">,
     MarshallingInfoNegativeFlag<CodeGenOpts<"X86RelaxRelocations">>;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 34c08818dbb9ad..fdd89edd72e109 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -471,6 +471,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
   Options.MCOptions.Dwarf64 = CodeGenOpts.Dwarf64;
   Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
   Options.MCOptions.Crel = CodeGenOpts.Crel;
+  Options.MCOptions.ImplicitMapSyms = CodeGenOpts.ImplicitMapSyms;
   Options.MCOptions.X86RelaxRelocations = CodeGenOpts.X86RelaxRelocations;
   Options.MCOptions.CompressDebugSections =
       CodeGenOpts.getCompressDebugSections();
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index daffa7cf96978a..c14b62ff3212ca 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2584,6 +2584,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
   const llvm::Triple &Triple = C.getDefaultToolChain().getTriple();
   bool IsELF = Triple.isOSBinFormatELF();
   bool Crel = false, ExperimentalCrel = false;
+  bool ImplicitMapSyms = false;
   bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations();
   bool UseNoExecStack = false;
   const char *MipsTargetFeature = nullptr;
@@ -2671,6 +2672,15 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
           // recognize but skip over here.
           continue;
         break;
+      case llvm::Triple::aarch64:
+      case llvm::Triple::aarch64_be:
+      case llvm::Triple::aarch64_32:
+        if (Equal.first == "-mmapsyms") {
+          ImplicitMapSyms = Equal.second == "implicit";
+          checkArg(IsELF, {"default", "implicit"});
+          continue;
+        }
+        break;
       case llvm::Triple::mips:
       case llvm::Triple::mipsel:
       case llvm::Triple::mips64:
@@ -2807,6 +2817,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
           << "-Wa,--crel" << D.getTargetTriple();
     }
   }
+  if (ImplicitMapSyms)
+    CmdArgs.push_back("-mmapsyms=implicit");
   if (!UseRelaxRelocations)
     CmdArgs.push_back("-mrelax-relocations=no");
   if (UseNoExecStack)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 320d2901da06ed..0738ed18f54078 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1143,10 +1143,27 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
   addMachineOutlinerArgs(D, Args, CmdArgs, ToolChain.getEffectiveTriple(),
                          /*IsLTO=*/true, PluginOptPrefix);
 
+  bool IsELF = Triple.isOSBinFormatELF();
   bool Crel = false;
+  bool ImplicitMapSyms = false;
   for (const Arg *A : Args.filtered(options::OPT_Wa_COMMA)) {
     for (StringRef V : A->getValues()) {
-      if (V == "--crel")
+      auto Equal = V.split('=');
+      auto checkArg = [&](bool ValidTarget,
+                          std::initializer_list<const char *> Set) {
+        if (!ValidTarget) {
+          D.Diag(diag::err_drv_unsupported_opt_for_target)
+              << (Twine("-Wa,") + Equal.first + "=").str()
+              << Triple.getTriple();
+        } else if (!llvm::is_contained(Set, Equal.second)) {
+          D.Diag(diag::err_drv_unsupported_option_argument)
+              << (Twine("-Wa,") + Equal.first + "=").str() << Equal.second;
+        }
+      };
+      if (Equal.first == "-mmapsyms") {
+        ImplicitMapSyms = Equal.second == "implicit";
+        checkArg(IsELF && Triple.isAArch64(), {"default", "implicit"});
+      } else if (V == "--crel")
         Crel = true;
       else if (V == "--no-crel")
         Crel = false;
@@ -1156,13 +1173,16 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
     }
   }
   if (Crel) {
-    if (Triple.isOSBinFormatELF() && !Triple.isMIPS()) {
+    if (IsELF && !Triple.isMIPS()) {
       CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + "-crel"));
     } else {
       D.Diag(diag::err_drv_unsupported_opt_for_target)
           << "-Wa,--crel" << D.getTargetTriple();
     }
   }
+  if (ImplicitMapSyms)
+    CmdArgs.push_back(
+        Args.MakeArgString(Twine(PluginOptPrefix) + "-implicit-mapsyms"));
 }
 
 void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
diff --git a/clang/test/Driver/mmapsyms.c b/clang/test/Driver/mmapsyms.c
new file mode 100644
index 00000000000000..3535af3cf1cdda
--- /dev/null
+++ b/clang/test/Driver/mmapsyms.c
@@ -0,0 +1,28 @@
+/// Alternative mapping symbol scheme for AArch64.
+// RUN: %clang -### -c --target=aarch64 -Wa,-mmapsyms=implicit %s -Werror 2>&1 | FileCheck %s
+// RUN: %clang -### -c --target=aarch64_be -Wa,-mmapsyms=implicit %s -Werror 2>&1 | FileCheck %s
+// RUN: %clang -### -c --target=aarch64 -Wa,-mmapsyms=implicit,-mmapsyms=default %s -Werror 2>&1 | FileCheck %s --check-prefix=NO
+// RUN: not %clang -### -c --target=arm64-apple-darwin -Wa,-mmapsyms=implicit %s 2>&1 | FileCheck %s --check-prefix=ERR
+// RUN: not %clang -### -c --target=x86_64 -Wa,-mmapsyms=implicit %s 2>&1 | FileCheck %s --check-prefix=ERR2
+
+// RUN: %clang -### -c --target=aarch64 -Werror -Wa,-mmapsyms=implicit -x assembler %s -Werror 2>&1 | FileCheck %s --check-prefix=ASM
+// RUN: not %clang -### -c --target=x86_64 -Wa,-mmapsyms=implicit -x assembler %s 2>&1 | FileCheck %s --check-prefix=ERR2
+
+// CHECK:  "-cc1" {{.*}}"-mmapsyms=implicit"
+// NO:     "-cc1"
+// NO-NOT: "-mmapsyms=implicit"
+// ASM:    "-cc1as" {{.*}}"-mmapsyms=implicit"
+// ERR: error: unsupported option '-Wa,-mmapsyms=' for target 'arm64-apple-darwin'
+// ERR2: error: unsupported argument '-mmapsyms=implicit' to option '-Wa,'
+
+/// Check LTO.
+// RUN: %clang -### --target=aarch64-linux -Werror -flto -Wa,-mmapsyms=implicit %s 2>&1 | FileCheck %s --check-prefix=LTO
+// RUN: %clang -### --target=aarch64-linux -Werror -flto -Wa,-mmapsyms=implicit -Wa,-mmapsyms=default %s 2>&1 | FileCheck %s --check-prefix=LTO-NO
+
+// LTO: "-plugin-opt=-implicit-mapsyms"
+// LTO-NO-NOT: "-plugin-opt=-implicit-mapsyms"
+
+// RUN: touch %t.o
+// RUN: not %clang -### --target=x86_64-unknown-linux -flto -Wa,-mmapsyms=implicit %t.o 2>&1 | FileCheck %s --check-prefix=LTO-ERR
+
+// LTO-ERR: error: unsupported option '-Wa,-mmapsyms=' for target 'x86_64-unknown-linux'
diff --git a/clang/test/Misc/cc1as-mmapsyms.c b/clang/test/Misc/cc1as-mmapsyms.c
new file mode 100644
index 00000000000000..550281903c216e
--- /dev/null
+++ b/clang/test/Misc/cc1as-mmapsyms.c
@@ -0,0 +1,9 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang -cc1as -triple aarch64 %s -filetype obj -mmapsyms=implicit -o %t.o
+// RUN: llvm-readelf -s %t.o | FileCheck %s
+
+// CHECK: Symbol table '.symtab' contains 1 entries:
+nop
+
+.data
+.quad 0
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index 070cf8b44e8eb6..7fe97cc6e6ace1 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -164,6 +164,8 @@ struct AssemblerInvocation {
 
   LLVM_PREFERRED_TYPE(bool)
   unsigned Crel : 1;
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned ImplicitMapsyms : 1;
 
   LLVM_PREFERRED_TYPE(bool)
   unsigned X86RelaxRelocations : 1;
@@ -211,6 +213,7 @@ struct AssemblerInvocation {
     EmitDwarfUnwind = EmitDwarfUnwindType::Default;
     EmitCompactUnwindNonCanonical = false;
     Crel = false;
+    ImplicitMapsyms = 0;
     X86RelaxRelocations = 0;
     X86Sse2Avx = 0;
   }
@@ -382,6 +385,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
   Opts.EmitCompactUnwindNonCanonical =
       Args.hasArg(OPT_femit_compact_unwind_non_canonical);
   Opts.Crel = Args.hasArg(OPT_crel);
+  Opts.ImplicitMapsyms = Args.hasArg(OPT_mmapsyms_implicit);
   Opts.X86RelaxRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
   Opts.X86Sse2Avx = Args.hasArg(OPT_msse2avx);
 
@@ -442,6 +446,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
   MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical;
   MCOptions.MCSaveTempLabels = Opts.SaveTemporaryLabels;
   MCOptions.Crel = Opts.Crel;
+  MCOptions.ImplicitMapSyms = Opts.ImplicitMapsyms;
   MCOptions.X86RelaxRelocations = Opts.X86RelaxRelocations;
   MCOptions.X86Sse2Avx = Opts.X86Sse2Avx;
   MCOptions.CompressDebugSections = Opts.CompressDebugSections;

Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could do with some help text. Otherwise code changes look good.

@@ -7131,6 +7131,8 @@ def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">,
def crel : Flag<["--"], "crel">,
HelpText<"Enable CREL relocation format (ELF only)">,
MarshallingInfoFlag<CodeGenOpts<"Crel">>;
def mmapsyms_implicit : Flag<["-"], "mmapsyms=implicit">,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx. Added help message for clang -cc1 and clang -cc1as

Created using spr 1.3.5-bogner

[skip ci]
Created using spr 1.3.5-bogner
Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the help. LGTM.

Created using spr 1.3.5-bogner
@MaskRay MaskRay changed the base branch from users/MaskRay/spr/main.driver-add-wa-options-mmapsymsdefaultimplicit to main August 22, 2024 16:20
@MaskRay MaskRay merged commit eb549da into main Aug 22, 2024
@MaskRay MaskRay deleted the users/MaskRay/spr/driver-add-wa-options-mmapsymsdefaultimplicit branch August 22, 2024 16:20
@Endilll Endilll removed their request for review August 22, 2024 16:22
cjdb pushed a commit to cjdb/llvm-project that referenced this pull request Aug 23, 2024
-Wa,-mmapsyms=implicit enables the alternative mapping symbol scheme
discussed at llvm#99718.

While not conforming to the current aaelf64 ABI, the option is
invaluable for those with full control over their toolchain, no reliance
on weird relocatable files, and a strong focus on minimizing both
relocatable and executable sizes.

The option is discouraged when portability of the relocatable objects is
a concern.
https://maskray.me/blog/2024-07-21-mapping-symbols-rethinking-for-efficiency
elaborates the risk.

Pull Request: llvm#104542
@ldionne ldionne removed the request for review from a team August 29, 2024 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants