Index: llvm/include/llvm/Object/COFF.h =================================================================== --- llvm/include/llvm/Object/COFF.h +++ 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; Index: llvm/tools/llvm-readobj/COFFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/COFFDumper.cpp +++ 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: Index: llvm/unittests/Object/CMakeLists.txt =================================================================== --- llvm/unittests/Object/CMakeLists.txt +++ llvm/unittests/Object/CMakeLists.txt @@ -7,6 +7,7 @@ add_llvm_unittest(ObjectTests ArchiveTest.cpp + COFFObjectFileTest.cpp DXContainerTest.cpp ELFObjectFileTest.cpp ELFTypesTest.cpp Index: llvm/unittests/Object/COFFObjectFileTest.cpp =================================================================== --- /dev/null +++ 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); +}