Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

563 lines
20 KiB
C++

//===- XCOFFObjectFileTest.cpp - Tests for XCOFFObjectFile ----------------===//
//
// 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/ELFObjectFile.h"
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace llvm::object;
using namespace llvm::XCOFF;
TEST(XCOFFObjectFileTest, XCOFFObjectType) {
// Create an arbitrary object of a non-XCOFF type and test that
// dyn_cast<XCOFFObjectFile> returns null for it.
char Buf[sizeof(ELF64LE::Ehdr)] = {};
memcpy(Buf, "\177ELF", 4);
auto *EHdr = reinterpret_cast<ELF64LE::Ehdr *>(Buf);
EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64;
EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB;
MemoryBufferRef Source(StringRef(Buf, sizeof(Buf)), "non-XCOFF");
Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
ObjectFile::createObjectFile(Source);
ASSERT_THAT_EXPECTED(ObjOrErr, Succeeded());
EXPECT_TRUE(dyn_cast<XCOFFObjectFile>((*ObjOrErr).get()) == nullptr);
}
TEST(XCOFFObjectFileTest, doesXCOFFTracebackTableBegin) {
EXPECT_TRUE(doesXCOFFTracebackTableBegin({0, 0, 0, 0}));
EXPECT_TRUE(doesXCOFFTracebackTableBegin({0, 0, 0, 0, 1}));
EXPECT_FALSE(doesXCOFFTracebackTableBegin({0, 0, 0, 1}));
EXPECT_FALSE(doesXCOFFTracebackTableBegin({0, 0, 0}));
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIGeneral) {
uint8_t V[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01, 0x05, 0x58, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07, 0x61, 0x64,
0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
uint64_t Size = sizeof(V);
Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
XCOFFTracebackTable TT = *TTOrErr;
EXPECT_EQ(TT.getVersion(), 0);
EXPECT_EQ(TT.getLanguageID(), 0);
EXPECT_FALSE(TT.isGlobalLinkage());
EXPECT_FALSE(TT.isOutOfLineEpilogOrPrologue());
EXPECT_TRUE(TT.hasTraceBackTableOffset());
EXPECT_FALSE(TT.isInternalProcedure());
EXPECT_FALSE(TT.hasControlledStorage());
EXPECT_FALSE(TT.isTOCless());
EXPECT_TRUE(TT.isFloatingPointPresent());
EXPECT_FALSE(TT.isFloatingPointOperationLogOrAbortEnabled());
EXPECT_FALSE(TT.isInterruptHandler());
EXPECT_TRUE(TT.isFuncNamePresent());
EXPECT_FALSE(TT.isAllocaUsed());
EXPECT_EQ(TT.getOnConditionDirective(), 0);
EXPECT_FALSE(TT.isCRSaved());
EXPECT_FALSE(TT.isLRSaved());
EXPECT_TRUE(TT.isBackChainStored());
EXPECT_FALSE(TT.isFixup());
EXPECT_EQ(TT.getNumOfFPRsSaved(), 0);
EXPECT_FALSE(TT.hasExtensionTable());
EXPECT_FALSE(TT.hasVectorInfo());
EXPECT_EQ(TT.getNumOfGPRsSaved(), 0);
EXPECT_EQ(TT.getNumberOfFixedParms(), 1);
EXPECT_EQ(TT.getNumberOfFPParms(), 2);
EXPECT_TRUE(TT.hasParmsOnStack());
ASSERT_TRUE(TT.getParmsType());
EXPECT_EQ(*TT.getParmsType(), "i, f, d");
ASSERT_TRUE(TT.getTraceBackTableOffset());
EXPECT_EQ(*TT.getTraceBackTableOffset(), 64u);
EXPECT_FALSE(TT.getHandlerMask());
ASSERT_TRUE(TT.getFunctionName());
EXPECT_EQ(*TT.getFunctionName(), "add_all");
EXPECT_EQ(TT.getFunctionName()->size(), 7u);
EXPECT_FALSE(TT.getAllocaRegister());
EXPECT_EQ(Size, 25u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIParmsType) {
uint8_t V[] = {0x01, 0x02, 0xA2, 0x40, 0x80, 0x00, 0x02, 0x07, 0x2B, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07, 0x61, 0x64,
0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
uint64_t Size = sizeof(V);
Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
XCOFFTracebackTable TT = *TTOrErr;
EXPECT_EQ(TT.getVersion(), 1);
EXPECT_EQ(TT.getLanguageID(), 2);
EXPECT_TRUE(TT.isGlobalLinkage());
EXPECT_EQ(TT.getNumberOfFixedParms(), 2);
EXPECT_EQ(TT.getNumberOfFPParms(), 3);
ASSERT_TRUE(TT.getParmsType());
EXPECT_EQ(*TT.getParmsType(), "i, i, f, f, d");
V[8] = 0xAC;
Size = sizeof(V);
Expected<XCOFFTracebackTable> TTOrErr1 = XCOFFTracebackTable::create(V, Size);
ASSERT_THAT_EXPECTED(TTOrErr1, Succeeded());
XCOFFTracebackTable TT1 = *TTOrErr1;
ASSERT_TRUE(TT1.getParmsType());
EXPECT_EQ(*TT1.getParmsType(), "f, f, d, i, i");
V[8] = 0xD4;
Size = sizeof(V);
Expected<XCOFFTracebackTable> TTOrErr2 = XCOFFTracebackTable::create(V, Size);
ASSERT_THAT_EXPECTED(TTOrErr2, Succeeded());
XCOFFTracebackTable TT2 = *TTOrErr2;
ASSERT_TRUE(TT2.getParmsType());
EXPECT_EQ(*TT2.getParmsType(), "d, i, f, f, i");
V[6] = 0x01;
Size = sizeof(V);
Expected<XCOFFTracebackTable> TTOrErr3 = XCOFFTracebackTable::create(V, Size);
ASSERT_THAT_EXPECTED(TTOrErr3, Succeeded());
XCOFFTracebackTable TT3 = *TTOrErr3;
ASSERT_TRUE(TT3.getParmsType());
EXPECT_EQ(*TT3.getParmsType(), "d, i, f, f");
V[6] = 0x04;
V[7] = 0x1E;
V[8] = 0xAC;
V[9] = 0xAA;
V[10] = 0xAA;
V[11] = 0xAA;
Size = sizeof(V);
Expected<XCOFFTracebackTable> TTOrErr4 = XCOFFTracebackTable::create(V, Size);
ASSERT_THAT_EXPECTED(TTOrErr4, Succeeded());
XCOFFTracebackTable TT4 = *TTOrErr4;
ASSERT_TRUE(TT4.getParmsType());
EXPECT_EQ(*TT4.getParmsType(),
"f, f, d, i, i, f, f, f, f, f, f, f, f, f, f, f, f, ...");
}
const uint8_t TBTableData[] = {
0x00, 0x00, 0x2A, 0x60, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc4,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02,
0x05, 0x05, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07,
0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x1f, 0x02, 0x05,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIControlledStorageInfoDisp) {
uint64_t Size = sizeof(TBTableData);
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
XCOFFTracebackTable TT = *TTOrErr;
EXPECT_TRUE(TT.hasControlledStorage());
ASSERT_TRUE(TT.getNumOfCtlAnchors());
EXPECT_EQ(*TT.getNumOfCtlAnchors(), 2u);
ASSERT_TRUE(TT.getControlledStorageInfoDisp());
SmallVector<uint32_t, 8> Disp = *TT.getControlledStorageInfoDisp();
ASSERT_EQ(Disp.size(), 2UL);
EXPECT_EQ(Disp[0], 0x05050000u);
EXPECT_EQ(Disp[1], 0x06060000u);
EXPECT_EQ(Size, 47u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIAllocaRegister) {
uint64_t Size = sizeof(TBTableData);
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
XCOFFTracebackTable TT = *TTOrErr;
ASSERT_TRUE(TT.getAllocaRegister());
EXPECT_EQ(*TT.getAllocaRegister(), 31u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
uint64_t Size = sizeof(TBTableData);
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
XCOFFTracebackTable TT = *TTOrErr;
EXPECT_EQ(TT.getNumberOfFixedParms(), 3);
EXPECT_EQ(TT.getNumberOfFPParms(), 2);
EXPECT_TRUE(TT.hasVectorInfo());
EXPECT_TRUE(TT.hasExtensionTable());
ASSERT_TRUE(TT.getParmsType());
EXPECT_EQ(*TT.getParmsType(), "v, i, f, i, d, i, v");
ASSERT_TRUE(TT.getVectorExt());
TBVectorExt VecExt = *TT.getVectorExt();
EXPECT_EQ(VecExt.getNumberOfVRSaved(), 0);
EXPECT_TRUE(VecExt.isVRSavedOnStack());
EXPECT_FALSE(VecExt.hasVarArgs());
EXPECT_EQ(VecExt.getNumberOfVectorParms(), 2u);
EXPECT_TRUE(VecExt.hasVMXInstruction());
EXPECT_EQ(VecExt.getVectorParmsInfo(), "vf, vf");
ASSERT_TRUE(TT.getExtensionTable());
EXPECT_EQ(*TT.getExtensionTable(), ExtendedTBTableFlag::TB_SSP_CANARY);
EXPECT_EQ(Size, 47u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
const uint8_t TBTableData[] = {
0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc5,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02,
0x05, 0x05, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07,
0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x11, 0x07, 0x90,
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
uint64_t Size = sizeof(TBTableData);
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
XCOFFTracebackTable TT = *TTOrErr;
ASSERT_TRUE(TT.getParmsType());
EXPECT_EQ(*TT.getParmsType(), "v, i, f, i, d, i, v, v");
ASSERT_TRUE(TT.getVectorExt());
TBVectorExt VecExt = *TT.getVectorExt();
EXPECT_EQ(VecExt.getNumberOfVRSaved(), 4);
EXPECT_FALSE(VecExt.isVRSavedOnStack());
EXPECT_TRUE(VecExt.hasVarArgs());
EXPECT_EQ(VecExt.getNumberOfVectorParms(), 3u);
EXPECT_TRUE(VecExt.hasVMXInstruction());
EXPECT_EQ(VecExt.getVectorParmsInfo(), "vi, vs, vc");
ASSERT_TRUE(TT.getExtensionTable());
EXPECT_EQ(*TT.getExtensionTable(), ExtendedTBTableFlag::TB_SSP_CANARY);
EXPECT_EQ(Size, 46u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtMandatory) {
uint64_t Size = 6;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x6 while reading [0x0, 0x8)"));
EXPECT_EQ(Size, 0u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtParmsType) {
uint64_t Size = 9;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x9 while reading [0x8, 0xc)"));
EXPECT_EQ(Size, 8u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtTBOffset) {
uint64_t Size = 14;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0xe while reading [0xc, 0x10)"));
EXPECT_EQ(Size, 12u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtHandlerMask) {
uint8_t V[] = {0x00, 0x00, 0x22, 0xC0, 0x80, 0x00, 0x01, 0x05, 0x58,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07};
uint64_t Size = sizeof(V);
Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x12 while reading [0x10, 0x14)"));
EXPECT_EQ(Size, 16u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNumOfCtlAnchors) {
uint64_t Size = 19;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x13 while reading [0x10, 0x14)"));
EXPECT_EQ(Size, 16u);
}
TEST(XCOFFObjectFileTest,
XCOFFTracebackTableTruncatedAtControlledStorageInfoDisp) {
uint64_t Size = 21;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x15 while reading [0x14, 0x18)"));
EXPECT_EQ(Size, 20u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNameLen) {
uint64_t Size = 29;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x1d while reading [0x1c, 0x1e)"));
EXPECT_EQ(Size, 28u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtFunctionName) {
uint64_t Size = 36;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x24 while reading [0x1e, 0x25)"));
EXPECT_EQ(Size, 30u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtAllocaUsed) {
uint64_t Size = 37;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x25 while reading [0x25, 0x26)"));
EXPECT_EQ(Size, 37u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoData) {
uint64_t Size = 39;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x27 while reading [0x26, 0x2c)"));
EXPECT_EQ(Size, 38u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoParmsInfo) {
uint64_t Size = 43;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x2b while reading [0x26, 0x2c)"));
EXPECT_EQ(Size, 38u);
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtExtLongTBTable) {
uint64_t Size = 46;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage(
"unexpected end of data at offset 0x2e while reading [0x2e, 0x2f)"));
EXPECT_EQ(Size, 46u);
}
TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef32) {
uint8_t XCOFF32Binary[] = {
// File header.
0x01, 0xdf, 0x00, 0x01, 0x5f, 0x58, 0xf8, 0x95, 0x00, 0x00, 0x00, 0x3c,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
// Section header for empty .data section.
0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40,
// Start of symbol table.
// C_File symbol.
0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xfe, 0x00, 0x03, 0x67, 0x01,
// File Auxiliary Entry.
0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// Csect symbol.
0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
// Csect auxiliary entry.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ArrayRef<uint8_t> XCOFF32Ref(XCOFF32Binary, sizeof(XCOFF32Binary));
Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
object::ObjectFile::createObjectFile(
MemoryBufferRef(toStringRef(XCOFF32Ref), "dummyXCOFF"),
file_magic::xcoff_object_32);
ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
DataRefImpl Ref;
Ref.p = File.getSymbolEntryAddressByIndex(2);
XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
// Set csect symbol's auxiliary entry count to 0.
XCOFF32Binary[113] = 0;
Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
EXPECT_THAT_ERROR(
ExpectErr.takeError(),
FailedWithMessage(
"csect symbol \".data\" with index 2 contains no auxiliary entry"));
}
TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) {
uint8_t XCOFF64Binary[] = {
// File header.
0x01, 0xf7, 0x00, 0x01, 0x5f, 0x59, 0x25, 0xeb, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
// Section header for empty .data section.
0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
// Start of symbol table.
// C_File symbol.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
0xff, 0xfe, 0x00, 0x02, 0x67, 0x01,
// File Auxiliary Entry.
0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
// Csect symbol.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
// Csect auxiliary entry.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfb,
// String table.
0x00, 0x00, 0x00, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x2e, 0x64,
0x61, 0x74, 0x61, 0x00};
ArrayRef<uint8_t> XCOFF64Ref(XCOFF64Binary, sizeof(XCOFF64Binary));
Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
object::ObjectFile::createObjectFile(
MemoryBufferRef(toStringRef(XCOFF64Ref), "dummyXCOFF"),
file_magic::xcoff_object_64);
ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
DataRefImpl Ref;
Ref.p = File.getSymbolEntryAddressByIndex(2);
XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
// Inject incorrect auxiliary type value.
XCOFF64Binary[167] = static_cast<uint8_t>(XCOFF::AUX_SYM);
Expected<XCOFFCsectAuxRef> NotFoundErr = SymRef.getXCOFFCsectAuxRef();
EXPECT_THAT_ERROR(
NotFoundErr.takeError(),
FailedWithMessage("a csect auxiliary entry has not been found for symbol "
"\".data\" with index 2"));
// Set csect symbol's auxiliary entry count to 0.
XCOFF64Binary[149] = 0;
Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
EXPECT_THAT_ERROR(
ExpectErr.takeError(),
FailedWithMessage(
"csect symbol \".data\" with index 2 contains no auxiliary entry"));
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterType) {
const uint8_t TBTableData[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01,
0x05, 0x58, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x40, 0x00, 0x07, 0x61, 0x64, 0x64,
0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
uint64_t Size = 28;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
"in parseParmsType."));
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterTypeWithVecInfo) {
const uint8_t TBTableData[] = {
0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0,
0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02,
0x05, 0x05, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07,
0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x11, 0x07, 0x90,
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
uint64_t Size = 46;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(
TTOrErr.takeError(),
FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
"in parseParmsTypeWithVecInfo."));
}
TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtVecParameterType) {
const uint8_t TBTableData[] = {
0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02,
0x05, 0x05, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07,
0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x11, 0x07, 0x90,
0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
uint64_t Size = 46;
Expected<XCOFFTracebackTable> TTOrErr =
XCOFFTracebackTable::create(TBTableData, Size);
EXPECT_THAT_ERROR(TTOrErr.takeError(),
FailedWithMessage("ParmsType encodes more than ParmsNum "
"parameters in parseVectorParmsType."));
}