diff options
Diffstat (limited to 'llvm/lib/Object')
-rw-r--r-- | llvm/lib/Object/Binary.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Object/CMakeLists.txt | 2 | ||||
-rw-r--r-- | llvm/lib/Object/LLVMBuild.txt | 2 | ||||
-rw-r--r-- | llvm/lib/Object/TapiFile.cpp | 104 | ||||
-rw-r--r-- | llvm/lib/Object/TapiUniversal.cpp | 54 |
5 files changed, 163 insertions, 3 deletions
diff --git a/llvm/lib/Object/Binary.cpp b/llvm/lib/Object/Binary.cpp index 1ceda54..944d2bc 100644 --- a/llvm/lib/Object/Binary.cpp +++ b/llvm/lib/Object/Binary.cpp @@ -18,6 +18,7 @@ #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/Minidump.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Object/TapiUniversal.h" #include "llvm/Object/WindowsResource.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" @@ -87,8 +88,7 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer, case file_magic::minidump: return MinidumpFile::create(Buffer); case file_magic::tapi_file: - // Placeholder until TAPI is supported for lib/Object - return errorCodeToError(object_error::invalid_file_type); + return TapiUniversal::create(Buffer); } llvm_unreachable("Unexpected Binary File Type"); } diff --git a/llvm/lib/Object/CMakeLists.txt b/llvm/lib/Object/CMakeLists.txt index e3ed640..59f21e9 100644 --- a/llvm/lib/Object/CMakeLists.txt +++ b/llvm/lib/Object/CMakeLists.txt @@ -21,6 +21,8 @@ add_llvm_library(LLVMObject RelocationResolver.cpp SymbolicFile.cpp SymbolSize.cpp + TapiFile.cpp + TapiUniversal.cpp WasmObjectFile.cpp WindowsMachineFlag.cpp WindowsResource.cpp diff --git a/llvm/lib/Object/LLVMBuild.txt b/llvm/lib/Object/LLVMBuild.txt index 605f1fb..dd30496 100644 --- a/llvm/lib/Object/LLVMBuild.txt +++ b/llvm/lib/Object/LLVMBuild.txt @@ -18,4 +18,4 @@ type = Library name = Object parent = Libraries -required_libraries = BitReader Core MC BinaryFormat MCParser Support +required_libraries = BitReader Core MC BinaryFormat MCParser Support TextAPI diff --git a/llvm/lib/Object/TapiFile.cpp b/llvm/lib/Object/TapiFile.cpp new file mode 100644 index 0000000..be7d762 --- /dev/null +++ b/llvm/lib/Object/TapiFile.cpp @@ -0,0 +1,104 @@ +//===- TapiFile.cpp -------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the Text-based Dynamcic Library Stub format. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/TapiFile.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/Error.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace llvm; +using namespace MachO; +using namespace object; + +static constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_"; +static constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_"; +static constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_"; +static constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_"; +static constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_"; + +static uint32_t getFlags(const Symbol *Sym) { + uint32_t Flags = BasicSymbolRef::SF_Global; + if (Sym->isUndefined()) + Flags |= BasicSymbolRef::SF_Undefined; + else + Flags |= BasicSymbolRef::SF_Exported; + + if (Sym->isWeakDefined() || Sym->isWeakReferenced()) + Flags |= BasicSymbolRef::SF_Weak; + + return Flags; +} + +TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface, + Architecture Arch) + : SymbolicFile(ID_TapiFile, Source) { + for (const auto *Symbol : interface.symbols()) { + if (!Symbol->getArchitectures().has(Arch)) + continue; + + auto PlatformKind = interface.getPlatform(); + switch (Symbol->getKind()) { + case SymbolKind::GlobalSymbol: + Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol)); + break; + case SymbolKind::ObjectiveCClass: + if (PlatformKind == PlatformKind::macOS && Arch == AK_i386) { + Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(), + getFlags(Symbol)); + } else { + Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(), + getFlags(Symbol)); + Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(), + getFlags(Symbol)); + } + break; + case SymbolKind::ObjectiveCClassEHType: + Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(), + getFlags(Symbol)); + break; + case SymbolKind::ObjectiveCInstanceVariable: + Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), + getFlags(Symbol)); + break; + } + } +} + +TapiFile::~TapiFile() = default; + +void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { + const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); + DRI.p = reinterpret_cast<uintptr_t>(++Sym); +} + +Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { + const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); + OS << Sym->Prefix << Sym->Name; + return Error::success(); +} + +uint32_t TapiFile::getSymbolFlags(DataRefImpl DRI) const { + const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); + return Sym->Flags; +} + +basic_symbol_iterator TapiFile::symbol_begin() const { + DataRefImpl DRI; + DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.begin()); + return BasicSymbolRef{DRI, this}; +} + +basic_symbol_iterator TapiFile::symbol_end() const { + DataRefImpl DRI; + DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.end()); + return BasicSymbolRef{DRI, this}; +} diff --git a/llvm/lib/Object/TapiUniversal.cpp b/llvm/lib/Object/TapiUniversal.cpp new file mode 100644 index 0000000..b3273e3 --- /dev/null +++ b/llvm/lib/Object/TapiUniversal.cpp @@ -0,0 +1,54 @@ +//===- TapiUniversal.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the Text-based Dynamic Library Stub format. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/TapiUniversal.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/Error.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/TextAPI/MachO/TextAPIReader.h" + +using namespace llvm; +using namespace MachO; +using namespace object; + +TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err) + : Binary(ID_TapiUniversal, Source) { + auto Result = TextAPIReader::get(Source); + ErrorAsOutParameter ErrAsOuParam(&Err); + if (!Result) { + Err = Result.takeError(); + return; + } + ParsedFile = std::move(Result.get()); + + auto Archs = ParsedFile->getArchitectures(); + for (auto Arch : Archs) + Architectures.emplace_back(Arch); +} + +TapiUniversal::~TapiUniversal() = default; + +Expected<std::unique_ptr<TapiFile>> +TapiUniversal::ObjectForArch::getAsObjectFile() const { + return std::unique_ptr<TapiFile>(new TapiFile(Parent->getMemoryBufferRef(), + *Parent->ParsedFile.get(), + Parent->Architectures[Index])); +} + +Expected<std::unique_ptr<TapiUniversal>> +TapiUniversal::create(MemoryBufferRef Source) { + Error Err = Error::success(); + std::unique_ptr<TapiUniversal> Ret(new TapiUniversal(Source, Err)); + if (Err) + return std::move(Err); + return std::move(Ret); +} |