diff options
author | diggerlin <digger.llvm@gmail.com> | 2020-11-19 10:23:43 -0500 |
---|---|---|
committer | diggerlin <digger.llvm@gmail.com> | 2020-11-19 10:23:43 -0500 |
commit | ab77fa515583ca906f2cb09a5f5e1ea3c48ec725 (patch) | |
tree | 35dc12071fa68351e33c79d7eb19b336f14daff2 /llvm/lib/Object/XCOFFObjectFile.cpp | |
parent | 341f3c1120dfa8879e5f714a07fc8b16c8887a7f (diff) | |
download | llvm-ab77fa515583ca906f2cb09a5f5e1ea3c48ec725.zip llvm-ab77fa515583ca906f2cb09a5f5e1ea3c48ec725.tar.gz llvm-ab77fa515583ca906f2cb09a5f5e1ea3c48ec725.tar.bz2 |
[AIX][XCOFF][Patch2] decode vector information and extent long table 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
Diffstat (limited to 'llvm/lib/Object/XCOFFObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/XCOFFObjectFile.cpp | 114 |
1 files changed, 109 insertions, 5 deletions
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp index 23ecafd..9c4f97d 100644 --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -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) { @@ -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); } } @@ -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(); |