mirror of
https://github.com/intel/llvm.git
synced 2026-02-08 17:28:30 +08:00
I've adjusted the RelocAttrBits to better fit the semantics of the relocations. In particular: 1. *_UNSIGNED relocations are no longer marked with the `TLV` bit, even though they can occur within TLV sections. Instead the `TLV` bit is reserved for relocations that can reference thread-local symbols, and *_UNSIGNED relocations have their own `UNSIGNED` bit. The previous implementation caused TLV and regular UNSIGNED semantics to be conflated, resulting in rebase opcodes being incorrectly emitted for TLV relocations. 2. I've added a new `POINTER` bit to denote non-relaxable GOT relocations. This distinction isn't important on x86 -- the GOT relocations there are either relaxable or non-relaxable loads -- but arm64 has `GOT_LOAD_PAGE21` which loads the page that the referent symbol is in (regardless of whether the symbol ends up in the GOT). This relocation must reference a GOT symbol (so must have the `GOT` bit set) but isn't itself relaxable (so must not have the `LOAD` bit). The `POINTER` bit is used for relocations that *must* reference a GOT slot. 3. A similar situation occurs for TLV relocations. 4. ld64 supports both a pcrel and an absolute version of ARM64_RELOC_POINTER_TO_GOT. But the semantics of the absolute version are pretty weird -- it results in the value of the GOT slot being written, rather than the address. (That means a reference to a dynamically-bound slot will result in zeroes being written.) The programs I've tried linking don't use this form of the relocation, so I've dropped our partial support for it by removing the relevant RelocAttrBits. Reviewed By: alexshap Differential Revision: https://reviews.llvm.org/D97031
47 lines
1.7 KiB
C++
47 lines
1.7 KiB
C++
//===- Target.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 "Target.h"
|
|
#include "InputSection.h"
|
|
#include "Symbols.h"
|
|
#include "SyntheticSections.h"
|
|
|
|
#include "lld/Common/ErrorHandler.h"
|
|
|
|
using namespace llvm;
|
|
using namespace lld;
|
|
using namespace lld::macho;
|
|
|
|
const TargetInfo::RelocAttrs TargetInfo::invalidRelocAttrs{"INVALID",
|
|
RelocAttrBits::_0};
|
|
|
|
bool TargetInfo::validateSymbolRelocation(const Symbol *sym,
|
|
const InputSection *isec,
|
|
const Reloc &r) {
|
|
const RelocAttrs &relocAttrs = getRelocAttrs(r.type);
|
|
bool valid = true;
|
|
auto message = [relocAttrs, sym, isec, &valid](const Twine &diagnostic) {
|
|
valid = false;
|
|
return (relocAttrs.name + " relocation " + diagnostic + " for `" +
|
|
sym->getName() + "' in " + toString(isec))
|
|
.str();
|
|
};
|
|
|
|
if (relocAttrs.hasAttr(RelocAttrBits::TLV) != sym->isTlv())
|
|
error(message(Twine("requires that variable ") +
|
|
(sym->isTlv() ? "not " : "") + "be thread-local"));
|
|
if (relocAttrs.hasAttr(RelocAttrBits::DYSYM8) && isa<DylibSymbol>(sym) &&
|
|
r.length != 3)
|
|
error(message("has width " + std::to_string(1 << r.length) +
|
|
" bytes, but must be 8 bytes"));
|
|
|
|
return valid;
|
|
}
|
|
|
|
TargetInfo *macho::target = nullptr;
|