Skip to content

Commit 8f208ed

Browse files
committed
[ELFAttributeParser] Skip unknown vendor subsections.
An .ARM.attributes section is divided into subsections, each labelled with a vendor name. There is one standardised vendor name, which must be used for all attributes that affect compatibility. Subsections labelled with other vendor names can be used for optimisation purposes, but it has to be safe for an object file consumer to ignore them if it doesn't recognise the vendor name. LLD currently terminates parsing of the whole attributes section as soon as it encounters a subsection with a vendor name it doesn't recognise (which is anything other than the standard one). This can prevent it from detecting compatibility issues, if a standard subsection followed the vendor-specific one. This patch modifies the attribute parser so that unrecognised vendor subsections are silently skipped, and the subsections beyond them are still processed. Differential Revision: https://reviews.llvm.org/D153335
1 parent 268032f commit 8f208ed

File tree

2 files changed

+76
-14
lines changed

2 files changed

+76
-14
lines changed

lld/test/ELF/arm-tag-vfp-args-errs.s

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
// REQUIRES:arm
2-
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-base.s -o %tbase.o
3-
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-vfp.s -o %tvfp.o
4-
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-toolchain.s -o %ttoolchain.o
5-
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
6-
// RUN: not ld.lld %t.o %tbase.o %tvfp.o -o%t 2>&1 | FileCheck %s
7-
// RUN: not ld.lld %t.o %tbase.o %ttoolchain.o -o%t 2>&1 | FileCheck %s
8-
// RUN: not ld.lld %t.o %tvfp.o %tbase.o -o%t 2>&1 | FileCheck %s
9-
// RUN: not ld.lld %t.o %tvfp.o %ttoolchain.o -o%t 2>&1 | FileCheck %s
10-
// RUN: not ld.lld %t.o %ttoolchain.o %tbase.o -o%t 2>&1 | FileCheck %s
11-
// RUN: not ld.lld %t.o %ttoolchain.o %tvfp.o -o%t 2>&1 | FileCheck %s
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
6+
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-base.s -o %t/base.o
7+
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-vfp.s -o %t/vfp.o
8+
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-toolchain.s -o %t/toolchain.o
9+
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %t/main.s -o %t/main.o
10+
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %t/vendor.s -o %t/vendor.o
11+
// RUN: not ld.lld %t/main.o %t/base.o %t/vfp.o -o%t/a.out 2>&1 | FileCheck %s
12+
// RUN: not ld.lld %t/main.o %t/base.o %t/vendor.o -o%t/a.out 2>&1 | FileCheck %s
13+
// RUN: not ld.lld %t/main.o %t/base.o %t/toolchain.o -o%t/a.out 2>&1 | FileCheck %s
14+
// RUN: not ld.lld %t/main.o %t/vfp.o %t/base.o -o%t/a.out 2>&1 | FileCheck %s
15+
// RUN: not ld.lld %t/main.o %t/vfp.o %t/toolchain.o -o%t/a.out 2>&1 | FileCheck %s
16+
// RUN: not ld.lld %t/main.o %t/toolchain.o %t/base.o -o%t/a.out 2>&1 | FileCheck %s
17+
// RUN: not ld.lld %t/main.o %t/toolchain.o %t/vfp.o -o%t/a.out 2>&1 | FileCheck %s
1218

1319
// CHECK: incompatible Tag_ABI_VFP_args
20+
21+
//--- main.s
22+
1423
.arch armv7-a
1524
.eabi_attribute 20, 1
1625
.eabi_attribute 21, 1
@@ -27,3 +36,52 @@
2736
.globl _start
2837
.type _start, %function
2938
_start: bx lr
39+
40+
//--- vendor.s
41+
42+
.syntax unified
43+
44+
// Manually construct a custom .ARM.attributes section
45+
.section .ARM.attributes,"",%0x70000003 // SHT_ARM_ATTRIBUTES
46+
47+
// Initial byte giving the section format version
48+
.byte 'A'
49+
50+
// Subsection with a name that won't be recognised as a known vendor
51+
vendor_subsect_start:
52+
.word vendor_subsect_end - vendor_subsect_start // subsection length
53+
.asciz "ShouldBeIgnored" // vendor name
54+
.dcb.b 64, 0xff // dummy vendor section contents
55+
vendor_subsect_end:
56+
57+
// Subsection that should be identical to the attributes defined by
58+
// Inputs/arm-vfp-arg-vfp.s
59+
aeabi_subsect_start:
60+
.word aeabi_subsect_end - aeabi_subsect_start
61+
.asciz "aeabi" // vendor name indicating the standard subsection
62+
file_subsubsect_start:
63+
.byte 1 // introduce sub-subsection of attributes for the whole file
64+
.word file_subsubsect_end - file_subsubsect_start // sub-subsection len
65+
.byte 5 // CPU_name
66+
.asciz "7-A"
67+
.byte 6, 10 // CPU_arch = ARM v7
68+
.byte 7, 'A' // CPU_arch_profile = Application
69+
.byte 8, 1 // ARM_ISA_use = Permitted
70+
.byte 9, 2 // THUMB_ISA_use = Thumb-2
71+
.byte 18, 4 // ABI_PCS_wchar_t = 4-byte
72+
.byte 20, 1 // ABI_FP_denormal = IEEE-754
73+
.byte 21, 1 // ABI_FP_exceptions = IEEE-754
74+
.byte 23, 3 // ABI_FP_number_model = IEEE-754
75+
.byte 24, 1 // ABI_align_needed = 8-byte alignment
76+
.byte 25, 1 // ABI_align_preserved = 8-byte data alignment
77+
.byte 26, 2 // ABI_enum_size = Int32
78+
.byte 28, 1 // ABI_VFP_args = AAPCS VFP
79+
.byte 30, 6 // ABI_optimization_goals = Best Debugging
80+
.byte 34, 1 // CPU_unaligned_access = v6-style
81+
file_subsubsect_end:
82+
aeabi_subsect_end:
83+
84+
.text
85+
.global f1
86+
.type f1, %function
87+
f1: bx lr

llvm/lib/Support/ELFAttributeParser.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,14 @@ Error ELFAttributeParser::parseSubsection(uint32_t length) {
127127
sw->printString("Vendor", vendorName);
128128
}
129129

130-
// Ignore unrecognized vendor-name.
131-
if (vendorName.lower() != vendor)
132-
return createStringError(errc::invalid_argument,
133-
"unrecognized vendor-name: " + vendorName);
130+
// Handle a subsection with an unrecognized vendor-name by skipping
131+
// over it to the next subsection. ADDENDA32 in the Arm ABI defines
132+
// that vendor attribute sections must not affect compatibility, so
133+
// this should always be safe.
134+
if (vendorName.lower() != vendor) {
135+
cursor.seek(end);
136+
return Error::success();
137+
}
134138

135139
while (cursor.tell() < end) {
136140
/// Tag_File | Tag_Section | Tag_Symbol uleb128:byte-size

0 commit comments

Comments
 (0)