[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
This commit is contained in:
Vincent Lee 2023-05-15 02:00:29 -07:00
parent ac73c48e09
commit ed59b8a11c
16 changed files with 40 additions and 377 deletions

View File

@ -1,214 +0,0 @@
//===- ARM.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 "InputFiles.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/Bitfields.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
using namespace llvm::MachO;
using namespace llvm::support::endian;
using namespace lld;
using namespace lld::macho;
namespace {
struct ARM : TargetInfo {
ARM(uint32_t cpuSubtype);
int64_t getEmbeddedAddend(MemoryBufferRef, uint64_t offset,
const relocation_info) const override;
void relocateOne(uint8_t *loc, const Reloc &, uint64_t va,
uint64_t pc) const override;
void writeStub(uint8_t *buf, const Symbol &, uint64_t) const override;
void writeStubHelperHeader(uint8_t *buf) const override;
void writeStubHelperEntry(uint8_t *buf, const Symbol &,
uint64_t entryAddr) const override;
void writeObjCMsgSendStub(uint8_t *buf, Symbol *sym, uint64_t stubsAddr,
uint64_t stubOffset, uint64_t selrefsVA,
uint64_t selectorIndex, uint64_t gotAddr,
uint64_t msgSendIndex) const override;
void relaxGotLoad(uint8_t *loc, uint8_t type) const override;
uint64_t getPageSize() const override { return 4 * 1024; }
void handleDtraceReloc(const Symbol *sym, const Reloc &r,
uint8_t *loc) const override;
};
} // namespace
static constexpr std::array<RelocAttrs, 10> relocAttrsArray{{
#define B(x) RelocAttrBits::x
{"VANILLA", /* FIXME populate this */ B(_0)},
{"PAIR", /* FIXME populate this */ B(_0)},
{"SECTDIFF", /* FIXME populate this */ B(_0)},
{"LOCAL_SECTDIFF", /* FIXME populate this */ B(_0)},
{"PB_LA_PTR", /* FIXME populate this */ B(_0)},
{"BR24", B(PCREL) | B(LOCAL) | B(EXTERN) | B(BRANCH) | B(BYTE4)},
{"BR22", B(PCREL) | B(LOCAL) | B(EXTERN) | B(BRANCH) | B(BYTE4)},
{"32BIT_BRANCH", /* FIXME populate this */ B(_0)},
{"HALF", /* FIXME populate this */ B(_0)},
{"HALF_SECTDIFF", /* FIXME populate this */ B(_0)},
#undef B
}};
int64_t ARM::getEmbeddedAddend(MemoryBufferRef mb, uint64_t offset,
relocation_info rel) const {
// FIXME: implement this
return 0;
}
template <int N> using BitfieldFlag = Bitfield::Element<bool, N, 1>;
// ARM BL encoding:
//
// 30 28 24 0
// +---------+---------+----------------------------------------------+
// | cond | 1 0 1 1 | imm24 |
// +---------+---------+----------------------------------------------+
//
// `cond` here varies depending on whether we have bleq, blne, etc.
// `imm24` encodes a 26-bit pcrel offset -- last 2 bits are zero as ARM
// functions are 4-byte-aligned.
//
// ARM BLX encoding:
//
// 30 28 24 0
// +---------+---------+----------------------------------------------+
// | 1 1 1 1 | 1 0 1 H | imm24 |
// +---------+---------+----------------------------------------------+
//
// Since Thumb functions are 2-byte-aligned, we need one extra bit to encode
// the offset -- that is the H bit.
//
// BLX is always unconditional, so while we can convert directly from BLX to BL,
// we need to insert a shim if a BL's target is a Thumb function.
//
// Helper aliases for decoding BL / BLX:
using Cond = Bitfield::Element<uint32_t, 28, 4>;
using Imm24 = Bitfield::Element<int32_t, 0, 24>;
void ARM::relocateOne(uint8_t *loc, const Reloc &r, uint64_t value,
uint64_t pc) const {
switch (r.type) {
case ARM_RELOC_BR24: {
uint32_t base = read32le(loc);
bool isBlx = Bitfield::get<Cond>(base) == 0xf;
const Symbol *sym = r.referent.get<Symbol *>();
int32_t offset = value - (pc + 8);
if (auto *defined = dyn_cast<Defined>(sym)) {
if (!isBlx && defined->thumb) {
error("TODO: implement interworking shim");
return;
} else if (isBlx && !defined->thumb) {
Bitfield::set<Cond>(base, 0xe); // unconditional BL
Bitfield::set<BitfieldFlag<24>>(base, true);
isBlx = false;
}
} else {
error("TODO: Implement ARM_RELOC_BR24 for dylib symbols");
return;
}
if (isBlx) {
assert((0x1 & value) == 0);
Bitfield::set<Imm24>(base, offset >> 2);
Bitfield::set<BitfieldFlag<24>>(base, (offset >> 1) & 1); // H bit
} else {
assert((0x3 & value) == 0);
Bitfield::set<Imm24>(base, offset >> 2);
}
write32le(loc, base);
break;
}
default:
fatal("unhandled relocation type");
}
}
void ARM::writeStub(uint8_t *buf, const Symbol &sym, uint64_t) const {
fatal("TODO: implement this");
}
void ARM::writeStubHelperHeader(uint8_t *buf) const {
fatal("TODO: implement this");
}
void ARM::writeStubHelperEntry(uint8_t *buf, const Symbol &sym,
uint64_t entryAddr) const {
fatal("TODO: implement this");
}
void ARM::writeObjCMsgSendStub(uint8_t *buf, Symbol *sym, uint64_t stubsAddr,
uint64_t stubOffset, uint64_t selrefsVA,
uint64_t selectorIndex, uint64_t gotAddr,
uint64_t msgSendIndex) const {
fatal("TODO: implement this");
}
void ARM::relaxGotLoad(uint8_t *loc, uint8_t type) const {
fatal("TODO: implement this");
}
ARM::ARM(uint32_t cpuSubtype) : TargetInfo(ILP32()) {
cpuType = CPU_TYPE_ARM;
this->cpuSubtype = cpuSubtype;
stubSize = 0 /* FIXME */;
stubHelperHeaderSize = 0 /* FIXME */;
stubHelperEntrySize = 0 /* FIXME */;
relocAttrs = {relocAttrsArray.data(), relocAttrsArray.size()};
}
TargetInfo *macho::createARMTargetInfo(uint32_t cpuSubtype) {
static ARM t(cpuSubtype);
return &t;
}
void ARM::handleDtraceReloc(const Symbol *sym, const Reloc &r,
uint8_t *loc) const {
if (config->outputType == MH_OBJECT)
return;
switch (r.type) {
case ARM_RELOC_BR24:
if (sym->getName().startswith("___dtrace_probe")) {
// change call site to a NOP
write32le(loc, 0xE1A00000);
} else if (sym->getName().startswith("___dtrace_isenabled")) {
// change call site to 'eor r0, r0, r0'
write32le(loc, 0xE0200000);
} else {
error("Unrecognized dtrace symbol prefix: " + toString(*sym));
}
break;
case ARM_THUMB_RELOC_BR22:
if (sym->getName().startswith("___dtrace_probe")) {
// change 32-bit blx call site to two thumb NOPs
write32le(loc, 0x46C046C0);
} else if (sym->getName().startswith("___dtrace_isenabled")) {
// change 32-bit blx call site to 'nop', 'eor r0, r0'
write32le(loc, 0x46C04040);
} else {
error("Unrecognized dtrace symbol prefix: " + toString(*sym));
}
break;
default:
llvm_unreachable("Unsupported dtrace relocation type for ARM");
}
}

View File

@ -5,7 +5,6 @@ add_public_tablegen_target(MachOOptionsTableGen)
include_directories(${LLVM_MAIN_SRC_DIR}/../libunwind/include)
add_lld_library(lldMachO
Arch/ARM.cpp
Arch/ARM64.cpp
Arch/ARM64Common.cpp
Arch/ARM64_32.cpp

View File

@ -335,15 +335,14 @@ void TextOutputSection::finalize() {
r.referent = thunkInfo.sym = symtab->addDefined(
thunkName, /*file=*/nullptr, thunkInfo.isec, /*value=*/0, thunkSize,
/*isWeakDef=*/false, /*isPrivateExtern=*/true,
/*isThumb=*/false, /*isReferencedDynamically=*/false,
/*noDeadStrip=*/false, /*isWeakDefCanBeHidden=*/false);
/*isReferencedDynamically=*/false, /*noDeadStrip=*/false,
/*isWeakDefCanBeHidden=*/false);
} else {
r.referent = thunkInfo.sym = make<Defined>(
thunkName, /*file=*/nullptr, thunkInfo.isec, /*value=*/0, thunkSize,
/*isWeakDef=*/false, /*isExternal=*/false, /*isPrivateExtern=*/true,
/*includeInSymtab=*/true, /*isThumb=*/false,
/*isReferencedDynamically=*/false, /*noDeadStrip=*/false,
/*isWeakDefCanBeHidden=*/false);
/*includeInSymtab=*/true, /*isReferencedDynamically=*/false,
/*noDeadStrip=*/false, /*isWeakDefCanBeHidden=*/false);
}
thunkInfo.sym->used = true;
target->populateThunk(thunkInfo.isec, funcSym);

