123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- //===-- 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"
- #include "llvm/Support/Errc.h"
- #include "llvm/Support/Error.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";
- }
- #undef RELOC_CASE
- #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
- Expected<SmallString<32>> XCOFF::parseParmsType(uint32_t Value,
- unsigned FixedParmsNum,
- unsigned FloatingParmsNum) {
- SmallString<32> ParmsType;
- int Bits = 0;
- unsigned ParsedFixedNum = 0;
- unsigned ParsedFloatingNum = 0;
- unsigned ParsedNum = 0;
- unsigned ParmsNum = FixedParmsNum + FloatingParmsNum;
- // In the function PPCFunctionInfo::getParmsType(), when there are no vector
- // parameters, the 31st bit of ParmsType is always zero even if it indicates a
- // floating point parameter. The parameter type information is lost. There
- // are only 8 GPRs used for parameters passing, the floating parameters
- // also occupy GPRs if there are available, so the 31st bit can never be a
- // fixed parameter. At the same time, we also do not know whether the zero of
- // the 31st bit indicates a float or double parameter type here. Therefore, we
- // ignore the 31st bit.
- while (Bits < 31 && ParsedNum < ParmsNum) {
- if (++ParsedNum > 1)
- ParmsType += ", ";
- if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
- // Fixed parameter type.
- ParmsType += "i";
- ++ParsedFixedNum;
- Value <<= 1;
- ++Bits;
- } else {
- if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
- // Float parameter type.
- ParmsType += "f";
- else
- // Double parameter type.
- ParmsType += "d";
- ++ParsedFloatingNum;
- Value <<= 2;
- Bits += 2;
- }
- }
- // We have more parameters than the 32 Bits could encode.
- if (ParsedNum < ParmsNum)
- ParmsType += ", ...";
- if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
- ParsedFloatingNum > FloatingParmsNum)
- return createStringError(errc::invalid_argument,
- "ParmsType encodes can not map to ParmsNum "
- "parameters in parseParmsType.");
- 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;
- }
- Expected<SmallString<32>>
- XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum,
- unsigned FloatingParmsNum,
- unsigned VectorParmsNum) {
- SmallString<32> ParmsType;
- unsigned ParsedFixedNum = 0;
- unsigned ParsedFloatingNum = 0;
- unsigned ParsedVectorNum = 0;
- unsigned ParsedNum = 0;
- unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum;
- for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) {
- if (++ParsedNum > 1)
- ParmsType += ", ";
- switch (Value & TracebackTable::ParmTypeMask) {
- case TracebackTable::ParmTypeIsFixedBits:
- ParmsType += "i";
- ++ParsedFixedNum;
- break;
- case TracebackTable::ParmTypeIsVectorBits:
- ParmsType += "v";
- ++ParsedVectorNum;
- break;
- case TracebackTable::ParmTypeIsFloatingBits:
- ParmsType += "f";
- ++ParsedFloatingNum;
- break;
- case TracebackTable::ParmTypeIsDoubleBits:
- ParmsType += "d";
- ++ParsedFloatingNum;
- break;
- default:
- assert(false && "Unrecognized bits in ParmsType.");
- }
- Value <<= 2;
- }
- // We have more parameters than the 32 Bits could encode.
- if (ParsedNum < ParmsNum)
- ParmsType += ", ...";
- if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
- ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum)
- return createStringError(
- errc::invalid_argument,
- "ParmsType encodes can not map to ParmsNum parameters "
- "in parseParmsTypeWithVecInfo.");
- return ParmsType;
- }
- Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value,
- unsigned ParmsNum) {
- SmallString<32> ParmsType;
- unsigned ParsedNum = 0;
- for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) {
- if (++ParsedNum > 1)
- 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;
- }
- // We have more parameters than the 32 Bits could encode.
- if (ParsedNum < ParmsNum)
- ParmsType += ", ...";
- if (Value != 0u)
- return createStringError(errc::invalid_argument,
- "ParmsType encodes more than ParmsNum parameters "
- "in parseVectorParmsType.");
- return ParmsType;
- }
|