Index: lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- lib/Target/ARM/ARMAsmPrinter.cpp +++ lib/Target/ARM/ARMAsmPrinter.cpp @@ -831,6 +831,8 @@ ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_R9_use, ARMBuildAttrs::R9IsGPR); + ATS.emitTextAttribute(ARMBuildAttrs::conformance, "2.09"); + if (Subtarget->hasTrustZone() && Subtarget->hasVirtualization()) ATS.emitAttribute(ARMBuildAttrs::Virtualization_use, ARMBuildAttrs::AllowTZVirtualization); Index: lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -308,6 +308,11 @@ unsigned FPU; unsigned Arch; unsigned EmittedArch; + // Tag_conformance must be special cased when emitted into an object + // file. See 2.3.7.4 of the Addenda to the ARM ABI document. + bool EmitConformance = false; + StringRef ConformanceValue; + SmallVector Contents; const MCSection *AttributeSection; @@ -342,6 +347,12 @@ void setAttributeItem(unsigned Attribute, StringRef Value, bool OverwriteExisting) { + if (Attribute == ARMBuildAttrs::conformance) { + EmitConformance = true; + ConformanceValue = Value; + return; + } + // Look for existing attribute item if (AttributeItem *Item = getAttributeItem(Attribute)) { if (!OverwriteExisting) @@ -931,7 +942,7 @@ if (Arch != ARM::INVALID_ARCH) emitArchDefaultAttributes(); - if (Contents.empty()) + if (Contents.empty() && !EmitConformance) return; std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag); @@ -959,7 +970,8 @@ // Tag + Tag Size const size_t TagHeaderSize = 1 + 4; - const size_t ContentsSize = calculateContentSize(); + // + 6 for conformance tag (Tag (1) + 2.09 (4) + NB (1) = 6) + const size_t ContentsSize = calculateContentSize() + (EmitConformance ? 6 : 0); Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); Streamer.EmitBytes(CurrentVendor); @@ -968,6 +980,12 @@ Streamer.EmitIntValue(ARMBuildAttrs::File, 1); Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); + if (EmitConformance) { + Streamer.EmitULEB128IntValue(67); + Streamer.EmitBytes(ConformanceValue); + Streamer.EmitIntValue(0, 1); // '\0 + } + // Size should have been accounted for already, now // emit each field as its type (ULEB or String) for (size_t i = 0; i < Contents.size(); ++i) { Index: test/CodeGen/ARM/build-attributes.ll =================================================================== --- test/CodeGen/ARM/build-attributes.ll +++ test/CodeGen/ARM/build-attributes.ll @@ -280,6 +280,7 @@ ; V8: .eabi_attribute 21, 1 ; V8-NOT: .eabi_attribute 22 ; V8: .eabi_attribute 23, 3 +; V8: .eabi_attribute 67, "2.09" ; V8-FAST-NOT: .eabi_attribute 19 ;; The default does have an FPU, and for V8-A, it flushes preserving sign. Index: test/MC/ARM/directive-eabi_attribute.s =================================================================== --- test/MC/ARM/directive-eabi_attribute.s +++ test/MC/ARM/directive-eabi_attribute.s @@ -5,6 +5,14 @@ .syntax unified .thumb + .eabi_attribute Tag_conformance, "2.09" +@ CHECK: .eabi_attribute 67, "2.09" +@ Tag_conformance should be be emitted first in a file-scope +@ sub-subsection of the first public subsection of the attributes +@ section. 2.3.7.4 of ABI Addenda. +@ CHECK-OBJ: Tag: 67 +@ CHECK-OBJ-NEXT: TagName: conformance +@ CHECK-OBJ-NEXT: Value: 2.09 .eabi_attribute Tag_CPU_raw_name, "Cortex-A9" @ CHECK: .eabi_attribute 4, "Cortex-A9" @ CHECK-OBJ: Tag: 4 @@ -220,11 +228,6 @@ @ CHECK-OBJ-NEXT: Value: 0 @ CHECK-OBJ-NEXT: TagName: T2EE_use @ CHECK-OBJ-NEXT: Description: Not Permitted - .eabi_attribute Tag_conformance, "2.09" -@ CHECK: .eabi_attribute 67, "2.09" -@ CHECK-OBJ: Tag: 67 -@ CHECK-OBJ-NEXT: TagName: conformance -@ CHECK-OBJ-NEXT: Value: 2.09 .eabi_attribute Tag_Virtualization_use, 0 @ CHECK: .eabi_attribute 68, 0 @ CHECK-OBJ: Tag: 68 Index: test/tools/llvm-readobj/ARM/attribute-conformance.s =================================================================== --- /dev/null +++ test/tools/llvm-readobj/ARM/attribute-conformance.s @@ -0,0 +1,8 @@ +@ RUN: llvm-mc -triple armv7-elf -filetype asm -o - %s | FileCheck %s +@ RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s \ +@ RUN: | llvm-readobj -arm-attributes - | FileCheck %s --check-prefix=CHECK-OBJ +.eabi_attribute Tag_conformance, "2.11" +@CHECK: .eabi_attribute 67, "2.11" +@CHECK-OBJ: Tag: 67 +@CHECK-OBJ-NEXT: TagName: conformance +@CHECK-OBJ-NEXT: Value: 2.11