1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00
llvm-mirror/lib/BinaryFormat/XCOFF.cpp
diggerlin 44531d9a39 [XCOFF][AIX] Emit EH information in traceback table
SUMMARY:

In order for the runtime on AIX to find the compact unwind section(EHInfo table),
we would need to set the following on the traceback table:

The 6th byte's longtbtable field to true to signal there is an Extended TB Table Flag.
The Extended TB Table Flag to be 0x08 to signal there is an exception handling info presents.
Emit the offset between ehinfo TC entry and TOC base after all other optional portions of traceback table.

The patch is authored by Jason Liu.

Reviewers: David Tenty, Digger Lin
Differential Revision: https://reviews.llvm.org/D92766
2020-12-16 09:34:59 -05:00

157 lines
4.0 KiB
C++

//===-- llvm/BinaryFormat/XCOFF.cpp - The XCOFF file format -----*- C++/-*-===//
//
// 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/BinaryFormat/XCOFF.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
using namespace llvm;
#define SMC_CASE(A) \
case XCOFF::XMC_##A: \
return #A;
StringRef XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC) {
switch (SMC) {
SMC_CASE(PR)
SMC_CASE(RO)
SMC_CASE(DB)
SMC_CASE(GL)
SMC_CASE(XO)
SMC_CASE(SV)
SMC_CASE(SV64)
SMC_CASE(SV3264)
SMC_CASE(TI)
SMC_CASE(TB)
SMC_CASE(RW)
SMC_CASE(TC0)
SMC_CASE(TC)
SMC_CASE(TD)
SMC_CASE(DS)
SMC_CASE(UA)
SMC_CASE(BS)
SMC_CASE(UC)
SMC_CASE(TL)
SMC_CASE(UL)
SMC_CASE(TE)
#undef SMC_CASE
}
// TODO: need to add a test case for "Unknown" and other SMC.
return "Unknown";
}
#define RELOC_CASE(A) \
case XCOFF::A: \
return #A;
StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {
switch (Type) {
RELOC_CASE(R_POS)
RELOC_CASE(R_RL)
RELOC_CASE(R_RLA)
RELOC_CASE(R_NEG)
RELOC_CASE(R_REL)
RELOC_CASE(R_TOC)
RELOC_CASE(R_TRL)
RELOC_CASE(R_TRLA)
RELOC_CASE(R_GL)
RELOC_CASE(R_TCL)
RELOC_CASE(R_REF)
RELOC_CASE(R_BA)
RELOC_CASE(R_BR)
RELOC_CASE(R_RBA)
RELOC_CASE(R_RBR)
RELOC_CASE(R_TLS)
RELOC_CASE(R_TLS_IE)
RELOC_CASE(R_TLS_LD)
RELOC_CASE(R_TLS_LE)
RELOC_CASE(R_TLSM)
RELOC_CASE(R_TLSML)
RELOC_CASE(R_TOCU)
RELOC_CASE(R_TOCL)
}
return "Unknown";
}
#define LANG_CASE(A) \
case XCOFF::TracebackTable::A: \
return #A;
StringRef XCOFF::getNameForTracebackTableLanguageId(
XCOFF::TracebackTable::LanguageID LangId) {
switch (LangId) {
LANG_CASE(C)
LANG_CASE(Fortran)
LANG_CASE(Pascal)
LANG_CASE(Ada)
LANG_CASE(PL1)
LANG_CASE(Basic)
LANG_CASE(Lisp)
LANG_CASE(Cobol)
LANG_CASE(Modula2)
LANG_CASE(Rpg)
LANG_CASE(PL8)
LANG_CASE(Assembly)
LANG_CASE(Java)
LANG_CASE(ObjectiveC)
LANG_CASE(CPlusPlus)
}
return "Unknown";
}
#undef LANG_CASE
SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
SmallString<32> ParmsType;
for (unsigned I = 0; I < ParmsNum; ++I) {
if (I != 0)
ParmsType += ", ";
if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
// Fixed parameter type.
ParmsType += "i";
Value <<= 1;
} else {
if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
// Float parameter type.
ParmsType += "f";
else
// Double parameter type.
ParmsType += "d";
Value <<= 2;
}
}
assert(Value == 0u && "ParmsType encodes more than ParmsNum parameters.");
return ParmsType;
}
SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
SmallString<32> Res;
if (Flag & ExtendedTBTableFlag::TB_OS1)
Res += "TB_OS1 ";
if (Flag & ExtendedTBTableFlag::TB_RESERVED)
Res += "TB_RESERVED ";
if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY)
Res += "TB_SSP_CANARY ";
if (Flag & ExtendedTBTableFlag::TB_OS2)
Res += "TB_OS2 ";
if (Flag & ExtendedTBTableFlag::TB_EH_INFO)
Res += "TB_EH_INFO ";
if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2)
Res += "TB_LONGTBTABLE2 ";
// Two of the bits that haven't got used in the mask.
if (Flag & 0x06)
Res += "Unknown ";
// Pop the last space.
Res.pop_back();
return Res;
}
#undef RELOC_CASE