brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 22551a6 Raw
166 lines · cpp
1//===-- CoreSpec.cpp ------------------------------------------------------===//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 "CoreSpec.h"10#include "llvm/BinaryFormat/MachO.h"11#include "llvm/Support/YAMLTraits.h"12#include <stdio.h>13#include <string>14 15using llvm::yaml::Input;16using llvm::yaml::IO;17using llvm::yaml::MappingTraits;18 19template <> struct llvm::yaml::MappingTraits<RegisterNameAndValue> {20  static void mapping(IO &io, RegisterNameAndValue &name_value) {21    io.mapRequired("name", name_value.name);22    io.mapRequired("value", name_value.value);23  }24};25LLVM_YAML_IS_SEQUENCE_VECTOR(RegisterNameAndValue)26 27template <> struct llvm::yaml::ScalarEnumerationTraits<RegisterFlavor> {28  static void enumeration(IO &io, RegisterFlavor &flavor) {29    io.enumCase(flavor, "gpr", RegisterFlavor::GPR);30    io.enumCase(flavor, "fpr", RegisterFlavor::FPR);31    io.enumCase(flavor, "exc", RegisterFlavor::EXC);32  }33};34 35template <> struct llvm::yaml::MappingTraits<RegisterSet> {36  static void mapping(IO &io, RegisterSet &regset) {37    io.mapRequired("flavor", regset.flavor);38    io.mapRequired("registers", regset.registers);39  }40};41LLVM_YAML_IS_SEQUENCE_VECTOR(RegisterSet)42 43template <> struct llvm::yaml::MappingTraits<Thread> {44  static void mapping(IO &io, Thread &thread) {45    io.mapRequired("regsets", thread.regsets);46  }47};48LLVM_YAML_IS_SEQUENCE_VECTOR(Thread)49 50template <> struct llvm::yaml::MappingTraits<MemoryRegion> {51  static void mapping(IO &io, MemoryRegion &memory) {52    io.mapRequired("addr", memory.addr);53    io.mapOptional("UInt8", memory.bytes);54    io.mapOptional("UInt32", memory.words);55    io.mapOptional("UInt64", memory.doublewords);56 57    if (memory.bytes.size()) {58      memory.type = MemoryType::UInt8;59      memory.size = memory.bytes.size();60    } else if (memory.words.size()) {61      memory.type = MemoryType::UInt32;62      memory.size = memory.words.size() * 4;63    } else if (memory.doublewords.size()) {64      memory.type = MemoryType::UInt64;65      memory.size = memory.doublewords.size() * 8;66    }67  }68};69LLVM_YAML_IS_SEQUENCE_VECTOR(MemoryRegion)70 71template <> struct llvm::yaml::MappingTraits<Binary> {72  static void mapping(IO &io, Binary &binary) {73    io.mapOptional("name", binary.name);74    io.mapRequired("uuid", binary.uuid);75    std::optional<uint64_t> va, slide;76    io.mapOptional("virtual-address", va);77    io.mapOptional("slide", slide);78    if (va && *va != UINT64_MAX) {79      binary.value_is_slide = false;80      binary.value = *va;81    } else if (slide && *slide != UINT64_MAX) {82      binary.value_is_slide = true;83      binary.value = *slide;84    } else {85      fprintf(stderr,86              "No virtual-address or slide specified for binary %s, aborting\n",87              binary.uuid.c_str());88      exit(1);89    }90  }91};92LLVM_YAML_IS_SEQUENCE_VECTOR(Binary)93 94template <> struct llvm::yaml::MappingTraits<AddressableBits> {95  static void mapping(IO &io, AddressableBits &addr_bits) {96    std::optional<int> addressable_bits;97    io.mapOptional("num-bits", addressable_bits);98    if (addressable_bits) {99      addr_bits.lowmem_bits = *addressable_bits;100      addr_bits.highmem_bits = *addressable_bits;101    } else {102      io.mapOptional("lowmem-num-bits", addr_bits.lowmem_bits);103      io.mapOptional("highmem-num-bits", addr_bits.highmem_bits);104    }105  }106};107 108template <> struct llvm::yaml::MappingTraits<CoreSpec> {109  static void mapping(IO &io, CoreSpec &corespec) {110    std::string cpuname;111    io.mapRequired("cpu", cpuname);112    if (cpuname == "armv7m") {113      corespec.cputype = llvm::MachO::CPU_TYPE_ARM;114      corespec.cpusubtype = llvm::MachO::CPU_SUBTYPE_ARM_V7M;115    } else if (cpuname == "armv7") {116      corespec.cputype = llvm::MachO::CPU_TYPE_ARM;117      corespec.cpusubtype = llvm::MachO::CPU_SUBTYPE_ARM_ALL;118    } else if (cpuname == "riscv") {119      corespec.cputype = llvm::MachO::CPU_TYPE_RISCV;120      corespec.cpusubtype = llvm::MachO::CPU_SUBTYPE_RISCV_ALL;121    } else if (cpuname == "arm64") {122      corespec.cputype = llvm::MachO::CPU_TYPE_ARM64;123      corespec.cpusubtype = llvm::MachO::CPU_SUBTYPE_ARM64_ALL;124    } else {125      fprintf(stderr, "Unrecognized cpu name %s, exiting.\n", cpuname.c_str());126      exit(1);127    }128    io.mapOptional("threads", corespec.threads);129    io.mapOptional("memory-regions", corespec.memory_regions);130    if (corespec.cputype == llvm::MachO::CPU_TYPE_ARM ||131        corespec.cputype == llvm::MachO::CPU_TYPE_RISCV)132      corespec.wordsize = 4;133    else if (corespec.cputype == llvm::MachO::CPU_TYPE_ARM64)134      corespec.wordsize = 8;135    else {136      fprintf(stderr,137              "Unrecognized cputype, could not set wordsize, exiting.\n");138      exit(1);139    }140    io.mapOptional("addressable-bits", corespec.addressable_bits);141    io.mapOptional("binaries", corespec.binaries);142    if (corespec.addressable_bits) {143      if (!corespec.addressable_bits->lowmem_bits)144        corespec.addressable_bits->lowmem_bits = corespec.wordsize * 8;145      if (!corespec.addressable_bits->highmem_bits)146        corespec.addressable_bits->highmem_bits = corespec.wordsize * 8;147    }148  }149};150 151CoreSpec from_yaml(char *buf, size_t len) {152  llvm::StringRef file_corespec_strref(buf, len);153 154  Input yin(file_corespec_strref);155 156  CoreSpec v;157  yin >> v;158 159  if (yin.error()) {160    fprintf(stderr, "Unable to parse YAML, exiting\n");161    exit(1);162  }163 164  return v;165}166