-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[ObjCopy][DX] Support for -dump-section flag #159999
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
Changes from 3 commits
2f5835f
826d77c
8acfeef
cbe01cb
8cc7959
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 |
|---|---|---|
|
|
@@ -9,8 +9,10 @@ | |
| #include "llvm/ObjCopy/DXContainer/DXContainerObjcopy.h" | ||
| #include "DXContainerReader.h" | ||
| #include "DXContainerWriter.h" | ||
| #include "llvm/BinaryFormat/DXContainer.h" | ||
| #include "llvm/ObjCopy/CommonConfig.h" | ||
| #include "llvm/ObjCopy/DXContainer/DXContainerConfig.h" | ||
| #include "llvm/Support/FileOutputBuffer.h" | ||
| #include "llvm/Support/raw_ostream.h" | ||
|
|
||
| namespace llvm { | ||
|
|
@@ -42,7 +44,49 @@ static Error extractPartAsObject(StringRef PartName, StringRef OutFilename, | |
| "part '%s' not found", PartName.str().c_str()); | ||
| } | ||
|
|
||
| static Error dumpPartToFile(StringRef PartName, StringRef Filename, | ||
| StringRef InputFilename, Object &Obj) { | ||
| for (const Part &P : Obj.Parts) { | ||
| if (P.Name == PartName) { | ||
| ArrayRef<uint8_t> Contents = P.Data; | ||
| // The DXContainer format is a bit odd because the part-specific headers | ||
| // are contained inside the part data itself. For parts that contain LLVM | ||
| // bitcode when we dump the part we want to skip the part-specific header | ||
| // so that we get a valid .bc file that we can inspect. All the data | ||
| // contained inside the program header is pulled out of the bitcode, so | ||
| // the header can be reconstructed if needed from the bitcode itself. | ||
| // More comprehensive documentation on the DXContainer format can be found | ||
| // at https://llvm.org/docs/DirectX/DXContainer.html. | ||
| if (PartName == "DXIL" || PartName == "STAT") | ||
| Contents = Contents.drop_front(sizeof(llvm::dxbc::ProgramHeader)); | ||
| if (Contents.empty()) | ||
| return createFileError(Filename, object_error::parse_failed, | ||
| "part '%s' is empty", PartName.str().c_str()); | ||
| Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = | ||
| FileOutputBuffer::create(Filename, Contents.size()); | ||
| if (!BufferOrErr) | ||
| return createFileError(Filename, BufferOrErr.takeError()); | ||
|
||
| std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr); | ||
| llvm::copy(Contents, Buf->getBufferStart()); | ||
| if (Error E = Buf->commit()) | ||
| return createFileError(Filename, std::move(E)); | ||
|
||
| return Error::success(); | ||
| } | ||
| } | ||
| return createFileError(Filename, | ||
| std::make_error_code(std::errc::invalid_argument), | ||
| "part '%s' not found", PartName.str().c_str()); | ||
| } | ||
|
|
||
| static Error handleArgs(const CommonConfig &Config, Object &Obj) { | ||
| for (StringRef Flag : Config.DumpSection) { | ||
| StringRef SecName; | ||
| StringRef FileName; | ||
| std::tie(SecName, FileName) = Flag.split("="); | ||
llvm-beanz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (Error E = dumpPartToFile(SecName, FileName, Config.InputFilename, Obj)) | ||
| return E; | ||
| } | ||
|
|
||
| // Extract all sections before any modifications. | ||
| for (StringRef Flag : Config.ExtractSection) { | ||
| StringRef SectionName; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # RUN: yaml2obj %s -o %t.dxbc | ||
| # RUN: not llvm-objcopy --dump-section=FKE0=%t.fek0 %t.dxbc 2>&1 | FileCheck %s --check-prefix=CHECK-EMPTY -DFILE=%t.fek0 | ||
|
||
| # RUN: not llvm-objcopy --dump-section=FKE3=%t.fek1 %t.dxbc 2>&1 | FileCheck %s --check-prefix=CHECK-MISSING -DFILE=%t.fek1 | ||
| # RUN: not llvm-objcopy --dump-section=FKE2=%t/does_not_exist/.fek2 %t.dxbc 2>&1 | FileCheck %s --check-prefix=CHECK-BAD-PATH -DFILE=%t/does_not_exist/.fek2 -DMSG=%errc_ENOENT | ||
|
|
||
| # CHECK-EMPTY: error: '[[FILE]]': part 'FKE0' is empty | ||
| # CHECK-MISSING: error: '[[FILE]]': part 'FKE3' not found | ||
| # CHECK-BAD-PATH: error: '[[FILE]]': [[MSG]] | ||
|
|
||
| --- !dxcontainer | ||
| Header: | ||
| Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | ||
| 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ] | ||
| Version: | ||
| Major: 1 | ||
| Minor: 0 | ||
| FileSize: 108 | ||
| PartCount: 3 | ||
| PartOffsets: [ 60, 68, 76 ] | ||
| Parts: | ||
| - Name: FKE0 | ||
| Size: 0 | ||
| - Name: FKE1 | ||
| Size: 0 | ||
| - Name: FKE2 | ||
| Size: 8 | ||
| ... | ||
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.
This seems like a weird pattern for this. Why not use
find_ifand return early if it isn't found instead?