diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h --- a/llvm/include/llvm/Object/COFF.h +++ b/llvm/include/llvm/Object/COFF.h @@ -745,12 +745,18 @@ support::ulittle32_t AuxiliaryIATCopy; }; +enum chpe_range_type { Arm64 = 0, Arm64EC = 1, Amd64 = 2 }; + struct chpe_range_entry { support::ulittle32_t StartOffset; support::ulittle32_t Length; -}; -enum chpe_range_type { CHPE_RANGE_ARM64, CHPE_RANGE_ARM64EC, CHPE_RANGE_AMD64 }; + // The two low bits of StartOffset contain a range type. + static constexpr uint32_t TypeMask = 3; + + uint32_t getStart() const { return StartOffset & ~TypeMask; } + uint16_t getType() const { return StartOffset & TypeMask; } +}; struct chpe_code_range_entry { support::ulittle32_t StartRva; diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -854,17 +854,17 @@ reportError(std::move(E), Obj->getFileName()); auto CodeMap = reinterpret_cast(CodeMapInt); for (uint32_t i = 0; i < CHPE->CodeMapCount; i++) { - uint32_t Start = CodeMap[i].StartOffset & ~3; + uint32_t Start = CodeMap[i].getStart(); W.startLine() << W.hex(Start) << " - " << W.hex(Start + CodeMap[i].Length) << " "; - switch (CodeMap[i].StartOffset & 3) { - case CHPE_RANGE_ARM64: + switch (CodeMap[i].getType()) { + case chpe_range_type::Arm64: W.getOStream() << "ARM64\n"; break; - case CHPE_RANGE_ARM64EC: + case chpe_range_type::Arm64EC: W.getOStream() << "ARM64EC\n"; break; - case CHPE_RANGE_AMD64: + case chpe_range_type::Amd64: W.getOStream() << "X64\n"; break; default: diff --git a/llvm/unittests/Object/CMakeLists.txt b/llvm/unittests/Object/CMakeLists.txt --- a/llvm/unittests/Object/CMakeLists.txt +++ b/llvm/unittests/Object/CMakeLists.txt @@ -7,6 +7,7 @@ add_llvm_unittest(ObjectTests ArchiveTest.cpp + COFFObjectFileTest.cpp DXContainerTest.cpp ELFObjectFileTest.cpp ELFTypesTest.cpp diff --git a/llvm/unittests/Object/COFFObjectFileTest.cpp b/llvm/unittests/Object/COFFObjectFileTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/Object/COFFObjectFileTest.cpp @@ -0,0 +1,28 @@ +//===- COFFObjectFileTest.cpp - Tests for COFFObjectFile ----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/COFF.h" +#include "gtest/gtest.h" + +using namespace llvm::object; + +TEST(COFFObjectFileTest, CHPERangeEntry) { + chpe_range_entry range; + + range.StartOffset = 0x1000; + EXPECT_EQ(range.getStart(), 0x1000u); + EXPECT_EQ(range.getType(), chpe_range_type::Arm64); + + range.StartOffset = 0x2000 | chpe_range_type::Arm64EC; + EXPECT_EQ(range.getStart(), 0x2000u); + EXPECT_EQ(range.getType(), chpe_range_type::Arm64EC); + + range.StartOffset = 0x3000 | chpe_range_type::Amd64; + EXPECT_EQ(range.getStart(), 0x3000u); + EXPECT_EQ(range.getType(), chpe_range_type::Amd64); +}