Skip to content

Commit d24935c

Browse files
david-salinasdsalinas_amdeng
authored and
dsalinas_amdeng
committed
Add Offoading to llvm-readobj and llvm-objcopy
Utilize new extensions to LLVM Offloading API to handle offloading fatbin Bundles. Change-Id: Ib24a722be16f499ffb56bf46e4b82e90d8775040
1 parent de93f7e commit d24935c

File tree

15 files changed

+328
-129
lines changed

15 files changed

+328
-129
lines changed

llvm/docs/CommandGuide/llvm-objcopy.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ multiple file formats.
7474
For MachO objects, ``<section>`` must be formatted as
7575
``<segment name>,<section name>``.
7676

77+
.. option:: --dump-offload-bundle=<URI>
78+
79+
Dump the HIP Offload Bundle entry specified by the URI syntax given, into a
80+
code object file.
81+
82+
7783
.. option:: --enable-deterministic-archives, -D
7884

7985
Enable deterministic mode when copying archives, i.e. use 0 for archive member

llvm/docs/CommandGuide/llvm-readobj.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ file formats.
104104
Do not demangle symbol names in the output. This option is only for ELF and
105105
XCOFF file formats. The option is enabled by default.
106106

107+
.. option:: --offloading
108+
109+
Display list of HIP Offload bundles using URI syntax.
110+
107111
.. option:: --relocations, --relocs, -r
108112

109113
Display the relocation entries in the file.

llvm/include/llvm/ObjCopy/CommonConfig.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ struct CommonConfig {
276276
bool StripUnneeded = false;
277277
bool Weaken = false;
278278
bool DecompressDebugSections = false;
279+
bool DumpOffloadBundle = false;
280+
bool NeedPositional = true;
279281

280282
DebugCompressionType CompressionType = DebugCompressionType::None;
281283

llvm/include/llvm/Object/OffloadBundle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ struct OffloadBundleURI {
160160
OffsetStr.getAsInteger(10, O);
161161
Str = Str.drop_front(OffsetStr.size());
162162

163-
if (Str.consume_front("&size="))
163+
if (!Str.consume_front("&size="))
164164
return createStringError(object_error::parse_failed,
165165
"Reading 'size' in URI");
166166

llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,27 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
210210
"section '%s' not found", SecName.str().c_str());
211211
}
212212

