aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/ELF.cpp
diff options
context:
space:
mode:
authorRahman Lavaee <rahmanl@google.com>2023-05-11 11:15:12 -0700
committerRahman Lavaee <rahmanl@google.com>2023-05-11 11:21:26 -0700
commit5ac48ef51393e6d8392182ad439a22002571d554 (patch)
tree428e38834baef75c66850a6d3d9406fb50e1e541 /llvm/lib/Object/ELF.cpp
parent7fbfcc653f372aed37f81ec0ca4bb2b0ee90a9f4 (diff)
downloadllvm-5ac48ef51393e6d8392182ad439a22002571d554.zip
llvm-5ac48ef51393e6d8392182ad439a22002571d554.tar.gz
llvm-5ac48ef51393e6d8392182ad439a22002571d554.tar.bz2
[Propeller] Use a bit-field struct for the metdata fields of BBEntry.
This patch encapsulates the encoding and decoding logic of basic block metadata into the Metadata struct, and also reduces the decoded size of `SHT_LLVM_BB_ADDR_MAP` section. The patch would've looked more readable if we could use designated initializer, but that is a c++20 feature. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D148360
Diffstat (limited to 'llvm/lib/Object/ELF.cpp')
-rw-r--r--llvm/lib/Object/ELF.cpp26
1 files changed, 18 insertions, 8 deletions
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index b9e7384..e4f42f0 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -674,6 +674,7 @@ ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec,
DataExtractor::Cursor Cur(0);
Error ULEBSizeErr = Error::success();
+ Error MetadataDecodeErr = Error::success();
// Helper to extract and decode the next ULEB128 value as uint32_t.
// Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the uint32_t
// limit.
@@ -694,7 +695,8 @@ ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec,
};
uint8_t Version = 0;
- while (!ULEBSizeErr && Cur && Cur.tell() < Content.size()) {
+ while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&
+ Cur.tell() < Content.size()) {
if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
Version = Data.getU8(Cur);
if (!Cur)
@@ -722,24 +724,32 @@ ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec,
std::vector<BBAddrMap::BBEntry> BBEntries;
uint32_t PrevBBEndOffset = 0;
for (uint32_t BlockIndex = 0;
- !ULEBSizeErr && Cur && (BlockIndex < NumBlocks); ++BlockIndex) {
+ !MetadataDecodeErr && !ULEBSizeErr && Cur && (BlockIndex < NumBlocks);
+ ++BlockIndex) {
uint32_t ID = Version >= 2 ? ReadULEB128AsUInt32() : BlockIndex;
uint32_t Offset = ReadULEB128AsUInt32();
uint32_t Size = ReadULEB128AsUInt32();
- uint32_t Metadata = ReadULEB128AsUInt32();
+ uint32_t MD = ReadULEB128AsUInt32();
if (Version >= 1) {
// Offset is calculated relative to the end of the previous BB.
Offset += PrevBBEndOffset;
PrevBBEndOffset = Offset + Size;
}
- BBEntries.push_back({ID, Offset, Size, Metadata});
+ Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =
+ BBAddrMap::BBEntry::Metadata::decode(MD);
+ if (!MetadataOrErr) {
+ MetadataDecodeErr = MetadataOrErr.takeError();
+ break;
+ }
+ BBEntries.push_back({ID, Offset, Size, *MetadataOrErr});
}
FunctionEntries.push_back({Address, std::move(BBEntries)});
}
- // Either Cur is in the error state, or ULEBSizeError is set (not both), but
- // we join the two errors here to be safe.
- if (!Cur || ULEBSizeErr)
- return joinErrors(Cur.takeError(), std::move(ULEBSizeErr));
+ // Either Cur is in the error state, or we have an error in ULEBSizeErr or
+ // MetadataDecodeErr (but not both), but we join all errors here to be safe.
+ if (!Cur || ULEBSizeErr || MetadataDecodeErr)
+ return joinErrors(joinErrors(Cur.takeError(), std::move(ULEBSizeErr)),
+ std::move(MetadataDecodeErr));
return FunctionEntries;
}