- Notifications
You must be signed in to change notification settings - Fork 15.6k
[MsgPack] Return an Error instead of bool from readFromBlob #74357
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 |
|---|---|---|
| | @@ -63,27 +63,27 @@ void AMDGPUPALMetadata::readFromIR(Module &M) { | |
| } | ||
| } | ||
| | ||
| // Set PAL metadata from a binary blob from the applicable .note record. | ||
| // Returns false if bad format. Blob must remain valid for the lifetime of the | ||
| // Metadata. | ||
| bool AMDGPUPALMetadata::setFromBlob(unsigned Type, StringRef Blob) { | ||
| // Set PAL metadata from a binary blob from the applicable .note record. Blob | ||
| // must remain valid for the lifetime of the Metadata. | ||
| void AMDGPUPALMetadata::setFromBlob(unsigned Type, StringRef Blob) { | ||
| BlobType = Type; | ||
| if (Type == ELF::NT_AMD_PAL_METADATA) | ||
| return setFromLegacyBlob(Blob); | ||
| return setFromMsgPackBlob(Blob); | ||
| setFromLegacyBlob(Blob); | ||
| else | ||
| setFromMsgPackBlob(Blob); | ||
| } | ||
| | ||
| // Set PAL metadata from legacy (array of key=value pairs) blob. | ||
| bool AMDGPUPALMetadata::setFromLegacyBlob(StringRef Blob) { | ||
| void AMDGPUPALMetadata::setFromLegacyBlob(StringRef Blob) { | ||
| auto Data = reinterpret_cast<const uint32_t *>(Blob.data()); | ||
| for (unsigned I = 0; I != Blob.size() / sizeof(uint32_t) / 2; ++I) | ||
| setRegister(Data[I * 2], Data[I * 2 + 1]); | ||
| return true; | ||
| } | ||
| | ||
| // Set PAL metadata from msgpack blob. | ||
| bool AMDGPUPALMetadata::setFromMsgPackBlob(StringRef Blob) { | ||
| return MsgPackDoc.readFromBlob(Blob, /*Multi=*/false); | ||
| void AMDGPUPALMetadata::setFromMsgPackBlob(StringRef Blob) { | ||
| if (!Blob.empty()) | ||
slinder1 marked this conversation as resolved. Show resolved Hide resolved | ||
| handleAllErrors(MsgPackDoc.readFromBlob(Blob, /*Multi=*/false)); | ||
| Contributor 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. I'm not sure I follow why this buries the Member Author 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. I guess it's an assertion that the Blob is valid. There should never be an error so long as the frontend* generates valid metadata. I don't think its possible to fail more gracefully here either, our options are either 1) discard and overwrite the metadata, or 2) don't make any amendments to it. Previously we were doing 1) implicitly, which seems wrong to me, but 2) also seems wrong. * What frontend am I talking about? That's not rhetorical, I don't know! Clang doesn't seem to be aware of "!amdgpu.pal.metadata", but this comment references a frontend: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp#L29 . This metadata is used by lit tests. Contributor 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 might be worth updating that comment, I agree "the frontend" is a little opaque here! I believe it refers to LLPC: https://github.com/GPUOpen-Drivers/llpc For example: https://github.com/GPUOpen-Drivers/llpc/blob/1005e28c078e07fc0b83363260811f733edaeafd/lgc/state/PalMetadata.cpp#L123 and https://github.com/GPUOpen-Drivers/llpc/blob/1005e28c078e07fc0b83363260811f733edaeafd/lgc/include/lgc/state/AbiMetadata.h#L636 In general we don't want to actually I can't seem to find where this method is actually used, though. @trenouf do you know where the Contributor 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. We should never assert on invalid input. The only way an assert would be OK is if the IR verifier rejected any malformed metadata which could reach here | ||
| } | ||
| | ||
| // Given the calling convention, calculate the register number for rsrc1. In | ||
| | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -5513,41 +5513,42 @@ static AMDNote getAMDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) { | |
| struct AMDGPUNote { | ||
| std::string Type; | ||
| std::string Value; | ||
| bool IsError; | ||
| }; | ||
| | ||
| template <typename ELFT> | ||
| static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) { | ||
| Member 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. Maybe this should return Expected instead of adding the extra boolean field? Member Author 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 isn't really a "I'm returning either an Error or a valid AMDGPUNote" situation. In the error case, the Error object gets written into the std::string fields, I just wanted to indicate to the caller that there was an error pretty-printing so it would still dump the binary blob, which seems useful to include. Member 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 should still be possible if you return an Expected<> object? We can just print the error string from the bad Expected<> and then continue to the raw dumping? Member 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. Something like const Expected<AMDGPUNote> N = getAMDGPUNote<ELFT>(Type, Descriptor); if (!N) { OS << " AMDGPU Metadata:\n " <<toString(N.takeError())) << '\n'; // Fallthrough to printing the description data blob on error. } else { OS << " " << N->Type << ":\n " << N->Value << '\n'; return Error::success(); } | ||
| switch (NoteType) { | ||
| default: | ||
| return {"", ""}; | ||
| return {"", "", true}; | ||
| case ELF::NT_AMDGPU_METADATA: { | ||
| StringRef MsgPackString = | ||
| StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size()); | ||
| msgpack::Document MsgPackDoc; | ||
| if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false)) | ||
| return {"", ""}; | ||
| if (Error E = MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false)) | ||
| return {"AMDGPU Metadata", toString(std::move(E)), /*IsError=*/true}; | ||
| | ||
| if (MsgPackDoc.getRoot().isScalar()) { | ||
| // TODO: passing a scalar root to toYAML() asserts: | ||
| // (PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && | ||
| // "plain scalar documents are not supported") | ||
| // To avoid this crash we print the raw data instead. | ||
| return {"AMDGPU Metadata", "Invalid AMDGPU Metadata", /*IsError=*/true}; | ||
| } | ||
| | ||
| std::string MetadataString; | ||
| raw_string_ostream StrOS(MetadataString); | ||
| | ||
| // FIXME: Metadata Verifier only works with AMDHSA. | ||
| // This is an ugly workaround to avoid the verifier for other MD | ||
| // formats (e.g. amdpal) | ||
| // FIXME: Metadata Verifier only works with AMDHSA. This is an ugly | ||
| // workaround to avoid the verifier for other MD formats (e.g. amdpal) | ||
| if (MsgPackString.contains("amdhsa.")) { | ||
| AMDGPU::HSAMD::V3::MetadataVerifier Verifier(true); | ||
| if (!Verifier.verify(MsgPackDoc.getRoot())) | ||
| MetadataString = "Invalid AMDGPU Metadata\n"; | ||
| StrOS << "Invalid AMDGPU Metadata\n"; | ||
| } | ||
| | ||
| raw_string_ostream StrOS(MetadataString); | ||
| if (MsgPackDoc.getRoot().isScalar()) { | ||
| // TODO: passing a scalar root to toYAML() asserts: | ||
| // (PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && | ||
| // "plain scalar documents are not supported") | ||
| // To avoid this crash we print the raw data instead. | ||
| return {"", ""}; | ||
| } | ||
| MsgPackDoc.toYAML(StrOS); | ||
| return {"AMDGPU Metadata", StrOS.str()}; | ||
| return {"AMDGPU Metadata", StrOS.str(), /*IsError=*/false}; | ||
| } | ||
| } | ||
| } | ||
| | @@ -5964,7 +5965,9 @@ template <class ELFT> void GNUELFDumper<ELFT>::printNotes() { | |
| const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor); | ||
| if (!N.Type.empty()) { | ||
| OS << " " << N.Type << ":\n " << N.Value << '\n'; | ||
| return Error::success(); | ||
| if (!N.IsError) | ||
| return Error::success(); | ||
| // Fallthrough to printing the description data blob on error. | ||
| } | ||
| } else if (Name == "LLVMOMPOFFLOAD") { | ||
| if (printLLVMOMPOFFLOADNote<ELFT>(OS, Type, Descriptor)) | ||
| | @@ -7661,7 +7664,9 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() { | |
| const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor); | ||
| if (!N.Type.empty()) { | ||
| W.printString(N.Type, N.Value); | ||
| return Error::success(); | ||
| if (!N.IsError) | ||
| return Error::success(); | ||
| // Fallthrough to printing the description data blob on error. | ||
| } | ||
| } else if (Name == "LLVMOMPOFFLOAD") { | ||
| if (printLLVMOMPOFFLOADNoteLLVMStyle<ELFT>(Type, Descriptor, W)) | ||
| | ||
Uh oh!
There was an error while loading. Please reload this page.