213+
static Error dumpRawDataURIToFile(StringRef Filename, int64_t Offset,
214+
int64_t Size, ObjectFile &Obj) {
215+
SmallString<2048> NameBuf;
216+
raw_svector_ostream OutputFileName(NameBuf);
217+
OutputFileName << Obj.getFileName().str() << "-offset" << Offset << "-size"
218+
<< Size << ".co";
219+
220+
Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
221+
FileOutputBuffer::create(OutputFileName.str(), Size);
222+
223+
if (!BufferOrErr)
224+
return BufferOrErr.takeError();
225+
226+
MemoryBufferRef Input = Obj.getMemoryBufferRef();
227+
std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
228+
std::copy(Input.getBufferStart(), Input.getBufferStart() + Size,
229+
Buf->getBufferStart());
230+
231+
return Buf->commit();
232+
}
233+
213234
Error Object::compressOrDecompressSections(const CommonConfig &Config) {
214235
// Build a list of sections we are going to replace.
215236
// We can't call `addSection` while iterating over sections,

llvm/test/tools/llvm-objcopy/ELF/dump-offload-bundle.test

Lines changed: 60 additions & 0 deletions
Large diffs are not rendered by default.

llvm/test/tools/llvm-readobj/ELF/AMDGPU/offloading.test

Lines changed: 42 additions & 0 deletions
Large diffs are not rendered by default.

llvm/tools/llvm-objcopy/ObjcopyOptions.cpp

Lines changed: 79 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include "llvm/ObjCopy/ConfigManager.h"
1717
#include "llvm/ObjCopy/MachO/MachOConfig.h"
1818
#include "llvm/Object/Binary.h"
19+
#include "llvm/Object/OffloadBinary.h"
20+
#include "llvm/Object/OffloadBundle.h"
1921
#include "llvm/Option/Arg.h"
2022
#include "llvm/Option/ArgList.h"
2123
#include "llvm/Support/CRC.h"
@@ -284,6 +286,11 @@ static Expected<uint8_t> parseVisibilityType(StringRef VisType) {
284286
return type;
285287
}
286288

289+
static void llvm::objcopy::parseDumpOffloadBundle(StringRef URI) {
290+
if (Error Err = object::extractOffloadBundleByURI(URI))
291+
outs() << "Failed to extract from URI.";
292+
}
293+
287294
namespace {
288295
struct TargetInfo {
289296
FileFormat Format;
@@ -727,34 +734,45 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
727734

728735
SmallVector<const char *, 2> Positional;
729736

737+
ConfigManager ConfigMgr;
738+
CommonConfig &Config = ConfigMgr.Common;
739+
COFFConfig &COFFConfig = ConfigMgr.COFF;
740+
ELFConfig &ELFConfig = ConfigMgr.ELF;
741+
MachOConfig &MachOConfig = ConfigMgr.MachO;
742+
743+
if (InputArgs.hasArg(OBJCOPY_dump_offload_bundle))
744+
Config.NeedPositional = false;
745+
730746
for (auto *Arg : InputArgs.filtered(OBJCOPY_UNKNOWN))
731747
return createStringError(errc::invalid_argument, "unknown argument '%s'",
732748
Arg->getAsString(InputArgs).c_str());
733749

734750
for (auto *Arg : InputArgs.filtered(OBJCOPY_INPUT))
735751
Positional.push_back(Arg->getValue());
736752

737-
if (Positional.empty())
753+
if (Positional.empty() && Config.NeedPositional)
738754
return createStringError(errc::invalid_argument, "no input file specified");
739755

740-
if (Positional.size() > 2)
756+
if (Positional.size() > 2 && Config.NeedPositional)
741757
return createStringError(errc::invalid_argument,
742758
"too many positional arguments");
743759

744-
ConfigManager ConfigMgr;
745-
CommonConfig &Config = ConfigMgr.Common;
746-
COFFConfig &COFFConfig = ConfigMgr.COFF;
747-
ELFConfig &ELFConfig = ConfigMgr.ELF;
748-
MachOConfig &MachOConfig = ConfigMgr.MachO;
749-
Config.InputFilename = Positional[0];
750-
Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1];
751-
if (InputArgs.hasArg(OBJCOPY_target) &&
752-
(InputArgs.hasArg(OBJCOPY_input_target) ||
753-
InputArgs.hasArg(OBJCOPY_output_target)))
754-
return createStringError(
755-
errc::invalid_argument,
756-
"--target cannot be used with --input-target or --output-target");
760+
if (Arg *A = InputArgs.getLastArg(OBJCOPY_dump_offload_bundle)) {
761+
for (StringRef URIStr : llvm::split(A->getValue(), ",")) {
762+
llvm::objcopy::parseDumpOffloadBundle(URIStr);
763+
}
764+
}
757765

766+
if (Config.NeedPositional) {
767+
Config.InputFilename = Positional[0];
768+
Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1];
769+
if (InputArgs.hasArg(OBJCOPY_target) &&
770+
(InputArgs.hasArg(OBJCOPY_input_target) ||
771+
InputArgs.hasArg(OBJCOPY_output_target)))
772+
return createStringError(
773+
errc::invalid_argument,
774+
"--target cannot be used with --input-target or --output-target");
775+
}
758776
if (InputArgs.hasArg(OBJCOPY_regex) && InputArgs.hasArg(OBJCOPY_wildcard))
759777
return createStringError(errc::invalid_argument,
760778
"--regex and --wildcard are incompatible");
@@ -1417,25 +1435,26 @@ objcopy::parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
14171435
Arg->getAsString(InputArgs).c_str());
14181436
for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_INPUT))
14191437
Positional.push_back(Arg->getValue());
1420-
if (Positional.empty())
1438+
if (Positional.empty() && Config.NeedPositional)
14211439
return createStringError(errc::invalid_argument, "no input file specified");
1422-
if (Positional.size() > 1)
1440+
if (Positional.size() > 1 && Config.NeedPositional)
14231441
return createStringError(
14241442
errc::invalid_argument,
14251443
"llvm-install-name-tool expects a single input file");
1426-
Config.InputFilename = Positional[0];
1427-
Config.OutputFilename = Positional[0];
1428-
1429-
Expected<OwningBinary<Binary>> BinaryOrErr =
1430-
createBinary(Config.InputFilename);
1431-
if (!BinaryOrErr)
1432-
return createFileError(Config.InputFilename, BinaryOrErr.takeError());
1433-
auto *Binary = (*BinaryOrErr).getBinary();
1434-
if (!Binary->isMachO() && !Binary->isMachOUniversalBinary())
1435-
return createStringError(errc::invalid_argument,
1436-
"input file: %s is not a Mach-O file",
1437-
Config.InputFilename.str().c_str());
1438-
1444+
if (Config.NeedPositional) {
1445+
Config.InputFilename = Positional[0];
1446+
Config.OutputFilename = Positional[0];
1447+
1448+
Expected<OwningBinary<Binary>> BinaryOrErr =
1449+
createBinary(Config.InputFilename);
1450+
if (!BinaryOrErr)
1451+
return createFileError(Config.InputFilename, BinaryOrErr.takeError());
1452+
auto *Binary = (*BinaryOrErr).getBinary();
1453+
if (!Binary->isMachO() && !Binary->isMachOUniversalBinary())
1454+
return createStringError(errc::invalid_argument,
1455+
"input file: %s is not a Mach-O file",
1456+
Config.InputFilename.str().c_str());
1457+
}
14391458
DC.CopyConfigs.push_back(std::move(ConfigMgr));
14401459
return std::move(DC);
14411460
}
@@ -1474,13 +1493,16 @@ objcopy::parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr,
14741493
Arg->getAsString(InputArgs).c_str());
14751494

