brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · 6b9e89e Raw
117 lines · cpp
1//===- TapiFile.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// This file defines the Text-based Dynamcic Library Stub format.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/Object/TapiFile.h"14#include "llvm/ADT/StringRef.h"15#include "llvm/BinaryFormat/MachO.h"16#include "llvm/Support/MemoryBufferRef.h"17#include "llvm/TextAPI/ArchitectureSet.h"18#include "llvm/TextAPI/InterfaceFile.h"19#include "llvm/TextAPI/Platform.h"20#include "llvm/TextAPI/Symbol.h"21 22using namespace llvm;23using namespace MachO;24using namespace object;25 26static uint32_t getFlags(const Symbol *Sym) {27  uint32_t Flags = BasicSymbolRef::SF_Global;28  if (Sym->isUndefined())29    Flags |= BasicSymbolRef::SF_Undefined;30  else31    Flags |= BasicSymbolRef::SF_Exported;32 33  if (Sym->isWeakDefined() || Sym->isWeakReferenced())34    Flags |= BasicSymbolRef::SF_Weak;35 36  return Flags;37}38 39static SymbolRef::Type getType(const Symbol *Sym) {40  SymbolRef::Type Type = SymbolRef::ST_Unknown;41  if (Sym->isData())42    Type = SymbolRef::ST_Data;43  else if (Sym->isText())44    Type = SymbolRef::ST_Function;45 46  return Type;47}48 49TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &Interface,50                   Architecture Arch)51    : SymbolicFile(ID_TapiFile, Source), Arch(Arch),52      FileKind(Interface.getFileType()) {53  for (const auto *Symbol : Interface.symbols()) {54    if (!Symbol->getArchitectures().has(Arch))55      continue;56 57    switch (Symbol->getKind()) {58    case EncodeKind::GlobalSymbol:59      Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol),60                           ::getType(Symbol));61      break;62    case EncodeKind::ObjectiveCClass:63      if (Interface.getPlatforms().count(PLATFORM_MACOS) && Arch == AK_i386) {64        Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(),65                             getFlags(Symbol), ::getType(Symbol));66      } else {67        Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(),68                             getFlags(Symbol), ::getType(Symbol));69        Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(),70                             getFlags(Symbol), ::getType(Symbol));71      }72      break;73    case EncodeKind::ObjectiveCClassEHType:74      Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(),75                           getFlags(Symbol), ::getType(Symbol));76      break;77    case EncodeKind::ObjectiveCInstanceVariable:78      Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), getFlags(Symbol),79                           ::getType(Symbol));80      break;81    }82  }83}84 85TapiFile::~TapiFile() = default;86 87void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; }88 89Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const {90  assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");91  const Symbol &Sym = Symbols[DRI.d.a];92  OS << Sym.Prefix << Sym.Name;93  return Error::success();94}95 96Expected<SymbolRef::Type> TapiFile::getSymbolType(DataRefImpl DRI) const {97  assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");98  return Symbols[DRI.d.a].Type;99}100 101Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const {102  assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");103  return Symbols[DRI.d.a].Flags;104}105 106basic_symbol_iterator TapiFile::symbol_begin() const {107  DataRefImpl DRI;108  DRI.d.a = 0;109  return BasicSymbolRef{DRI, this};110}111 112basic_symbol_iterator TapiFile::symbol_end() const {113  DataRefImpl DRI;114  DRI.d.a = Symbols.size();115  return BasicSymbolRef{DRI, this};116}117