aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/XCOFFObjectFile.cpp
diff options
context:
space:
mode:
authordiggerlin <digger.llvm@gmail.com>2020-11-19 10:23:43 -0500
committerdiggerlin <digger.llvm@gmail.com>2020-11-19 10:23:43 -0500
commitab77fa515583ca906f2cb09a5f5e1ea3c48ec725 (patch)
tree35dc12071fa68351e33c79d7eb19b336f14daff2 /llvm/lib/Object/XCOFFObjectFile.cpp
parent341f3c1120dfa8879e5f714a07fc8b16c8887a7f (diff)
downloadllvm-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.cpp114
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();