View File

@ -596,8 +596,8 @@ static void replaceCommonSymbols() {
replaceSymbol<Defined>(
sym, sym->getName(), common->getFile(), isec, /*value=*/0, common->size,
/*isWeakDef=*/false, /*isExternal=*/true, common->privateExtern,
/*includeInSymtab=*/true, /*isThumb=*/false,
/*isReferencedDynamically=*/false, /*noDeadStrip=*/false);
/*includeInSymtab=*/true, /*isReferencedDynamically=*/false,
/*noDeadStrip=*/false);
}
}
@ -752,8 +752,6 @@ static TargetInfo *createTargetInfo(InputArgList &args) {
return createARM64TargetInfo();
case CPU_TYPE_ARM64_32:
return createARM64_32TargetInfo();
case CPU_TYPE_ARM:
return createARMTargetInfo(cpuSubtype);
default:
error("missing or unsupported -arch " + archName);
return nullptr;

View File

@ -655,6 +655,8 @@ static macho::Symbol *createDefined(const NList &sym, StringRef name,
bool isWeakDefCanBeHidden =
(sym.n_desc & (N_WEAK_DEF | N_WEAK_REF)) == (N_WEAK_DEF | N_WEAK_REF);
assert(!(sym.n_desc & N_ARM_THUMB_DEF) && "ARM32 arch is not supported");
if (sym.n_type & N_EXT) {
// -load_hidden makes us treat global symbols as linkage unit scoped.
// Duplicates are reported but the symbol does not go in the export trie.
@ -697,16 +699,14 @@ static macho::Symbol *createDefined(const NList &sym, StringRef name,
isPrivateExtern = true;
return symtab->addDefined(
name, isec->getFile(), isec, value, size, sym.n_desc & N_WEAK_DEF,
isPrivateExtern, sym.n_desc & N_ARM_THUMB_DEF,
sym.n_desc & REFERENCED_DYNAMICALLY, sym.n_desc & N_NO_DEAD_STRIP,
isWeakDefCanBeHidden);
isPrivateExtern, sym.n_desc & REFERENCED_DYNAMICALLY,
sym.n_desc & N_NO_DEAD_STRIP, isWeakDefCanBeHidden);
}
bool includeInSymtab = !isPrivateLabel(name) && !isEhFrameSection(isec);
return make<Defined>(
name, isec->getFile(), isec, value, size, sym.n_desc & N_WEAK_DEF,
/*isExternal=*/false, /*isPrivateExtern=*/false, includeInSymtab,
sym.n_desc & N_ARM_THUMB_DEF, sym.n_desc & REFERENCED_DYNAMICALLY,
sym.n_desc & N_NO_DEAD_STRIP);
sym.n_desc & REFERENCED_DYNAMICALLY, sym.n_desc & N_NO_DEAD_STRIP);
}
// Absolute symbols are defined symbols that do not have an associated
@ -714,18 +714,20 @@ static macho::Symbol *createDefined(const NList &sym, StringRef name,
template <class NList>
static macho::Symbol *createAbsolute(const NList &sym, InputFile *file,
StringRef name, bool forceHidden) {
assert(!(sym.n_desc & N_ARM_THUMB_DEF) && "ARM32 arch is not supported");
if (sym.n_type & N_EXT) {
bool isPrivateExtern = sym.n_type & N_PEXT || forceHidden;
return symtab->addDefined(
name, file, nullptr, sym.n_value, /*size=*/0,
/*isWeakDef=*/false, isPrivateExtern, sym.n_desc & N_ARM_THUMB_DEF,
/*isReferencedDynamically=*/false, sym.n_desc & N_NO_DEAD_STRIP,
/*isWeakDefCanBeHidden=*/false);
return symtab->addDefined(name, file, nullptr, sym.n_value, /*size=*/0,
/*isWeakDef=*/false, isPrivateExtern,
/*isReferencedDynamically=*/false,
sym.n_desc & N_NO_DEAD_STRIP,
/*isWeakDefCanBeHidden=*/false);
}
return make<Defined>(name, file, nullptr, sym.n_value, /*size=*/0,
/*isWeakDef=*/false,
/*isExternal=*/false, /*isPrivateExtern=*/false,
/*includeInSymtab=*/true, sym.n_desc & N_ARM_THUMB_DEF,
/*includeInSymtab=*/true,
/*isReferencedDynamically=*/false,
sym.n_desc & N_NO_DEAD_STRIP);
}
@ -1366,7 +1368,7 @@ void ObjFile::registerEhFrames(Section &ehFrameSection) {
make<Defined>("EH_Frame", isec->getFile(), isec, /*value=*/0,
isec->getSize(), /*isWeakDef=*/false, /*isExternal=*/false,
/*isPrivateExtern=*/false, /*includeInSymtab=*/false,
/*isThumb=*/false, /*isReferencedDynamically=*/false,
/*isReferencedDynamically=*/false,
/*noDeadStrip=*/false);
else if (isec->symbols[0]->value != 0)
fatal("found symbol at unexpected offset in __eh_frame");
@ -2184,7 +2186,6 @@ static macho::Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &objSym,
return symtab->addDefined(name, &file, /*isec=*/nullptr, /*value=*/0,
/*size=*/0, objSym.isWeak(), isPrivateExtern,
/*isThumb=*/false,
/*isReferencedDynamically=*/false,
/*noDeadStrip=*/false,
/*isWeakDefCanBeHidden=*/false);

View File

@ -96,7 +96,7 @@ static void transplantSymbolsAtOffset(InputSection *fromIsec,
Defined *SymbolTable::addDefined(StringRef name, InputFile *file,
InputSection *isec, uint64_t value,
uint64_t size, bool isWeakDef,
bool isPrivateExtern, bool isThumb,
bool isPrivateExtern,
bool isReferencedDynamically, bool noDeadStrip,
bool isWeakDefCanBeHidden) {
bool overridesWeakDef = false;
@ -166,9 +166,8 @@ Defined *SymbolTable::addDefined(StringRef name, InputFile *file,
!isPrivateExtern;
Defined *defined = replaceSymbol<Defined>(
s, name, file, isec, value, size, isWeakDef, /*isExternal=*/true,
isPrivateExtern, /*includeInSymtab=*/true, isThumb,
isReferencedDynamically, noDeadStrip, overridesWeakDef,
isWeakDefCanBeHidden, interposable);
isPrivateExtern, /*includeInSymtab=*/true, isReferencedDynamically,
noDeadStrip, overridesWeakDef, isWeakDefCanBeHidden, interposable);
return defined;
}
@ -176,7 +175,7 @@ Defined *SymbolTable::aliasDefined(Defined *src, StringRef target,
InputFile *newFile, bool makePrivateExtern) {
bool isPrivateExtern = makePrivateExtern || src->privateExtern;
return addDefined(target, newFile, src->isec, src->value, src->size,
src->isWeakDef(), isPrivateExtern, src->thumb,
src->isWeakDef(), isPrivateExtern,
src->referencedDynamically, src->noDeadStrip,
src->weakDefCanBeHidden);
}
@ -295,11 +294,10 @@ Defined *SymbolTable::addSynthetic(StringRef name, InputSection *isec,
bool includeInSymtab,
bool referencedDynamically) {
assert(!isec || !isec->getFile()); // See makeSyntheticInputSection().
Defined *s =
addDefined(name, /*file=*/nullptr, isec, value, /*size=*/0,
/*isWeakDef=*/false, isPrivateExtern, /*isThumb=*/false,
referencedDynamically, /*noDeadStrip=*/false,
/*isWeakDefCanBeHidden=*/false);
Defined *s = addDefined(name, /*file=*/nullptr, isec, value, /*size=*/0,
/*isWeakDef=*/false, isPrivateExtern,
referencedDynamically, /*noDeadStrip=*/false,
/*isWeakDefCanBeHidden=*/false);
s->includeInSymtab = includeInSymtab;
return s;
}

View File

@ -38,9 +38,8 @@ class SymbolTable {
public:
Defined *addDefined(StringRef name, InputFile *, InputSection *,
uint64_t value, uint64_t size, bool isWeakDef,
bool isPrivateExtern, bool isThumb,
bool isReferencedDynamically, bool noDeadStrip,
bool isWeakDefCanBeHidden);
bool isPrivateExtern, bool isReferencedDynamically,
bool noDeadStrip, bool isWeakDefCanBeHidden);
Defined *aliasDefined(Defined *src, StringRef target, InputFile *newFile,
bool makePrivateExtern = false);

View File

@ -54,13 +54,13 @@ 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 isThumb,
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), thumb(isThumb),
wasIdenticalCodeFolded(false),
referencedDynamically(isReferencedDynamically), noDeadStrip(noDeadStrip),
interposable(interposable), weakDefCanBeHidden(isWeakDefCanBeHidden),
weakDef(isWeakDef), external(isExternal), isec(isec), value(value),

View File

@ -118,9 +118,9 @@ class Defined : public Symbol {
public:
Defined(StringRefZ name, InputFile *file, InputSection *isec, uint64_t value,
uint64_t size, bool isWeakDef, bool isExternal, bool isPrivateExtern,
bool includeInSymtab, bool isThumb, bool isReferencedDynamically,
bool noDeadStrip, bool canOverrideWeakDef = false,
bool isWeakDefCanBeHidden = false, bool interposable = false);
bool includeInSymtab, bool isReferencedDynamically, bool noDeadStrip,
bool canOverrideWeakDef = false, bool isWeakDefCanBeHidden = false,
bool interposable = false);
bool isWeakDef() const override { return weakDef; }
bool isExternalWeakDef() const {
@ -154,8 +154,6 @@ public:
bool includeInSymtab : 1;
// Whether this symbol was folded into a different symbol during ICF.
bool wasIdenticalCodeFolded : 1;
// Only relevant when compiling for Thumb-supporting arm32 archs.
bool thumb : 1;
// Symbols marked referencedDynamically won't be removed from the output's
// symbol table by tools like strip. In theory, this could be set on arbitrary
// symbols in input object files. In practice, it's used solely for the

View File

@ -808,7 +808,7 @@ void StubHelperSection::setUp() {
/*isWeakDef=*/false,
/*isExternal=*/false, /*isPrivateExtern=*/false,
/*includeInSymtab=*/true,
/*isThumb=*/false, /*isReferencedDynamically=*/false,
/*isReferencedDynamically=*/false,
/*noDeadStrip=*/false);
dyldPrivate->used = true;
}
@ -829,8 +829,8 @@ void ObjCStubsSection::addEntry(Symbol *sym) {
/*value=*/symbols.size() * target->objcStubsFastSize,
/*size=*/target->objcStubsFastSize,
/*isWeakDef=*/false, /*isExternal=*/true, /*isPrivateExtern=*/true,
/*includeInSymtab=*/true, /*isThumb=*/false,
/*isReferencedDynamically=*/false, /*noDeadStrip=*/false);
/*includeInSymtab=*/true, /*isReferencedDynamically=*/false,
/*noDeadStrip=*/false);
symbols.push_back(newSym);
}
@ -1064,8 +1064,6 @@ void FunctionStartsSection::finalizeContents() {
if (!defined->isec || !isCodeSection(defined->isec) ||
!defined->isLive())
continue;
// TODO: Add support for thumbs, in that case
// the lowest bit of nextAddr needs to be set to 1.
addrs.push_back(defined->getVA());
}
}
@ -1347,7 +1345,6 @@ template <class LP> void SymtabSectionImpl<LP>::writeTo(uint8_t *buf) const {
// For the N_SECT symbol type, n_value is the address of the symbol
nList->n_value = defined->getVA();
}
nList->n_desc |= defined->thumb ? N_ARM_THUMB_DEF : 0;
nList->n_desc |= defined->isExternalWeakDef() ? N_WEAK_DEF : 0;
nList->n_desc |=
defined->referencedDynamically ? REFERENCED_DYNAMICALLY : 0;

