llvm-project/lld/MachO/Symbols.cpp
Vincent Lee ed59b8a11c [lld-macho] Remove partially supported 32-bit ARM arch
We never really supported 32-bit ARM arch entirely, and partial support was added for
very specific features. Regardless, it fails to even link the most basic applications that at
this point, it might be better to move this arch as unsupported. Given that Apple will be
moving towards arm64 long term, I don't see any reason for anyone to invest time in
supporting this either, and for those who still need it should use apple's ld64 linker.

Fixes #62691

Reviewed By: #lld-macho, int3

Differential Revision: https://reviews.llvm.org/D150544
2023-05-20 13:06:03 -07:00

130 lines
4.2 KiB
C++

//===- Symbols.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
//
//===----------------------------------------------------------------------===//
#include "Symbols.h"
#include "InputFiles.h"
#include "SyntheticSections.h"
#include "llvm/Demangle/Demangle.h"
using namespace llvm;
using namespace lld;
using namespace lld::macho;
static_assert(sizeof(void *) != 8 || sizeof(Symbol) == 56,
"Try to minimize Symbol's size; we create many instances");
// The Microsoft ABI doesn't support using parent class tail padding for child
// members, hence the _MSC_VER check.
#if !defined(_MSC_VER)
static_assert(sizeof(void *) != 8 || sizeof(Defined) == 88,
"Try to minimize Defined's size; we create many instances");
#endif
static_assert(sizeof(SymbolUnion) == sizeof(Defined),
"Defined should be the largest Symbol kind");
// Returns a symbol name for an error message.
static std::string maybeDemangleSymbol(StringRef symName) {
if (config->demangle) {
symName.consume_front("_");
return demangle(symName.str());
}
return symName.str();
}
std::string lld::toString(const Symbol &sym) {
return maybeDemangleSymbol(sym.getName());
}
std::string lld::toMachOString(const object::Archive::Symbol &b) {
return maybeDemangleSymbol(b.getName());
}
uint64_t Symbol::getStubVA() const { return in.stubs->getVA(stubsIndex); }
uint64_t Symbol::getLazyPtrVA() const {
return in.lazyPointers->getVA(stubsIndex);
}
uint64_t Symbol::getGotVA() const { return in.got->getVA(gotIndex); }
uint64_t Symbol::getTlvVA() const { return in.tlvPointers->getVA(gotIndex); }
Defined::Defined(StringRefZ name, InputFile *file, InputSection *isec,
uint64_t value, uint64_t size, bool isWeakDef, bool isExternal,
bool isPrivateExtern, bool includeInSymtab,
bool isReferencedDynamically, bool noDeadStrip,
bool canOverrideWeakDef, bool isWeakDefCanBeHidden,
bool interposable)
: Symbol(DefinedKind, name, file), overridesWeakDef(canOverrideWeakDef),
privateExtern(isPrivateExtern), includeInSymtab(includeInSymtab),
wasIdenticalCodeFolded(false),
referencedDynamically(isReferencedDynamically), noDeadStrip(noDeadStrip),
interposable(interposable), weakDefCanBeHidden(isWeakDefCanBeHidden),
weakDef(isWeakDef), external(isExternal), isec(isec), value(value),
size(size) {
if (isec) {
isec->symbols.push_back(this);
// Maintain sorted order.
for (auto it = isec->symbols.rbegin(), rend = isec->symbols.rend();
it != rend; ++it) {
auto next = std::next(it);
if (next == rend)
break;
if ((*it)->value < (*next)->value)
std::swap(*next, *it);
else
break;
}
}
}
bool Defined::isTlv() const {
return !isAbsolute() && isThreadLocalVariables(isec->getFlags());
}
uint64_t Defined::getVA() const {
assert(isLive() && "this should only be called for live symbols");
if (isAbsolute())
return value;
if (!isec->isFinal) {
// A target arch that does not use thunks ought never ask for
// the address of a function that has not yet been finalized.
assert(target->usesThunks());
// ConcatOutputSection::finalize() can seek the address of a
// function before its address is assigned. The thunking algorithm
// knows that unfinalized functions will be out of range, so it is
// expedient to return a contrived out-of-range address.
return TargetInfo::outOfRangeVA;
}
return isec->getVA(value);
}
ObjFile *Defined::getObjectFile() const {
return isec ? dyn_cast_or_null<ObjFile>(isec->getFile()) : nullptr;
}
void Defined::canonicalize() {
if (unwindEntry)
unwindEntry = unwindEntry->canonical();
if (isec)
isec = isec->canonical();
}
std::string Defined::getSourceLocation() {
if (!isec)
return {};
return isec->getSourceLocation(value);
}
uint64_t DylibSymbol::getVA() const {
return isInStubs() ? getStubVA() : Symbol::getVA();
}
void LazyArchive::fetchArchiveMember() { getFile()->fetch(sym); }