Path: blob/main/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp
35232 views
//===- TapiFile.cpp -------------------------------------------------------===//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//===----------------------------------------------------------------------===//7//8// This file defines the Text-based Dynamcic Library Stub format.9//10//===----------------------------------------------------------------------===//1112#include "llvm/Object/TapiFile.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/BinaryFormat/MachO.h"15#include "llvm/Object/Error.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"2122using namespace llvm;23using namespace MachO;24using namespace object;2526static uint32_t getFlags(const Symbol *Sym) {27uint32_t Flags = BasicSymbolRef::SF_Global;28if (Sym->isUndefined())29Flags |= BasicSymbolRef::SF_Undefined;30else31Flags |= BasicSymbolRef::SF_Exported;3233if (Sym->isWeakDefined() || Sym->isWeakReferenced())34Flags |= BasicSymbolRef::SF_Weak;3536return Flags;37}3839static SymbolRef::Type getType(const Symbol *Sym) {40SymbolRef::Type Type = SymbolRef::ST_Unknown;41if (Sym->isData())42Type = SymbolRef::ST_Data;43else if (Sym->isText())44Type = SymbolRef::ST_Function;4546return Type;47}4849TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &Interface,50Architecture Arch)51: SymbolicFile(ID_TapiFile, Source), Arch(Arch),52FileKind(Interface.getFileType()) {53for (const auto *Symbol : Interface.symbols()) {54if (!Symbol->getArchitectures().has(Arch))55continue;5657switch (Symbol->getKind()) {58case EncodeKind::GlobalSymbol:59Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol),60::getType(Symbol));61break;62case EncodeKind::ObjectiveCClass:63if (Interface.getPlatforms().count(PLATFORM_MACOS) && Arch == AK_i386) {64Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(),65getFlags(Symbol), ::getType(Symbol));66} else {67Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(),68getFlags(Symbol), ::getType(Symbol));69Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(),70getFlags(Symbol), ::getType(Symbol));71}72break;73case EncodeKind::ObjectiveCClassEHType:74Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(),75getFlags(Symbol), ::getType(Symbol));76break;77case EncodeKind::ObjectiveCInstanceVariable:78Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), getFlags(Symbol),79::getType(Symbol));80break;81}82}83}8485TapiFile::~TapiFile() = default;8687void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; }8889Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const {90assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");91const Symbol &Sym = Symbols[DRI.d.a];92OS << Sym.Prefix << Sym.Name;93return Error::success();94}9596Expected<SymbolRef::Type> TapiFile::getSymbolType(DataRefImpl DRI) const {97assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");98return Symbols[DRI.d.a].Type;99}100101Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const {102assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");103return Symbols[DRI.d.a].Flags;104}105106basic_symbol_iterator TapiFile::symbol_begin() const {107DataRefImpl DRI;108DRI.d.a = 0;109return BasicSymbolRef{DRI, this};110}111112basic_symbol_iterator TapiFile::symbol_end() const {113DataRefImpl DRI;114DRI.d.a = Symbols.size();115return BasicSymbolRef{DRI, this};116}117118119