View File

@ -145,7 +145,6 @@ public:
TargetInfo *createX86_64TargetInfo();
TargetInfo *createARM64TargetInfo();
TargetInfo *createARM64_32TargetInfo();
TargetInfo *createARMTargetInfo(uint32_t cpuSubtype);
struct LP64 {
using mach_header = llvm::MachO::mach_header_64;

View File

@ -307,7 +307,7 @@ void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) {
r.addend, /*size=*/0, /*isWeakDef=*/false,
/*isExternal=*/false, /*isPrivateExtern=*/false,
/*includeInSymtab=*/true,
/*isThumb=*/false, /*isReferencedDynamically=*/false,
/*isReferencedDynamically=*/false,
/*noDeadStrip=*/false);
s->used = true;
in.got->addEntry(s);

View File

@ -1,33 +0,0 @@
# REQUIRES: arm
# RUN: llvm-mc -filetype=obj -triple=armv7-apple-watchos %s -o %t.o
# RUN: %lld-watchos -dylib -arch armv7 -lSystem -o %t %t.o
# RUN: llvm-objdump --macho -d %t | FileCheck %s
# CHECK: _arm:
# CHECK-NEXT: blx _thumb_1
# CHECK-NEXT: blx _thumb_2
# CHECK-NEXT: bl _arm
# CHECK-NEXT: bl _arm
.globl _arm, _thumb_1, _thumb_2
.syntax unified
.thumb_func _thumb_1
.thumb_func _thumb_2
.p2align 2
.code 16
## These two thumb functions are exactly 2 bytes apart in order to test that we
## set the H bit correctly in the BLX instruction.
_thumb_1:
nop
_thumb_2:
nop
.code 32
_arm:
blx _thumb_1
blx _thumb_2
bl _arm
blx _arm

