Skip to content

Commit

Permalink
[AIX][XCOFF][Patch2] decode vector information and extent long table …
Browse files Browse the repository at this point in the history
…of the traceback table of the xcoff.

SUMMARY:

1. decode the Vector extension if has_vec is set
2. decode long table fields, if longtbtable is set.

There is conflict on the bit order of HasVectorInfoMask and HasExtensionTableMask between AIX os header and IBM aix compiler XLC.
In the /usr/include/sys/debug.h defines
static constexpr uint32_t HasVectorInfoMask = 0x0040'0000;
static constexpr uint32_t HasExtensionTableMask = 0x0080'0000;
but the XLC defines as

static constexpr uint32_t HasVectorInfoMask = 0x0080'0000;
static constexpr uint32_t HasExtensionTableMask = 0x0040'0000;
we follows the definition of the IBM AIX compiler XLC here.

Reviewer: Jason Liu

Differential Revision: https://reviews.llvm.org/D86461
  • Loading branch information
diggerlin committed Nov 19, 2020
1 parent 341f3c1 commit ab77fa5
Show file tree
Hide file tree
Showing 4 changed files with 281 additions and 23 deletions.
35 changes: 33 additions & 2 deletions llvm/include/llvm/BinaryFormat/XCOFF.h
Expand Up @@ -331,8 +331,8 @@ struct TracebackTable {
static constexpr uint32_t FPRSavedShift = 24;

// Byte 6
static constexpr uint32_t HasExtensionTableMask = 0x0080'0000;
static constexpr uint32_t HasVectorInfoMask = 0x0040'0000;
static constexpr uint32_t HasVectorInfoMask = 0x0080'0000;
static constexpr uint32_t HasExtensionTableMask = 0x0040'0000;
static constexpr uint32_t GPRSavedMask = 0x003F'0000;
static constexpr uint32_t GPRSavedShift = 16;

Expand All @@ -346,8 +346,39 @@ struct TracebackTable {
static constexpr uint8_t NumberOfFloatingPointParmsShift = 1;

// Masks to select leftmost bits for decoding parameter type information.
// Bit to use when vector info is not presented.
static constexpr uint32_t ParmTypeIsFloatingBit = 0x8000'0000;
static constexpr uint32_t ParmTypeFloatingIsDoubleBit = 0x4000'0000;
// Bits to use when vector info is presented.
static constexpr uint32_t ParmTypeIsFixedBits = 0x0000'0000;
static constexpr uint32_t ParmTypeIsVectorBits = 0x4000'0000;
static constexpr uint32_t ParmTypeIsFloatingBits = 0x8000'0000;
static constexpr uint32_t ParmTypeIsDoubleBits = 0xC000'0000;
static constexpr uint32_t ParmTypeMask = 0xC000'0000;

// Vector extension
static constexpr uint16_t NumberOfVRSavedMask = 0xFC00;
static constexpr uint16_t IsVRSavedOnStackMask = 0x0200;
static constexpr uint16_t HasVarArgsMask = 0x0100;
static constexpr uint8_t NumberOfVRSavedShift = 10;

static constexpr uint16_t NumberOfVectorParmsMask = 0x00FE;
static constexpr uint16_t HasVMXInstructionMask = 0x0001;
static constexpr uint8_t NumberOfVectorParmsShift = 1;

static constexpr uint32_t ParmTypeIsVectorCharBit = 0x0000'0000;
static constexpr uint32_t ParmTypeIsVectorShortBit = 0x4000'0000;
static constexpr uint32_t ParmTypeIsVectorIntBit = 0x8000'0000;
static constexpr uint32_t ParmTypeIsVectorFloatBit = 0xC000'0000;
};

// Extended Traceback table flags.
enum ExtendedTBTableFlag : uint8_t {
TB_OS1 = 0x80, ///< Reserved for OS use
TB_RESERVED = 0x40, ///< Reserved for compiler
TB_SSP_CANARY = 0x20, ///< stack smasher canary present on stack
TB_OS2 = 0x10, ///< Reserved for OS use
TB_LONGTBTABLE2 = 0x01 ///< Additional tbtable extension exists
};

} // end namespace XCOFF
Expand Down
22 changes: 21 additions & 1 deletion llvm/include/llvm/Object/XCOFFObjectFile.h
Expand Up @@ -395,6 +395,23 @@ class XCOFFSymbolRef {
bool isFunction() const;
};

class TBVectorExt {
friend class XCOFFTracebackTable;

uint16_t Data;
uint32_t VecParmsInfo;

TBVectorExt(StringRef TBvectorStrRef);

public:
uint8_t geNumberOfVRSaved() const;
bool isVRSavedOnStack() const;
bool hasVarArgs() const;
uint8_t getNumberOfVectorParms() const;
bool hasVMXInstruction() const;
SmallString<32> getVectorParmsInfoString() const;
};

/// This class provides methods to extract traceback table data from a buffer.
/// The various accessors may reference the buffer provided via the constructor.

Expand All @@ -407,9 +424,10 @@ class XCOFFTracebackTable {
Optional<SmallVector<uint32_t, 8>> ControlledStorageInfoDisp;
Optional<StringRef> FunctionName;
Optional<uint8_t> AllocaRegister;
Optional<TBVectorExt> VecExt;
Optional<uint8_t> ExtensionTable;

XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size, Error &Err);

public:
/// Parse an XCOFF Traceback Table from \a Ptr with \a Size bytes.
/// Returns an XCOFFTracebackTable upon successful parsing, otherwise an
Expand Down Expand Up @@ -469,6 +487,8 @@ class XCOFFTracebackTable {
}
const Optional<StringRef> &getFunctionName() const { return FunctionName; }
const Optional<uint8_t> &getAllocaRegister() const { return AllocaRegister; }
const Optional<TBVectorExt> &getVectorExt() const { return VecExt; }
const Optional<uint8_t> &getExtensionTable() const { return ExtensionTable; }
};

bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes);
Expand Down
114 changes: 109 additions & 5 deletions llvm/lib/Object/XCOFFObjectFile.cpp
Expand Up @@ -845,6 +845,103 @@ bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
return support::endian::read32be(Bytes.data()) == 0;
}

TBVectorExt::TBVectorExt(StringRef TBvectorStrRef) {
const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
Data = support::endian::read16be(Ptr);
VecParmsInfo = support::endian::read32be(Ptr + 2);
}

#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
#define GETVALUEWITHMASKSHIFT(X, S) \
((Data & (TracebackTable::X)) >> (TracebackTable::S))
uint8_t TBVectorExt::geNumberOfVRSaved() const {
return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
}

bool TBVectorExt::isVRSavedOnStack() const {
return GETVALUEWITHMASK(IsVRSavedOnStackMask);
}

bool TBVectorExt::hasVarArgs() const {
return GETVALUEWITHMASK(HasVarArgsMask);
}
uint8_t TBVectorExt::getNumberOfVectorParms() const {
return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
NumberOfVectorParmsShift);
}

bool TBVectorExt::hasVMXInstruction() const {
return GETVALUEWITHMASK(HasVMXInstructionMask);
}
#undef GETVALUEWITHMASK
#undef GETVALUEWITHMASKSHIFT

SmallString<32> TBVectorExt::getVectorParmsInfoString() const {
SmallString<32> ParmsType;
uint32_t Value = VecParmsInfo;
for (uint8_t I = 0; I < getNumberOfVectorParms(); ++I) {
if (I != 0)
ParmsType += ", ";
switch (Value & TracebackTable::ParmTypeMask) {
case TracebackTable::ParmTypeIsVectorCharBit:
ParmsType += "vc";
break;

case TracebackTable::ParmTypeIsVectorShortBit:
ParmsType += "vs";
break;

case TracebackTable::ParmTypeIsVectorIntBit:
ParmsType += "vi";
break;

case TracebackTable::ParmTypeIsVectorFloatBit:
ParmsType += "vf";
break;
}
Value <<= 2;
}
return ParmsType;
}

static SmallString<32> parseParmsTypeWithVecInfo(uint32_t Value,
unsigned int ParmsNum) {
SmallString<32> ParmsType;
unsigned I = 0;
bool Begin = false;
while (I < ParmsNum || Value) {
if (Begin)
ParmsType += ", ";
else
Begin = true;

switch (Value & TracebackTable::ParmTypeMask) {
case TracebackTable::ParmTypeIsFixedBits:
ParmsType += "i";
++I;
break;
case TracebackTable::ParmTypeIsVectorBits:
ParmsType += "v";
break;
case TracebackTable::ParmTypeIsFloatingBits:
ParmsType += "f";
++I;
break;
case TracebackTable::ParmTypeIsDoubleBits:
ParmsType += "d";
++I;
break;
default:
assert(false && "Unrecognized bits in ParmsType.");
}
Value <<= 2;
}
assert(I == ParmsNum &&
"The total parameters number of fixed-point or floating-point "
"parameters not equal to the number in the parameter type!");
return ParmsType;
}

static SmallString<32> parseParmsType(uint32_t Value, unsigned ParmsNum) {
SmallString<32> ParmsType;
for (unsigned I = 0; I < ParmsNum; ++I) {
Expand Down Expand Up @@ -897,10 +994,10 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
// indicates the presence of vector parameters.
if (ParmNum > 0) {
uint32_t ParamsTypeValue = DE.getU32(Cur);
// TODO: when hasVectorInfo() is true, we need to implement a new version
// of parsing parameter type for vector info.
if (Cur && !hasVectorInfo())
ParmsType = parseParmsType(ParamsTypeValue, ParmNum);
if (Cur)
ParmsType = hasVectorInfo()
? parseParmsTypeWithVecInfo(ParamsTypeValue, ParmNum)
: parseParmsType(ParamsTypeValue, ParmNum);
}
}

Expand Down Expand Up @@ -931,7 +1028,14 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
if (Cur && isAllocaUsed())
AllocaRegister = DE.getU8(Cur);

// TODO: Need to parse vector info and extension table if there is one.
if (Cur && hasVectorInfo()) {
StringRef VectorExtRef = DE.getBytes(Cur, 6);
if (Cur)
VecExt = TBVectorExt(VectorExtRef);
}

if (Cur && hasExtensionTable())
ExtensionTable = DE.getU8(Cur);

if (!Cur)
Err = Cur.takeError();
Expand Down

0 comments on commit ab77fa5

Please sign in to comment.