[lld-macho] Parse & emit the N_ARM_THUMB_DEF symbol flag

Eventually we'll use this flag to properly handle bl/blx
opcodes.

Reviewed By: #lld-macho, gkm

Differential Revision: https://reviews.llvm.org/D101558
This commit is contained in:
Jez Ng 2021-04-30 16:17:26 -04:00
parent 2d28100bf2
commit 05c5363b39
8 changed files with 56 additions and 14 deletions

View File

@ -553,7 +553,8 @@ static void replaceCommonSymbols() {
replaceSymbol<Defined>(sym, sym->getName(), isec->file, isec, /*value=*/0,
/*size=*/0,
/*isWeakDef=*/false,
/*isExternal=*/true, common->privateExtern);
/*isExternal=*/true, common->privateExtern,
/*isThumb=*/false);
}
}

View File

@ -467,14 +467,16 @@ static macho::Symbol *createDefined(const NList &sym, StringRef name,
isPrivateExtern = true;
return symtab->addDefined(name, isec->file, isec, value, size,
sym.n_desc & N_WEAK_DEF, isPrivateExtern);
sym.n_desc & N_WEAK_DEF, isPrivateExtern,
sym.n_desc & N_ARM_THUMB_DEF);
}
assert(!isWeakDefCanBeHidden &&
"weak_def_can_be_hidden on already-hidden symbol?");
return make<Defined>(name, isec->file, isec, value, size,
sym.n_desc & N_WEAK_DEF,
/*isExternal=*/false, /*isPrivateExtern=*/false);
/*isExternal=*/false, /*isPrivateExtern=*/false,
sym.n_desc & N_ARM_THUMB_DEF);
}
// Absolute symbols are defined symbols that do not have an associated
@ -485,11 +487,13 @@ static macho::Symbol *createAbsolute(const NList &sym, InputFile *file,
if (sym.n_type & (N_EXT | N_PEXT)) {
assert((sym.n_type & N_EXT) && "invalid input");
return symtab->addDefined(name, file, nullptr, sym.n_value, /*size=*/0,
/*isWeakDef=*/false, sym.n_type & N_PEXT);
/*isWeakDef=*/false, sym.n_type & N_PEXT,
sym.n_desc & N_ARM_THUMB_DEF);
}
return make<Defined>(name, file, nullptr, sym.n_value, /*size=*/0,
/*isWeakDef=*/false,
/*isExternal=*/false, /*isPrivateExtern=*/false);
/*isExternal=*/false, /*isPrivateExtern=*/false,
sym.n_desc & N_ARM_THUMB_DEF);
}
template <class NList>
@ -988,7 +992,8 @@ static macho::Symbol *createBitcodeSymbol(const lto::InputFile::Symbol &objSym,
}
return symtab->addDefined(name, &file, /*isec=*/nullptr, /*value=*/0,
/*size=*/0, objSym.isWeak(), isPrivateExtern);
/*size=*/0, objSym.isWeak(), isPrivateExtern,
/*isThumb=*/false);
}
BitcodeFile::BitcodeFile(MemoryBufferRef mbref)

View File

@ -45,7 +45,7 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef name,
Defined *SymbolTable::addDefined(StringRef name, InputFile *file,
InputSection *isec, uint64_t value,
uint64_t size, bool isWeakDef,
bool isPrivateExtern) {
bool isPrivateExtern, bool isThumb) {
Symbol *s;
bool wasInserted;
bool overridesWeakDef = false;
@ -73,7 +73,7 @@ Defined *SymbolTable::addDefined(StringRef name, InputFile *file,
Defined *defined =
replaceSymbol<Defined>(s, name, file, isec, value, size, isWeakDef,
/*isExternal=*/true, isPrivateExtern);
/*isExternal=*/true, isPrivateExtern, isThumb);
defined->overridesWeakDef = overridesWeakDef;
return defined;
}
@ -167,7 +167,8 @@ Defined *SymbolTable::addSynthetic(StringRef name, InputSection *isec,
uint64_t value, bool isPrivateExtern,
bool includeInSymtab) {
Defined *s = addDefined(name, nullptr, isec, value, /*size=*/0,
/*isWeakDef=*/false, isPrivateExtern);
/*isWeakDef=*/false, isPrivateExtern,
/*isThumb=*/false);
s->includeInSymtab = includeInSymtab;
return s;
}

View File

@ -39,7 +39,7 @@ class SymbolTable {
public:
Defined *addDefined(StringRef name, InputFile *, InputSection *,
uint64_t value, uint64_t size, bool isWeakDef,
bool isPrivateExtern);
bool isPrivateExtern, bool isThumb);
Symbol *addUndefined(StringRef name, InputFile *, bool isWeakRef);

View File

@ -101,10 +101,12 @@ public:
class Defined : public Symbol {
public:
Defined(StringRefZ name, InputFile *file, InputSection *isec, uint64_t value,
uint64_t size, bool isWeakDef, bool isExternal, bool isPrivateExtern)
uint64_t size, bool isWeakDef, bool isExternal, bool isPrivateExtern,
bool isThumb)
: Symbol(DefinedKind, name, file), isec(isec), value(value), size(size),
overridesWeakDef(false), privateExtern(isPrivateExtern),
includeInSymtab(true), weakDef(isWeakDef), external(isExternal) {}
includeInSymtab(true), thumb(isThumb), weakDef(isWeakDef),
external(isExternal) {}
bool isWeakDef() const override { return weakDef; }
bool isExternalWeakDef() const {
@ -134,6 +136,8 @@ public:
bool privateExtern : 1;
// Whether this symbol should appear in the output symbol table.
bool includeInSymtab : 1;
// Only relevant when compiling for Thumb-supporting arm32 archs.
bool thumb : 1;
private:
const bool weakDef : 1;

View File

@ -483,7 +483,8 @@ void StubHelperSection::setup() {
dyldPrivate =
make<Defined>("__dyld_private", nullptr, in.imageLoaderCache, 0, 0,
/*isWeakDef=*/false,
/*isExternal=*/false, /*isPrivateExtern=*/false);
/*isExternal=*/false, /*isPrivateExtern=*/false,
/*isThumb=*/false);
}
ImageLoaderCacheSection::ImageLoaderCacheSection() {
@ -865,6 +866,7 @@ 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;
} else if (auto *dysym = dyn_cast<DylibSymbol>(entry.sym)) {
uint16_t n_desc = nList->n_desc;

View File

@ -182,7 +182,8 @@ void UnwindInfoSectionImpl<Ptr>::prepareRelocations(InputSection *isec) {
if (s == nullptr) {
s = make<Defined>("<internal>", /*file=*/nullptr, referentIsec,
r.addend, /*size=*/0, /*isWeakDef=*/false,
/*isExternal=*/false, /*isPrivateExtern=*/false);
/*isExternal=*/false, /*isPrivateExtern=*/false,
/*isThumb=*/false);
in.got->addEntry(s);
}
r.referent = s;

View File

@ -0,0 +1,28 @@
# 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: