forked from OSchip/llvm-project
561 lines
21 KiB
C++
561 lines
21 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(typename ELF64LE::Ehdr)] = {};
|
|
memcpy(Buf, "\177ELF", 4);
|
|
|
|
auto *EHdr = reinterpret_cast<typename 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().getValue(), "i, f, d");
|
|
|
|
ASSERT_TRUE(TT.getTraceBackTableOffset());
|
|
EXPECT_EQ(TT.getTraceBackTableOffset().getValue(), 64u);
|
|
|
|
EXPECT_FALSE(TT.getHandlerMask());
|
|
|
|
ASSERT_TRUE(TT.getFunctionName());
|
|
EXPECT_EQ(TT.getFunctionName().getValue(), "add_all");
|
|
EXPECT_EQ(TT.getFunctionName().getValue().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().getValue(), "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().getValue(), "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().getValue(), "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().getValue(), "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().getValue(),
|
|
"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, 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().getValue(), 2u);
|
|
|
|
ASSERT_TRUE(TT.getControlledStorageInfoDisp());
|
|
|
|
SmallVector<uint32_t, 8> Disp = TT.getControlledStorageInfoDisp().getValue();
|
|
|
|
ASSERT_EQ(Disp.size(), 2UL);
|
|
EXPECT_EQ(Disp[0], 0x05050000u);
|
|
EXPECT_EQ(Disp[1], 0x06060000u);
|
|
EXPECT_EQ(Size, 45u);
|
|
}
|
|
|
|
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().getValue(), 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().getValue(), "v, i, f, i, d, i, v");
|
|
|
|
ASSERT_TRUE(TT.getVectorExt());
|
|
TBVectorExt VecExt = TT.getVectorExt().getValue();
|
|
|
|
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().getValue(),
|
|
ExtendedTBTableFlag::TB_SSP_CANARY);
|
|
|
|
EXPECT_EQ(Size, 45u);
|
|
}
|
|
|
|
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, 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().getValue(), "v, i, f, i, d, i, v, v");
|
|
|
|
ASSERT_TRUE(TT.getVectorExt());
|
|
TBVectorExt VecExt = TT.getVectorExt().getValue();
|
|
|
|
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().getValue(),
|
|
ExtendedTBTableFlag::TB_SSP_CANARY);
|
|
|
|
EXPECT_EQ(Size, 44u);
|
|
}
|
|
|
|
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 = 44;
|
|
Expected<XCOFFTracebackTable> TTOrErr =
|
|
XCOFFTracebackTable::create(TBTableData, Size);
|
|
|
|
EXPECT_THAT_ERROR(
|
|
TTOrErr.takeError(),
|
|
FailedWithMessage(
|
|
"unexpected end of data at offset 0x2c while reading [0x2c, 0x2d)"));
|
|
EXPECT_EQ(Size, 44u);
|
|
}
|
|
|
|
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, 0x20, 0x00, 0x00, 0x00};
|
|
uint64_t Size = 44;
|
|
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, 0x20, 0x00, 0x00, 0x00};
|
|
uint64_t Size = 44;
|
|
Expected<XCOFFTracebackTable> TTOrErr =
|
|
XCOFFTracebackTable::create(TBTableData, Size);
|
|
|
|
EXPECT_THAT_ERROR(TTOrErr.takeError(),
|
|
FailedWithMessage("ParmsType encodes more than ParmsNum "
|
|
"parameters in parseVectorParmsType."));
|
|
}
|