Home | History | Annotate | Line # | Download | only in bfd
      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