View File

@ -1,47 +0,0 @@
# REQUIRES: arm
# RUN: rm -rf %t; split-file %s %t
# TODO: Replace %no-lsystem-lld with %lld
# RUN: llvm-mc -filetype=obj -triple=armv4t-apple-darwin %t/armv4t-dtrace.s -o %t/armv4t-dtrace.o
# RUN: %no-lsystem-lld -arch armv4t -o %t/armv4t-dtrace %t/armv4t-dtrace.o
## If references of dtrace symbols are handled by lld, their relocation should be replaced with the following instructions
# RUN: llvm-objdump --macho -D %t/armv4t-dtrace | FileCheck %s --check-prefix=CHECK-armv4t
# CHECK-armv4t: 00 00 20 e0 eor r0, r0, r0
# CHECK-armv4t: 00 00 a0 e1 mov r0, r0
# RUN: llvm-mc -filetype=obj -triple=thumbv7-apple-darwin %t/armv7-dtrace.s -o %t/armv7-dtrace.o
# RUN: %no-lsystem-lld -arch armv7 -o %t/armv7-dtrace %t/armv7-dtrace.o
## If references of dtrace symbols are handled by lld, their relocation should be replaced with the following instructions
# RUN: llvm-objdump --macho -D %t/armv7-dtrace | FileCheck %s --check-prefix=CHECK-armv7
# CHECK-armv7: 40 40 eors r0, r0
# CHECK-armv7-NEXT: c0 46 mov r8, r8
# CHECK-armv7: c0 46 mov r8, r8
# CHECK-armv7-NEXT: c0 46 mov r8, r8
;--- armv4t-dtrace.s
.globl _main
_main:
bl ___dtrace_isenabled$Foo$added$v1
.reference ___dtrace_typedefs$Foo$v2
bl ___dtrace_probe$Foo$added$v1$696e74
.reference ___dtrace_stability$Foo$v1$1_1_0_1_1_0_1_1_0_1_1_0_1_1_0
.subsections_via_symbols
;--- armv7-dtrace.s
.globl _main
.thumb_func _main
_main:
bl ___dtrace_isenabled$Foo$added$v1
.reference ___dtrace_typedefs$Foo$v2
bl ___dtrace_probe$Foo$added$v1$696e74
.reference ___dtrace_stability$Foo$v1$1_1_0_1_1_0_1_1_0_1_1_0_1_1_0
.subsections_via_symbols

