1 1.1 christos /* ELF attributes support (based on ARM EABI attributes). 2 1.11 christos Copyright (C) 2005-2024 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of BFD, the Binary File Descriptor library. 5 1.1 christos 6 1.1 christos This program is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program; if not, write to the Free Software 18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 1.1 christos MA 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos #include "sysdep.h" 22 1.1 christos #include "bfd.h" 23 1.1 christos #include "libiberty.h" 24 1.1 christos #include "libbfd.h" 25 1.1 christos #include "elf-bfd.h" 26 1.1 christos 27 1.1 christos /* Return the number of bytes needed by I in uleb128 format. */ 28 1.1 christos static int 29 1.1 christos uleb128_size (unsigned int i) 30 1.1 christos { 31 1.1 christos int size; 32 1.1 christos size = 1; 33 1.1 christos while (i >= 0x80) 34 1.1 christos { 35 1.1 christos i >>= 7; 36 1.1 christos size++; 37 1.1 christos } 38 1.1 christos return size; 39 1.1 christos } 40 1.1 christos 41 1.1 christos /* Return TRUE if the attribute has the default value (0/""). */ 42 1.10 christos static bool 43 1.1 christos is_default_attr (obj_attribute *attr) 44 1.1 christos { 45 1.8 christos if (ATTR_TYPE_HAS_ERROR (attr->type)) 46 1.10 christos return true; 47 1.1 christos if (ATTR_TYPE_HAS_INT_VAL (attr->type) && attr->i != 0) 48 1.10 christos return false; 49 1.1 christos if (ATTR_TYPE_HAS_STR_VAL (attr->type) && attr->s && *attr->s) 50 1.10 christos return false; 51 1.1 christos if (ATTR_TYPE_HAS_NO_DEFAULT (attr->type)) 52 1.10 christos return false; 53 1.1 christos 54 1.10 christos return true; 55 1.1 christos } 56 1.1 christos 57 1.1 christos /* Return the size of a single attribute. */ 58 1.1 christos static bfd_vma 59 1.5 christos obj_attr_size (unsigned int tag, obj_attribute *attr) 60 1.1 christos { 61 1.1 christos bfd_vma size; 62 1.1 christos 63 1.1 christos if (is_default_attr (attr)) 64 1.1 christos return 0; 65 1.1 christos 66 1.1 christos size = uleb128_size (tag); 67 1.1 christos if (ATTR_TYPE_HAS_INT_VAL (attr->type)) 68 1.1 christos size += uleb128_size (attr->i); 69 1.1 christos if (ATTR_TYPE_HAS_STR_VAL (attr->type)) 70 1.1 christos size += strlen ((char *)attr->s) + 1; 71 1.1 christos return size; 72 1.1 christos } 73 1.1 christos 74 1.1 christos /* Return the vendor name for a given object attributes section. */ 75 1.1 christos static const char * 76 1.1 christos vendor_obj_attr_name (bfd *abfd, int vendor) 77 1.1 christos { 78 1.1 christos return (vendor == OBJ_ATTR_PROC 79 1.1 christos ? get_elf_backend_data (abfd)->obj_attrs_vendor 80 1.1 christos : "gnu"); 81 1.1 christos } 82 1.1 christos 83 1.1 christos /* Return the size of the object attributes section for VENDOR 84 1.1 christos (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes 85 1.1 christos for that vendor to record and the vendor is OBJ_ATTR_GNU. */ 86 1.1 christos static bfd_vma 87 1.1 christos vendor_obj_attr_size (bfd *abfd, int vendor) 88 1.1 christos { 89 1.1 christos bfd_vma size; 90 1.1 christos obj_attribute *attr; 91 1.1 christos obj_attribute_list *list; 92 1.1 christos int i; 93 1.1 christos const char *vendor_name = vendor_obj_attr_name (abfd, vendor); 94 1.1 christos 95 1.1 christos if (!vendor_name) 96 1.1 christos return 0; 97 1.1 christos 98 1.1 christos attr = elf_known_obj_attributes (abfd)[vendor]; 99 1.1 christos size = 0; 100 1.1 christos for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) 101 1.1 christos size += obj_attr_size (i, &attr[i]); 102 1.1 christos 103 1.1 christos for (list = elf_other_obj_attributes (abfd)[vendor]; 104 1.1 christos list; 105 1.1 christos list = list->next) 106 1.1 christos size += obj_attr_size (list->tag, &list->attr); 107 1.1 christos 108 1.1 christos /* <size> <vendor_name> NUL 0x1 <size> */ 109 1.8 christos return (size 110 1.1 christos ? size + 10 + strlen (vendor_name) 111 1.1 christos : 0); 112 1.1 christos } 113 1.1 christos 114 1.1 christos /* Return the size of the object attributes section. */ 115 1.1 christos bfd_vma 116 1.1 christos bfd_elf_obj_attr_size (bfd *abfd) 117 1.1 christos { 118 1.1 christos bfd_vma size; 119 1.1 christos 120 1.1 christos size = vendor_obj_attr_size (abfd, OBJ_ATTR_PROC); 121 1.1 christos size += vendor_obj_attr_size (abfd, OBJ_ATTR_GNU); 122 1.1 christos 123 1.1 christos /* 'A' <sections for each vendor> */ 124 1.1 christos return (size ? size + 1 : 0); 125 1.1 christos } 126 1.1 christos 127 1.1 christos /* Write VAL in uleb128 format to P, returning a pointer to the 128 1.1 christos following byte. */ 129 1.1 christos static bfd_byte * 130 1.1 christos write_uleb128 (bfd_byte *p, unsigned int val) 131 1.1 christos { 132 1.1 christos bfd_byte c; 133 1.1 christos do 134 1.1 christos { 135 1.1 christos c = val & 0x7f; 136 1.1 christos val >>= 7; 137 1.1 christos if (val) 138 1.1 christos c |= 0x80; 139 1.1 christos *(p++) = c; 140 1.1 christos } 141 1.1 christos while (val); 142 1.1 christos return p; 143 1.1 christos } 144 1.1 christos 145 1.1 christos /* Write attribute ATTR to butter P, and return a pointer to the following 146 1.1 christos byte. */ 147 1.1 christos static bfd_byte * 148 1.5 christos write_obj_attribute (bfd_byte *p, unsigned int tag, obj_attribute *attr) 149 1.1 christos { 150 1.1 christos /* Suppress default entries. */ 151 1.1 christos if (is_default_attr (attr)) 152 1.1 christos return p; 153 1.1 christos 154 1.1 christos p = write_uleb128 (p, tag); 155 1.1 christos if (ATTR_TYPE_HAS_INT_VAL (attr->type)) 156 1.1 christos p = write_uleb128 (p, attr->i); 157 1.1 christos if (ATTR_TYPE_HAS_STR_VAL (attr->type)) 158 1.1 christos { 159 1.1 christos int len; 160 1.1 christos 161 1.1 christos len = strlen (attr->s) + 1; 162 1.1 christos memcpy (p, attr->s, len); 163 1.1 christos p += len; 164 1.1 christos } 165 1.1 christos 166 1.1 christos return p; 167 1.1 christos } 168 1.1 christos 169 1.1 christos /* Write the contents of the object attributes section (length SIZE) 170 1.1 christos for VENDOR to CONTENTS. */ 171 1.1 christos static void 172 1.1 christos vendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size, 173 1.1 christos int vendor) 174 1.1 christos { 175 1.1 christos bfd_byte *p; 176 1.1 christos obj_attribute *attr; 177 1.1 christos obj_attribute_list *list; 178 1.1 christos int i; 179 1.1 christos const char *vendor_name = vendor_obj_attr_name (abfd, vendor); 180 1.1 christos size_t vendor_length = strlen (vendor_name) + 1; 181 1.1 christos 182 1.1 christos p = contents; 183 1.1 christos bfd_put_32 (abfd, size, p); 184 1.1 christos p += 4; 185 1.1 christos memcpy (p, vendor_name, vendor_length); 186 1.1 christos p += vendor_length; 187 1.1 christos *(p++) = Tag_File; 188 1.1 christos bfd_put_32 (abfd, size - 4 - vendor_length, p); 189 1.1 christos p += 4; 190 1.1 christos 191 1.1 christos attr = elf_known_obj_attributes (abfd)[vendor]; 192 1.1 christos for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) 193 1.1 christos { 194 1.5 christos unsigned int tag = i; 195 1.1 christos if (get_elf_backend_data (abfd)->obj_attrs_order) 196 1.1 christos tag = get_elf_backend_data (abfd)->obj_attrs_order (i); 197 1.1 christos p = write_obj_attribute (p, tag, &attr[tag]); 198 1.1 christos } 199 1.1 christos 200 1.1 christos for (list = elf_other_obj_attributes (abfd)[vendor]; 201 1.1 christos list; 202 1.1 christos list = list->next) 203 1.1 christos p = write_obj_attribute (p, list->tag, &list->attr); 204 1.1 christos } 205 1.1 christos 206 1.1 christos /* Write the contents of the object attributes section to CONTENTS. */ 207 1.1 christos void 208 1.1 christos bfd_elf_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size) 209 1.1 christos { 210 1.1 christos bfd_byte *p; 211 1.1 christos int vendor; 212 1.1 christos bfd_vma my_size; 213 1.1 christos 214 1.1 christos p = contents; 215 1.1 christos *(p++) = 'A'; 216 1.1 christos my_size = 1; 217 1.1 christos for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++) 218 1.1 christos { 219 1.1 christos bfd_vma vendor_size = vendor_obj_attr_size (abfd, vendor); 220 1.1 christos if (vendor_size) 221 1.1 christos vendor_set_obj_attr_contents (abfd, p, vendor_size, vendor); 222 1.1 christos p += vendor_size; 223 1.1 christos my_size += vendor_size; 224 1.1 christos } 225 1.1 christos 226 1.1 christos if (size != my_size) 227 1.1 christos abort (); 228 1.1 christos } 229 1.1 christos 230 1.1 christos /* Allocate/find an object attribute. */ 231 1.1 christos static obj_attribute * 232 1.5 christos elf_new_obj_attr (bfd *abfd, int vendor, unsigned int tag) 233 1.1 christos { 234 1.1 christos obj_attribute *attr; 235 1.1 christos obj_attribute_list *list; 236 1.1 christos obj_attribute_list *p; 237 1.1 christos obj_attribute_list **lastp; 238 1.1 christos 239 1.1 christos 240 1.1 christos if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) 241 1.1 christos { 242 1.1 christos /* Known tags are preallocated. */ 243 1.1 christos attr = &elf_known_obj_attributes (abfd)[vendor][tag]; 244 1.1 christos } 245 1.1 christos else 246 1.1 christos { 247 1.1 christos /* Create a new tag. */ 248 1.1 christos list = (obj_attribute_list *) 249 1.1 christos bfd_alloc (abfd, sizeof (obj_attribute_list)); 250 1.11 christos if (list == NULL) 251 1.11 christos return NULL; 252 1.1 christos memset (list, 0, sizeof (obj_attribute_list)); 253 1.1 christos list->tag = tag; 254 1.1 christos /* Keep the tag list in order. */ 255 1.1 christos lastp = &elf_other_obj_attributes (abfd)[vendor]; 256 1.1 christos for (p = *lastp; p; p = p->next) 257 1.1 christos { 258 1.1 christos if (tag < p->tag) 259 1.1 christos break; 260 1.1 christos lastp = &p->next; 261 1.1 christos } 262 1.1 christos list->next = *lastp; 263 1.1 christos *lastp = list; 264 1.1 christos attr = &list->attr; 265 1.1 christos } 266 1.1 christos 267 1.1 christos return attr; 268 1.1 christos } 269 1.1 christos 270 1.1 christos /* Return the value of an integer object attribute. */ 271 1.1 christos int 272 1.5 christos bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, unsigned int tag) 273 1.1 christos { 274 1.1 christos obj_attribute_list *p; 275 1.1 christos 276 1.1 christos if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) 277 1.1 christos { 278 1.1 christos /* Known tags are preallocated. */ 279 1.1 christos return elf_known_obj_attributes (abfd)[vendor][tag].i; 280 1.1 christos } 281 1.1 christos else 282 1.1 christos { 283 1.1 christos for (p = elf_other_obj_attributes (abfd)[vendor]; 284 1.1 christos p; 285 1.1 christos p = p->next) 286 1.1 christos { 287 1.1 christos if (tag == p->tag) 288 1.1 christos return p->attr.i; 289 1.1 christos if (tag < p->tag) 290 1.1 christos break; 291 1.1 christos } 292 1.1 christos return 0; 293 1.1 christos } 294 1.1 christos } 295 1.1 christos 296 1.1 christos /* Add an integer object attribute. */ 297 1.11 christos obj_attribute * 298 1.5 christos bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, unsigned int tag, unsigned int i) 299 1.1 christos { 300 1.1 christos obj_attribute *attr; 301 1.1 christos 302 1.1 christos attr = elf_new_obj_attr (abfd, vendor, tag); 303 1.11 christos if (attr != NULL) 304 1.11 christos { 305 1.11 christos attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); 306 1.11 christos attr->i = i; 307 1.11 christos } 308 1.11 christos return attr; 309 1.1 christos } 310 1.1 christos 311 1.1 christos /* Duplicate an object attribute string value. */ 312 1.10 christos static char * 313 1.10 christos elf_attr_strdup (bfd *abfd, const char *s, const char *end) 314 1.10 christos { 315 1.10 christos char *p; 316 1.10 christos size_t len; 317 1.10 christos 318 1.10 christos if (end) 319 1.10 christos len = strnlen (s, end - s); 320 1.10 christos else 321 1.10 christos len = strlen (s); 322 1.10 christos 323 1.10 christos p = (char *) bfd_alloc (abfd, len + 1); 324 1.10 christos if (p != NULL) 325 1.10 christos { 326 1.10 christos memcpy (p, s, len); 327 1.10 christos p[len] = 0; 328 1.10 christos } 329 1.10 christos return p; 330 1.10 christos } 331 1.10 christos 332 1.1 christos char * 333 1.10 christos _bfd_elf_attr_strdup (bfd *abfd, const char *s) 334 1.1 christos { 335 1.10 christos return elf_attr_strdup (abfd, s, NULL); 336 1.1 christos } 337 1.1 christos 338 1.1 christos /* Add a string object attribute. */ 339 1.11 christos static obj_attribute * 340 1.10 christos elf_add_obj_attr_string (bfd *abfd, int vendor, unsigned int tag, 341 1.10 christos const char *s, const char *end) 342 1.1 christos { 343 1.1 christos obj_attribute *attr; 344 1.1 christos 345 1.1 christos attr = elf_new_obj_attr (abfd, vendor, tag); 346 1.11 christos if (attr != NULL) 347 1.11 christos { 348 1.11 christos attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); 349 1.11 christos attr->s = elf_attr_strdup (abfd, s, end); 350 1.11 christos if (attr->s == NULL) 351 1.11 christos return NULL; 352 1.11 christos } 353 1.11 christos return attr; 354 1.10 christos } 355 1.10 christos 356 1.11 christos obj_attribute * 357 1.10 christos bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, unsigned int tag, 358 1.10 christos const char *s) 359 1.10 christos { 360 1.11 christos return elf_add_obj_attr_string (abfd, vendor, tag, s, NULL); 361 1.1 christos } 362 1.1 christos 363 1.1 christos /* Add a int+string object attribute. */ 364 1.11 christos static obj_attribute * 365 1.10 christos elf_add_obj_attr_int_string (bfd *abfd, int vendor, unsigned int tag, 366 1.10 christos unsigned int i, const char *s, const char *end) 367 1.1 christos { 368 1.1 christos obj_attribute *attr; 369 1.1 christos 370 1.1 christos attr = elf_new_obj_attr (abfd, vendor, tag); 371 1.11 christos if (attr != NULL) 372 1.11 christos { 373 1.11 christos attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); 374 1.11 christos attr->i = i; 375 1.11 christos attr->s = elf_attr_strdup (abfd, s, end); 376 1.11 christos if (attr->s == NULL) 377 1.11 christos return NULL; 378 1.11 christos } 379 1.11 christos return attr; 380 1.10 christos } 381 1.10 christos 382 1.11 christos obj_attribute * 383 1.10 christos bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, unsigned int tag, 384 1.10 christos unsigned int i, const char *s) 385 1.10 christos { 386 1.11 christos return elf_add_obj_attr_int_string (abfd, vendor, tag, i, s, NULL); 387 1.1 christos } 388 1.1 christos 389 1.1 christos /* Copy the object attributes from IBFD to OBFD. */ 390 1.1 christos void 391 1.1 christos _bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd) 392 1.1 christos { 393 1.1 christos obj_attribute *in_attr; 394 1.1 christos obj_attribute *out_attr; 395 1.1 christos obj_attribute_list *list; 396 1.1 christos int i; 397 1.1 christos int vendor; 398 1.1 christos 399 1.1 christos if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 400 1.1 christos || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 401 1.1 christos return; 402 1.1 christos 403 1.1 christos for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++) 404 1.1 christos { 405 1.1 christos in_attr 406 1.1 christos = &elf_known_obj_attributes (ibfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE]; 407 1.1 christos out_attr 408 1.1 christos = &elf_known_obj_attributes (obfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE]; 409 1.1 christos for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++) 410 1.1 christos { 411 1.1 christos out_attr->type = in_attr->type; 412 1.1 christos out_attr->i = in_attr->i; 413 1.1 christos if (in_attr->s && *in_attr->s) 414 1.11 christos { 415 1.11 christos out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s); 416 1.11 christos if (out_attr->s == NULL) 417 1.11 christos bfd_perror (_("error adding attribute")); 418 1.11 christos } 419 1.1 christos in_attr++; 420 1.1 christos out_attr++; 421 1.1 christos } 422 1.1 christos 423 1.1 christos for (list = elf_other_obj_attributes (ibfd)[vendor]; 424 1.1 christos list; 425 1.1 christos list = list->next) 426 1.1 christos { 427 1.11 christos bool ok = false; 428 1.1 christos in_attr = &list->attr; 429 1.1 christos switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL)) 430 1.1 christos { 431 1.1 christos case ATTR_TYPE_FLAG_INT_VAL: 432 1.11 christos ok = bfd_elf_add_obj_attr_int (obfd, vendor, 433 1.11 christos list->tag, in_attr->i); 434 1.1 christos break; 435 1.1 christos case ATTR_TYPE_FLAG_STR_VAL: 436 1.11 christos ok = bfd_elf_add_obj_attr_string (obfd, vendor, list->tag, 437 1.11 christos in_attr->s); 438 1.1 christos break; 439 1.1 christos case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL: 440 1.11 christos ok = bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag, 441 1.11 christos in_attr->i, in_attr->s); 442 1.1 christos break; 443 1.1 christos default: 444 1.1 christos abort (); 445 1.1 christos } 446 1.11 christos if (!ok) 447 1.11 christos bfd_perror (_("error adding attribute")); 448 1.1 christos } 449 1.1 christos } 450 1.1 christos } 451 1.1 christos 452 1.1 christos /* Determine whether a GNU object attribute tag takes an integer, a 453 1.1 christos string or both. */ 454 1.1 christos static int 455 1.5 christos gnu_obj_attrs_arg_type (unsigned int tag) 456 1.1 christos { 457 1.1 christos /* Except for Tag_compatibility, for GNU attributes we follow the 458 1.1 christos same rule ARM ones > 32 follow: odd-numbered tags take strings 459 1.1 christos and even-numbered tags take integers. In addition, tag & 2 is 460 1.1 christos nonzero for architecture-independent tags and zero for 461 1.1 christos architecture-dependent ones. */ 462 1.1 christos if (tag == Tag_compatibility) 463 1.1 christos return 3; 464 1.1 christos else 465 1.1 christos return (tag & 1) != 0 ? 2 : 1; 466 1.1 christos } 467 1.1 christos 468 1.1 christos /* Determine what arguments an attribute tag takes. */ 469 1.1 christos int 470 1.5 christos _bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, unsigned int tag) 471 1.1 christos { 472 1.1 christos switch (vendor) 473 1.1 christos { 474 1.1 christos case OBJ_ATTR_PROC: 475 1.1 christos return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag); 476 1.1 christos break; 477 1.1 christos case OBJ_ATTR_GNU: 478 1.1 christos return gnu_obj_attrs_arg_type (tag); 479 1.1 christos break; 480 1.1 christos default: 481 1.1 christos abort (); 482 1.1 christos } 483 1.1 christos } 484 1.1 christos 485 1.1 christos /* Parse an object attributes section. */ 486 1.1 christos void 487 1.1 christos _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr) 488 1.1 christos { 489 1.1 christos bfd_byte *contents; 490 1.1 christos bfd_byte *p; 491 1.3 christos bfd_byte *p_end; 492 1.1 christos const char *std_sec; 493 1.9 christos ufile_ptr filesize; 494 1.1 christos 495 1.3 christos /* PR 17512: file: 2844a11d. */ 496 1.3 christos if (hdr->sh_size == 0) 497 1.3 christos return; 498 1.9 christos 499 1.9 christos filesize = bfd_get_file_size (abfd); 500 1.9 christos if (filesize != 0 && hdr->sh_size > filesize) 501 1.8 christos { 502 1.8 christos /* xgettext:c-format */ 503 1.8 christos _bfd_error_handler (_("%pB: error: attribute section '%pA' too big: %#llx"), 504 1.8 christos abfd, hdr->bfd_section, (long long) hdr->sh_size); 505 1.8 christos bfd_set_error (bfd_error_invalid_operation); 506 1.8 christos return; 507 1.8 christos } 508 1.8 christos 509 1.10 christos contents = (bfd_byte *) bfd_malloc (hdr->sh_size); 510 1.1 christos if (!contents) 511 1.1 christos return; 512 1.1 christos if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0, 513 1.1 christos hdr->sh_size)) 514 1.1 christos { 515 1.1 christos free (contents); 516 1.1 christos return; 517 1.1 christos } 518 1.1 christos p = contents; 519 1.3 christos p_end = p + hdr->sh_size; 520 1.1 christos std_sec = get_elf_backend_data (abfd)->obj_attrs_vendor; 521 1.6 christos 522 1.10 christos if (*p++ == 'A') 523 1.1 christos { 524 1.10 christos while (p_end - p >= 4) 525 1.1 christos { 526 1.10 christos size_t len = p_end - p; 527 1.10 christos size_t namelen; 528 1.10 christos size_t section_len; 529 1.1 christos int vendor; 530 1.1 christos 531 1.1 christos section_len = bfd_get_32 (abfd, p); 532 1.1 christos p += 4; 533 1.3 christos if (section_len == 0) 534 1.3 christos break; 535 1.1 christos if (section_len > len) 536 1.1 christos section_len = len; 537 1.8 christos if (section_len <= 4) 538 1.8 christos { 539 1.8 christos _bfd_error_handler 540 1.10 christos (_("%pB: error: attribute section length too small: %ld"), 541 1.10 christos abfd, (long) section_len); 542 1.8 christos break; 543 1.8 christos } 544 1.3 christos section_len -= 4; 545 1.3 christos namelen = strnlen ((char *) p, section_len) + 1; 546 1.10 christos if (namelen >= section_len) 547 1.3 christos break; 548 1.1 christos if (std_sec && strcmp ((char *) p, std_sec) == 0) 549 1.1 christos vendor = OBJ_ATTR_PROC; 550 1.1 christos else if (strcmp ((char *) p, "gnu") == 0) 551 1.1 christos vendor = OBJ_ATTR_GNU; 552 1.1 christos else 553 1.1 christos { 554 1.1 christos /* Other vendor section. Ignore it. */ 555 1.10 christos p += section_len; 556 1.1 christos continue; 557 1.1 christos } 558 1.1 christos 559 1.1 christos p += namelen; 560 1.10 christos section_len -= namelen; 561 1.10 christos while (section_len > 0) 562 1.1 christos { 563 1.5 christos unsigned int tag; 564 1.1 christos unsigned int val; 565 1.10 christos size_t subsection_len; 566 1.10 christos bfd_byte *end, *orig_p; 567 1.1 christos 568 1.10 christos orig_p = p; 569 1.10 christos tag = _bfd_safe_read_leb128 (abfd, &p, false, p_end); 570 1.10 christos if (p_end - p >= 4) 571 1.10 christos { 572 1.10 christos subsection_len = bfd_get_32 (abfd, p); 573 1.10 christos p += 4; 574 1.10 christos } 575 1.3 christos else 576 1.10 christos { 577 1.10 christos p = p_end; 578 1.10 christos break; 579 1.10 christos } 580 1.1 christos if (subsection_len > section_len) 581 1.1 christos subsection_len = section_len; 582 1.1 christos section_len -= subsection_len; 583 1.10 christos end = orig_p + subsection_len; 584 1.10 christos if (end < p) 585 1.10 christos break; 586 1.1 christos switch (tag) 587 1.1 christos { 588 1.1 christos case Tag_File: 589 1.1 christos while (p < end) 590 1.1 christos { 591 1.1 christos int type; 592 1.11 christos bool ok = false; 593 1.1 christos 594 1.10 christos tag = _bfd_safe_read_leb128 (abfd, &p, false, end); 595 1.1 christos type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag); 596 1.1 christos switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL)) 597 1.1 christos { 598 1.1 christos case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL: 599 1.10 christos val = _bfd_safe_read_leb128 (abfd, &p, false, end); 600 1.11 christos ok = elf_add_obj_attr_int_string (abfd, vendor, tag, 601 1.11 christos val, (char *) p, 602 1.11 christos (char *) end); 603 1.10 christos p += strnlen ((char *) p, end - p); 604 1.10 christos if (p < end) 605 1.10 christos p++; 606 1.1 christos break; 607 1.1 christos case ATTR_TYPE_FLAG_STR_VAL: 608 1.11 christos ok = elf_add_obj_attr_string (abfd, vendor, tag, 609 1.11 christos (char *) p, 610 1.11 christos (char *) end); 611 1.10 christos p += strnlen ((char *) p, end - p); 612 1.10 christos if (p < end) 613 1.10 christos p++; 614 1.1 christos break; 615 1.1 christos case ATTR_TYPE_FLAG_INT_VAL: 616 1.10 christos val = _bfd_safe_read_leb128 (abfd, &p, false, end); 617 1.11 christos ok = bfd_elf_add_obj_attr_int (abfd, vendor, tag, val); 618 1.1 christos break; 619 1.1 christos default: 620 1.1 christos abort (); 621 1.1 christos } 622 1.11 christos if (!ok) 623 1.11 christos bfd_perror (_("error adding attribute")); 624 1.1 christos } 625 1.1 christos break; 626 1.1 christos case Tag_Section: 627 1.1 christos case Tag_Symbol: 628 1.1 christos /* Don't have anywhere convenient to attach these. 629 1.1 christos Fall through for now. */ 630 1.1 christos default: 631 1.10 christos /* Ignore things we don't know about. */ 632 1.10 christos p = end; 633 1.1 christos break; 634 1.1 christos } 635 1.1 christos } 636 1.1 christos } 637 1.1 christos } 638 1.1 christos free (contents); 639 1.1 christos } 640 1.1 christos 641 1.1 christos /* Merge common object attributes from IBFD into OBFD. Raise an error 642 1.1 christos if there are conflicting attributes. Any processor-specific 643 1.1 christos attributes have already been merged. This must be called from the 644 1.1 christos bfd_elfNN_bfd_merge_private_bfd_data hook for each individual 645 1.1 christos target, along with any target-specific merging. Because there are 646 1.1 christos no common attributes other than Tag_compatibility at present, and 647 1.1 christos non-"gnu" Tag_compatibility is not expected in "gnu" sections, this 648 1.1 christos is not presently called for targets without their own 649 1.1 christos attributes. */ 650 1.1 christos 651 1.10 christos bool 652 1.7 christos _bfd_elf_merge_object_attributes (bfd *ibfd, struct bfd_link_info *info) 653 1.1 christos { 654 1.7 christos bfd *obfd = info->output_bfd; 655 1.1 christos obj_attribute *in_attr; 656 1.1 christos obj_attribute *out_attr; 657 1.1 christos int vendor; 658 1.1 christos 659 1.1 christos /* The only common attribute is currently Tag_compatibility, 660 1.1 christos accepted in both processor and "gnu" sections. */ 661 1.1 christos for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++) 662 1.1 christos { 663 1.1 christos /* Handle Tag_compatibility. The tags are only compatible if the flags 664 1.1 christos are identical and, if the flags are '1', the strings are identical. 665 1.1 christos If the flags are non-zero, then we can only use the string "gnu". */ 666 1.1 christos in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility]; 667 1.1 christos out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility]; 668 1.1 christos 669 1.1 christos if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0) 670 1.1 christos { 671 1.1 christos _bfd_error_handler 672 1.7 christos /* xgettext:c-format */ 673 1.8 christos (_("error: %pB: object has vendor-specific contents that " 674 1.1 christos "must be processed by the '%s' toolchain"), 675 1.1 christos ibfd, in_attr->s); 676 1.10 christos return false; 677 1.1 christos } 678 1.1 christos 679 1.1 christos if (in_attr->i != out_attr->i 680 1.1 christos || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0)) 681 1.1 christos { 682 1.7 christos /* xgettext:c-format */ 683 1.8 christos _bfd_error_handler (_("error: %pB: object tag '%d, %s' is " 684 1.1 christos "incompatible with tag '%d, %s'"), 685 1.1 christos ibfd, 686 1.1 christos in_attr->i, in_attr->s ? in_attr->s : "", 687 1.1 christos out_attr->i, out_attr->s ? out_attr->s : ""); 688 1.10 christos return false; 689 1.1 christos } 690 1.1 christos } 691 1.1 christos 692 1.10 christos return true; 693 1.1 christos } 694 1.1 christos 695 1.1 christos /* Merge an unknown processor-specific attribute TAG, within the range 696 1.1 christos of known attributes, from IBFD into OBFD; return TRUE if the link 697 1.1 christos is OK, FALSE if it must fail. */ 698 1.1 christos 699 1.10 christos bool 700 1.1 christos _bfd_elf_merge_unknown_attribute_low (bfd *ibfd, bfd *obfd, int tag) 701 1.1 christos { 702 1.1 christos obj_attribute *in_attr; 703 1.1 christos obj_attribute *out_attr; 704 1.1 christos bfd *err_bfd = NULL; 705 1.10 christos bool result = true; 706 1.1 christos 707 1.1 christos in_attr = elf_known_obj_attributes_proc (ibfd); 708 1.1 christos out_attr = elf_known_obj_attributes_proc (obfd); 709 1.1 christos 710 1.1 christos if (out_attr[tag].i != 0 || out_attr[tag].s != NULL) 711 1.1 christos err_bfd = obfd; 712 1.1 christos else if (in_attr[tag].i != 0 || in_attr[tag].s != NULL) 713 1.1 christos err_bfd = ibfd; 714 1.1 christos 715 1.1 christos if (err_bfd != NULL) 716 1.1 christos result 717 1.1 christos = get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, tag); 718 1.1 christos 719 1.1 christos /* Only pass on attributes that match in both inputs. */ 720 1.1 christos if (in_attr[tag].i != out_attr[tag].i 721 1.1 christos || (in_attr[tag].s == NULL) != (out_attr[tag].s == NULL) 722 1.1 christos || (in_attr[tag].s != NULL && out_attr[tag].s != NULL 723 1.1 christos && strcmp (in_attr[tag].s, out_attr[tag].s) != 0)) 724 1.1 christos { 725 1.1 christos out_attr[tag].i = 0; 726 1.1 christos out_attr[tag].s = NULL; 727 1.1 christos } 728 1.1 christos 729 1.1 christos return result; 730 1.1 christos } 731 1.1 christos 732 1.1 christos /* Merge the lists of unknown processor-specific attributes, outside 733 1.1 christos the known range, from IBFD into OBFD; return TRUE if the link is 734 1.1 christos OK, FALSE if it must fail. */ 735 1.1 christos 736 1.10 christos bool 737 1.1 christos _bfd_elf_merge_unknown_attribute_list (bfd *ibfd, bfd *obfd) 738 1.1 christos { 739 1.1 christos obj_attribute_list *in_list; 740 1.1 christos obj_attribute_list *out_list; 741 1.1 christos obj_attribute_list **out_listp; 742 1.10 christos bool result = true; 743 1.1 christos 744 1.1 christos in_list = elf_other_obj_attributes_proc (ibfd); 745 1.1 christos out_listp = &elf_other_obj_attributes_proc (obfd); 746 1.1 christos out_list = *out_listp; 747 1.1 christos 748 1.1 christos for (; in_list || out_list; ) 749 1.1 christos { 750 1.1 christos bfd *err_bfd = NULL; 751 1.5 christos unsigned int err_tag = 0; 752 1.1 christos 753 1.1 christos /* The tags for each list are in numerical order. */ 754 1.1 christos /* If the tags are equal, then merge. */ 755 1.1 christos if (out_list && (!in_list || in_list->tag > out_list->tag)) 756 1.1 christos { 757 1.1 christos /* This attribute only exists in obfd. We can't merge, and we don't 758 1.1 christos know what the tag means, so delete it. */ 759 1.1 christos err_bfd = obfd; 760 1.1 christos err_tag = out_list->tag; 761 1.1 christos *out_listp = out_list->next; 762 1.1 christos out_list = *out_listp; 763 1.1 christos } 764 1.1 christos else if (in_list && (!out_list || in_list->tag < out_list->tag)) 765 1.1 christos { 766 1.1 christos /* This attribute only exists in ibfd. We can't merge, and we don't 767 1.1 christos know what the tag means, so ignore it. */ 768 1.1 christos err_bfd = ibfd; 769 1.1 christos err_tag = in_list->tag; 770 1.1 christos in_list = in_list->next; 771 1.1 christos } 772 1.1 christos else /* The tags are equal. */ 773 1.1 christos { 774 1.1 christos /* As present, all attributes in the list are unknown, and 775 1.1 christos therefore can't be merged meaningfully. */ 776 1.1 christos err_bfd = obfd; 777 1.1 christos err_tag = out_list->tag; 778 1.1 christos 779 1.1 christos /* Only pass on attributes that match in both inputs. */ 780 1.1 christos if (in_list->attr.i != out_list->attr.i 781 1.1 christos || (in_list->attr.s == NULL) != (out_list->attr.s == NULL) 782 1.1 christos || (in_list->attr.s && out_list->attr.s 783 1.1 christos && strcmp (in_list->attr.s, out_list->attr.s) != 0)) 784 1.1 christos { 785 1.1 christos /* No match. Delete the attribute. */ 786 1.1 christos *out_listp = out_list->next; 787 1.1 christos out_list = *out_listp; 788 1.1 christos } 789 1.1 christos else 790 1.1 christos { 791 1.1 christos /* Matched. Keep the attribute and move to the next. */ 792 1.1 christos out_list = out_list->next; 793 1.1 christos in_list = in_list->next; 794 1.1 christos } 795 1.1 christos } 796 1.1 christos 797 1.1 christos if (err_bfd) 798 1.1 christos result = result 799 1.1 christos && get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, 800 1.1 christos err_tag); 801 1.1 christos } 802 1.1 christos 803 1.1 christos return result; 804 1.1 christos } 805