From: Jez Ng Date: Fri, 30 Apr 2021 20:17:26 +0000 (-0400) Subject: [lld-macho] Parse & emit the N_ARM_THUMB_DEF symbol flag X-Git-Tag: llvmorg-14-init~7923 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=05c5363b39980d818324f2b9336319c699701cfe;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 0b59397..dafd914 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -553,7 +553,8 @@ static void replaceCommonSymbols() { replaceSymbol(sym, sym->getName(), isec->file, isec, /*value=*/0, /*size=*/0, /*isWeakDef=*/false, - /*isExternal=*/true, common->privateExtern); + /*isExternal=*/true, common->privateExtern, + /*isThumb=*/false); } } diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index bff7f35..a553754 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -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(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(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 @@ -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) diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp index 1fd7704..51b11a0 100644 --- a/lld/MachO/SymbolTable.cpp +++ b/lld/MachO/SymbolTable.cpp @@ -45,7 +45,7 @@ std::pair 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(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; } diff --git a/lld/MachO/SymbolTable.h b/lld/MachO/SymbolTable.h index 10d17f6..611eb8b 100644 --- a/lld/MachO/SymbolTable.h +++ b/lld/MachO/SymbolTable.h @@ -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); diff --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h index 962aad3..c6375e1 100644 --- a/lld/MachO/Symbols.h +++ b/lld/MachO/Symbols.h @@ -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; diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index 4ea3091..cc595b3 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -483,7 +483,8 @@ void StubHelperSection::setup() { dyldPrivate = make("__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 void SymtabSectionImpl::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(entry.sym)) { uint16_t n_desc = nList->n_desc; diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp index 5148206..370e140 100644 --- a/lld/MachO/UnwindInfoSection.cpp +++ b/lld/MachO/UnwindInfoSection.cpp @@ -182,7 +182,8 @@ void UnwindInfoSectionImpl::prepareRelocations(InputSection *isec) { if (s == nullptr) { s = make("", /*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; diff --git a/lld/test/MachO/weak-def-thumb-conflict.s b/lld/test/MachO/weak-def-thumb-conflict.s new file mode 100644 index 0000000..4f6c604 --- /dev/null +++ b/lld/test/MachO/weak-def-thumb-conflict.s @@ -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: