Skip to content

Commit 6e82d0d

Browse files
committed
[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
1 parent 4b04e11 commit 6e82d0d

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

clang/test/Driver/clang-offload-bundler.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@
253253

254254
// 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 \
255255
// 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
256-
// 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]]"
256+
// 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:.*]]"
257+
// 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]]"
257258

258259
// 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
259260
// 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

clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "llvm/Support/Error.h"
3131
#include "llvm/Support/ErrorOr.h"
3232
#include "llvm/Support/FileSystem.h"
33+
#include "llvm/Support/FileUtilities.h"
3334
#include "llvm/Support/MemoryBuffer.h"
3435
#include "llvm/Support/Path.h"
3536
#include "llvm/Support/Program.h"
@@ -463,6 +464,15 @@ class ObjectFileHandler final : public FileHandler {
463464
if (NumberOfProcessedInputs != NumberOfInputs)
464465
return Error::success();
465466

467+
// We will use llvm-objcopy to add target objects sections to the output
468+
// fat object. These sections should have 'exclude' flag set which tells
469+
// link editor to remove them from linker inputs when linking executable or
470+
// shared library. llvm-objcopy currently does not support adding new
471+
// section and changing flags for the added section in one invocation, and
472+
// because of that we have to run it two times. First run adds sections and
473+
// the second changes flags.
474+
// TODO: change it to one run once llvm-objcopy starts supporting that.
475+
466476
// Find llvm-objcopy in order to create the bundle binary.
467477
ErrorOr<std::string> Objcopy = sys::findProgramByName(
468478
"llvm-objcopy", sys::path::parent_path(BundlerExecutable));
@@ -476,7 +486,15 @@ class ObjectFileHandler final : public FileHandler {
476486
// to pass down to llvm-objcopy.
477487
OS.close();
478488

479-
// Compose command line for the objcopy tool.
489+
// Create an intermediate temporary file to save object after the first
490+
// llvm-objcopy run.
491+
SmallString<128u> IntermediateObj;
492+
if (std::error_code EC = sys::fs::createTemporaryFile(
493+
"clang-offload-bundler", "tmp", IntermediateObj))
494+
return createFileError(IntermediateObj, EC);
495+
FileRemover IntermediateObjRemover(IntermediateObj);
496+
497+
// Compose llvm-objcopy command line for add target objects' sections.
480498
BumpPtrAllocator Alloc;
481499
StringSaver SS{Alloc};
482500
SmallVector<StringRef, 8u> ObjcopyArgs{"llvm-objcopy"};
@@ -485,25 +503,44 @@ class ObjectFileHandler final : public FileHandler {
485503
OFFLOAD_BUNDLER_MAGIC_STR + TargetNames[I] +
486504
"=" + InputFileNames[I]));
487505
ObjcopyArgs.push_back(InputFileNames[HostInputIndex]);
506+
ObjcopyArgs.push_back(IntermediateObj);
507+
508+
if (Error Err = executeObjcopy(*Objcopy, ObjcopyArgs))
509+
return Err;
510+
511+
// And run llvm-objcopy for the second time to update section flags.
512+
ObjcopyArgs.resize(1);
513+
for (unsigned I = 0; I < NumberOfInputs; ++I)
514+
ObjcopyArgs.push_back(SS.save(Twine("--set-section-flags=") +
515+
OFFLOAD_BUNDLER_MAGIC_STR + TargetNames[I] +
516+
"=readonly,exclude"));
517+
ObjcopyArgs.push_back(IntermediateObj);
488518
ObjcopyArgs.push_back(OutputFileNames.front());
489519

490-
// If the user asked for the commands to be printed out, we do that instead
491-
// of executing it.
520+
if (Error Err = executeObjcopy(*Objcopy, ObjcopyArgs))
521+
return Err;
522+
523+
return Error::success();
524+
}
525+
526+
Error WriteBundle(raw_fd_ostream &OS, MemoryBuffer &Input) final {
527+
return Error::success();
528+
}
529+
530+
private:
531+
static Error executeObjcopy(StringRef Objcopy, ArrayRef<StringRef> Args) {
532+
// If the user asked for the commands to be printed out, we do that
533+
// instead of executing it.
492534
if (PrintExternalCommands) {
493-
errs() << "\"" << *Objcopy << "\"";
494-
for (StringRef Arg : drop_begin(ObjcopyArgs, 1))
535+
errs() << "\"" << Objcopy << "\"";
536+
for (StringRef Arg : drop_begin(Args, 1))
495537
errs() << " \"" << Arg << "\"";
496538
errs() << "\n";
497539
} else {
498-
if (sys::ExecuteAndWait(*Objcopy, ObjcopyArgs))
540+
if (sys::ExecuteAndWait(Objcopy, Args))
499541
return createStringError(inconvertibleErrorCode(),
500542
"'llvm-objcopy' tool failed");
501543
}
502-
503-
return Error::success();
504-
}
505-
506-
Error WriteBundle(raw_fd_ostream &OS, MemoryBuffer &Input) final {
507544
return Error::success();
508545
}
509546
};

0 commit comments

Comments
 (0)