forked from OSchip/llvm-project
[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:
parent
2d28100bf2
commit
05c5363b39
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
Loading…
Reference in New Issue