-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Add --dump-offload-bundle option to llvm-objcopy #143347
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -277,6 +277,8 @@ struct CommonConfig { | |
bool StripUnneeded = false; | ||
bool Weaken = false; | ||
bool DecompressDebugSections = false; | ||
bool DumpOffloadBundle = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You've only implemented this for ELF, but you've put this in |
||
bool NeedPositional = true; | ||
|
||
DebugCompressionType CompressionType = DebugCompressionType::None; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -210,6 +210,27 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename, | |
"section '%s' not found", SecName.str().c_str()); | ||
} | ||
|
||
static Error dumpRawDataURIToFile(StringRef Filename, int64_t Offset, | ||
int64_t Size, ObjectFile &Obj) { | ||
SmallString<2048> NameBuf; | ||
raw_svector_ostream OutputFileName(NameBuf); | ||
OutputFileName << Obj.getFileName().str() << "-offset" << Offset << "-size" | ||
<< Size << ".co"; | ||
|
||
Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = | ||
FileOutputBuffer::create(OutputFileName.str(), Size); | ||
|
||
if (!BufferOrErr) | ||
return BufferOrErr.takeError(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add tests that show the error handling here and elsewhere in this change is correct. |
||
|
||
MemoryBufferRef Input = Obj.getMemoryBufferRef(); | ||
std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr); | ||
std::copy(Input.getBufferStart(), Input.getBufferStart() + Size, | ||
Buf->getBufferStart()); | ||
Comment on lines
+228
to
+229
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, you can use |
||
|
||
return Buf->commit(); | ||
} | ||
|
||
Error Object::compressOrDecompressSections(const CommonConfig &Config) { | ||
// Build a list of sections we are going to replace. | ||
// We can't call `addSection` while iterating over sections, | ||
|
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -16,6 +16,8 @@ | |||||||||||
#include "llvm/ObjCopy/ConfigManager.h" | ||||||||||||
#include "llvm/ObjCopy/MachO/MachOConfig.h" | ||||||||||||
#include "llvm/Object/Binary.h" | ||||||||||||
#include "llvm/Object/OffloadBinary.h" | ||||||||||||
#include "llvm/Object/OffloadBundle.h" | ||||||||||||
#include "llvm/Option/Arg.h" | ||||||||||||
#include "llvm/Option/ArgList.h" | ||||||||||||
#include "llvm/Support/CRC.h" | ||||||||||||
|
@@ -284,6 +286,11 @@ static Expected<uint8_t> parseVisibilityType(StringRef VisType) { | |||||||||||
return type; | ||||||||||||
} | ||||||||||||
|
||||||||||||
static void llvm::objcopy::parseDumpOffloadBundle(StringRef URI) { | ||||||||||||
if (Error Err = object::extractOffloadBundleByURI(URI)) | ||||||||||||
outs() << "Failed to extract from URI."; | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Error messages should start with lowercase and not end in a period https://llvm.org/docs/CodingStandards.html#error-and-warning-messages There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It shouldn't be either |
||||||||||||
} | ||||||||||||
|
||||||||||||
namespace { | ||||||||||||
struct TargetInfo { | ||||||||||||
FileFormat Format; | ||||||||||||
|
@@ -727,34 +734,45 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr, | |||||||||||
|
||||||||||||
SmallVector<const char *, 2> Positional; | ||||||||||||
|
||||||||||||
ConfigManager ConfigMgr; | ||||||||||||
CommonConfig &Config = ConfigMgr.Common; | ||||||||||||
COFFConfig &COFFConfig = ConfigMgr.COFF; | ||||||||||||
ELFConfig &ELFConfig = ConfigMgr.ELF; | ||||||||||||
MachOConfig &MachOConfig = ConfigMgr.MachO; | ||||||||||||
|
||||||||||||
if (InputArgs.hasArg(OBJCOPY_dump_offload_bundle)) | ||||||||||||
Config.NeedPositional = false; | ||||||||||||
|
||||||||||||
for (auto *Arg : InputArgs.filtered(OBJCOPY_UNKNOWN)) | ||||||||||||
return createStringError(errc::invalid_argument, "unknown argument '%s'", | ||||||||||||
Arg->getAsString(InputArgs).c_str()); | ||||||||||||
|
||||||||||||
for (auto *Arg : InputArgs.filtered(OBJCOPY_INPUT)) | ||||||||||||
Positional.push_back(Arg->getValue()); | ||||||||||||
|
||||||||||||
if (Positional.empty()) | ||||||||||||
if (Positional.empty() && Config.NeedPositional) | ||||||||||||
return createStringError(errc::invalid_argument, "no input file specified"); | ||||||||||||
|
||||||||||||
if (Positional.size() > 2) | ||||||||||||
if (Positional.size() > 2 && Config.NeedPositional) | ||||||||||||
return createStringError(errc::invalid_argument, | ||||||||||||
"too many positional arguments"); | ||||||||||||
|
||||||||||||
ConfigManager ConfigMgr; | ||||||||||||
CommonConfig &Config = ConfigMgr.Common; | ||||||||||||
COFFConfig &COFFConfig = ConfigMgr.COFF; | ||||||||||||
ELFConfig &ELFConfig = ConfigMgr.ELF; | ||||||||||||
MachOConfig &MachOConfig = ConfigMgr.MachO; | ||||||||||||
Config.InputFilename = Positional[0]; | ||||||||||||
Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1]; | ||||||||||||
if (InputArgs.hasArg(OBJCOPY_target) && | ||||||||||||
(InputArgs.hasArg(OBJCOPY_input_target) || | ||||||||||||
InputArgs.hasArg(OBJCOPY_output_target))) | ||||||||||||
return createStringError( | ||||||||||||
errc::invalid_argument, | ||||||||||||
"--target cannot be used with --input-target or --output-target"); | ||||||||||||
if (Arg *A = InputArgs.getLastArg(OBJCOPY_dump_offload_bundle)) { | ||||||||||||
for (StringRef URIStr : llvm::split(A->getValue(), ",")) { | ||||||||||||
llvm::objcopy::parseDumpOffloadBundle(URIStr); | ||||||||||||
} | ||||||||||||
Comment on lines
+761
to
+763
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||||||||||||
} | ||||||||||||
|
||||||||||||
if (Config.NeedPositional) { | ||||||||||||
Config.InputFilename = Positional[0]; | ||||||||||||
Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1]; | ||||||||||||
if (InputArgs.hasArg(OBJCOPY_target) && | ||||||||||||
(InputArgs.hasArg(OBJCOPY_input_target) || | ||||||||||||
InputArgs.hasArg(OBJCOPY_output_target))) | ||||||||||||
return createStringError( | ||||||||||||
errc::invalid_argument, | ||||||||||||
"--target cannot be used with --input-target or --output-target"); | ||||||||||||
} | ||||||||||||
if (InputArgs.hasArg(OBJCOPY_regex) && InputArgs.hasArg(OBJCOPY_wildcard)) | ||||||||||||
return createStringError(errc::invalid_argument, | ||||||||||||
"--regex and --wildcard are incompatible"); | ||||||||||||
|
@@ -1417,25 +1435,26 @@ objcopy::parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) { | |||||||||||
Arg->getAsString(InputArgs).c_str()); | ||||||||||||
for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_INPUT)) | ||||||||||||
Positional.push_back(Arg->getValue()); | ||||||||||||
if (Positional.empty()) | ||||||||||||
if (Positional.empty() && Config.NeedPositional) | ||||||||||||
return createStringError(errc::invalid_argument, "no input file specified"); | ||||||||||||
if (Positional.size() > 1) | ||||||||||||
if (Positional.size() > 1 && Config.NeedPositional) | ||||||||||||
return createStringError( | ||||||||||||
errc::invalid_argument, | ||||||||||||
"llvm-install-name-tool expects a single input file"); | ||||||||||||
Config.InputFilename = Positional[0]; | ||||||||||||
Config.OutputFilename = Positional[0]; | ||||||||||||
|
||||||||||||
Expected<OwningBinary<Binary>> BinaryOrErr = | ||||||||||||
createBinary(Config.InputFilename); | ||||||||||||
if (!BinaryOrErr) | ||||||||||||
return createFileError(Config.InputFilename, BinaryOrErr.takeError()); | ||||||||||||
auto *Binary = (*BinaryOrErr).getBinary(); | ||||||||||||
if (!Binary->isMachO() && !Binary->isMachOUniversalBinary()) | ||||||||||||
return createStringError(errc::invalid_argument, | ||||||||||||
"input file: %s is not a Mach-O file", | ||||||||||||
Config.InputFilename.str().c_str()); | ||||||||||||
|
||||||||||||
if (Config.NeedPositional) { | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code refers to |
||||||||||||
Config.InputFilename = Positional[0]; | ||||||||||||
Config.OutputFilename = Positional[0]; | ||||||||||||
|
||||||||||||
Expected<OwningBinary<Binary>> BinaryOrErr = | ||||||||||||
createBinary(Config.InputFilename); | ||||||||||||
if (!BinaryOrErr) | ||||||||||||
return createFileError(Config.InputFilename, BinaryOrErr.takeError()); | ||||||||||||
auto *Binary = (*BinaryOrErr).getBinary(); | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is actually existing code that I'm just indenting because I had to add "if (Config.NeedsPositional)". I need to do this because llvm-objcopy is set up to always expect a source file argument unless the "NeedsPositional" config setting is negative/false. And with the new --dump-offload-bundle option I'm adding, it takes a URI argument which contains the source file argument. So if the --dump-offload-bundle option is specified I set "NeedsPositional" to false. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See the above comment: this code isn't used by llvm-objcopy itself. |
||||||||||||
if (!Binary->isMachO() && !Binary->isMachOUniversalBinary()) | ||||||||||||
return createStringError(errc::invalid_argument, | ||||||||||||
"input file: %s is not a Mach-O file", | ||||||||||||
Config.InputFilename.str().c_str()); | ||||||||||||
} | ||||||||||||
DC.CopyConfigs.push_back(std::move(ConfigMgr)); | ||||||||||||
return std::move(DC); | ||||||||||||
} | ||||||||||||
|
@@ -1474,13 +1493,16 @@ objcopy::parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr, | |||||||||||
Arg->getAsString(InputArgs).c_str()); | ||||||||||||
|
||||||||||||
SmallVector<StringRef, 2> Positional; | ||||||||||||
for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_INPUT)) | ||||||||||||
Positional.push_back(Arg->getValue()); | ||||||||||||
if (Positional.size() > 1) | ||||||||||||
return createStringError(errc::invalid_argument, | ||||||||||||
"llvm-bitcode-strip expects a single input file"); | ||||||||||||
assert(!Positional.empty()); | ||||||||||||
Config.InputFilename = Positional[0]; | ||||||||||||
if (Config.NeedPositional) { | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above, this code isn't used by llvm-objcopy. It's to do with |
||||||||||||
for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_INPUT)) | ||||||||||||
Positional.push_back(Arg->getValue()); | ||||||||||||
if (Positional.size() > 1) | ||||||||||||
return createStringError( | ||||||||||||
errc::invalid_argument, | ||||||||||||
"llvm-bitcode-strip expects a single input file"); | ||||||||||||
assert(!Positional.empty()); | ||||||||||||
Config.InputFilename = Positional[0]; | ||||||||||||
} | ||||||||||||
|
||||||||||||
if (!InputArgs.hasArg(BITCODE_STRIP_output)) { | ||||||||||||
return createStringError(errc::invalid_argument, | ||||||||||||
|
@@ -1542,27 +1564,31 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr, | |||||||||||
exit(0); | ||||||||||||
} | ||||||||||||
|
||||||||||||
SmallVector<StringRef, 2> Positional; | ||||||||||||
for (auto *Arg : InputArgs.filtered(STRIP_UNKNOWN)) | ||||||||||||
return createStringError(errc::invalid_argument, "unknown argument '%s'", | ||||||||||||
Arg->getAsString(InputArgs).c_str()); | ||||||||||||
for (auto *Arg : InputArgs.filtered(STRIP_INPUT)) | ||||||||||||
Positional.push_back(Arg->getValue()); | ||||||||||||
std::copy(DashDash, RawArgsArr.end(), std::back_inserter(Positional)); | ||||||||||||
|
||||||||||||
if (Positional.empty()) | ||||||||||||
return createStringError(errc::invalid_argument, "no input file specified"); | ||||||||||||
|
||||||||||||
if (Positional.size() > 1 && InputArgs.hasArg(STRIP_output)) | ||||||||||||
return createStringError( | ||||||||||||
errc::invalid_argument, | ||||||||||||
"multiple input files cannot be used in combination with -o"); | ||||||||||||
|
||||||||||||
ConfigManager ConfigMgr; | ||||||||||||
CommonConfig &Config = ConfigMgr.Common; | ||||||||||||
ELFConfig &ELFConfig = ConfigMgr.ELF; | ||||||||||||
MachOConfig &MachOConfig = ConfigMgr.MachO; | ||||||||||||
|
||||||||||||
SmallVector<StringRef, 2> Positional; | ||||||||||||
if (Config.NeedPositional) { | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, not llvm-objcopy. This is for |
||||||||||||
for (auto *Arg : InputArgs.filtered(STRIP_UNKNOWN)) | ||||||||||||
return createStringError(errc::invalid_argument, "unknown argument '%s'", | ||||||||||||
Arg->getAsString(InputArgs).c_str()); | ||||||||||||
for (auto *Arg : InputArgs.filtered(STRIP_INPUT)) | ||||||||||||
Positional.push_back(Arg->getValue()); | ||||||||||||
std::copy(DashDash, RawArgsArr.end(), std::back_inserter(Positional)); | ||||||||||||
|
||||||||||||
if (Positional.empty()) | ||||||||||||
return createStringError(errc::invalid_argument, | ||||||||||||
"no input file specified"); | ||||||||||||
|
||||||||||||
if (Positional.size() > 1 && InputArgs.hasArg(STRIP_output)) { | ||||||||||||
return createStringError( | ||||||||||||
errc::invalid_argument, | ||||||||||||
"multiple input files cannot be used in combination with -o"); | ||||||||||||
} | ||||||||||||
} | ||||||||||||
|
||||||||||||
if (InputArgs.hasArg(STRIP_regex) && InputArgs.hasArg(STRIP_wildcard)) | ||||||||||||
return createStringError(errc::invalid_argument, | ||||||||||||
"--regex and --wildcard are incompatible"); | ||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,11 @@ parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr, | |
Expected<DriverConfig> | ||
parseStripOptions(ArrayRef<const char *> ArgsArr, | ||
llvm::function_ref<Error(Error)> ErrorCallback); | ||
|
||
// parseDumpURI reads a URI as a string, and extracts the raw memory into a | ||
// code object file named from the URI string given | ||
Comment on lines
+55
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
static void parseDumpOffloadBundle(StringRef URI); | ||
|
||
} // namespace objcopy | ||
} // namespace llvm | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -239,6 +239,9 @@ defm dump_section | |
: Eq<"dump-section", | ||
"Dump contents of section named <section> into file <file>">, | ||
MetaVarName<"section=file">; | ||
|
||
defm dump_offload_bundle : Eq<"dump-offload-bundle", "Dump the contents specified by URI">; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: alphabetical order. |
||
|
||
defm prefix_symbols | ||
: Eq<"prefix-symbols", "Add <prefix> to the start of every symbol name">, | ||
MetaVarName<"prefix">; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: options should be in alphabetical order.