mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[MC][ARM] make Thumb function also if type attribute is set
Make sure to set the bottom bit of the symbol even when the type attribute of a label is set after the label. GNU as sets the thumb state according to the thumb state of the label. If a .type directive is placed after the label, set the symbol's thumb state according to the thumb state of the .type directive. This matches GNU as in most cases. From: Stefan Agner <stefan@agner.ch> This fixes: https://bugs.llvm.org/show_bug.cgi?id=44860 https://github.com/ClangBuiltLinux/linux/issues/866 Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D74927
This commit is contained in:
parent
17dfbfc9e3
commit
53b1283520
@ -579,6 +579,28 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/// If a label is defined before the .type directive sets the label's type
|
||||
/// then the label can't be recorded as thumb function when the label is
|
||||
/// defined. We override emitSymbolAttribute() which is called as part of the
|
||||
/// parsing of .type so that if the symbol has already been defined we can
|
||||
/// record the label as Thumb. FIXME: there is a corner case where the state
|
||||
/// is changed in between the label definition and the .type directive, this
|
||||
/// is not expected to occur in practice and handling it would require the
|
||||
/// backend to track IsThumb for every label.
|
||||
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
|
||||
bool Val = MCELFStreamer::emitSymbolAttribute(Symbol, Attribute);
|
||||
|
||||
if (!IsThumb)
|
||||
return Val;
|
||||
|
||||
unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
|
||||
if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) &&
|
||||
Symbol->isDefined())
|
||||
getAssembler().setIsThumbFunc(Symbol);
|
||||
|
||||
return Val;
|
||||
};
|
||||
|
||||
private:
|
||||
enum ElfMappingSymbol {
|
||||
EMS_None,
|
||||
|
42
test/MC/ARM/thumb-function-address.s
Normal file
42
test/MC/ARM/thumb-function-address.s
Normal file
@ -0,0 +1,42 @@
|
||||
@ RUN: llvm-mc -filetype=obj -triple=armv7-linux-gnueabi %s -o %t
|
||||
@ RUN: llvm-readelf -s %t | FileCheck %s
|
||||
|
||||
@@ GNU as sets the thumb state according to the thumb state of the label. If a
|
||||
@@ .type directive is placed after the label, set the symbol's thumb state
|
||||
@@ according to the thumb state of the .type directive. This matches GNU as in
|
||||
@@ most cases.
|
||||
|
||||
.syntax unified
|
||||
.text
|
||||
.thumb
|
||||
func_label:
|
||||
.type func_label, %function
|
||||
|
||||
.type foo_impl, %function
|
||||
foo_impl:
|
||||
bx lr
|
||||
.type foo_resolver, %function
|
||||
foo_resolver:
|
||||
b foo_impl
|
||||
.type foo, %gnu_indirect_function
|
||||
.set foo, foo_resolver
|
||||
|
||||
@@ Note: GNU as sets the value to 1.
|
||||
.thumb
|
||||
label:
|
||||
bx lr
|
||||
.arm
|
||||
bx lr
|
||||
.type label, %function
|
||||
|
||||
@@ Check func_label, foo_impl, foo_resolver, and foo addresses have bit 0 set.
|
||||
@@ Check label has bit 0 unset.
|
||||
@ CHECK: Value Size Type Bind Vis Ndx Name
|
||||
@ CHECK-NEXT: 00000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
@ CHECK-NEXT: 00000001 0 FUNC LOCAL DEFAULT 2 func_label
|
||||
@ CHECK-NEXT: 00000001 0 FUNC LOCAL DEFAULT 2 foo_impl
|
||||
@ CHECK-NEXT: 00000000 0 NOTYPE LOCAL DEFAULT 2 $t.0
|
||||
@ CHECK-NEXT: 00000003 0 FUNC LOCAL DEFAULT 2 foo_resolver
|
||||
@ CHECK-NEXT: 00000003 0 IFUNC LOCAL DEFAULT 2 foo
|
||||
@ CHECK-NEXT: 00000004 0 FUNC LOCAL DEFAULT 2 label
|
||||
@ CHECK-NEXT: 00000006 0 NOTYPE LOCAL DEFAULT 2 $a.1
|
Loading…
Reference in New Issue
Block a user