[clang] 6e82d0d - [Clang][Bundler] Add 'exclude' flag to target objects sections

Sergey Dmitriev via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 29 09:01:03 PST 2020


Author: Sergey Dmitriev
Date: 2020-01-29T09:00:45-08:00
New Revision: 6e82d0dfd8dfaebc3985e73740a020b273a2dd31

URL: https://github.com/llvm/llvm-project/commit/6e82d0dfd8dfaebc3985e73740a020b273a2dd31
DIFF: https://github.com/llvm/llvm-project/commit/6e82d0dfd8dfaebc3985e73740a020b273a2dd31.diff

LOG: [Clang][Bundler] Add 'exclude' flag to target objects sections

Summary: This flag tells link editor to exclude section from linker inputs when linking executable or shared library.

Reviewers: ABataev, alexshap, jdoerfert

Reviewed By: ABataev

Subscribers: cfe-commits

Tags: #clang

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

Added: 
    

Modified: 
    clang/test/Driver/clang-offload-bundler.c
    clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/Driver/clang-offload-bundler.c b/clang/test/Driver/clang-offload-bundler.c
index 35c327c56b3b..99d638cb889b 100644
--- a/clang/test/Driver/clang-offload-bundler.c
+++ b/clang/test/Driver/clang-offload-bundler.c
@@ -253,7 +253,8 @@
 
 // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -inputs=%t.o,%t.tgt1,%t.tgt2 -outputs=%t.bundle3.o -### 2>&1 \
 // RUN: | FileCheck %s -DHOST=%itanium_abi_triple -DINOBJ1=%t.o -DINOBJ2=%t.tgt1 -DINOBJ3=%t.tgt2 -DOUTOBJ=%t.bundle3.o --check-prefix CK-OBJ-CMD
-// CK-OBJ-CMD: llvm-objcopy{{(.exe)?}}" "--add-section=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]=[[INOBJ1]]" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu=[[INOBJ2]]" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu=[[INOBJ3]]" "[[INOBJ1]]" "[[OUTOBJ]]"
+// CK-OBJ-CMD: llvm-objcopy{{(.exe)?}}" "--add-section=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]=[[INOBJ1]]" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu=[[INOBJ2]]" "--add-section=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu=[[INOBJ3]]" "[[INOBJ1]]" "[[TEMPOBJ:.*]]"
+// CK-OBJ-CMD: llvm-objcopy{{(.exe)?}}" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__host-[[HOST]]=readonly,exclude" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-powerpc64le-ibm-linux-gnu=readonly,exclude" "--set-section-flags=__CLANG_OFFLOAD_BUNDLE__openmp-x86_64-pc-linux-gnu=readonly,exclude" "[[TEMPOBJ]]" "[[OUTOBJ]]"
 
 // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -inputs=%t.o,%t.tgt1,%t.tgt2 -outputs=%t.bundle3.o
 // RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.o,%t.res.tgt1,%t.res.tgt2 -inputs=%t.bundle3.o -unbundle

diff  --git a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
index a75d2a630cf4..c215cff303e7 100644
--- a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
+++ b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
@@ -30,6 +30,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
@@ -463,6 +464,15 @@ class ObjectFileHandler final : public FileHandler {
     if (NumberOfProcessedInputs != NumberOfInputs)
       return Error::success();
 
+    // We will use llvm-objcopy to add target objects sections to the output
+    // fat object. These sections should have 'exclude' flag set which tells
+    // link editor to remove them from linker inputs when linking executable or
+    // shared library. llvm-objcopy currently does not support adding new
+    // section and changing flags for the added section in one invocation, and
+    // because of that we have to run it two times. First run adds sections and
+    // the second changes flags.
+    // TODO: change it to one run once llvm-objcopy starts supporting that.
+
     // Find llvm-objcopy in order to create the bundle binary.
     ErrorOr<std::string> Objcopy = sys::findProgramByName(
         "llvm-objcopy", sys::path::parent_path(BundlerExecutable));
@@ -476,7 +486,15 @@ class ObjectFileHandler final : public FileHandler {
     // to pass down to llvm-objcopy.
     OS.close();
 
-    // Compose command line for the objcopy tool.
+    // Create an intermediate temporary file to save object after the first
+    // llvm-objcopy run.
+    SmallString<128u> IntermediateObj;
+    if (std::error_code EC = sys::fs::createTemporaryFile(
+            "clang-offload-bundler", "tmp", IntermediateObj))
+      return createFileError(IntermediateObj, EC);
+    FileRemover IntermediateObjRemover(IntermediateObj);
+
+    // Compose llvm-objcopy command line for add target objects' sections.
     BumpPtrAllocator Alloc;
     StringSaver SS{Alloc};
     SmallVector<StringRef, 8u> ObjcopyArgs{"llvm-objcopy"};
@@ -485,25 +503,44 @@ class ObjectFileHandler final : public FileHandler {
                                     OFFLOAD_BUNDLER_MAGIC_STR + TargetNames[I] +
                                     "=" + InputFileNames[I]));
     ObjcopyArgs.push_back(InputFileNames[HostInputIndex]);
+    ObjcopyArgs.push_back(IntermediateObj);
+
+    if (Error Err = executeObjcopy(*Objcopy, ObjcopyArgs))
+      return Err;
+
+    // And run llvm-objcopy for the second time to update section flags.
+    ObjcopyArgs.resize(1);
+    for (unsigned I = 0; I < NumberOfInputs; ++I)
+      ObjcopyArgs.push_back(SS.save(Twine("--set-section-flags=") +
+                                    OFFLOAD_BUNDLER_MAGIC_STR + TargetNames[I] +
+                                    "=readonly,exclude"));
+    ObjcopyArgs.push_back(IntermediateObj);
     ObjcopyArgs.push_back(OutputFileNames.front());
 
-    // If the user asked for the commands to be printed out, we do that instead
-    // of executing it.
+    if (Error Err = executeObjcopy(*Objcopy, ObjcopyArgs))
+      return Err;
+
+    return Error::success();
+  }
+
+  Error WriteBundle(raw_fd_ostream &OS, MemoryBuffer &Input) final {
+    return Error::success();
+  }
+
+private:
+  static Error executeObjcopy(StringRef Objcopy, ArrayRef<StringRef> Args) {
+    // If the user asked for the commands to be printed out, we do that
+    // instead of executing it.
     if (PrintExternalCommands) {
-      errs() << "\"" << *Objcopy << "\"";
-      for (StringRef Arg : drop_begin(ObjcopyArgs, 1))
+      errs() << "\"" << Objcopy << "\"";
+      for (StringRef Arg : drop_begin(Args, 1))
         errs() << " \"" << Arg << "\"";
       errs() << "\n";
     } else {
-      if (sys::ExecuteAndWait(*Objcopy, ObjcopyArgs))
+      if (sys::ExecuteAndWait(Objcopy, Args))
         return createStringError(inconvertibleErrorCode(),
                                  "'llvm-objcopy' tool failed");
     }
-
-    return Error::success();
-  }
-
-  Error WriteBundle(raw_fd_ostream &OS, MemoryBuffer &Input) final {
     return Error::success();
   }
 };


        


More information about the cfe-commits mailing list