This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/binutils.git] / ld / ldwrite.c
1 /* ldwrite.c -- write out the linked file
2    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002
3    Free Software Foundation, Inc.
4    Written by Steve Chamberlain sac@cygnus.com
5
6 This file is part of GLD, the Gnu Linker.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "bfdlink.h"
25 #include "libiberty.h"
26
27 #include "ld.h"
28 #include "ldexp.h"
29 #include "ldlang.h"
30 #include "ldwrite.h"
31 #include "ldmisc.h"
32 #include "ldgram.h"
33 #include "ldmain.h"
34
35 static void build_link_order PARAMS ((lang_statement_union_type *));
36 static asection *clone_section PARAMS ((bfd *, asection *, const char *, int *));
37 static void split_sections PARAMS ((bfd *, struct bfd_link_info *));
38
39 /* Build link_order structures for the BFD linker.  */
40
41 static void
42 build_link_order (statement)
43      lang_statement_union_type *statement;
44 {
45   switch (statement->header.type)
46     {
47     case lang_data_statement_enum:
48       {
49         asection *output_section;
50         struct bfd_link_order *link_order;
51         bfd_vma value;
52         boolean big_endian = false;
53
54         output_section = statement->data_statement.output_section;
55         ASSERT (output_section->owner == output_bfd);
56
57         link_order = bfd_new_link_order (output_bfd, output_section);
58         if (link_order == NULL)
59           einfo (_("%P%F: bfd_new_link_order failed\n"));
60
61         link_order->type = bfd_data_link_order;
62         link_order->offset = statement->data_statement.output_vma;
63         link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
64
65         value = statement->data_statement.value;
66
67         /* If the endianness of the output BFD is not known, then we
68            base the endianness of the data on the first input file.
69            By convention, the bfd_put routines for an unknown
70            endianness are big endian, so we must swap here if the
71            input file is little endian.  */
72         if (bfd_big_endian (output_bfd))
73           big_endian = true;
74         else if (bfd_little_endian (output_bfd))
75           big_endian = false;
76         else
77           {
78             boolean swap;
79
80             swap = false;
81             if (command_line.endian == ENDIAN_BIG)
82               big_endian = true;
83             else if (command_line.endian == ENDIAN_LITTLE)
84               {
85                 big_endian = false;
86                 swap = true;
87               }
88             else if (command_line.endian == ENDIAN_UNSET)
89               {
90                 big_endian = true;
91                 {
92                   LANG_FOR_EACH_INPUT_STATEMENT (s)
93                     {
94                       if (s->the_bfd != NULL)
95                         {
96                           if (bfd_little_endian (s->the_bfd))
97                             {
98                               big_endian = false;
99                               swap = true;
100                             }
101                           break;
102                         }
103                     }
104                 }
105               }
106
107             if (swap)
108               {
109                 bfd_byte buffer[8];
110
111                 switch (statement->data_statement.type)
112                   {
113                   case QUAD:
114                   case SQUAD:
115                     if (sizeof (bfd_vma) >= QUAD_SIZE)
116                       {
117                         bfd_putl64 (value, buffer);
118                         value = bfd_getb64 (buffer);
119                         break;
120                       }
121                     /* Fall through.  */
122                   case LONG:
123                     bfd_putl32 (value, buffer);
124                     value = bfd_getb32 (buffer);
125                     break;
126                   case SHORT:
127                     bfd_putl16 (value, buffer);
128                     value = bfd_getb16 (buffer);
129                     break;
130                   case BYTE:
131                     break;
132                   default:
133                     abort ();
134                   }
135               }
136           }
137
138         ASSERT (output_section->owner == output_bfd);
139         switch (statement->data_statement.type)
140           {
141           case QUAD:
142           case SQUAD:
143             if (sizeof (bfd_vma) >= QUAD_SIZE)
144               bfd_put_64 (output_bfd, value, link_order->u.data.contents);
145             else
146               {
147                 bfd_vma high;
148
149                 if (statement->data_statement.type == QUAD)
150                   high = 0;
151                 else if ((value & 0x80000000) == 0)
152                   high = 0;
153                 else
154                   high = (bfd_vma) -1;
155                 bfd_put_32 (output_bfd, high,
156                             (link_order->u.data.contents
157                              + (big_endian ? 0 : 4)));
158                 bfd_put_32 (output_bfd, value,
159                             (link_order->u.data.contents
160                              + (big_endian ? 4 : 0)));
161               }
162             link_order->size = QUAD_SIZE;
163             break;
164           case LONG:
165             bfd_put_32 (output_bfd, value, link_order->u.data.contents);
166             link_order->size = LONG_SIZE;
167             break;
168           case SHORT:
169             bfd_put_16 (output_bfd, value, link_order->u.data.contents);
170             link_order->size = SHORT_SIZE;
171             break;
172           case BYTE:
173             bfd_put_8 (output_bfd, value, link_order->u.data.contents);
174             link_order->size = BYTE_SIZE;
175             break;
176           default:
177             abort ();
178           }
179       }
180       break;
181
182     case lang_reloc_statement_enum:
183       {
184         lang_reloc_statement_type *rs;
185         asection *output_section;
186         struct bfd_link_order *link_order;
187
188         rs = &statement->reloc_statement;
189
190         output_section = rs->output_section;
191         ASSERT (output_section->owner == output_bfd);
192
193         link_order = bfd_new_link_order (output_bfd, output_section);
194         if (link_order == NULL)
195           einfo (_("%P%F: bfd_new_link_order failed\n"));
196
197         link_order->offset = rs->output_vma;
198         link_order->size = bfd_get_reloc_size (rs->howto);
199
200         link_order->u.reloc.p =
201           ((struct bfd_link_order_reloc *)
202            xmalloc (sizeof (struct bfd_link_order_reloc)));
203
204         link_order->u.reloc.p->reloc = rs->reloc;
205         link_order->u.reloc.p->addend = rs->addend_value;
206
207         if (rs->name == NULL)
208           {
209             link_order->type = bfd_section_reloc_link_order;
210             if (rs->section->owner == output_bfd)
211               link_order->u.reloc.p->u.section = rs->section;
212             else
213               {
214                 link_order->u.reloc.p->u.section = rs->section->output_section;
215                 link_order->u.reloc.p->addend += rs->section->output_offset;
216               }
217           }
218         else
219           {
220             link_order->type = bfd_symbol_reloc_link_order;
221             link_order->u.reloc.p->u.name = rs->name;
222           }
223       }
224       break;
225
226     case lang_input_section_enum:
227       /* Create a new link_order in the output section with this
228          attached */
229       if (statement->input_section.ifile->just_syms_flag == false)
230         {
231           asection *i = statement->input_section.section;
232           asection *output_section = i->output_section;
233
234           ASSERT (output_section->owner == output_bfd);
235
236           if ((output_section->flags & SEC_HAS_CONTENTS) != 0
237               || ((output_section->flags & SEC_LOAD) != 0
238                   && (output_section->flags & SEC_THREAD_LOCAL)))
239             {
240               struct bfd_link_order *link_order;
241
242               link_order = bfd_new_link_order (output_bfd, output_section);
243
244               if (i->flags & SEC_NEVER_LOAD)
245                 {
246                   /* We've got a never load section inside one which
247                      is going to be output, we'll change it into a
248                      fill.  */
249                   link_order->type = bfd_data_link_order;
250                   link_order->u.data.contents = "";
251                   link_order->u.data.size = 1;
252                 }
253               else
254                 {
255                   link_order->type = bfd_indirect_link_order;
256                   link_order->u.indirect.section = i;
257                   ASSERT (i->output_section == output_section);
258                 }
259               if (i->_cooked_size)
260                 link_order->size = i->_cooked_size;
261               else
262                 link_order->size = bfd_get_section_size_before_reloc (i);
263               link_order->offset = i->output_offset;
264             }
265         }
266       break;
267
268     case lang_padding_statement_enum:
269       /* Make a new link_order with the right filler */
270       {
271         asection *output_section;
272         struct bfd_link_order *link_order;
273
274         output_section = statement->padding_statement.output_section;
275         ASSERT (statement->padding_statement.output_section->owner
276                 == output_bfd);
277         if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
278           {
279             link_order = bfd_new_link_order (output_bfd, output_section);
280             link_order->type = bfd_data_link_order;
281             link_order->size = statement->padding_statement.size;
282             link_order->offset = statement->padding_statement.output_offset;
283             link_order->u.data.contents = statement->padding_statement.fill->data;
284             link_order->u.data.size = statement->padding_statement.fill->size;
285           }
286       }
287       break;
288
289     default:
290       /* All the other ones fall through */
291       break;
292     }
293 }
294
295 /* Call BFD to write out the linked file.  */
296
297 /**********************************************************************/
298
299 /* Wander around the input sections, make sure that
300    we'll never try and create an output section with more relocs
301    than will fit.. Do this by always assuming the worst case, and
302    creating new output sections with all the right bits.  */
303 #define TESTIT 1
304 static asection *
305 clone_section (abfd, s, name, count)
306      bfd *abfd;
307      asection *s;
308      const char *name;
309      int *count;
310 {
311   char templ[6];
312   char *sname;
313   asection *n;
314   struct bfd_link_hash_entry *h;
315
316   /* Invent a section name from the first five chars of the base
317      section name and a digit suffix.  */
318   strncpy (templ, name, sizeof (templ) - 1);
319   templ[sizeof (templ) - 1] = '\0';
320   if ((sname = bfd_get_unique_section_name (abfd, templ, count)) == NULL
321       || (n = bfd_make_section_anyway (abfd, sname)) == NULL
322       || (h = bfd_link_hash_lookup (link_info.hash,
323                                     sname, true, true, false)) == NULL)
324     {
325       einfo (_("%F%P: clone section failed: %E\n"));
326       /* Silence gcc warnings.  einfo exits, so we never reach here.  */
327       return NULL;
328     }
329
330   /* Set up section symbol.  */
331   h->type = bfd_link_hash_defined;
332   h->u.def.value = 0;
333   h->u.def.section = n;
334
335   n->flags = s->flags;
336   n->vma = s->vma;
337   n->user_set_vma = s->user_set_vma;
338   n->lma = s->lma;
339   n->_cooked_size = 0;
340   n->_raw_size = 0;
341   n->output_offset = s->output_offset;
342   n->output_section = n;
343   n->orelocation = 0;
344   n->reloc_count = 0;
345   n->alignment_power = s->alignment_power;
346   return n;
347 }
348
349 #if TESTING
350 static void
351 ds (s)
352      asection *s;
353 {
354   struct bfd_link_order *l = s->link_order_head;
355   printf ("vma %x size %x\n", s->vma, s->_raw_size);
356   while (l)
357     {
358       if (l->type == bfd_indirect_link_order)
359         {
360           printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
361         }
362       else
363         {
364           printf (_("%8x something else\n"), l->offset);
365         }
366       l = l->next;
367     }
368   printf ("\n");
369 }
370
371 dump (s, a1, a2)
372      char *s;
373      asection *a1;
374      asection *a2;
375 {
376   printf ("%s\n", s);
377   ds (a1);
378   ds (a2);
379 }
380
381 static void
382 sanity_check (abfd)
383      bfd *abfd;
384 {
385   asection *s;
386   for (s = abfd->sections; s; s = s->next)
387     {
388       struct bfd_link_order *p;
389       bfd_vma prev = 0;
390       for (p = s->link_order_head; p; p = p->next)
391         {
392           if (p->offset > 100000)
393             abort ();
394           if (p->offset < prev)
395             abort ();
396           prev = p->offset;
397         }
398     }
399 }
400 #else
401 #define sanity_check(a)
402 #define dump(a, b, c)
403 #endif
404
405 static void
406 split_sections (abfd, info)
407      bfd *abfd;
408      struct bfd_link_info *info;
409 {
410   asection *original_sec;
411   int nsecs = abfd->section_count;
412   sanity_check (abfd);
413   /* Look through all the original sections.  */
414   for (original_sec = abfd->sections;
415        original_sec && nsecs;
416        original_sec = original_sec->next, nsecs--)
417     {
418       int count = 0;
419       unsigned int lines = 0;
420       unsigned int relocs = 0;
421       bfd_size_type sec_size = 0;
422       struct bfd_link_order *l;
423       struct bfd_link_order *p;
424       bfd_vma vma = original_sec->vma;
425       asection *cursor = original_sec;
426
427       /* Count up the relocations and line entries to see if anything
428          would be too big to fit.  Accumulate section size too.  */
429       for (l = NULL, p = cursor->link_order_head; p != NULL; p = l->next)
430         {
431           unsigned int thislines = 0;
432           unsigned int thisrelocs = 0;
433           bfd_size_type thissize = 0;
434           if (p->type == bfd_indirect_link_order)
435             {
436               asection *sec;
437
438               sec = p->u.indirect.section;
439
440               if (info->strip == strip_none
441                   || info->strip == strip_some)
442                 thislines = sec->lineno_count;
443
444               if (info->relocateable)
445                 thisrelocs = sec->reloc_count;
446
447               if (sec->_cooked_size != 0)
448                 thissize = sec->_cooked_size;
449               else
450                 thissize = sec->_raw_size;
451
452             }
453           else if (info->relocateable
454                    && (p->type == bfd_section_reloc_link_order
455                        || p->type == bfd_symbol_reloc_link_order))
456             thisrelocs++;
457
458           if (l != NULL
459               && (thisrelocs + relocs >= config.split_by_reloc
460                   || thislines + lines >= config.split_by_reloc
461                   || thissize + sec_size >= config.split_by_file))
462             {
463               /* Create a new section and put this link order and the
464                  following link orders into it.  */
465               bfd_vma shift_offset;
466               asection *n;
467
468               n = clone_section (abfd, cursor, original_sec->name, &count);
469
470               /* Attach the link orders to the new section and snip
471                  them off from the old section.  */
472               n->link_order_head = p;
473               n->link_order_tail = cursor->link_order_tail;
474               cursor->link_order_tail = l;
475               l->next = NULL;
476               l = p;
477
478               /* Change the size of the original section and
479                  update the vma of the new one.  */
480
481               dump ("before snip", cursor, n);
482
483               shift_offset = p->offset;
484               if (cursor->_cooked_size != 0)
485                 {
486                   n->_cooked_size = cursor->_cooked_size - shift_offset;
487                   cursor->_cooked_size = shift_offset;
488                 }
489               n->_raw_size = cursor->_raw_size - shift_offset;
490               cursor->_raw_size = shift_offset;
491
492               vma += shift_offset;
493               n->lma = n->vma = vma;
494
495               /* Run down the chain and change the output section to
496                  the right one, update the offsets too.  */
497               do
498                 {
499                   p->offset -= shift_offset;
500                   if (p->type == bfd_indirect_link_order)
501                     {
502                       p->u.indirect.section->output_section = n;
503                       p->u.indirect.section->output_offset = p->offset;
504                     }
505                   p = p->next;
506                 }
507               while (p);
508
509               dump ("after snip", cursor, n);
510               cursor = n;
511               relocs = thisrelocs;
512               lines = thislines;
513               sec_size = thissize;
514             }
515           else
516             {
517               l = p;
518               relocs += thisrelocs;
519               lines += thislines;
520               sec_size += thissize;
521             }
522         }
523     }
524   sanity_check (abfd);
525 }
526
527 /**********************************************************************/
528
529 void
530 ldwrite ()
531 {
532   /* Reset error indicator, which can typically something like invalid
533      format from opening up the .o files.  */
534   bfd_set_error (bfd_error_no_error);
535   lang_for_each_statement (build_link_order);
536
537   if (config.split_by_reloc != (unsigned) -1
538       || config.split_by_file != (bfd_size_type) -1)
539     split_sections (output_bfd, &link_info);
540   if (!bfd_final_link (output_bfd, &link_info))
541     {
542       /* If there was an error recorded, print it out.  Otherwise assume
543          an appropriate error message like unknown symbol was printed
544          out.  */
545
546       if (bfd_get_error () != bfd_error_no_error)
547         einfo (_("%F%P: final link failed: %E\n"));
548       else
549         xexit (1);
550     }
551 }