View File

@ -1,15 +1,13 @@
# REQUIRES: x86, aarch64, arm
# REQUIRES: x86, aarch64
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/x86-64-test.o
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %s -o %t/arm64-test.o
# RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-watchos %s -o %t/arm64-32-test.o
# RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-watchos %s -o %t/arm64-32-test.o
# RUN: llvm-mc -filetype=obj -triple=armv7-apple-watchos %s -o %t/arm-test.o
# RUN: %lld -lSystem -arch x86_64 -o %t/x86-64-executable %t/x86-64-test.o
# RUN: %lld -lSystem -arch arm64 -o %t/arm64-executable %t/arm64-test.o
# RUN: %lld-watchos -lSystem -o %t/arm64-32-executable %t/arm64-32-test.o
# RUN: %lld-watchos -lSystem -arch armv7 -o %t/arm-executable %t/arm-test.o
# RUN: %lld -arch x86_64 -dylib -o %t/x86-64-dylib %t/x86-64-test.o
@ -17,7 +15,6 @@
# RUN: llvm-objdump --macho --private-header %t/x86-64-executable | FileCheck %s --check-prefix=EXEC -DCPU=X86_64 -DSUBTYPE=ALL -DCAPS=LIB64
# RUN: llvm-objdump --macho --private-header %t/arm64-executable | FileCheck %s --check-prefix=EXEC -DCPU=ARM64 -DSUBTYPE=ALL -DCAPS=0x00
# RUN: llvm-objdump --macho --private-header %t/arm64-32-executable | FileCheck %s --check-prefix=EXEC -DCPU=ARM64_32 -DSUBTYPE=V8 -DCAPS=0x00
# RUN: llvm-objdump --macho --private-header %t/arm-executable | FileCheck %s --check-prefix=EXEC -DCPU=ARM -DSUBTYPE=V7 -DCAPS=0x00
# RUN: llvm-objdump --macho --private-header %t/x86-64-dylib | FileCheck %s --check-prefix=DYLIB -DCPU=X86_64 -DSUBTYPE=ALL -DCAPS=0x00

