Subversion Repositories Kolibri OS

Rev

Rev 5197 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5197 Rev 6324
Line 1... Line 1...
1
/* ELF attributes support (based on ARM EABI attributes).
1
/* ELF attributes support (based on ARM EABI attributes).
2
   Copyright 2005, 2006, 2007, 2009, 2010, 2012
-
 
3
   Free Software Foundation, Inc.
2
   Copyright (C) 2005-2015 Free Software Foundation, Inc.
Line 4... Line 3...
4
 
3
 
Line 5... Line 4...
5
   This file is part of BFD, the Binary File Descriptor library.
4
   This file is part of BFD, the Binary File Descriptor library.
6
 
5
 
Line 53... Line 52...
53
  return TRUE;
52
  return TRUE;
54
}
53
}
Line 55... Line 54...
55
 
54
 
56
/* Return the size of a single attribute.  */
55
/* Return the size of a single attribute.  */
57
static bfd_vma
56
static bfd_vma
58
obj_attr_size (int tag, obj_attribute *attr)
57
obj_attr_size (unsigned int tag, obj_attribute *attr)
59
{
58
{
Line 60... Line 59...
60
  bfd_vma size;
59
  bfd_vma size;
61
 
60
 
Line 142... Line 141...
142
}
141
}
Line 143... Line 142...
143
 
142
 
144
/* Write attribute ATTR to butter P, and return a pointer to the following
143
/* Write attribute ATTR to butter P, and return a pointer to the following
145
   byte.  */
144
   byte.  */
146
static bfd_byte *
145
static bfd_byte *
147
write_obj_attribute (bfd_byte *p, int tag, obj_attribute *attr)
146
write_obj_attribute (bfd_byte *p, unsigned int tag, obj_attribute *attr)
148
{
147
{
149
  /* Suppress default entries.  */
148
  /* Suppress default entries.  */
150
  if (is_default_attr (attr))
149
  if (is_default_attr (attr))
Line 188... Line 187...
188
  p += 4;
187
  p += 4;
Line 189... Line 188...
189
 
188
 
190
  attr = elf_known_obj_attributes (abfd)[vendor];
189
  attr = elf_known_obj_attributes (abfd)[vendor];
191
  for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
190
  for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
192
    {
191
    {
193
      int tag = i;
192
      unsigned int tag = i;
194
      if (get_elf_backend_data (abfd)->obj_attrs_order)
193
      if (get_elf_backend_data (abfd)->obj_attrs_order)
195
	tag = get_elf_backend_data (abfd)->obj_attrs_order (i);
194
	tag = get_elf_backend_data (abfd)->obj_attrs_order (i);
196
      p = write_obj_attribute (p, tag, &attr[tag]);
195
      p = write_obj_attribute (p, tag, &attr[tag]);
Line 226... Line 225...
226
    abort ();
225
    abort ();
227
}
226
}
Line 228... Line 227...
228
 
227
 
229
/* Allocate/find an object attribute.  */
228
/* Allocate/find an object attribute.  */
230
static obj_attribute *
229
static obj_attribute *
231
elf_new_obj_attr (bfd *abfd, int vendor, int tag)
230
elf_new_obj_attr (bfd *abfd, int vendor, unsigned int tag)
232
{
231
{
233
  obj_attribute *attr;
232
  obj_attribute *attr;
234
  obj_attribute_list *list;
233
  obj_attribute_list *list;
235
  obj_attribute_list *p;
234
  obj_attribute_list *p;
Line 264... Line 263...
264
  return attr;
263
  return attr;
265
}
264
}
Line 266... Line 265...
266
 
265
 
267
/* Return the value of an integer object attribute.  */
266
/* Return the value of an integer object attribute.  */
268
int
267
int
269
bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, int tag)
268
bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, unsigned int tag)
270
{
269
{
Line 271... Line 270...
271
  obj_attribute_list *p;
270
  obj_attribute_list *p;
272
 
271
 
Line 290... Line 289...
290
    }
289
    }
291
}
290
}
Line 292... Line 291...
292
 
291
 
293
/* Add an integer object attribute.  */
292
/* Add an integer object attribute.  */
294
void
293
void
295
bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, int tag, unsigned int i)
294
bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, unsigned int tag, unsigned int i)
296
{
295
{
Line 297... Line 296...
297
  obj_attribute *attr;
296
  obj_attribute *attr;
298
 
297
 
Line 313... Line 312...
313
  return (char *) memcpy (p, s, len);
312
  return (char *) memcpy (p, s, len);
314
}
313
}
Line 315... Line 314...
315
 
314
 
316
/* Add a string object attribute.  */
315
/* Add a string object attribute.  */
317
void
316
void
318
bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, int tag, const char *s)
317
bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, unsigned int tag, const char *s)
319
{
318
{
Line 320... Line 319...
320
  obj_attribute *attr;
319
  obj_attribute *attr;
321
 
320
 
322
  attr = elf_new_obj_attr (abfd, vendor, tag);
321
  attr = elf_new_obj_attr (abfd, vendor, tag);
323
  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
322
  attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
Line 324... Line 323...
324
  attr->s = _bfd_elf_attr_strdup (abfd, s);
323
  attr->s = _bfd_elf_attr_strdup (abfd, s);
325
}
324
}
326
 
325
 
-
 
326
/* Add a int+string object attribute.  */
327
/* Add a int+string object attribute.  */
327
void
328
void
328
bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor,
329
bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, int tag,
329
				 unsigned int tag,
Line 330... Line 330...
330
				 unsigned int i, const char *s)
330
				 unsigned int i, const char *s)
Line 393... Line 393...
393
}
393
}
Line 394... Line 394...
394
 
394
 
395
/* Determine whether a GNU object attribute tag takes an integer, a
395
/* Determine whether a GNU object attribute tag takes an integer, a
396
   string or both.  */
396
   string or both.  */