14761495
SmallVector<StringRef, 2> Positional;
1477-
for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_INPUT))
1478-
Positional.push_back(Arg->getValue());
1479-
if (Positional.size() > 1)
1480-
return createStringError(errc::invalid_argument,
1481-
"llvm-bitcode-strip expects a single input file");
1482-
assert(!Positional.empty());
1483-
Config.InputFilename = Positional[0];
1496+
if (Config.NeedPositional) {
1497+
for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_INPUT))
1498+
Positional.push_back(Arg->getValue());
1499+
if (Positional.size() > 1)
1500+
return createStringError(
1501+
errc::invalid_argument,
1502+
"llvm-bitcode-strip expects a single input file");
1503+
assert(!Positional.empty());
1504+
Config.InputFilename = Positional[0];
1505+
}
14841506

14851507
if (!InputArgs.hasArg(BITCODE_STRIP_output)) {
14861508
return createStringError(errc::invalid_argument,
@@ -1542,27 +1564,31 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
15421564
exit(0);
15431565
}
15441566

1545-
SmallVector<StringRef, 2> Positional;
1546-
for (auto *Arg : InputArgs.filtered(STRIP_UNKNOWN))
1547-
return createStringError(errc::invalid_argument, "unknown argument '%s'",
1548-
Arg->getAsString(InputArgs).c_str());
1549-
for (auto *Arg : InputArgs.filtered(STRIP_INPUT))
1550-
Positional.push_back(Arg->getValue());
1551-
std::copy(DashDash, RawArgsArr.end(), std::back_inserter(Positional));
1552-
1553-
if (Positional.empty())
1554-
return createStringError(errc::invalid_argument, "no input file specified");
1555-
1556-
if (Positional.size() > 1 && InputArgs.hasArg(STRIP_output))
1557-
return createStringError(
1558-
errc::invalid_argument,
1559-
"multiple input files cannot be used in combination with -o");
1560-
15611567
ConfigManager ConfigMgr;
15621568
CommonConfig &Config = ConfigMgr.Common;
15631569
ELFConfig &ELFConfig = ConfigMgr.ELF;
15641570
MachOConfig &MachOConfig = ConfigMgr.MachO;
15651571

1572+
SmallVector<StringRef, 2> Positional;
1573+
if (Config.NeedPositional) {
1574+
for (auto *Arg : InputArgs.filtered(STRIP_UNKNOWN))
1575+
return createStringError(errc::invalid_argument, "unknown argument '%s'",
1576+
Arg->getAsString(InputArgs).c_str());
1577+
for (auto *Arg : InputArgs.filtered(STRIP_INPUT))
1578+
Positional.push_back(Arg->getValue());
1579+
std::copy(DashDash, RawArgsArr.end(), std::back_inserter(Positional));
1580+
1581+
if (Positional.empty())
1582+
return createStringError(errc::invalid_argument,
1583+
"no input file specified");
1584+
1585+
if (Positional.size() > 1 && InputArgs.hasArg(STRIP_output)) {
1586+
return createStringError(
1587+
errc::invalid_argument,
1588+
"multiple input files cannot be used in combination with -o");
1589+
}
1590+
}
1591+
15661592
if (InputArgs.hasArg(STRIP_regex) && InputArgs.hasArg(STRIP_wildcard))
15671593
return createStringError(errc::invalid_argument,
15681594
"--regex and --wildcard are incompatible");

llvm/tools/llvm-objcopy/ObjcopyOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr,
5151
Expected<DriverConfig>
5252
parseStripOptions(ArrayRef<const char *> ArgsArr,
5353
llvm::function_ref<Error(Error)> ErrorCallback);
54+
55+
// parseDumpURI reads a URI as a string, and extracts the raw memory into a
56+
// code object file named from the URI string given
57+
static void parseDumpOffloadBundle(StringRef URI);
58+
5459
} // namespace objcopy
5560
} // namespace llvm
5661

llvm/tools/llvm-objcopy/ObjcopyOpts.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ defm dump_section
239239
: Eq<"dump-section",
240240
"Dump contents of section named <section> into file <file>">,
241241
MetaVarName<"section=file">;
242+
243+
defm dump_offload_bundle : Eq<"dump-offload-bundle", "Dump the contents specified by URI">;
244+
242245
defm prefix_symbols
243246
: Eq<"prefix-symbols", "Add <prefix> to the start of every symbol name">,
244247
MetaVarName<"prefix">;

0 commit comments

Comments
 (0)