User account creation filtered due to spam.

View | Details | Raw Unified | Return to bug 48108 | Differences between
and this patch

Collapse All | Expand All

(-)include/simple-object.h (-12 / +13 lines)
Lines 45-56 typedef struct simple_object_read_struct simple_ob Link Here
45
   descriptor, and OFFSET, an offset within the file.  The offset is
45
   descriptor, and OFFSET, an offset within the file.  The offset is
46
   for use with archives, and should be 0 for an ordinary object file.
46
   for use with archives, and should be 0 for an ordinary object file.
47
   The descriptor must remain open until done with the returned
47
   The descriptor must remain open until done with the returned
48
   simple_object_read.  SEGMENT_NAME is used on Mach-O and is required
48
   simple_object_read.  SEGMENT_NAME is used to provide a GNU extension
49
   on that platform: it means to only look at sections within the
49
   to Mach-O.  When provided, only sections within that segment will be
50
   segment with that name.  It is ignored for other object file
50
   considered and, additionally, they will be processed according to a GNU
51
   formats.  On error, this function returns NULL, and sets *ERRMSG to
51
   sub-sectioning extension to Mach-O.  SEGMENT_NAME is ignored for other
52
   an error string and sets *ERR to an errno value or 0 if there is no
52
   object file formats.  On error, this function returns NULL, and sets
53
   relevant errno.  */
53
   *ERRMSG to an error string and sets *ERR to an errno value or 0 if there
54
   is no relevant errno.  */
54
55
55
extern simple_object_read *
56
extern simple_object_read *
56
simple_object_start_read (int descriptor, off_t offset,
57
simple_object_start_read (int descriptor, off_t offset,
Lines 139-150 typedef struct simple_object_write_struct simple_o Link Here
139
/* Start creating a new object file which is like ATTRS.  You must
140
/* Start creating a new object file which is like ATTRS.  You must
140
   fetch attribute information from an existing object file before you
141
   fetch attribute information from an existing object file before you
141
   can create a new one.  There is currently no support for creating
142
   can create a new one.  There is currently no support for creating
142
   an object file de novo.  The segment name is only used on Mach-O,
143
   an object file de novo.  SEGMENT_NAME is only used on Mach-O and, if
143
   where it is required.  It means that all sections are created
144
   set, it will cause all sections supplied to be stored according to a
144
   within that segment.  It is ignored for other object file formats.
145
   GNU sub-sectioning extension to the format.  It is ignored for other
145
   On error this function returns NULL, sets *ERRMSG to an error
146
   object file formats.  On error this function returns NULL, sets *ERRMSG
146
   message, and sets *ERR to an errno value or 0 if there isn't
147
   to an error message, and sets *ERR to an errno value or 0 if there
147
   one.  */
148
   isn't one.  */
148
149
149
extern simple_object_write *
150
extern simple_object_write *
150
simple_object_start_write (simple_object_attributes *attrs,
151
simple_object_start_write (simple_object_attributes *attrs,
(-)libiberty/simple-object-mach-o.c (-132 / +349 lines)
Lines 170-178 struct mach_o_section_64 Link Here
170
170
171
#define MACH_O_NAME_LEN (16)
171
#define MACH_O_NAME_LEN (16)
172
172
173
/* A GNU specific extension for long section names.  */
173
/* A GNU-specific extension to wrap multiple subsections using three 
174
   mach-o sections within a given segment.  The section '__subsect_sects'
175
   is subdivided according to the index '__subsect_index' and each sub
176
   sect is named according to the names supplied in '__subsect_names'.  */
174
177
175
#define GNU_SECTION_NAMES "__section_names"
178
#define GNU_SECTION_SECTS "__subsect_sects"
179
#define GNU_SECTION_INDEX "__subsect_index"
180
#define GNU_SECTION_NAMES "__subsect_names"
176
181
177
/* Private data for an simple_object_read.  */
182
/* Private data for an simple_object_read.  */
178
183
Lines 214-221 struct simple_object_mach_o_attributes Link Here
214
  unsigned int reserved;
219
  unsigned int reserved;
215
};
220
};
216
221
217
/* See if we have a Mach-O file.  */
222
/* See if we have a Mach-O MH_OBJECT file:
218
223
224
   A standard MH_OBJECT (from as) will have three load commands:
225
   0 - LC_SEGMENT/LC_SEGMENT64
226
   1 - LC_SYMTAB
227
   2 - LC_DYSYMTAB
228
   
229
   The LC_SEGMENT/LC_SEGMENT64 will introduce a single anonymous segment
230
   containing all the sections.
231
   
232
   Files written by simple-object will have only the segment command
233
   (no symbol tables).  */
234
219
static void *
235
static void *
220
simple_object_mach_o_match (
236
simple_object_mach_o_match (
221
    unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
237
    unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
Lines 258-275 simple_object_mach_o_match ( Link Here
258
    }
274
    }
259
#endif
275
#endif
260
276
261
  /* We require the user to provide a segment name.  This is
277
  /* Although a standard MH_OBJECT has a single anonymous segment, we allow
262
     unfortunate but I don't see any good choices here.  */
278
     a segment name to be specified - but don't act on it at this stage.  */
263
279
  if (segment_name && strlen (segment_name) > MACH_O_NAME_LEN)
264
  if (segment_name == NULL)
265
    {
280
    {
266
      *errmsg = "Mach-O file found but no segment name specified";
267
      *err = 0;
268
      return NULL;
269
    }
270
271
  if (strlen (segment_name) > MACH_O_NAME_LEN)
272
    {
273
      *errmsg = "Mach-O segment name too long";
281
      *errmsg = "Mach-O segment name too long";
274
      *err = 0;
282
      *err = 0;
275
      return NULL;
283
      return NULL;
Lines 294-306 simple_object_mach_o_match ( Link Here
294
  filetype = (*fetch_32) (b + offsetof (struct mach_o_header_32, filetype));
302
  filetype = (*fetch_32) (b + offsetof (struct mach_o_header_32, filetype));
295
  if (filetype != MACH_O_MH_OBJECT)
303
  if (filetype != MACH_O_MH_OBJECT)
296
    {
304
    {
297
      *errmsg = "Mach-O file is not object file";
305
      *errmsg = "Mach-O file is not an MH_OBJECT file";
298
      *err = 0;
306
      *err = 0;
299
      return NULL;
307
      return NULL;
300
    }
308
    }
301
309
302
  omr = XNEW (struct simple_object_mach_o_read);
310
  omr = XNEW (struct simple_object_mach_o_read);
303
  omr->segment_name = xstrdup (segment_name);
311
  if (segment_name)
312
    omr->segment_name = xstrdup (segment_name);
304
  omr->magic = magic;
313
  omr->magic = magic;
305
  omr->is_big_endian = is_big_endian;
314
  omr->is_big_endian = is_big_endian;
306
  omr->cputype = (*fetch_32) (b + offsetof (struct mach_o_header_32, cputype));
315
  omr->cputype = (*fetch_32) (b + offsetof (struct mach_o_header_32, cputype));
Lines 356-364 simple_object_mach_o_section_info (int is_big_endi Link Here
356
    }
365
    }
357
}
366
}
358
367
359
/* Handle a segment in a Mach-O file.  Return 1 if we should continue,
368
/* Handle a segment in a Mach-O Object file.
360
   0 if the caller should return.  */
361
369
370
   This will callback to the function pfn for each "section found" the meaning
371
   of which depends on a gnu extension to mach-o:
372
   
373
   When omr->segment_name is specified, we implement a wrapper scheme (which
374
   whilst it will, in principle, work with any segment name, is likely to be
375
   meaningless current for anything except __GNU_LTO).
376
   
377
   If we find mach-o sections (with the segment name as specified) which also
378
   contain: a 'sects' wrapper, an index, and a  name table, we expand this into
379
   as many sections as are specified in the index.  In this case, there will
380
   be a callback for each of these.
381
   
382
   When the omr->segment_name is not specified, then we would call-back for
383
   every mach-o section specified in the file.
384
385
   Return 1 if we should continue, 0 if the caller should return.  */
386
362
static int
387
static int
363
simple_object_mach_o_segment (simple_object_read *sobj, off_t offset,
388
simple_object_mach_o_segment (simple_object_read *sobj, off_t offset,
364
			      const unsigned char *segbuf,
389
			      const unsigned char *segbuf,
Lines 375-386 simple_object_mach_o_segment (simple_object_read * Link Here
375
  size_t sechdrsize;
400
  size_t sechdrsize;
376
  size_t segname_offset;
401
  size_t segname_offset;
377
  size_t sectname_offset;
402
  size_t sectname_offset;
378
  unsigned int nsects;
403
  int nsects;
379
  unsigned char *secdata;
404
  unsigned char *secdata = NULL;
380
  unsigned int i;
405
  int i;
381
  unsigned int strtab_index;
406
  int strtab_index, index_index, sections_index;
382
  char *strtab;
407
  char *strtab = NULL;
383
  size_t strtab_size;
408
  size_t strtab_size = 0;
409
  unsigned char *index = NULL;
410
  size_t index_size;
411
  unsigned int n_wrapped_sects = 0;
412
  size_t wrapper_sect_size = 0;
413
  off_t wrapper_sect_offset = (off_t)0;
414
  int wrapping = (omr->segment_name && strlen (omr->segment_name) > 0);
415
  strtab_index = index_index = sections_index = -1;
384
416
385
  fetch_32 = (omr->is_big_endian
417
  fetch_32 = (omr->is_big_endian
386
	      ? simple_object_fetch_big_32
418
	      ? simple_object_fetch_big_32
Lines 409-414 simple_object_mach_o_segment (simple_object_read * Link Here
409
					nsects));
441
					nsects));
410
    }
442
    }
411
443
444
  /* Fetch the section headers from the segment command.  */
412
  secdata = XNEWVEC (unsigned char, nsects * sechdrsize);
445
  secdata = XNEWVEC (unsigned char, nsects * sechdrsize);
413
  if (!simple_object_internal_read (sobj->descriptor, offset + seghdrsize,
446
  if (!simple_object_internal_read (sobj->descriptor, offset + seghdrsize,
414
				    secdata, nsects * sechdrsize, errmsg, err))
447
				    secdata, nsects * sechdrsize, errmsg, err))
Lines 417-503 simple_object_mach_o_segment (simple_object_read * Link Here
417
      return 0;
450
      return 0;
418
    }
451
    }
419
452
420
  /* Scan for a __section_names section.  This is in effect a GNU
453
  /* If the user has set a segment name to be processed for GNU sub-sections
421
     extension that permits section names longer than 16 chars.  */
454
     then scan for the three relevant sections.  */
422
455
  if (wrapping)
423
  for (i = 0; i < nsects; ++i)
424
    {
456
    {
425
      size_t nameoff;
457
      off_t strtab_offset;
458
      off_t index_offset;
426
459
427
      nameoff = i * sechdrsize + segname_offset;
460
      for (i = 0; i < nsects; ++i)
428
      if (strcmp ((char *) secdata + nameoff, omr->segment_name) != 0)
461
	{
429
	continue;
462
	  size_t nameoff;
430
      nameoff = i * sechdrsize + sectname_offset;
431
      if (strcmp ((char *) secdata + nameoff, GNU_SECTION_NAMES) == 0)
432
	break;
433
    }
434
463
435
  strtab_index = i;
464
	nameoff = i * sechdrsize + segname_offset;
436
  if (strtab_index >= nsects)
465
	if (strcmp ((char *) secdata + nameoff, omr->segment_name) != 0)
437
    {
466
	  continue;
438
      strtab = NULL;
439
      strtab_size = 0;
440
    }
441
  else
442
    {
443
      off_t strtab_offset;
444
467
445
      simple_object_mach_o_section_info (omr->is_big_endian, is_32,
468
	nameoff = i * sechdrsize + sectname_offset;
446
					 secdata + strtab_index * sechdrsize,
469
	if (strcmp ((char *) secdata + nameoff, GNU_SECTION_NAMES) == 0)
447
					 &strtab_offset, &strtab_size);
470
	  strtab_index = i;
448
      strtab = XNEWVEC (char, strtab_size);
471
	else if (strcmp ((char *) secdata + nameoff, GNU_SECTION_INDEX) == 0)
449
      if (!simple_object_internal_read (sobj->descriptor,
472
	  index_index = i;
450
					sobj->offset + strtab_offset,
473
	else if (strcmp ((char *) secdata + nameoff, GNU_SECTION_SECTS) == 0)
451
					(unsigned char *) strtab, strtab_size,
474
	  sections_index = i;
475
      }
476
477
      /* If any of the special wrapper section components is present, then
478
	 they all should be.  */
479
      if (sections_index >= 0 || index_index >= 0 || strtab_index >= 0)
480
	{
481
	  if (sections_index < 0 || index_index < 0 || strtab_index < 0)
482
	    {
483
	      *errmsg = "GNU Mach-o section wrapper: required section missing";
484
	      *err = -1;
485
	      XDELETEVEC (secdata);
486
	      return 0;
487
	    }
488
489
	  /* Fetch the name table.  */
490
	  simple_object_mach_o_section_info (omr->is_big_endian, is_32,
491
					     secdata + strtab_index * sechdrsize,
492
					     &strtab_offset, &strtab_size);
493
	  strtab = XNEWVEC (char, strtab_size);
494
	  if (!simple_object_internal_read (sobj->descriptor,
495
					    sobj->offset + strtab_offset,
496
					    (unsigned char *) strtab, strtab_size,
497
					    errmsg, err))
498
	    {
499
	      XDELETEVEC (strtab);
500
	      XDELETEVEC (secdata);
501
	      return 0;
502
	    }
503
504
	  /* Fetch the index.  */
505
	  simple_object_mach_o_section_info (omr->is_big_endian, is_32,
506
					 secdata + index_index * sechdrsize,
507
					 &index_offset, &index_size);
508
	  index = XNEWVEC (unsigned char, index_size);
509
	  if (!simple_object_internal_read (sobj->descriptor,
510
					sobj->offset + index_offset,
511
					index, index_size,
452
					errmsg, err))
512
					errmsg, err))
453
	{
513
	    {
454
	  XDELETEVEC (strtab);
514
	      XDELETEVEC (index);
455
	  XDELETEVEC (secdata);
515
	      XDELETEVEC (strtab);
456
	  return 0;
516
	      XDELETEVEC (secdata);
517
	      return 0;
518
	   }
519
520
	  /* The index contains 4 uint32_t per sub-section:
521
	     sub-section offset/length, sub-section name/length.  
522
	     We fix this for both 32 and 64 bit mach-o for now, since
523
	     other fields limit the maximum size of an object to 4G.  */
524
	  n_wrapped_sects = index_size / 16;
525
526
	  /* Get the parameters for the wrapper too.  */
527
	  simple_object_mach_o_section_info (omr->is_big_endian, is_32,
528
				       secdata + sections_index * sechdrsize,
529
				       &wrapper_sect_offset, 
530
				       &wrapper_sect_size);
531
457
	}
532
	}
533
      else
534
	wrapping = 0; /* We thought we were, but no wrapped sections found.  */
458
    }
535
    }
459
536
460
  /* Process the sections.  */
537
  /* Process the sections.  */
461
462
  for (i = 0; i < nsects; ++i)
538
  for (i = 0; i < nsects; ++i)
463
    {
539
    {
464
      const unsigned char *sechdr;
540
      const unsigned char *sechdr;
465
      char namebuf[MACH_O_NAME_LEN + 1];
541
      char namebuf[MACH_O_NAME_LEN*2 + 2]; /* space for segment,section\0.  */
466
      char *name;
542
      char *name;
467
      off_t secoffset;
543
      off_t secoffset;
468
      size_t secsize;
544
      size_t secsize;
545
      int l;
469
546
470
      if (i == strtab_index)
471
	continue;
472
473
      sechdr = secdata + i * sechdrsize;
547
      sechdr = secdata + i * sechdrsize;
548
      /* Process sections associated with the wrapper.  */
549
      if (wrapping)
550
	{
551
	  if (i == strtab_index || i == index_index)
552
	    continue;
474
553
475
      if (strcmp ((char *) sechdr + segname_offset, omr->segment_name) != 0)
554
	  if (strcmp ((char *) sechdr + segname_offset, omr->segment_name) != 0)
476
	continue;
555
	    continue;
477
556
478
      memcpy (namebuf, sechdr + sectname_offset, MACH_O_NAME_LEN);
557
	  if (i == sections_index)
479
      namebuf[MACH_O_NAME_LEN] = '\0';
480
481
      name = &namebuf[0];
482
      if (strtab != NULL && name[0] == '_' && name[1] == '_')
483
	{
484
	  unsigned long stringoffset;
485
486
	  if (sscanf (name + 2, "%08lX", &stringoffset) == 1)
487
	    {
558
	    {
488
	      if (stringoffset >= strtab_size)
559
	      int j;
560
	      for (j = 0; j < n_wrapped_sects; ++j)
489
		{
561
		{
490
		  *errmsg = "section name offset out of range";
562
		  unsigned int subsect_offset, subsect_length, name_offset;
491
		  *err = 0;
563
		  subsect_offset = (*fetch_32) (index + 16 * j);
492
		  XDELETEVEC (strtab);
564
		  subsect_length = (*fetch_32) (index + 16 * j + 4);
493
		  XDELETEVEC (secdata);
565
		  name_offset = (*fetch_32) (index + 16 * j + 8);
494
		  return 0;
566
		  /* We don't need the name_length yet.  */
567
	  
568
		  secoffset = wrapper_sect_offset + subsect_offset;
569
		  secsize = subsect_length;
570
		  name = strtab + name_offset;
571
572
		  if (!(*pfn) (data, name, secoffset, secsize))
573
		    {
574
		      *errmsg = NULL;
575
		      *err = 0;
576
		      XDELETEVEC (index);
577
		      XDELETEVEC (strtab);
578
		      XDELETEVEC (secdata);
579
		      return 0;
580
		    }
495
		}
581
		}
496
582
	      continue;
497
	      name = strtab + stringoffset;
498
	    }
583
	    }
499
	}
584
	}
500
585
586
      /* Otherwise, make a name like __segment,__section as per the convention
587
         in mach-o asm.  */
588
      memset (namebuf, 0, MACH_O_NAME_LEN*2+2);
589
      memcpy (namebuf, (char *) sechdr + segname_offset, MACH_O_NAME_LEN);
590
      l = strlen (namebuf);
591
      namebuf[l] = ',';
592
      memcpy (namebuf, (char *) sechdr + sectname_offset, MACH_O_NAME_LEN);
593
501
      simple_object_mach_o_section_info (omr->is_big_endian, is_32, sechdr,
594
      simple_object_mach_o_section_info (omr->is_big_endian, is_32, sechdr,
502
					 &secoffset, &secsize);
595
					 &secoffset, &secsize);
503
596
Lines 505-516 simple_object_mach_o_segment (simple_object_read * Link Here
505
	{
598
	{
506
	  *errmsg = NULL;
599
	  *errmsg = NULL;
507
	  *err = 0;
600
	  *err = 0;
601
	  XDELETEVEC (index);
508
	  XDELETEVEC (strtab);
602
	  XDELETEVEC (strtab);
509
	  XDELETEVEC (secdata);
603
	  XDELETEVEC (secdata);
510
	  return 0;
604
	  return 0;
511
	}
605
	}
512
    }
606
    }
513
607
608
  XDELETEVEC (index);
514
  XDELETEVEC (strtab);
609
  XDELETEVEC (strtab);
515
  XDELETEVEC (secdata);
610
  XDELETEVEC (secdata);
516
611
Lines 724-732 static int Link Here
724
simple_object_mach_o_write_section_header (simple_object_write *sobj,
819
simple_object_mach_o_write_section_header (simple_object_write *sobj,
725
					   int descriptor,
820
					   int descriptor,
726
					   size_t sechdr_offset,
821
					   size_t sechdr_offset,
727
					   const char *name, size_t secaddr,
822
					   const char *name, const char *segn,
728
					   size_t secsize, size_t offset,
823
					   size_t secaddr, size_t secsize,
729
					   unsigned int align,
824
					   size_t offset, unsigned int align,
730
					   const char **errmsg, int *err)
825
					   const char **errmsg, int *err)
731
{
826
{
732
  struct simple_object_mach_o_attributes *attrs =
827
  struct simple_object_mach_o_attributes *attrs =
Lines 748-754 simple_object_mach_o_write_section_header (simple_ Link Here
748
      strncpy ((char *) hdr + offsetof (struct mach_o_section_32, sectname),
843
      strncpy ((char *) hdr + offsetof (struct mach_o_section_32, sectname),
749
	       name, MACH_O_NAME_LEN);
844
	       name, MACH_O_NAME_LEN);
750
      strncpy ((char *) hdr + offsetof (struct mach_o_section_32, segname),
845
      strncpy ((char *) hdr + offsetof (struct mach_o_section_32, segname),
751
	       sobj->segment_name, MACH_O_NAME_LEN);
846
	       segn, MACH_O_NAME_LEN);
752
      set_32 (hdr + offsetof (struct mach_o_section_32, addr), secaddr);
847
      set_32 (hdr + offsetof (struct mach_o_section_32, addr), secaddr);
753
      set_32 (hdr + offsetof (struct mach_o_section_32, size), secsize);
848
      set_32 (hdr + offsetof (struct mach_o_section_32, size), secsize);
754
      set_32 (hdr + offsetof (struct mach_o_section_32, offset), offset);
849
      set_32 (hdr + offsetof (struct mach_o_section_32, offset), offset);
Lines 773-779 simple_object_mach_o_write_section_header (simple_ Link Here
773
      strncpy ((char *) hdr + offsetof (struct mach_o_section_64, sectname),
868
      strncpy ((char *) hdr + offsetof (struct mach_o_section_64, sectname),
774
	       name, MACH_O_NAME_LEN);
869
	       name, MACH_O_NAME_LEN);
775
      strncpy ((char *) hdr + offsetof (struct mach_o_section_64, segname),
870
      strncpy ((char *) hdr + offsetof (struct mach_o_section_64, segname),
776
	       sobj->segment_name, MACH_O_NAME_LEN);
871
	       segn, MACH_O_NAME_LEN);
777
      set_64 (hdr + offsetof (struct mach_o_section_64, addr), secaddr);
872
      set_64 (hdr + offsetof (struct mach_o_section_64, addr), secaddr);
778
      set_64 (hdr + offsetof (struct mach_o_section_64, size), secsize);
873
      set_64 (hdr + offsetof (struct mach_o_section_64, size), secsize);
779
      set_32 (hdr + offsetof (struct mach_o_section_64, offset), offset);
874
      set_32 (hdr + offsetof (struct mach_o_section_64, offset), offset);
Lines 793-803 simple_object_mach_o_write_section_header (simple_ Link Here
793
				       sechdrsize, errmsg, err);
888
				       sechdrsize, errmsg, err);
794
}
889
}
795
890
796
/* Write out the single segment and the sections of a Mach-O file.  */
891
/* Write out the single (anonymous) segment containing the sections of a Mach-O
892
   Object file.
893
   
894
   As a GNU extension to mach-o, when the caller specifies a segment name in
895
   sobj->segment_name, all the sections passed will be output under a single
896
   mach-o section header.  The caller's sections are indexed within this 
897
   'wrapper' section by a table stored in a second mach-o section.  Finally,
898
   arbitrary length section names are permitted by the extension and these are
899
   stored in a table in a third mach-o section.
900
   
901
   Note that this is unlikely to make any sense for anything other than the 
902
   __GNU_LTO segment present.
903
   
904
   If the segment_name is not specified (or zero-length) we just write out the 
905
   sections as we find them.  */
797
906
798
static int
907
static int
799
simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor,
908
simple_object_mach_o_write_segment (simple_object_write *sobj, int descriptor,
800
				    size_t nsects, const char **errmsg,
909
				    size_t *nsects, const char **errmsg,
801
				    int *err)
910
				    int *err)
802
{
911
{
803
  struct simple_object_mach_o_attributes *attrs =
912
  struct simple_object_mach_o_attributes *attrs =
Lines 814-819 simple_object_mach_o_write_segment (simple_object_ Link Here
814
  simple_object_write_section *section;
923
  simple_object_write_section *section;
815
  unsigned char hdrbuf[sizeof (struct mach_o_segment_command_64)];
924
  unsigned char hdrbuf[sizeof (struct mach_o_segment_command_64)];
816
  unsigned char *hdr;
925
  unsigned char *hdr;
926
  int wrapping = (sobj->segment_name && strlen (sobj->segment_name) > 0);
927
  size_t nsects_in;
928
  uint32_t *index = NULL;
929
  char *snames = NULL;
930
  unsigned int sect;
817
931
818
  set_32 = (attrs->is_big_endian
932
  set_32 = (attrs->is_big_endian
819
	    ? simple_object_set_big_32
933
	    ? simple_object_set_big_32
Lines 834-852 simple_object_mach_o_write_segment (simple_object_ Link Here
834
      sechdrsize = sizeof (struct mach_o_section_64);
948
      sechdrsize = sizeof (struct mach_o_section_64);
835
    }
949
    }
836
950
951
  name_offset = 0;
952
  *nsects = nsects_in = 0;
953
  
954
  /* Count the number of sections we start with.  */
955
  for (section = sobj->sections; section != NULL;section = section->next)
956
    nsects_in++;
957
958
  if (wrapping)
959
    {
960
      /* We will only write 3 sections: wrapped data, index and names.  */
961
      *nsects = 3; 
962
      /* The index has four entries per wrapped section:
963
	   Section Offset, length,  Name offset, length.
964
	 Where the offsets are based at the start of the wrapper and name
965
	 sections respectively.
966
	 The values are stored as uint32 for both 32 and 64 bit mach-o
967
	 since the size of a mach-o MH_OBJECT cannot exceed 4G owing to 
968
	 other constraints.  */
969
      index = XNEWVEC (uint32_t, nsects_in * 4);
970
      /* We now need to figure out the size of the names section.  This just
971
	 stores the names as null-terminated c strings, packed without any
972
	 alignment padding.  */
973
      for (section = sobj->sections, sect = 0; section != NULL;
974
	   section = section->next, sect++)
975
	{
976
	  index[sect*4+2] = name_offset;
977
	  index[sect*4+3] = strlen (section->name) + 1;
978
	  name_offset += strlen (section->name) + 1;
979
	}
980
      snames = XNEWVEC (char, name_offset);
981
    }
982
  else
983
    *nsects = nsects_in;
984
837
  sechdr_offset = hdrsize + seghdrsize;
985
  sechdr_offset = hdrsize + seghdrsize;
838
  cmdsize = seghdrsize + nsects * sechdrsize;
986
  cmdsize = seghdrsize + *nsects * sechdrsize;
839
  offset = hdrsize + cmdsize;
987
  offset = hdrsize + cmdsize;
840
  name_offset = 0;
841
  secaddr = 0;
988
  secaddr = 0;
842
989
843
  for (section = sobj->sections; section != NULL; section = section->next)
990
  for (section = sobj->sections, sect = 0; section != NULL; 
991
       section = section->next, sect++)
844
    {
992
    {
845
      size_t mask;
993
      size_t mask;
846
      size_t new_offset;
994
      size_t new_offset;
847
      size_t secsize;
995
      size_t secsize;
848
      struct simple_object_write_section_buffer *buffer;
996
      struct simple_object_write_section_buffer *buffer;
849
      char namebuf[MACH_O_NAME_LEN + 1];
850
997
851
      mask = (1U << section->align) - 1;
998
      mask = (1U << section->align) - 1;
852
      new_offset = offset + mask;
999
      new_offset = offset + mask;
Lines 877-915 simple_object_mach_o_write_segment (simple_object_ Link Here
877
	  secsize += buffer->size;
1024
	  secsize += buffer->size;
878
	}
1025
	}
879
1026
880
      snprintf (namebuf, sizeof namebuf, "__%08X", name_offset);
1027
      if (wrapping)
1028
	{
1029
	  index[sect*4+0] = (uint32_t) offset;
1030
	  index[sect*4+1] = secsize;
1031
	  /* Stash the section name in our table.  */
1032
	  memcpy (snames + index[sect*4+2], section->name, index[sect*4+3]);
1033
	}
1034
      else
1035
	{
1036
	  char namebuf[MACH_O_NAME_LEN + 1];
1037
	  char segnbuf[MACH_O_NAME_LEN + 1];
1038
	  char *comma;
1039
	  /* Try to extract segment,section from the input name.  */
1040
	  memset (namebuf, 0, sizeof namebuf);
1041
	  memset (segnbuf, 0, sizeof segnbuf);
1042
	  comma = strchr (section->name, ',');
1043
	  if (comma)
1044
	    {
1045
	      int len = comma-section->name;
1046
	      len = len > MACH_O_NAME_LEN ? MACH_O_NAME_LEN : len;
1047
	      if (len)
1048
	        strncpy (namebuf, section->name, len);
1049
	      strncpy (segnbuf, comma+1, MACH_O_NAME_LEN);
1050
	    }
1051
	  else /* just try to copy the name, leave segment blank.  */
1052
	    strncpy (namebuf, section->name, MACH_O_NAME_LEN);
1053
1054
	  if (!simple_object_mach_o_write_section_header (sobj, descriptor,
1055
							  sechdr_offset, 
1056
							  namebuf, segnbuf,
1057
							  secaddr, secsize,
1058
							  offset, 
1059
							  section->align,
1060
							  errmsg, err))
1061
	    return 0;
1062
	  sechdr_offset += sechdrsize;
1063
	}
1064
1065
      offset += secsize;
1066
      secaddr += secsize;
1067
    }
1068
1069
  if (wrapping)
1070
    {
1071
      size_t secsize;
1072
      int i;
1073
      /* Write the section header for the wrapper.  */
1074
      /* Account for any initial aligment - which becomes the alignment for this
1075
	 created section.  */
1076
      secsize = (offset - index[0]); 
881
      if (!simple_object_mach_o_write_section_header (sobj, descriptor,
1077
      if (!simple_object_mach_o_write_section_header (sobj, descriptor,
882
						      sechdr_offset, namebuf,
1078
						      sechdr_offset, 
883
						      secaddr, secsize, offset,
1079
						      GNU_SECTION_SECTS,
884
						      section->align,
1080
						      sobj->segment_name,
1081
						      0 /*secaddr*/, 
1082
						      secsize, 
1083
						      index[0] /* initial offset*/,
1084
						      sobj->sections->align,
885
						      errmsg, err))
1085
						      errmsg, err))
886
	return 0;
1086
	return 0;
887
1087
1088
      /* Subtract the wrapper section start from the begining of each sub
1089
	 section.  */
1090
      for (i=1; i<nsects_in;i++)
1091
	index[4*i] -= index[0];
1092
      index[0] = 0;
1093
      
888
      sechdr_offset += sechdrsize;
1094
      sechdr_offset += sechdrsize;
889
      offset += secsize;
1095
      /* Write out the section names.  
890
      name_offset += strlen (section->name) + 1;
1096
	 ... the header ...
891
      secaddr += secsize;
1097
	 name_offset contains the length of the section.  It is not aligned.  */
892
    }
1098
	 
1099
      if (!simple_object_mach_o_write_section_header (sobj, descriptor,
1100
						      sechdr_offset,
1101
						      GNU_SECTION_NAMES,
1102
						      sobj->segment_name,
1103
						      0 /*secaddr*/, name_offset, 
1104
						      offset,
1105
						      0, errmsg, err))
1106
	return 0;
893
1107
894
  /* Write out the section names.  */
1108
      /* ... and the content.. */
1109
      if (!simple_object_internal_write (descriptor, offset,
1110
					 (const unsigned char *) snames,
1111
					 name_offset, errmsg, err))
1112
	return 0;
895
1113
896
  if (!simple_object_mach_o_write_section_header (sobj, descriptor,
1114
      sechdr_offset += sechdrsize;
897
						  sechdr_offset,
1115
      secaddr += name_offset;
898
						  GNU_SECTION_NAMES, secaddr,
1116
      offset += name_offset;
899
						  name_offset, offset, 0,
900
						  errmsg, err))
901
    return 0;
902
1117
903
  for (section = sobj->sections; section != NULL; section = section->next)
1118
      /* Now do the index, we'll align this to 4 bytes although the read code
904
    {
1119
	 will handle unaligned.  */
905
      size_t namelen;
1120
      offset += 3; offset &= ~0x03;
906
1121
      if (!simple_object_mach_o_write_section_header (sobj, descriptor,
907
      namelen = strlen (section->name) + 1;
1122
						      sechdr_offset,
1123
						      GNU_SECTION_INDEX,
1124
						      sobj->segment_name,
1125
						      0 /*secaddr*/, nsects_in*16, 
1126
						      offset,
1127
						      2, errmsg, err))
1128
	return 0;
1129
      
1130
      /* ... and the content.. */
908
      if (!simple_object_internal_write (descriptor, offset,
1131
      if (!simple_object_internal_write (descriptor, offset,
909
					 (const unsigned char *) section->name,
1132
					 (const unsigned char *) index,
910
					 namelen, errmsg, err))
1133
					 nsects_in*16, errmsg, err))
911
	return 0;
1134
	return 0;
912
      offset += namelen;
1135
1136
      XDELETEVEC (index);
1137
      XDELETEVEC (snames);
913
    }
1138
    }
914
1139
915
  /* Write out the segment header.  */
1140
  /* Write out the segment header.  */
Lines 923-931 simple_object_mach_o_write_segment (simple_object_ Link Here
923
	      MACH_O_LC_SEGMENT);
1148
	      MACH_O_LC_SEGMENT);
924
      set_32 (hdr + offsetof (struct mach_o_segment_command_32, cmdsize),
1149
      set_32 (hdr + offsetof (struct mach_o_segment_command_32, cmdsize),
925
	      cmdsize);
1150
	      cmdsize);
926
      strncpy (((char *) hdr
1151
     /* MH_OBJECTS have a single, anonymous, segment - so the segment name
927
		+ offsetof (struct mach_o_segment_command_32, segname)),
1152
	 is left empty.  */
928
	       sobj->segment_name, MACH_O_NAME_LEN);
929
      /* vmaddr left as zero.  */
1153
      /* vmaddr left as zero.  */
930
      /* vmsize left as zero.  */
1154
      /* vmsize left as zero.  */
931
      set_32 (hdr + offsetof (struct mach_o_segment_command_32, fileoff),
1155
      set_32 (hdr + offsetof (struct mach_o_segment_command_32, fileoff),
Lines 935-941 simple_object_mach_o_write_segment (simple_object_ Link Here
935
      /* maxprot left as zero.  */
1159
      /* maxprot left as zero.  */
936
      /* initprot left as zero.  */
1160
      /* initprot left as zero.  */
937
      set_32 (hdr + offsetof (struct mach_o_segment_command_32, nsects),
1161
      set_32 (hdr + offsetof (struct mach_o_segment_command_32, nsects),
938
	      nsects);
1162
	      *nsects);
939
      /* flags left as zero.  */
1163
      /* flags left as zero.  */
940
    }
1164
    }
941
  else
1165
  else
Lines 951-959 simple_object_mach_o_write_segment (simple_object_ Link Here
951
	      MACH_O_LC_SEGMENT);
1175
	      MACH_O_LC_SEGMENT);
952
      set_32 (hdr + offsetof (struct mach_o_segment_command_64, cmdsize),
1176
      set_32 (hdr + offsetof (struct mach_o_segment_command_64, cmdsize),
953
	      cmdsize);
1177
	      cmdsize);
954
      strncpy (((char *) hdr
1178
      /* MH_OBJECTS have a single, anonymous, segment - so the segment name
955
		+ offsetof (struct mach_o_segment_command_64, segname)),
1179
	 is left empty.  */
956
	       sobj->segment_name, MACH_O_NAME_LEN);
957
      /* vmaddr left as zero.  */
1180
      /* vmaddr left as zero.  */
958
      /* vmsize left as zero.  */
1181
      /* vmsize left as zero.  */
959
      set_64 (hdr + offsetof (struct mach_o_segment_command_64, fileoff),
1182
      set_64 (hdr + offsetof (struct mach_o_segment_command_64, fileoff),
Lines 963-969 simple_object_mach_o_write_segment (simple_object_ Link Here
963
      /* maxprot left as zero.  */
1186
      /* maxprot left as zero.  */
964
      /* initprot left as zero.  */
1187
      /* initprot left as zero.  */
965
      set_32 (hdr + offsetof (struct mach_o_segment_command_64, nsects),
1188
      set_32 (hdr + offsetof (struct mach_o_segment_command_64, nsects),
966
	      nsects);
1189
	      *nsects);
967
      /* flags left as zero.  */
1190
      /* flags left as zero.  */
968
#endif
1191
#endif
969
    }
1192
    }
Lines 978-1000 static const char * Link Here
978
simple_object_mach_o_write_to_file (simple_object_write *sobj, int descriptor,
1201
simple_object_mach_o_write_to_file (simple_object_write *sobj, int descriptor,
979
				    int *err)
1202
				    int *err)
980
{
1203
{
981
  size_t nsects;
1204
  size_t nsects = 0;
982
  simple_object_write_section *section;
983
  const char *errmsg;
1205
  const char *errmsg;
984
1206
985
  /* Start at 1 for symbol_names section.  */
1207
  if (!simple_object_mach_o_write_segment (sobj, descriptor, &nsects,
986
  nsects = 1;
1208
					   &errmsg, err))
987
  for (section = sobj->sections; section != NULL; section = section->next)
1209
    return errmsg;
988
    ++nsects;
989
1210
990
  if (!simple_object_mach_o_write_header (sobj, descriptor, nsects,
1211
  if (!simple_object_mach_o_write_header (sobj, descriptor, nsects,
991
					  &errmsg, err))
1212
					  &errmsg, err))
992
    return errmsg;
1213
    return errmsg;
993
1214
994
  if (!simple_object_mach_o_write_segment (sobj, descriptor, nsects,
995
					   &errmsg, err))
996
    return errmsg;
997
998
  return NULL;
1215
  return NULL;
999
}
1216
}
1000
1217
(-)gcc/config/darwin.c (-52 / +114 lines)
Lines 1753-1772 darwin_label_is_anonymous_local_objc_name (const c Link Here
1753
  return (!strncmp ((const char *)p, "_OBJC_", 6));
1753
  return (!strncmp ((const char *)p, "_OBJC_", 6));
1754
}
1754
}
1755
1755
1756
/* LTO support for Mach-O.  */
1756
/* LTO support for Mach-O.
1757
1757
1758
/* Section names for LTO sections.  */
1758
   This version uses three mach-o sections to encapsulate the (unlimited
1759
static unsigned int lto_section_names_offset = 0;
1759
   number of) lto sections.
1760
   
1761
   __GNU_LTO, __lto_sections  contains the concatented GNU LTO section data.
1762
   __GNU_LTO, __section_names contains the GNU LTO section names.
1763
   __GNU_LTO, __section_index contains an array of values that index these.
1760
1764
1761
/* This is the obstack which we use to allocate the many strings.  */
1765
   Indexed thus:
1762
static struct obstack lto_section_names_obstack;
1766
     <section offset from the start of __GNU_LTO, __lto_sections>,
1767
     <section length>
1768
     <name offset from the start of __GNU_LTO, __section_names,
1769
     <name length>.
1763
1770
1764
/* Segment name for LTO sections.  */
1771
   At present, for both m32 and m64 mach-o files each of these fields is
1772
   represented  by a uint32_t.  This is because, AFAICT, a mach-o object
1773
   cannot exceed 4Gb because the section_64 offset field (see below) is 32bits.
1774
   
1775
    uint32_t offset;
1776
   "offset  An integer specifying the offset to this section in the file."  */
1777
1778
/* Count lto section numbers. */
1779
static unsigned int lto_section_num = 0;
1780
1781
/* A vector of information about LTO sections, at present, we only have
1782
   the name.  TODO: see if we can get the data length somehow.  */
1783
typedef struct GTY(()) darwin_lto_section_e {
1784
  const char *sectname;
1785
} darwin_lto_section_e ;
1786
DEF_VEC_O(darwin_lto_section_e);
1787
DEF_VEC_ALLOC_O(darwin_lto_section_e, gc);
1788
1789
static GTY (()) VEC (darwin_lto_section_e, gc) * lto_section_names;
1790
1791
/* Segment for LTO (sub-)sections.  */
1765
#define LTO_SEGMENT_NAME "__GNU_LTO"
1792
#define LTO_SEGMENT_NAME "__GNU_LTO"
1766
1793
1767
/* Section name for LTO section names section.  */
1794
/* Section for LTO sub-sections names.  */
1768
#define LTO_NAMES_SECTION "__section_names"
1795
#define LTO_NAMES_SECTION "__subsect_names"
1769
1796
1797
/* Section for LTO sub-sections index.  */
1798
#define LTO_INDEX_SECTION "__subsect_index"
1799
1800
/* Section for LTO sub-sections.  */
1801
#define LTO_SECTS_SECTION "__subsect_sects"
1802
1770
/* File to temporarily store LTO data.  This is appended to asm_out_file
1803
/* File to temporarily store LTO data.  This is appended to asm_out_file
1771
   in darwin_end_file.  */
1804
   in darwin_end_file.  */
1772
static FILE *lto_asm_out_file, *saved_asm_out_file;
1805
static FILE *lto_asm_out_file, *saved_asm_out_file;
Lines 1808-1844 darwin_asm_named_section (const char *name, Link Here
1808
			  unsigned int flags,
1841
			  unsigned int flags,
1809
			  tree decl ATTRIBUTE_UNUSED)
1842
			  tree decl ATTRIBUTE_UNUSED)
1810
{
1843
{
1811
  /* LTO sections go in a special segment __GNU_LTO.  We want to replace the
1844
  /* LTO sections go in a special section that encapsulates the (unlimited)
1812
     section name with something we can use to represent arbitrary-length
1845
     number of GNU LTO sections within a single mach-o one.  */
1813
     names (section names in Mach-O are at most 16 characters long).  */
1814
  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
1846
  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
1815
	       strlen (LTO_SECTION_NAME_PREFIX)) == 0)
1847
	       strlen (LTO_SECTION_NAME_PREFIX)) == 0)
1816
    {
1848
    {
1849
      darwin_lto_section_e e;
1817
      /* We expect certain flags to be set...  */
1850
      /* We expect certain flags to be set...  */
1818
      gcc_assert ((flags & (SECTION_DEBUG | SECTION_NAMED))
1851
      gcc_assert ((flags & (SECTION_DEBUG | SECTION_NAMED))
1819
		  == (SECTION_DEBUG | SECTION_NAMED));
1852
		  == (SECTION_DEBUG | SECTION_NAMED));
1820
1853
1821
      /* Add the section name to the things to output when we end the
1854
      /* Switch to our combined section.  */
1822
	 current assembler output file.
1855
      fprintf (asm_out_file, "\t.section %s,%s,regular,debug\n",
1823
	 This is all not very efficient, but that doesn't matter -- this
1856
	       LTO_SEGMENT_NAME, LTO_SECTS_SECTION);
1824
	 shouldn't be a hot path in the compiler...  */
1857
      /* Output a label for the start of this sub-section.  */
1825
      obstack_1grow (&lto_section_names_obstack, '\t');
1858
      fprintf (asm_out_file, "L_GNU_LTO%d:\t;# %s\n",
1826
      obstack_grow (&lto_section_names_obstack, ".ascii ", 7);
1859
	       lto_section_num, name);
1827
      obstack_1grow (&lto_section_names_obstack, '"');
1860
      /* We have to jump through hoops to get the values of the intra-section
1828
      obstack_grow (&lto_section_names_obstack, name, strlen (name));
1861
         offsets... */
1829
      obstack_grow (&lto_section_names_obstack, "\\0\"\n", 4);
1862
      fprintf (asm_out_file, "\t.set L$gnu$lto$offs%d,L_GNU_LTO%d-L_GNU_LTO0\n",
1830
1863
	       lto_section_num, lto_section_num);
1831
      /* Output the dummy section name.  */
1864
      fprintf (asm_out_file, "\t.set L$gnu$lto$size%d,L_GNU_LTO%d-L_GNU_LTO%d\n",
1832
      fprintf (asm_out_file, "\t# %s\n", name);
1865
	       lto_section_num, lto_section_num+1, lto_section_num);
1833
      fprintf (asm_out_file, "\t.section %s,__%08X,regular,debug\n",
1866
      lto_section_num++;
1834
	       LTO_SEGMENT_NAME, lto_section_names_offset);
1867
      e.sectname = xstrdup (name);
1835
1868
      /* Keep the names, we'll need to make a table later.
1836
      /* Update the offset for the next section name.  Make sure we stay
1869
         TODO: check that we do not revisit sections, that would break 
1837
	 within reasonable length.  */  
1870
         the assumption of how this is done. */
1838
      lto_section_names_offset += strlen (name) + 1;
1871
      if (lto_section_names == NULL)
1839
      gcc_assert (lto_section_names_offset > 0
1872
        lto_section_names = VEC_alloc (darwin_lto_section_e, gc, 16);
1840
		  && lto_section_names_offset < ((unsigned) 1 << 31));
1873
      VEC_safe_push (darwin_lto_section_e, gc, lto_section_names, &e);
1841
    }
1874
   }
1842
  else if (strncmp (name, "__DWARF,", 8) == 0)
1875
  else if (strncmp (name, "__DWARF,", 8) == 0)
1843
    darwin_asm_dwarf_section (name, flags, decl);
1876
    darwin_asm_dwarf_section (name, flags, decl);
1844
  else
1877
  else
Lines 2711-2726 darwin_asm_output_dwarf_offset (FILE *file, int si Link Here
2711
  darwin_asm_output_dwarf_delta (file, size, lab, sname);
2744
  darwin_asm_output_dwarf_delta (file, size, lab, sname);
2712
}
2745
}
2713
2746
2714
/* Called from the within the TARGET_ASM_FILE_START for each target. 
2747
/* Called from the within the TARGET_ASM_FILE_START for each target.  */
2715
  Initialize the stuff we need for LTO long section names support.  */
2716
2748
2717
void
2749
void
2718
darwin_file_start (void)
2750
darwin_file_start (void)
2719
{
2751
{
2720
  /* We fill this obstack with the complete section text for the lto section
2752
  /* Nothing to do.  */
2721
     names to write in darwin_file_end.  */
2722
  obstack_init (&lto_section_names_obstack);
2723
  lto_section_names_offset = 0;
2724
}
2753
}
2725
2754
2726
/* Called for the TARGET_ASM_FILE_END hook.
2755
/* Called for the TARGET_ASM_FILE_END hook.
Lines 2731-2738 darwin_file_start (void) Link Here
2731
void
2760
void
2732
darwin_file_end (void)
2761
darwin_file_end (void)
2733
{
2762
{
2734
  const char *lto_section_names;
2735
2736
  machopic_finish (asm_out_file);
2763
  machopic_finish (asm_out_file);
2737
  if (strcmp (lang_hooks.name, "GNU C++") == 0)
2764
  if (strcmp (lang_hooks.name, "GNU C++") == 0)
2738
    {
2765
    {
Lines 2762-2767 darwin_file_end (void) Link Here
2762
	  lto_asm_txt = buf = (char *) xmalloc (n + 1);
2789
	  lto_asm_txt = buf = (char *) xmalloc (n + 1);
2763
	  while (fgets (lto_asm_txt, n, lto_asm_out_file))
2790
	  while (fgets (lto_asm_txt, n, lto_asm_out_file))
2764
	    fputs (lto_asm_txt, asm_out_file);
2791
	    fputs (lto_asm_txt, asm_out_file);
2792
	  /* Put a termination label.  */
2793
	  fprintf (asm_out_file, "\t.section %s,%s,regular,debug\n",
2794
		   LTO_SEGMENT_NAME, LTO_SECTS_SECTION);
2795
	  fprintf (asm_out_file, "L_GNU_LTO%d:\t;# end of lto\n",
2796
		   lto_section_num);
2797
	  /* Make sure our termination label stays in this section.  */
2798
	  fputs ("\t.space\t1\n", asm_out_file);
2765
	}
2799
	}
2766
2800
2767
      /* Remove the temporary file.  */
2801
      /* Remove the temporary file.  */
Lines 2770-2790 darwin_file_end (void) Link Here
2770
      free (lto_asm_out_name);
2804
      free (lto_asm_out_name);
2771
    }
2805
    }
2772
2806
2773
  /* Finish the LTO section names obstack.  Don't output anything if
2807
  /* Output the names and indices.  */
2774
     there are no recorded section names.  */
2808
  if (lto_section_names && VEC_length (darwin_lto_section_e, lto_section_names))
2775
  obstack_1grow (&lto_section_names_obstack, '\0');
2776
  lto_section_names = XOBFINISH (&lto_section_names_obstack, const char *);
2777
  if (strlen (lto_section_names) > 0)
2778
    {
2809
    {
2779
      fprintf (asm_out_file,
2810
      int count;
2780
	       "\t.section %s,%s,regular,debug\n",
2811
      darwin_lto_section_e *ref;
2812
      /* For now, we'll make the offsets 4 bytes and unaligned - we'll fix
2813
         the latter up ourselves. */
2814
      const char *op = integer_asm_op (4,0); 
2815
2816
      /* Emit the names. */
2817
      fprintf (asm_out_file, "\t.section %s,%s,regular,debug\n",
2781
	       LTO_SEGMENT_NAME, LTO_NAMES_SECTION);
2818
	       LTO_SEGMENT_NAME, LTO_NAMES_SECTION);
2782
      fprintf (asm_out_file,
2819
      FOR_EACH_VEC_ELT (darwin_lto_section_e, lto_section_names, count, ref)
2783
	       "\t# Section names in %s are offsets into this table\n",
2820
	{
2784
	       LTO_SEGMENT_NAME);
2821
	  fprintf (asm_out_file, "L_GNU_LTO_NAME%d:\n", count);
2785
      fprintf (asm_out_file, "%s\n", lto_section_names);
2822
         /* We have to jump through hoops to get the values of the intra-section
2823
            offsets... */
2824
	  fprintf (asm_out_file, 
2825
		   "\t.set L$gnu$lto$noff%d,L_GNU_LTO_NAME%d-L_GNU_LTO_NAME0\n",
2826
		   count, count);
2827
	  fprintf (asm_out_file,
2828
		   "\t.set L$gnu$lto$nsiz%d,L_GNU_LTO_NAME%d-L_GNU_LTO_NAME%d\n",
2829
		   count, count+1, count);
2830
	  fprintf (asm_out_file, "\t.asciz\t\"%s\"\n", ref->sectname);
2831
	}
2832
      fprintf (asm_out_file, "L_GNU_LTO_NAME%d:\t;# end\n", lto_section_num);
2833
      /* make sure our termination label stays in this section.  */
2834
      fputs ("\t.space\t1\n", asm_out_file);
2835
2836
      /* Emit the Index. */
2837
      fprintf (asm_out_file, "\t.section %s,%s,regular,debug\n",
2838
	       LTO_SEGMENT_NAME, LTO_INDEX_SECTION);
2839
      fputs ("\t.align\t2\n", asm_out_file);
2840
      fputs ("# Section offset, Section length, Name offset, Name length\n", asm_out_file);
2841
      FOR_EACH_VEC_ELT (darwin_lto_section_e, lto_section_names, count, ref)
2842
	{
2843
	  fprintf (asm_out_file, "%s L$gnu$lto$offs%d\t;# %s\n",
2844
		   op, count, ref->sectname);
2845
	  fprintf (asm_out_file, "%s L$gnu$lto$size%d\n", op, count);
2846
	  fprintf (asm_out_file, "%s L$gnu$lto$noff%d\n", op, count);
2847
	  fprintf (asm_out_file, "%s L$gnu$lto$nsiz%d\n", op, count);
2848
	}
2786
    }
2849
    }
2787
  obstack_free (&lto_section_names_obstack, NULL);
2788
2850
2789
  /* If we have section anchors, then we must prevent the linker from
2851
  /* If we have section anchors, then we must prevent the linker from
2790
     re-arranging data.  */
2852
     re-arranging data.  */

Return to bug 48108