397
static int
397
static int
398
gnu_obj_attrs_arg_type (int tag)
398
gnu_obj_attrs_arg_type (unsigned int tag)
399
{
399
{
400
  /* Except for Tag_compatibility, for GNU attributes we follow the
400
  /* Except for Tag_compatibility, for GNU attributes we follow the
401
     same rule ARM ones > 32 follow: odd-numbered tags take strings
401
     same rule ARM ones > 32 follow: odd-numbered tags take strings
402
     and even-numbered tags take integers.  In addition, tag & 2 is
402
     and even-numbered tags take integers.  In addition, tag & 2 is
Line 408... Line 408...
408
    return (tag & 1) != 0 ? 2 : 1;
408
    return (tag & 1) != 0 ? 2 : 1;
409
}
409
}
Line 410... Line 410...
410
 
410
 
411
/* Determine what arguments an attribute tag takes.  */
411
/* Determine what arguments an attribute tag takes.  */
412
int
412
int
413
_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, int tag)
413
_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, unsigned int tag)
414
{
414
{
415
  switch (vendor)
415
  switch (vendor)
416
    {
416
    {
417
    case OBJ_ATTR_PROC:
417
    case OBJ_ATTR_PROC:
Line 429... Line 429...
429
void
429
void
430
_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
430
_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
431
{
431
{
432
  bfd_byte *contents;
432
  bfd_byte *contents;
433
  bfd_byte *p;
433
  bfd_byte *p;
-
 
434
  bfd_byte *p_end;
434
  bfd_vma len;
435
  bfd_vma len;
435
  const char *std_sec;
436
  const char *std_sec;
Line -... Line 437...
-
 
437
 
-
 
438
  /* PR 17512: file: 2844a11d.  */
-
 
439
  if (hdr->sh_size == 0)
436
 
440
    return;
437
  contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
441
  contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
438
  if (!contents)
442
  if (!contents)
439
    return;
443
    return;
440
  if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
444
  if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
441
				 hdr->sh_size))
445
				 hdr->sh_size))
442
    {
446
    {
443
      free (contents);
447
      free (contents);
444
      return;
448
      return;
445
    }
449
    }
-
 
450
  p = contents;
446
  p = contents;
451
  p_end = p + hdr->sh_size;
-
 
452
  std_sec = get_elf_backend_data (abfd)->obj_attrs_vendor;
447
  std_sec = get_elf_backend_data (abfd)->obj_attrs_vendor;
453
 
448
  if (*(p++) == 'A')
454
  if (*(p++) == 'A')
449
    {
455
    {
-
 
456
      len = hdr->sh_size - 1;
450
      len = hdr->sh_size - 1;
457
 
451
      while (len > 0)
458
      while (len > 0 && p < p_end - 4)
452
	{
459
	{
453
	  int namelen;
460
	  unsigned namelen;
454
	  bfd_vma section_len;
461
	  bfd_vma section_len;
Line 455... Line 462...
455
	  int vendor;
462
	  int vendor;
456
 
463
 
-
 
464
	  section_len = bfd_get_32 (abfd, p);
-
 
465
	  p += 4;
457
	  section_len = bfd_get_32 (abfd, p);
466
	  if (section_len == 0)
458
	  p += 4;
467
	    break;
459
	  if (section_len > len)
468
	  if (section_len > len)
-
 
469
	    section_len = len;
460
	    section_len = len;
470
	  len -= section_len;
-
 
471
	  section_len -= 4;
-
 
472
	  namelen = strnlen ((char *) p, section_len) + 1;
461
	  len -= section_len;
473
	  if (namelen == 0 || namelen >= section_len)
462
	  namelen = strlen ((char *) p) + 1;
474
	    break;
463
	  section_len -= namelen + 4;
475
	  section_len -= namelen;
464
	  if (std_sec && strcmp ((char *) p, std_sec) == 0)
476
	  if (std_sec && strcmp ((char *) p, std_sec) == 0)
465
	    vendor = OBJ_ATTR_PROC;
477
	    vendor = OBJ_ATTR_PROC;
466
	  else if (strcmp ((char *) p, "gnu") == 0)
478
	  else if (strcmp ((char *) p, "gnu") == 0)
Line 471... Line 483...
471
	      p += namelen + section_len;
483
	      p += namelen + section_len;
472
	      continue;
484
	      continue;
473
	    }
485
	    }
Line 474... Line 486...
474
 
486
 
475
	  p += namelen;
487
	  p += namelen;
476
	  while (section_len > 0)
488
	  while (section_len > 0 && p < p_end)
477
	    {
489
	    {
478
	      int tag;
490
	      unsigned int tag;
479
	      unsigned int n;
491
	      unsigned int n;
480
	      unsigned int val;
492
	      unsigned int val;
481
	      bfd_vma subsection_len;
493
	      bfd_vma subsection_len;
Line 482... Line 494...
482
	      bfd_byte *end;
494
	      bfd_byte *end;
483
 
495
 
-
 
496
	      tag = safe_read_leb128 (abfd, p, &n, FALSE, p_end);
484
	      tag = read_unsigned_leb128 (abfd, p, &n);
497
	      p += n;
-
 
498
	      if (p < p_end - 4)
-
 
499
	      subsection_len = bfd_get_32 (abfd, p);
485
	      p += n;
500
	      else
-
 
501
		subsection_len = 0;
-
 
502
	      p += 4;
486
	      subsection_len = bfd_get_32 (abfd, p);
503
	      if (subsection_len == 0)
487
	      p += 4;
504
		break;
488
	      if (subsection_len > section_len)
505
	      if (subsection_len > section_len)
489
		subsection_len = section_len;
506
		subsection_len = section_len;
490
	      section_len -= subsection_len;
507
	      section_len -= subsection_len;
-
 
508
	      subsection_len -= n + 4;
-
 
509
	      end = p + subsection_len;
-
 
510
	      /* PR 17512: file: 0e8c0c90.  */
491
	      subsection_len -= n + 4;
511
	      if (end > p_end)
492
	      end = p + subsection_len;
512
		end = p_end;
493
	      switch (tag)
513
	      switch (tag)
494
		{
514
		{
495
		case Tag_File:
515
		case Tag_File:
496
		  while (p < end)
516
		  while (p < end)
Line 497... Line 517...
497
		    {
517
		    {
498
		      int type;
518
		      int type;
499
 
519
 
500
		      tag = read_unsigned_leb128 (abfd, p, &n);
520
		      tag = safe_read_leb128 (abfd, p, &n, FALSE, end);
501
		      p += n;
521
		      p += n;
502
		      type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
522
		      type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
503
		      switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
523
		      switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
504
			{
524
			{
505
			case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
525
			case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
506
			  val = read_unsigned_leb128 (abfd, p, &n);
526
			  val = safe_read_leb128 (abfd, p, &n, FALSE, end);
507
			  p += n;
527
			  p += n;
508
			  bfd_elf_add_obj_attr_int_string (abfd, vendor, tag,
528
			  bfd_elf_add_obj_attr_int_string (abfd, vendor, tag,
Line 513... Line 533...
513
			  bfd_elf_add_obj_attr_string (abfd, vendor, tag,
533
			  bfd_elf_add_obj_attr_string (abfd, vendor, tag,
514
						       (char *)p);
534
						       (char *) p);
515
			  p += strlen ((char *)p) + 1;
535
			  p += strlen ((char *)p) + 1;
516
			  break;
536
			  break;
517
			case ATTR_TYPE_FLAG_INT_VAL:
537
			case ATTR_TYPE_FLAG_INT_VAL:
518
			  val = read_unsigned_leb128 (abfd, p, &n);
538
			  val = safe_read_leb128 (abfd, p, &n, FALSE, end);
519
			  p += n;
539
			  p += n;
520
			  bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
540
			  bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
521
			  break;
541
			  break;
522
			default:
542
			default:
523
			  abort ();
543
			  abort ();
Line 645... Line 665...
645
  out_list = *out_listp;
665
  out_list = *out_listp;
Line 646... Line 666...
646
 
666
 
647
  for (; in_list || out_list; )
667
  for (; in_list || out_list; )
648
    {
668
    {
649
      bfd *err_bfd = NULL;
669
      bfd *err_bfd = NULL;
Line 650... Line 670...
650
      int err_tag = 0;
670
      unsigned int err_tag = 0;
651
 
671
 
652
      /* The tags for each list are in numerical order.  */
672
      /* The tags for each list are in numerical order.  */
653
      /* If the tags are equal, then merge.  */
673
      /* If the tags are equal, then merge.  */