[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