1 | /* Functions for x86 GNU property. |
2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. |
3 | |
4 | This file is part of GCC. |
5 | |
6 | GCC is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation; either version 3, or (at your option) |
9 | any later version. |
10 | |
11 | GCC is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ |
19 | |
20 | #include "config.h" |
21 | #include "system.h" |
22 | #include "coretypes.h" |
23 | #include "tm.h" |
24 | #include "output.h" |
25 | #include "linux-common.h" |
26 | #include "i386-protos.h" |
27 | |
28 | static void |
29 | emit_gnu_property (unsigned int type, unsigned int data) |
30 | { |
31 | int p2align = ptr_mode == SImode ? 2 : 3; |
32 | |
33 | switch_to_section (get_section (".note.gnu.property" , |
34 | SECTION_NOTYPE, NULL)); |
35 | |
36 | ASM_OUTPUT_ALIGN (asm_out_file, p2align); |
37 | /* name length. */ |
38 | fprintf (stream: asm_out_file, ASM_LONG "1f - 0f\n" ); |
39 | /* data length. */ |
40 | fprintf (stream: asm_out_file, ASM_LONG "4f - 1f\n" ); |
41 | /* note type: NT_GNU_PROPERTY_TYPE_0. */ |
42 | fprintf (stream: asm_out_file, ASM_LONG "5\n" ); |
43 | fprintf (stream: asm_out_file, format: "0:\n" ); |
44 | /* vendor name: "GNU". */ |
45 | fprintf (stream: asm_out_file, STRING_ASM_OP "\"GNU\"\n" ); |
46 | fprintf (stream: asm_out_file, format: "1:\n" ); |
47 | ASM_OUTPUT_ALIGN (asm_out_file, p2align); |
48 | /* pr_type. */ |
49 | fprintf (stream: asm_out_file, ASM_LONG "0x%x\n" , type); |
50 | /* pr_datasz. */ |
51 | fprintf (stream: asm_out_file, ASM_LONG "3f - 2f\n" ); |
52 | fprintf (stream: asm_out_file, format: "2:\n" ); |
53 | fprintf (stream: asm_out_file, ASM_LONG "0x%x\n" , data); |
54 | fprintf (stream: asm_out_file, format: "3:\n" ); |
55 | ASM_OUTPUT_ALIGN (asm_out_file, p2align); |
56 | fprintf (stream: asm_out_file, format: "4:\n" ); |
57 | } |
58 | |
59 | void |
60 | file_end_indicate_exec_stack_and_gnu_property (void) |
61 | { |
62 | file_end_indicate_exec_stack (); |
63 | |
64 | if (flag_cf_protection == CF_NONE |
65 | && !ix86_needed |
66 | && !ix86_has_no_direct_extern_access) |
67 | return; |
68 | |
69 | unsigned int feature_1 = 0; |
70 | |
71 | if (flag_cf_protection & CF_BRANCH) |
72 | /* GNU_PROPERTY_X86_FEATURE_1_IBT. */ |
73 | feature_1 |= 0x1; |
74 | |
75 | if (flag_cf_protection & CF_RETURN) |
76 | /* GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ |
77 | feature_1 |= 0x2; |
78 | |
79 | /* Generate GNU_PROPERTY_X86_FEATURE_1_AND. */ |
80 | if (feature_1) |
81 | emit_gnu_property (type: 0xc0000002, data: feature_1); |
82 | |
83 | unsigned int isa_1 = 0; |
84 | if (ix86_needed) |
85 | { |
86 | /* GNU_PROPERTY_X86_ISA_1_BASELINE. */ |
87 | if (TARGET_64BIT |
88 | || TARGET_FXSR |
89 | || TARGET_80387 |
90 | || TARGET_MMX |
91 | || TARGET_SSE |
92 | || TARGET_SSE2) |
93 | isa_1 |= 1 << 0; |
94 | |
95 | /* GNU_PROPERTY_X86_ISA_1_V2. */ |
96 | if (TARGET_CMPXCHG16B |
97 | || (TARGET_64BIT && TARGET_SAHF) |
98 | || TARGET_POPCNT |
99 | || TARGET_SSE3 |
100 | || TARGET_SSSE3 |
101 | || TARGET_SSE4_1 |
102 | || TARGET_SSE4_2) |
103 | isa_1 |= 1 << 1; |
104 | |
105 | /* GNU_PROPERTY_X86_ISA_1_V3. */ |
106 | if (TARGET_AVX |
107 | || TARGET_AVX2 |
108 | || TARGET_F16C |
109 | || TARGET_FMA |
110 | || TARGET_LZCNT |
111 | || TARGET_MOVBE |
112 | || TARGET_XSAVE) |
113 | isa_1 |= 1 << 2; |
114 | |
115 | /* GNU_PROPERTY_X86_ISA_1_V4. */ |
116 | if (TARGET_AVX512F |
117 | || TARGET_AVX512BW |
118 | || TARGET_AVX512CD |
119 | || TARGET_AVX512DQ |
120 | || TARGET_AVX512VL) |
121 | isa_1 |= 1 << 3; |
122 | } |
123 | |
124 | /* Generate GNU_PROPERTY_X86_ISA_1_NEEDED. */ |
125 | if (isa_1) |
126 | emit_gnu_property (type: 0xc0008002, data: isa_1); |
127 | |
128 | if (ix86_has_no_direct_extern_access) |
129 | /* Emite a GNU_PROPERTY_1_NEEDED note with |
130 | GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. */ |
131 | emit_gnu_property (type: 0xb0008000, data: (1U << 0)); |
132 | } |
133 | |