View File

@ -1,28 +0,0 @@
# REQUIRES: arm
# RUN: rm -rf %t; split-file %s %t
# RUN: llvm-mc -filetype=obj -triple=armv7-apple-watchos %t/thumb-foo.s -o %t/thumb-foo.o
# RUN: llvm-mc -filetype=obj -triple=armv7-apple-watchos %t/arm-foo.s -o %t/arm-foo.o
# RUN: %lld-watchos -arch armv7 -dylib %t/arm-foo.o %t/thumb-foo.o -o %t/arm-foo
# RUN: %lld-watchos -arch armv7 -dylib %t/thumb-foo.o %t/arm-foo.o -o %t/thumb-foo
# RUN: llvm-nm -m %t/arm-foo | FileCheck %s --check-prefix=ARM
# RUN: llvm-nm -m %t/thumb-foo | FileCheck %s --check-prefix=THUMB
## Check that we preserve the .thumb_def flag if we pick the thumb definition of
## _foo.
# ARM: (__TEXT,arm) weak external _foo
# THUMB: (__TEXT,thumb) weak external [Thumb] _foo
#--- thumb-foo.s
.section __TEXT,thumb
.globl _foo
.weak_definition _foo
.thumb_func _foo
.p2align 2
_foo:
#--- arm-foo.s
.section __TEXT,arm
.globl _foo
.weak_definition _foo
.p2align 2
_foo: