Path: blob/main/contrib/llvm-project/llvm/lib/BinaryFormat/XCOFF.cpp
35234 views
//===-- llvm/BinaryFormat/XCOFF.cpp - The XCOFF file format -----*- C++/-*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/BinaryFormat/XCOFF.h"9#include "llvm/ADT/SmallString.h"10#include "llvm/ADT/StringRef.h"11#include "llvm/Support/Errc.h"12#include "llvm/Support/Error.h"1314using namespace llvm;1516#define SMC_CASE(A) \17case XCOFF::XMC_##A: \18return #A;19StringRef XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC) {20switch (SMC) {21SMC_CASE(PR)22SMC_CASE(RO)23SMC_CASE(DB)24SMC_CASE(GL)25SMC_CASE(XO)26SMC_CASE(SV)27SMC_CASE(SV64)28SMC_CASE(SV3264)29SMC_CASE(TI)30SMC_CASE(TB)31SMC_CASE(RW)32SMC_CASE(TC0)33SMC_CASE(TC)34SMC_CASE(TD)35SMC_CASE(DS)36SMC_CASE(UA)37SMC_CASE(BS)38SMC_CASE(UC)39SMC_CASE(TL)40SMC_CASE(UL)41SMC_CASE(TE)42#undef SMC_CASE43}4445// TODO: need to add a test case for "Unknown" and other SMC.46return "Unknown";47}4849#define RELOC_CASE(A) \50case XCOFF::A: \51return #A;52StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {53switch (Type) {54RELOC_CASE(R_POS)55RELOC_CASE(R_RL)56RELOC_CASE(R_RLA)57RELOC_CASE(R_NEG)58RELOC_CASE(R_REL)59RELOC_CASE(R_TOC)60RELOC_CASE(R_TRL)61RELOC_CASE(R_TRLA)62RELOC_CASE(R_GL)63RELOC_CASE(R_TCL)64RELOC_CASE(R_REF)65RELOC_CASE(R_BA)66RELOC_CASE(R_BR)67RELOC_CASE(R_RBA)68RELOC_CASE(R_RBR)69RELOC_CASE(R_TLS)70RELOC_CASE(R_TLS_IE)71RELOC_CASE(R_TLS_LD)72RELOC_CASE(R_TLS_LE)73RELOC_CASE(R_TLSM)74RELOC_CASE(R_TLSML)75RELOC_CASE(R_TOCU)76RELOC_CASE(R_TOCL)77}78return "Unknown";79}80#undef RELOC_CASE8182#define LANG_CASE(A) \83case XCOFF::TracebackTable::A: \84return #A;8586StringRef XCOFF::getNameForTracebackTableLanguageId(87XCOFF::TracebackTable::LanguageID LangId) {88switch (LangId) {89LANG_CASE(C)90LANG_CASE(Fortran)91LANG_CASE(Pascal)92LANG_CASE(Ada)93LANG_CASE(PL1)94LANG_CASE(Basic)95LANG_CASE(Lisp)96LANG_CASE(Cobol)97LANG_CASE(Modula2)98LANG_CASE(Rpg)99LANG_CASE(PL8)100LANG_CASE(Assembly)101LANG_CASE(Java)102LANG_CASE(ObjectiveC)103LANG_CASE(CPlusPlus)104}105return "Unknown";106}107#undef LANG_CASE108109Expected<SmallString<32>> XCOFF::parseParmsType(uint32_t Value,110unsigned FixedParmsNum,111unsigned FloatingParmsNum) {112SmallString<32> ParmsType;113int Bits = 0;114unsigned ParsedFixedNum = 0;115unsigned ParsedFloatingNum = 0;116unsigned ParsedNum = 0;117unsigned ParmsNum = FixedParmsNum + FloatingParmsNum;118119// In the function PPCFunctionInfo::getParmsType(), when there are no vector120// parameters, the 31st bit of ParmsType is always zero even if it indicates a121// floating point parameter. The parameter type information is lost. There122// are only 8 GPRs used for parameters passing, the floating parameters123// also occupy GPRs if there are available, so the 31st bit can never be a124// fixed parameter. At the same time, we also do not know whether the zero of125// the 31st bit indicates a float or double parameter type here. Therefore, we126// ignore the 31st bit.127while (Bits < 31 && ParsedNum < ParmsNum) {128if (++ParsedNum > 1)129ParmsType += ", ";130if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {131// Fixed parameter type.132ParmsType += "i";133++ParsedFixedNum;134Value <<= 1;135++Bits;136} else {137if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)138// Float parameter type.139ParmsType += "f";140else141// Double parameter type.142ParmsType += "d";143++ParsedFloatingNum;144Value <<= 2;145Bits += 2;146}147}148149// We have more parameters than the 32 Bits could encode.150if (ParsedNum < ParmsNum)151ParmsType += ", ...";152153if (Value != 0u || ParsedFixedNum > FixedParmsNum ||154ParsedFloatingNum > FloatingParmsNum)155return createStringError(errc::invalid_argument,156"ParmsType encodes can not map to ParmsNum "157"parameters in parseParmsType.");158return ParmsType;159}160161SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {162SmallString<32> Res;163164if (Flag & ExtendedTBTableFlag::TB_OS1)165Res += "TB_OS1 ";166if (Flag & ExtendedTBTableFlag::TB_RESERVED)167Res += "TB_RESERVED ";168if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY)169Res += "TB_SSP_CANARY ";170if (Flag & ExtendedTBTableFlag::TB_OS2)171Res += "TB_OS2 ";172if (Flag & ExtendedTBTableFlag::TB_EH_INFO)173Res += "TB_EH_INFO ";174if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2)175Res += "TB_LONGTBTABLE2 ";176177// Two of the bits that haven't got used in the mask.178if (Flag & 0x06)179Res += "Unknown ";180181// Pop the last space.182Res.pop_back();183return Res;184}185186Expected<SmallString<32>>187XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum,188unsigned FloatingParmsNum,189unsigned VectorParmsNum) {190SmallString<32> ParmsType;191192unsigned ParsedFixedNum = 0;193unsigned ParsedFloatingNum = 0;194unsigned ParsedVectorNum = 0;195unsigned ParsedNum = 0;196unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum;197198for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) {199if (++ParsedNum > 1)200ParmsType += ", ";201202switch (Value & TracebackTable::ParmTypeMask) {203case TracebackTable::ParmTypeIsFixedBits:204ParmsType += "i";205++ParsedFixedNum;206break;207case TracebackTable::ParmTypeIsVectorBits:208ParmsType += "v";209++ParsedVectorNum;210break;211case TracebackTable::ParmTypeIsFloatingBits:212ParmsType += "f";213++ParsedFloatingNum;214break;215case TracebackTable::ParmTypeIsDoubleBits:216ParmsType += "d";217++ParsedFloatingNum;218break;219default:220assert(false && "Unrecognized bits in ParmsType.");221}222Value <<= 2;223}224225// We have more parameters than the 32 Bits could encode.226if (ParsedNum < ParmsNum)227ParmsType += ", ...";228229if (Value != 0u || ParsedFixedNum > FixedParmsNum ||230ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum)231return createStringError(232errc::invalid_argument,233"ParmsType encodes can not map to ParmsNum parameters "234"in parseParmsTypeWithVecInfo.");235236return ParmsType;237}238239Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value,240unsigned ParmsNum) {241SmallString<32> ParmsType;242unsigned ParsedNum = 0;243for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) {244if (++ParsedNum > 1)245ParmsType += ", ";246switch (Value & TracebackTable::ParmTypeMask) {247case TracebackTable::ParmTypeIsVectorCharBit:248ParmsType += "vc";249break;250251case TracebackTable::ParmTypeIsVectorShortBit:252ParmsType += "vs";253break;254255case TracebackTable::ParmTypeIsVectorIntBit:256ParmsType += "vi";257break;258259case TracebackTable::ParmTypeIsVectorFloatBit:260ParmsType += "vf";261break;262}263264Value <<= 2;265}266267// We have more parameters than the 32 Bits could encode.268if (ParsedNum < ParmsNum)269ParmsType += ", ...";270271if (Value != 0u)272return createStringError(errc::invalid_argument,273"ParmsType encodes more than ParmsNum parameters "274"in parseVectorParmsType.");275return ParmsType;276}277278279