1 /* ELF attributes support (based on ARM EABI attributes). 2 Copyright (C) 2025 Free Software Foundation, Inc. 3 4 This file is part of BFD, the Binary File Descriptor library. 5 6 This program 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 of the License, or 9 (at your option) any later version. 10 11 This program 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 this program; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21 #pragma once 22 23 #include "hidden.h" 24 #include <stdint.h> 25 #include "hidden.h" 26 27 typedef enum obj_attr_version { 28 OBJ_ATTR_VERSION_NONE = 0, 29 OBJ_ATTR_VERSION_UNSUPPORTED, 30 OBJ_ATTR_V1, 31 OBJ_ATTR_V2, 32 OBJ_ATTR_VERSION_MAX = OBJ_ATTR_V2, 33 } obj_attr_version_t; 34 35 /* -------------------- 36 Object attributes v2 37 -------------------- */ 38 39 typedef enum obj_attr_encoding_v2 40 { 41 OA_ENC_UNSET = 0, 42 OA_ENC_ULEB128, 43 OA_ENC_NTBS, 44 OA_ENC_MAX = OA_ENC_NTBS, 45 } obj_attr_encoding_v2_t; 46 47 #define obj_attr_encoding_v2_from_u8(value) \ 48 ((enum obj_attr_encoding_v2) ((value) + 1)) 49 #define obj_attr_encoding_v2_to_u8(value) \ 50 ((uint8_t) ((value) - 1)) 51 52 extern const char * 53 bfd_oav2_encoding_to_string (obj_attr_encoding_v2_t); 54 55 typedef union obj_attr_value_v2 { 56 uint32_t uint; 57 58 /* Note: this field cannot hold e.g. a string literal as the value has to be 59 freeable. */ 60 const char *string; 61 } obj_attr_value_v2_t; 62 63 typedef enum obj_attr_v2_status 64 { 65 /* An attribute that is unknown to the linker, and so cannot be merged. */ 66 obj_attr_v2_unknown = 0, 67 /* An attribute that was reported as corrupted. */ 68 obj_attr_v2_corrupted, 69 /* A valid attribute. */ 70 obj_attr_v2_ok, 71 } obj_attr_v2_status_t; 72 73 typedef uint64_t obj_attr_tag_t; 74 75 typedef struct obj_attr_v2 { 76 /* The name/tag of an attribute. */ 77 obj_attr_tag_t tag; 78 79 /* The value assigned to an attribute, can be ULEB128 or NTBS. */ 80 union obj_attr_value_v2 val; 81 82 /* The attribute status after merge. */ 83 obj_attr_v2_status_t status; 84 85 /* The next attribute in the list or NULL. */ 86 struct obj_attr_v2 *next; 87 88 /* The previous attribute in the list or NULL. */ 89 struct obj_attr_v2 *prev; 90 } obj_attr_v2_t; 91 92 typedef enum obj_attr_subsection_scope_v2 93 { 94 OA_SUBSEC_PUBLIC, 95 OA_SUBSEC_PRIVATE, 96 } obj_attr_subsection_scope_v2_t; 97 98 typedef enum obj_attr_subsection_v2_status 99 { 100 /* A subsection that is unknown to the linker, and so cannot be merged. */ 101 obj_attr_subsection_v2_unknown = 0, 102 /* A subsection that was reported as corrupted. */ 103 obj_attr_subsection_v2_corrupted, 104 /* A valid subsection. */ 105 obj_attr_subsection_v2_ok, 106 } obj_attr_subsection_v2_status_t; 107 108 typedef struct obj_attr_subsection_v2 { 109 /* The name of the subsection. 110 Note: this field cannot hold e.g. a string literal as the value has to be 111 freeable. */ 112 const char *name; 113 114 /* The scope of the subsection. */ 115 obj_attr_subsection_scope_v2_t scope; 116 117 /* Is this subsection optional ? Can it be skipped ? */ 118 bool optional; 119 120 /* The value encoding of attributes in this subsection. */ 121 obj_attr_encoding_v2_t encoding; 122 123 /* The subsection status after merge. */ 124 obj_attr_subsection_v2_status_t status; 125 126 /* The size of the list. */ 127 unsigned int size; 128 129 /* The next subsection in the list, or NULL. */ 130 struct obj_attr_subsection_v2 *next; 131 132 /* The previous subsection in the list, or NULL. */ 133 struct obj_attr_subsection_v2 *prev; 134 135 /* A pointer to the first node of the list. */ 136 struct obj_attr_v2 *first; 137 138 /* A pointer to the last node of the list. */ 139 struct obj_attr_v2 *last; 140 } obj_attr_subsection_v2_t; 141 142 extern const char * 143 bfd_oav2_comprehension_to_string (bool); 144 145 typedef struct obj_attr_subsection_list 146 { 147 /* A pointer to the first node of the list. */ 148 obj_attr_subsection_v2_t *first; 149 150 /* A pointer to the last node of the list. */ 151 obj_attr_subsection_v2_t *last; 152 153 /* The size of the list. */ 154 unsigned int size; 155 } obj_attr_subsection_list_t; 156 157 typedef struct { 158 const char *const name; 159 obj_attr_tag_t value; 160 } obj_attr_tag_info_t; 161 162 /* Attribute information. */ 163 typedef struct { 164 obj_attr_tag_info_t tag; 165 obj_attr_value_v2_t default_value; 166 } obj_attr_info_t; 167 168 typedef struct 169 { 170 const char *const subsec_name; 171 const obj_attr_info_t *known_attrs; 172 const bool optional; 173 const obj_attr_encoding_v2_t encoding; 174 const size_t len; 175 } known_subsection_v2_t; 176 177 struct elf_backend_data; 178 179 extern const known_subsection_v2_t * 180 bfd_obj_attr_v2_identify_subsection (const struct elf_backend_data *, 181 const char *); 182 183 extern const obj_attr_info_t * 184 _bfd_obj_attr_v2_find_known_by_tag (const struct elf_backend_data *, 185 const char *, 186 obj_attr_tag_t) ATTRIBUTE_HIDDEN; 187 188 extern const char * 189 _bfd_obj_attr_v2_tag_to_string (const struct elf_backend_data *, 190 const char *, 191 obj_attr_tag_t) ATTRIBUTE_HIDDEN; 192 193 enum obj_attr_v2_merge_result_reason 194 { 195 /* Default: everything is ok. */ 196 OAv2_MERGE_OK = 0, 197 /* The result value of the merge is the same as REF. */ 198 OAv2_MERGE_SAME_VALUE_AS_REF, 199 /* No implementation of a merge for this attribute exists. */ 200 OAv2_MERGE_UNSUPPORTED, 201 /* The merge failed, an error message should be logged. */ 202 OAv2_MERGE_ERROR, 203 }; 204 typedef struct { 205 /* Should the merge be performed ? */ 206 bool merge; 207 /* The merged value. */ 208 union obj_attr_value_v2 val; 209 /* If the merge should not be performed, give the reason to differentiate 210 error cases from normal cases. Typically, if REF already is set to the 211 same value as the merged result, no merge is needed, and this is not an 212 error. */ 213 enum obj_attr_v2_merge_result_reason reason; 214 } obj_attr_v2_merge_result_t; 215 216 /* Re-usable merge policies. */ 217 /* For now, only AND-merge is used by AArch64 backend. Additional policies 218 (Integer-OR, String-ADD) are part of the GNU testing namespace. If they 219 appear to be usefull for a backend at some point, they should be exposed 220 to the backend here below. */ 221 extern obj_attr_v2_merge_result_t 222 _bfd_obj_attr_v2_merge_AND (const struct bfd_link_info *, const bfd *, 223 const obj_attr_subsection_v2_t *, 224 const obj_attr_v2_t *, const obj_attr_v2_t *, 225 const obj_attr_v2_t *) ATTRIBUTE_HIDDEN; 226