daily update
[deliverable/binutils-gdb.git] / bfd / elf-attrs.c
CommitLineData
104d59d1
JM
1/* ELF attributes support (based on ARM EABI attributes).
2 Copyright 2005, 2006, 2007
3 Free Software Foundation, Inc.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
104d59d1
JM
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
cd123cb7
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
104d59d1
JM
21
22#include "sysdep.h"
23#include "bfd.h"
24#include "libiberty.h"
25#include "libbfd.h"
26#include "elf-bfd.h"
27
28/* Return the number of bytes needed by I in uleb128 format. */
29static int
30uleb128_size (unsigned int i)
31{
32 int size;
33 size = 1;
34 while (i >= 0x80)
35 {
36 i >>= 7;
37 size++;
38 }
39 return size;
40}
41
42/* Return TRUE if the attribute has the default value (0/""). */
43static bfd_boolean
44is_default_attr (obj_attribute *attr)
45{
46 if ((attr->type & 1) && attr->i != 0)
47 return FALSE;
48 if ((attr->type & 2) && attr->s && *attr->s)
49 return FALSE;
50
51 return TRUE;
52}
53
54/* Return the size of a single attribute. */
55static bfd_vma
56obj_attr_size (int tag, obj_attribute *attr)
57{
58 bfd_vma size;
59
60 if (is_default_attr (attr))
61 return 0;
62
63 size = uleb128_size (tag);
64 if (attr->type & 1)
65 size += uleb128_size (attr->i);
66 if (attr->type & 2)
67 size += strlen ((char *)attr->s) + 1;
68 return size;
69}
70
71/* Return the vendor name for a given object attributes section. */
72static const char *
73vendor_obj_attr_name (bfd *abfd, int vendor)
74{
75 return (vendor == OBJ_ATTR_PROC
76 ? get_elf_backend_data (abfd)->obj_attrs_vendor
77 : "gnu");
78}
79
80/* Return the size of the object attributes section for VENDOR
81 (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes
82 for that vendor to record and the vendor is OBJ_ATTR_GNU. */
83static bfd_vma
84vendor_obj_attr_size (bfd *abfd, int vendor)
85{
86 bfd_vma size;
87 obj_attribute *attr;
88 obj_attribute_list *list;
89 int i;
90 const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
91
92 if (!vendor_name)
93 return 0;
94
95 attr = elf_known_obj_attributes (abfd)[vendor];
96 size = 0;
97 for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
98 size += obj_attr_size (i, &attr[i]);
99
100 for (list = elf_other_obj_attributes (abfd)[vendor];
101 list;
102 list = list->next)
103 size += obj_attr_size (list->tag, &list->attr);
104
105 /* <size> <vendor_name> NUL 0x1 <size> */
106 return ((size || vendor == OBJ_ATTR_PROC)
107 ? size + 10 + strlen (vendor_name)
108 : 0);
109}
110
111/* Return the size of the object attributes section. */
112bfd_vma
113bfd_elf_obj_attr_size (bfd *abfd)
114{
115 bfd_vma size;
116
117 size = vendor_obj_attr_size (abfd, OBJ_ATTR_PROC);
118 size += vendor_obj_attr_size (abfd, OBJ_ATTR_GNU);
119
120 /* 'A' <sections for each vendor> */
121 return (size ? size + 1 : 0);
122}
123
124/* Write VAL in uleb128 format to P, returning a pointer to the
125 following byte. */
126static bfd_byte *
127write_uleb128 (bfd_byte *p, unsigned int val)
128{
129 bfd_byte c;
130 do
131 {
132 c = val & 0x7f;
133 val >>= 7;
134 if (val)
135 c |= 0x80;
136 *(p++) = c;
137 }
138 while (val);
139 return p;
140}
141
142/* Write attribute ATTR to butter P, and return a pointer to the following
143 byte. */
144static bfd_byte *
145write_obj_attribute (bfd_byte *p, int tag, obj_attribute *attr)
146{
147 /* Suppress default entries. */
148 if (is_default_attr (attr))
149 return p;
150
151 p = write_uleb128 (p, tag);
152 if (attr->type & 1)
153 p = write_uleb128 (p, attr->i);
154 if (attr->type & 2)
155 {
156 int len;
157
158 len = strlen (attr->s) + 1;
159 memcpy (p, attr->s, len);
160 p += len;
161 }
162
163 return p;
164}
165
166/* Write the contents of the object attributes section (length SIZE)
167 for VENDOR to CONTENTS. */
168static void
169vendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size,
170 int vendor)
171{
172 bfd_byte *p;
173 obj_attribute *attr;
174 obj_attribute_list *list;
175 int i;
176 const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
177 size_t vendor_length = strlen (vendor_name) + 1;
178
179 p = contents;
180 bfd_put_32 (abfd, size, p);
181 p += 4;
182 memcpy (p, vendor_name, vendor_length);
183 p += vendor_length;
184 *(p++) = Tag_File;
185 bfd_put_32 (abfd, size - 4 - vendor_length, p);
186 p += 4;
187
188 attr = elf_known_obj_attributes (abfd)[vendor];
189 for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
190 p = write_obj_attribute (p, i, &attr[i]);
191
192 for (list = elf_other_obj_attributes (abfd)[vendor];
193 list;
194 list = list->next)
195 p = write_obj_attribute (p, list->tag, &list->attr);
196}
197
198/* Write the contents of the object attributes section to CONTENTS. */
199void
200bfd_elf_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size)
201{
202 bfd_byte *p;
203 int vendor;
204 bfd_vma my_size;
205
206 p = contents;
207 *(p++) = 'A';
208 my_size = 1;
209 for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
210 {
211 bfd_vma vendor_size = vendor_obj_attr_size (abfd, vendor);
212 if (vendor_size)
213 vendor_set_obj_attr_contents (abfd, p, vendor_size, vendor);
214 p += vendor_size;
215 my_size += vendor_size;
216 }
217
218 if (size != my_size)
219 abort ();
220}
221
222/* Allocate/find an object attribute. */
223static obj_attribute *
224elf_new_obj_attr (bfd *abfd, int vendor, int tag)
225{
226 obj_attribute *attr;
227 obj_attribute_list *list;
228 obj_attribute_list *p;
229 obj_attribute_list **lastp;
230
231
232 if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
233 {
234 /* Knwon tags are preallocated. */
235 attr = &elf_known_obj_attributes (abfd)[vendor][tag];
236 }
237 else
238 {
239 /* Create a new tag. */
240 list = (obj_attribute_list *)
241 bfd_alloc (abfd, sizeof (obj_attribute_list));
242 memset (list, 0, sizeof (obj_attribute_list));
243 list->tag = tag;
244 /* Keep the tag list in order. */
245 lastp = &elf_other_obj_attributes (abfd)[vendor];
246 for (p = *lastp; p; p = p->next)
247 {
248 if (tag < p->tag)
249 break;
250 lastp = &p->next;
251 }
252 list->next = *lastp;
253 *lastp = list;
254 attr = &list->attr;
255 }
256
257 return attr;
258}
259
260/* Return the value of an integer object attribute. */
261int
262bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, int tag)
263{
264 obj_attribute_list *p;
265
266 if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
267 {
268 /* Knwon tags are preallocated. */
269 return elf_known_obj_attributes (abfd)[vendor][tag].i;
270 }
271 else
272 {
273 for (p = elf_other_obj_attributes (abfd)[vendor];
274 p;
275 p = p->next)
276 {
277 if (tag == p->tag)
278 return p->attr.i;
279 if (tag < p->tag)
280 break;
281 }
282 return 0;
283 }
284}
285
286/* Add an integer object attribute. */
287void
288bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, int tag, unsigned int i)
289{
290 obj_attribute *attr;
291
292 attr = elf_new_obj_attr (abfd, vendor, tag);
293 attr->type = 1;
294 attr->i = i;
295}
296
297/* Duplicate an object attribute string value. */
298char *
299_bfd_elf_attr_strdup (bfd *abfd, const char * s)
300{
301 char * p;
302 int len;
303
304 len = strlen (s) + 1;
305 p = (char *) bfd_alloc (abfd, len);
306 return memcpy (p, s, len);
307}
308
309/* Add a string object attribute. */
310void
311bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, int tag, const char *s)
312{
313 obj_attribute *attr;
314
315 attr = elf_new_obj_attr (abfd, vendor, tag);
316 attr->type = 2;
317 attr->s = _bfd_elf_attr_strdup (abfd, s);
318}
319
7b86a9fa 320/* Add a int+string object attribute. */
104d59d1 321void
7b86a9fa
AS
322bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, int tag,
323 unsigned int i, const char *s)
104d59d1 324{
7b86a9fa 325 obj_attribute *attr;
104d59d1 326
7b86a9fa
AS
327 attr = elf_new_obj_attr (abfd, vendor, tag);
328 attr->type = 3;
329 attr->i = i;
330 attr->s = _bfd_elf_attr_strdup (abfd, s);
104d59d1
JM
331}
332
333/* Copy the object attributes from IBFD to OBFD. */
334void
335_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
336{
337 obj_attribute *in_attr;
338 obj_attribute *out_attr;
339 obj_attribute_list *list;
340 int i;
341 int vendor;
342
343 for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
344 {
345 in_attr = &elf_known_obj_attributes (ibfd)[vendor][4];
346 out_attr = &elf_known_obj_attributes (obfd)[vendor][4];
347 for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
348 {
349 out_attr->type = in_attr->type;
350 out_attr->i = in_attr->i;
351 if (in_attr->s && *in_attr->s)
352 out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s);
353 in_attr++;
354 out_attr++;
355 }
356
357 for (list = elf_other_obj_attributes (ibfd)[vendor];
358 list;
359 list = list->next)
360 {
361 in_attr = &list->attr;
362 switch (in_attr->type)
363 {
364 case 1:
365 bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
366 break;
367 case 2:
368 bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
369 in_attr->s);
370 break;
371 case 3:
7b86a9fa
AS
372 bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag,
373 in_attr->i, in_attr->s);
104d59d1
JM
374 break;
375 default:
376 abort ();
377 }
378 }
379 }
380}
381
382/* Determine whether a GNU object attribute tag takes an integer, a
383 string or both. */
384static int
385gnu_obj_attrs_arg_type (int tag)
386{
387 /* Except for Tag_compatibility, for GNU attributes we follow the
388 same rule ARM ones > 32 follow: odd-numbered tags take strings
389 and even-numbered tags take integers. In addition, tag & 2 is
390 nonzero for architecture-independent tags and zero for
391 architecture-dependent ones. */
392 if (tag == Tag_compatibility)
393 return 3;
394 else
395 return (tag & 1) != 0 ? 2 : 1;
396}
397
398/* Determine what arguments an attribute tag takes. */
399int
400_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, int tag)
401{
402 switch (vendor)
403 {
404 case OBJ_ATTR_PROC:
405 return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag);
406 break;
407 case OBJ_ATTR_GNU:
408 return gnu_obj_attrs_arg_type (tag);
409 break;
410 default:
411 abort ();
412 }
413}
414
415/* Parse an object attributes section. */
416void
417_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
418{
419 bfd_byte *contents;
420 bfd_byte *p;
421 bfd_vma len;
422 const char *std_section;
423
424 contents = bfd_malloc (hdr->sh_size);
425 if (!contents)
426 return;
427 if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
428 hdr->sh_size))
429 {
430 free (contents);
431 return;
432 }
433 p = contents;
434 std_section = get_elf_backend_data (abfd)->obj_attrs_vendor;
435 if (*(p++) == 'A')
436 {
437 len = hdr->sh_size - 1;
438 while (len > 0)
439 {
440 int namelen;
441 bfd_vma section_len;
442 int vendor;
443
444 section_len = bfd_get_32 (abfd, p);
445 p += 4;
446 if (section_len > len)
447 section_len = len;
448 len -= section_len;
449 namelen = strlen ((char *)p) + 1;
450 section_len -= namelen + 4;
451 if (std_section && strcmp ((char *)p, std_section) == 0)
452 vendor = OBJ_ATTR_PROC;
453 else if (strcmp ((char *)p, "gnu") == 0)
454 vendor = OBJ_ATTR_GNU;
455 else
456 {
457 /* Other vendor section. Ignore it. */
458 p += namelen + section_len;
459 continue;
460 }
461
462 p += namelen;
463 while (section_len > 0)
464 {
465 int tag;
466 unsigned int n;
467 unsigned int val;
468 bfd_vma subsection_len;
469 bfd_byte *end;
470
471 tag = read_unsigned_leb128 (abfd, p, &n);
472 p += n;
473 subsection_len = bfd_get_32 (abfd, p);
474 p += 4;
475 if (subsection_len > section_len)
476 subsection_len = section_len;
477 section_len -= subsection_len;
478 subsection_len -= n + 4;
479 end = p + subsection_len;
480 switch (tag)
481 {
482 case Tag_File:
483 while (p < end)
484 {
485 int type;
486
487 tag = read_unsigned_leb128 (abfd, p, &n);
488 p += n;
489 type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
490 switch (type)
491 {
492 case 3:
493 val = read_unsigned_leb128 (abfd, p, &n);
494 p += n;
7b86a9fa
AS
495 bfd_elf_add_obj_attr_int_string (abfd, vendor, tag,
496 val, (char *)p);
104d59d1
JM
497 p += strlen ((char *)p) + 1;
498 break;
499 case 2:
500 bfd_elf_add_obj_attr_string (abfd, vendor, tag,
501 (char *)p);
502 p += strlen ((char *)p) + 1;
503 break;
504 case 1:
505 val = read_unsigned_leb128 (abfd, p, &n);
506 p += n;
507 bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
508 break;
509 default:
510 abort ();
511 }
512 }
513 break;
514 case Tag_Section:
515 case Tag_Symbol:
516 /* Don't have anywhere convenient to attach these.
517 Fall through for now. */
518 default:
519 /* Ignore things we don't kow about. */
520 p += subsection_len;
521 subsection_len = 0;
522 break;
523 }
524 }
525 }
526 }
527 free (contents);
528}
529
530/* Merge common object attributes from IBFD into OBFD. Raise an error
531 if there are conflicting attributes. Any processor-specific
532 attributes have already been merged. This must be called from the
533 bfd_elfNN_bfd_merge_private_bfd_data hook for each individual
534 target, along with any target-specific merging. Because there are
535 no common attributes other than Tag_compatibility at present, and
536 non-"gnu" Tag_compatibility is not expected in "gnu" sections, this
537 is not presently called for targets without their own
538 attributes. */
539
540bfd_boolean
541_bfd_elf_merge_object_attributes (bfd *ibfd, bfd *obfd)
542{
543 obj_attribute *in_attr;
544 obj_attribute *out_attr;
104d59d1
JM
545 int vendor;
546
547 /* The only common attribute is currently Tag_compatibility,
548 accepted in both processor and "gnu" sections. */
549 for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
550 {
7b86a9fa
AS
551 /* Handle Tag_compatibility. The tags are only compatible if the flags
552 are identical and, if the flags are '1', the strings are identical.
553 If the flags are non-zero, then we can only use the string "gnu". */
554 in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility];
555 out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility];
556
557 if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0)
104d59d1 558 {
7b86a9fa 559 _bfd_error_handler
104d59d1
JM
560 (_("ERROR: %B: Must be processed by '%s' toolchain"),
561 ibfd, in_attr->s);
7b86a9fa
AS
562 return FALSE;
563 }
104d59d1 564
7b86a9fa
AS
565 if (in_attr->i != out_attr->i
566 || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0))
567 {
568 _bfd_error_handler (_("ERROR: %B: Object tag '%d, %s' is "
569 "incompatible with tag '%d, %s'"),
570 ibfd,
571 in_attr->i, in_attr->s ? in_attr->s : "",
572 out_attr->i, out_attr->s ? out_attr->s : "");
573 return FALSE;
104d59d1
JM
574 }
575 }
576
577 return TRUE;
578}
This page took 0.106677 seconds and 4 git commands to generate.