brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.9 KiB · 19d5b98 Raw
337 lines · cpp
1//===-- llvm/BinaryFormat/XCOFF.cpp - The XCOFF file format -----*- C++/-*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/BinaryFormat/XCOFF.h"10#include "llvm/ADT/SmallString.h"11#include "llvm/ADT/StringRef.h"12#include "llvm/ADT/StringSwitch.h"13#include "llvm/Support/Errc.h"14#include "llvm/Support/Error.h"15#include "llvm/TargetParser/PPCTargetParser.h"16 17using namespace llvm;18 19#define SMC_CASE(A)                                                            \20  case XCOFF::XMC_##A:                                                         \21    return #A;22StringRef XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC) {23  switch (SMC) {24    SMC_CASE(PR)25    SMC_CASE(RO)26    SMC_CASE(DB)27    SMC_CASE(GL)28    SMC_CASE(XO)29    SMC_CASE(SV)30    SMC_CASE(SV64)31    SMC_CASE(SV3264)32    SMC_CASE(TI)33    SMC_CASE(TB)34    SMC_CASE(RW)35    SMC_CASE(TC0)36    SMC_CASE(TC)37    SMC_CASE(TD)38    SMC_CASE(DS)39    SMC_CASE(UA)40    SMC_CASE(BS)41    SMC_CASE(UC)42    SMC_CASE(TL)43    SMC_CASE(UL)44    SMC_CASE(TE)45#undef SMC_CASE46  }47 48  // TODO: need to add a test case for "Unknown" and other SMC.49  return "Unknown";50}51 52#define RELOC_CASE(A)                                                          \53  case XCOFF::A:                                                               \54    return #A;55StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {56  switch (Type) {57    RELOC_CASE(R_POS)58    RELOC_CASE(R_RL)59    RELOC_CASE(R_RLA)60    RELOC_CASE(R_NEG)61    RELOC_CASE(R_REL)62    RELOC_CASE(R_TOC)63    RELOC_CASE(R_TRL)64    RELOC_CASE(R_TRLA)65    RELOC_CASE(R_GL)66    RELOC_CASE(R_TCL)67    RELOC_CASE(R_REF)68    RELOC_CASE(R_BA)69    RELOC_CASE(R_BR)70    RELOC_CASE(R_RBA)71    RELOC_CASE(R_RBR)72    RELOC_CASE(R_TLS)73    RELOC_CASE(R_TLS_IE)74    RELOC_CASE(R_TLS_LD)75    RELOC_CASE(R_TLS_LE)76    RELOC_CASE(R_TLSM)77    RELOC_CASE(R_TLSML)78    RELOC_CASE(R_TOCU)79    RELOC_CASE(R_TOCL)80  }81  return "Unknown";82}83#undef RELOC_CASE84 85#define LANG_CASE(A)                                                           \86  case XCOFF::TracebackTable::A:                                               \87    return #A;88 89StringRef XCOFF::getNameForTracebackTableLanguageId(90    XCOFF::TracebackTable::LanguageID LangId) {91  switch (LangId) {92    LANG_CASE(C)93    LANG_CASE(Fortran)94    LANG_CASE(Pascal)95    LANG_CASE(Ada)96    LANG_CASE(PL1)97    LANG_CASE(Basic)98    LANG_CASE(Lisp)99    LANG_CASE(Cobol)100    LANG_CASE(Modula2)101    LANG_CASE(Rpg)102    LANG_CASE(PL8)103    LANG_CASE(Assembly)104    LANG_CASE(Java)105    LANG_CASE(ObjectiveC)106    LANG_CASE(CPlusPlus)107  }108  return "Unknown";109}110#undef LANG_CASE111 112XCOFF::CFileCpuId XCOFF::getCpuID(StringRef CPUName) {113  StringRef CPU = PPC::normalizeCPUName(CPUName);114  return StringSwitch<XCOFF::CFileCpuId>(CPU)115      .Cases({"generic", "COM"}, XCOFF::TCPU_COM)116      .Case("601", XCOFF::TCPU_601)117      .Cases({"602", "603", "603e", "603ev"}, XCOFF::TCPU_603)118      .Cases({"604", "604e"}, XCOFF::TCPU_604)119      .Case("620", XCOFF::TCPU_620)120      .Case("970", XCOFF::TCPU_970)121      .Cases({"a2", "g3", "g4", "g5", "e500"}, XCOFF::TCPU_COM)122      .Cases({"pwr3", "pwr4"}, XCOFF::TCPU_COM)123      .Cases({"pwr5", "PWR5"}, XCOFF::TCPU_PWR5)124      .Cases({"pwr5x", "PWR5X"}, XCOFF::TCPU_PWR5X)125      .Cases({"pwr6", "PWR6"}, XCOFF::TCPU_PWR6)126      .Cases({"pwr6x", "PWR6E"}, XCOFF::TCPU_PWR6E)127      .Cases({"pwr7", "PWR7"}, XCOFF::TCPU_PWR7)128      .Cases({"pwr8", "PWR8"}, XCOFF::TCPU_PWR8)129      .Cases({"pwr9", "PWR9"}, XCOFF::TCPU_PWR9)130      .Cases({"pwr10", "PWR10"}, XCOFF::TCPU_PWR10)131      .Cases({"ppc", "PPC", "ppc32", "ppc64"}, XCOFF::TCPU_COM)132      .Case("ppc64le", XCOFF::TCPU_PWR8)133      .Case("future", XCOFF::TCPU_PWR10)134      .Cases({"any", "ANY"}, XCOFF::TCPU_ANY)135      .Default(XCOFF::TCPU_INVALID);136}137 138#define TCPU_CASE(A)                                                           \139  case XCOFF::TCPU_##A:                                                        \140    return #A;141StringRef XCOFF::getTCPUString(XCOFF::CFileCpuId TCPU) {142  switch (TCPU) {143    TCPU_CASE(INVALID)144    TCPU_CASE(PPC)145    TCPU_CASE(PPC64)146    TCPU_CASE(COM)147    TCPU_CASE(PWR)148    TCPU_CASE(ANY)149    TCPU_CASE(601)150    TCPU_CASE(603)151    TCPU_CASE(604)152    TCPU_CASE(620)153    TCPU_CASE(A35)154    TCPU_CASE(PWR5)155    TCPU_CASE(970)156    TCPU_CASE(PWR6)157    TCPU_CASE(PWR5X)158    TCPU_CASE(PWR6E)159    TCPU_CASE(PWR7)160    TCPU_CASE(PWR8)161    TCPU_CASE(PWR9)162    TCPU_CASE(PWR10)163    TCPU_CASE(PWRX)164  }165  return "INVALID";166}167#undef TCPU_CASE168 169Expected<SmallString<32>> XCOFF::parseParmsType(uint32_t Value,170                                                unsigned FixedParmsNum,171                                                unsigned FloatingParmsNum) {172  SmallString<32> ParmsType;173  int Bits = 0;174  unsigned ParsedFixedNum = 0;175  unsigned ParsedFloatingNum = 0;176  unsigned ParsedNum = 0;177  unsigned ParmsNum = FixedParmsNum + FloatingParmsNum;178 179  // In the function PPCFunctionInfo::getParmsType(), when there are no vector180  // parameters, the 31st bit of ParmsType is always zero even if it indicates a181  // floating point parameter. The parameter type information is lost. There182  // are only 8 GPRs used for parameters passing, the floating parameters183  // also occupy GPRs if there are available, so the 31st bit can never be a184  // fixed parameter. At the same time, we also do not know whether the zero of185  // the 31st bit indicates a float or double parameter type here. Therefore, we186  // ignore the 31st bit.187  while (Bits < 31 && ParsedNum < ParmsNum) {188    if (++ParsedNum > 1)189      ParmsType += ", ";190    if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {191      // Fixed parameter type.192      ParmsType += "i";193      ++ParsedFixedNum;194      Value <<= 1;195      ++Bits;196    } else {197      if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)198        // Float parameter type.199        ParmsType += "f";200      else201        // Double parameter type.202        ParmsType += "d";203      ++ParsedFloatingNum;204      Value <<= 2;205      Bits += 2;206    }207  }208 209  // We have more parameters than the 32 Bits could encode.210  if (ParsedNum < ParmsNum)211    ParmsType += ", ...";212 213  if (Value != 0u || ParsedFixedNum > FixedParmsNum ||214      ParsedFloatingNum > FloatingParmsNum)215    return createStringError(errc::invalid_argument,216                             "ParmsType encodes can not map to ParmsNum "217                             "parameters in parseParmsType.");218  return ParmsType;219}220 221SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {222  SmallString<32> Res;223 224  if (Flag & ExtendedTBTableFlag::TB_OS1)225    Res += "TB_OS1 ";226  if (Flag & ExtendedTBTableFlag::TB_RESERVED)227    Res += "TB_RESERVED ";228  if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY)229    Res += "TB_SSP_CANARY ";230  if (Flag & ExtendedTBTableFlag::TB_OS2)231    Res += "TB_OS2 ";232  if (Flag & ExtendedTBTableFlag::TB_EH_INFO)233    Res += "TB_EH_INFO ";234  if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2)235    Res += "TB_LONGTBTABLE2 ";236 237  // Two of the bits that haven't got used in the mask.238  if (Flag & 0x06)239    Res += "Unknown ";240 241  // Pop the last space.242  Res.pop_back();243  return Res;244}245 246Expected<SmallString<32>>247XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum,248                                 unsigned FloatingParmsNum,249                                 unsigned VectorParmsNum) {250  SmallString<32> ParmsType;251 252  unsigned ParsedFixedNum = 0;253  unsigned ParsedFloatingNum = 0;254  unsigned ParsedVectorNum = 0;255  unsigned ParsedNum = 0;256  unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum;257 258  for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) {259    if (++ParsedNum > 1)260      ParmsType += ", ";261 262    switch (Value & TracebackTable::ParmTypeMask) {263    case TracebackTable::ParmTypeIsFixedBits:264      ParmsType += "i";265      ++ParsedFixedNum;266      break;267    case TracebackTable::ParmTypeIsVectorBits:268      ParmsType += "v";269      ++ParsedVectorNum;270      break;271    case TracebackTable::ParmTypeIsFloatingBits:272      ParmsType += "f";273      ++ParsedFloatingNum;274      break;275    case TracebackTable::ParmTypeIsDoubleBits:276      ParmsType += "d";277      ++ParsedFloatingNum;278      break;279    default:280      assert(false && "Unrecognized bits in ParmsType.");281    }282    Value <<= 2;283  }284 285  // We have more parameters than the 32 Bits could encode.286  if (ParsedNum < ParmsNum)287    ParmsType += ", ...";288 289  if (Value != 0u || ParsedFixedNum > FixedParmsNum ||290      ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum)291    return createStringError(292        errc::invalid_argument,293        "ParmsType encodes can not map to ParmsNum parameters "294        "in parseParmsTypeWithVecInfo.");295 296  return ParmsType;297}298 299Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value,300                                                      unsigned ParmsNum) {301  SmallString<32> ParmsType;302  unsigned ParsedNum = 0;303  for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) {304    if (++ParsedNum > 1)305      ParmsType += ", ";306    switch (Value & TracebackTable::ParmTypeMask) {307    case TracebackTable::ParmTypeIsVectorCharBit:308      ParmsType += "vc";309      break;310 311    case TracebackTable::ParmTypeIsVectorShortBit:312      ParmsType += "vs";313      break;314 315    case TracebackTable::ParmTypeIsVectorIntBit:316      ParmsType += "vi";317      break;318 319    case TracebackTable::ParmTypeIsVectorFloatBit:320      ParmsType += "vf";321      break;322    }323 324    Value <<= 2;325  }326 327  // We have more parameters than the 32 Bits could encode.328  if (ParsedNum < ParmsNum)329    ParmsType += ", ...";330 331  if (Value != 0u)332    return createStringError(errc::invalid_argument,333                             "ParmsType encodes more than ParmsNum parameters "334                             "in parseVectorParmsType.");335  return ParmsType;336}337