* ld.h (split_by_reloc, split_by_file): New flags.
[platform/upstream/binutils.git] / ld / ldwrite.c
1 /* ldwrite.c -- write out the linked file
2    Copyright (C) 1993 Free Software Foundation, Inc.
3    Written by Steve Chamberlain sac@cygnus.com
4
5 This file is part of GLD, the Gnu Linker.
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
9 the Free Software Foundation; either version 2 of the License, or
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
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "bfdlink.h"
24
25 #include "ld.h"
26 #include "ldexp.h"
27 #include "ldlang.h"
28 #include "ldwrite.h"
29 #include "ldmisc.h"
30 #include "ldgram.h"
31 #include "ldmain.h"
32
33 static void build_link_order PARAMS ((lang_statement_union_type *));
34 static void print_symbol_table PARAMS ((void));
35 static void print_file_stuff PARAMS ((lang_input_statement_type *));
36 static boolean print_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
37
38 /* Build link_order structures for the BFD linker.  */
39
40 static void
41 build_link_order (statement)
42      lang_statement_union_type *statement;
43 {
44   switch (statement->header.type)
45     {
46     case lang_data_statement_enum:
47       {
48         asection *output_section;
49         struct bfd_link_order *link_order;
50         bfd_vma value;
51
52         output_section = statement->data_statement.output_section;
53         ASSERT (output_section->owner == output_bfd);
54
55         link_order = bfd_new_link_order (output_bfd, output_section);
56         if (link_order == NULL)
57           einfo ("%P%F: bfd_new_link_order failed");
58
59         link_order->type = bfd_data_link_order;
60         link_order->offset = statement->data_statement.output_vma;
61         link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
62
63         value = statement->data_statement.value;
64
65         ASSERT (output_section->owner == output_bfd);
66         switch (statement->data_statement.type)
67           {
68           case QUAD:
69             bfd_put_64 (output_bfd, value, link_order->u.data.contents);
70             link_order->size = QUAD_SIZE;
71             break;
72           case LONG:
73             bfd_put_32 (output_bfd, value, link_order->u.data.contents);
74             link_order->size = LONG_SIZE;
75             break;
76           case SHORT:
77             bfd_put_16 (output_bfd, value, link_order->u.data.contents);
78             link_order->size = SHORT_SIZE;
79             break;
80           case BYTE:
81             bfd_put_8 (output_bfd, value, link_order->u.data.contents);
82             link_order->size = BYTE_SIZE;
83             break;
84           default:
85             abort ();
86           }
87       }
88       break;
89
90     case lang_reloc_statement_enum:
91       {
92         lang_reloc_statement_type *rs;
93         asection *output_section;
94         struct bfd_link_order *link_order;
95
96         rs = &statement->reloc_statement;
97
98         output_section = rs->output_section;
99         ASSERT (output_section->owner == output_bfd);
100
101         link_order = bfd_new_link_order (output_bfd, output_section);
102         if (link_order == NULL)
103           einfo ("%P%F: bfd_new_link_order failed");
104
105         link_order->offset = rs->output_vma;
106         link_order->size = bfd_get_reloc_size (rs->howto);
107
108         link_order->u.reloc.p =
109           ((struct bfd_link_order_reloc *)
110            xmalloc (sizeof (struct bfd_link_order_reloc)));
111
112         link_order->u.reloc.p->reloc = rs->reloc;
113         link_order->u.reloc.p->addend = rs->addend_value;
114
115         if (rs->section != (asection *) NULL)
116           {
117             ASSERT (rs->name == (const char *) NULL);
118             link_order->type = bfd_section_reloc_link_order;
119             if (rs->section->owner == output_bfd)
120               link_order->u.reloc.p->u.section = rs->section;
121             else
122               {
123                 link_order->u.reloc.p->u.section = rs->section->output_section;
124                 link_order->u.reloc.p->addend += rs->section->output_offset;
125               }
126           }
127         else
128           {
129             ASSERT (rs->name != (const char *) NULL);
130             link_order->type = bfd_symbol_reloc_link_order;
131             link_order->u.reloc.p->u.name = rs->name;
132           }
133       }
134       break;
135
136     case lang_input_section_enum:
137       /* Create a new link_order in the output section with this
138          attached */
139       if (statement->input_section.ifile->just_syms_flag == false)
140         {
141           asection *i = statement->input_section.section;
142           asection *output_section = i->output_section;
143
144           ASSERT (output_section->owner == output_bfd);
145
146           if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
147             {
148               struct bfd_link_order *link_order;
149
150               link_order = bfd_new_link_order (output_bfd, output_section);
151
152               if (i->flags & SEC_NEVER_LOAD)
153                 {
154                   /* We've got a never load section inside one which
155                      is going to be output, we'll change it into a
156                      fill link_order */
157                   link_order->type = bfd_fill_link_order;
158                   link_order->u.fill.value = 0;
159                 }
160               else
161                 {
162                   link_order->type = bfd_indirect_link_order;
163                   link_order->u.indirect.section = i;
164                   ASSERT (i->output_section == output_section);
165                 }
166               if (i->_cooked_size)
167                 link_order->size = i->_cooked_size;
168               else
169                 link_order->size = bfd_get_section_size_before_reloc (i);
170               link_order->offset = i->output_offset;
171             }
172         }
173       break;
174
175     case lang_padding_statement_enum:
176       /* Make a new link_order with the right filler */
177       {
178         asection *output_section;
179         struct bfd_link_order *link_order;
180
181         output_section = statement->padding_statement.output_section;
182         ASSERT (statement->padding_statement.output_section->owner
183                 == output_bfd);
184         if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
185           {
186             link_order = bfd_new_link_order (output_bfd, output_section);
187             link_order->type = bfd_fill_link_order;
188             link_order->size = statement->padding_statement.size;
189             link_order->offset = statement->padding_statement.output_offset;
190             link_order->u.fill.value = statement->padding_statement.fill;
191           }
192       }
193       break;
194
195     default:
196       /* All the other ones fall through */
197       break;
198     }
199 }
200
201 /* Call BFD to write out the linked file.  */
202
203
204 /**********************************************************************/
205
206
207 /* Wander around the input sections, make sure that
208    we'll never try and create an output section with more relocs
209    than will fit.. Do this by always assuming the worst case, and
210    creating new output sections with all the right bits */
211 #define TESTIT 1
212 static asection *
213 clone_section (abfd, s, count)
214      bfd *abfd;
215      asection *s;
216      int *count;
217 {
218 #define SSIZE 8
219   char sname[SSIZE];            /* ??  find the name for this size */
220   asection *n;
221
222   /* Invent a section name - use first five
223      chars of base section name and a digit suffix */
224   do
225     {
226       int i;
227       char b[6];
228       for (i = 0; i < sizeof (b) - 1 && s->name[i]; i++)
229         b[i] = s->name[i];
230       b[i] = 0;
231       sprintf (sname, "%s%d", b, (*count)++);
232     }
233   while (bfd_get_section_by_name (abfd, sname));
234
235   n = bfd_make_section_anyway (abfd, strdup (sname));
236
237   n->flags = s->flags;
238   n->vma = s->vma;
239   n->user_set_vma = s->user_set_vma;
240   n->lma = s->lma;
241   n->_cooked_size = 0;
242   n->_raw_size = 0;
243   n->output_offset = s->output_offset;
244   n->output_section = n;
245   n->orelocation = 0;
246   n->reloc_count = 0;
247
248   return n;
249 }
250
251 #if TESTING
252 static void 
253 ds (s)
254      asection *s;
255 {
256   struct bfd_link_order *l = s->link_order_head;
257   printf ("vma %x size %x\n", s->vma, s->_raw_size);
258   while (l)
259     {
260       if (l->type == bfd_indirect_link_order)
261         {
262           printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
263         }
264       else
265         {
266           printf ("%8x something else\n", l->offset);
267         }
268       l = l->next;
269     }
270   printf ("\n");
271 }
272 dump (s, a1, a2)
273      char *s;
274      asection *a1;
275      asection *a2;
276 {
277   printf ("%s\n", s);
278   ds (a1);
279   ds (a2);
280 }
281
282 static void 
283 sanity_check (abfd)
284      bfd *abfd;
285 {
286   asection *s;
287   for (s = abfd->sections; s; s = s->next)
288     {
289       struct bfd_link_order *p;
290       bfd_vma prev = 0;
291       for (p = s->link_order_head; p; p = p->next)
292         {
293           if (p->offset > 100000)
294             abort ();
295           if (p->offset < prev)
296             abort ();
297           prev = p->offset;
298         }
299     }
300 }
301 #else
302 #define sanity_check(a)
303 #define dump(a, b, c)
304 #endif
305
306
307 void 
308 split_sections (abfd, info)
309      bfd *abfd;
310      struct bfd_link_info *info;
311 {
312   asection *original_sec;
313   int nsecs = abfd->section_count;
314   sanity_check (abfd);
315   /* look through all the original sections */
316   for (original_sec = abfd->sections;
317        original_sec && nsecs;
318        original_sec = original_sec->next, nsecs--)
319     {
320       int count = 0;
321       int lines = 0;
322       int relocs = 0;
323       struct bfd_link_order **pp;
324       bfd_vma vma = original_sec->vma;
325       bfd_vma shift_offset = 0;
326       asection *cursor = original_sec;
327       /* count up the relocations and line entries to see if
328          anything would be too big to fit */
329       for (pp = &(cursor->link_order_head); *pp; pp = &((*pp)->next))
330         {
331           struct bfd_link_order *p = *pp;
332           int thislines = 0;
333           int thisrelocs = 0;
334           if (p->type == bfd_indirect_link_order)
335             {
336               asection *sec;
337
338               sec = p->u.indirect.section;
339
340               if (info->strip == strip_none
341                   || info->strip == strip_some)
342                 thislines = sec->lineno_count;
343
344               if (info->relocateable)
345                 thisrelocs = sec->reloc_count;
346
347             }
348           else if (info->relocateable
349                    && (p->type == bfd_section_reloc_link_order
350                        || p->type == bfd_symbol_reloc_link_order))
351             thisrelocs++;
352
353           if (thisrelocs + relocs > config.split_by_reloc
354               || thislines + lines > config.split_by_reloc
355               || config.split_by_file)
356             {
357               /* create a new section and put this link order and the
358                  following link orders into it */
359               struct bfd_link_order *l = p;
360               asection *n = clone_section (abfd, cursor, &count);
361               *pp = NULL;       /* Snip off link orders from old section */
362               n->link_order_head = l;   /* attach to new section */
363               pp = &n->link_order_head;
364
365               /* change the size of the original section and
366                  update the vma of the new one */
367
368               dump ("before snip", cursor, n);
369
370               n->_raw_size = cursor->_raw_size - l->offset;
371               cursor->_raw_size = l->offset;
372
373               vma += cursor->_raw_size;
374               n->lma = n->vma = vma;
375
376               shift_offset = l->offset;
377
378               /* run down the chain and change the output section to
379                  the right one, update the offsets too */
380
381               while (l)
382                 {
383                   l->offset -= shift_offset;
384                   if (l->type == bfd_indirect_link_order)
385                     {
386                       l->u.indirect.section->output_section = n;
387                       l->u.indirect.section->output_offset = l->offset;
388                     }
389                   l = l->next;
390                 }
391               dump ("after snip", cursor, n);
392               cursor = n;
393               relocs = thisrelocs;
394               lines = thislines;
395             }
396           else
397             {
398               relocs += thisrelocs;
399               lines += thislines;
400             }
401         }
402     }
403   sanity_check (abfd);
404 }
405 /**********************************************************************/
406 void
407 ldwrite ()
408 {
409   lang_for_each_statement (build_link_order);
410
411   if (config.split_by_reloc || config.split_by_file)
412     split_sections (output_bfd, &link_info);
413   if (!bfd_final_link (output_bfd, &link_info))
414     einfo ("%F%P: final link failed: %E\n", output_bfd);
415
416   if (config.map_file)
417     {
418       print_symbol_table ();
419       lang_map ();
420     }
421 }
422
423 /* Print the symbol table.  */
424
425 static void
426 print_symbol_table ()
427 {
428   fprintf (config.map_file, "**FILES**\n\n");
429   lang_for_each_file (print_file_stuff);
430
431   fprintf (config.map_file, "**GLOBAL SYMBOLS**\n\n");
432   fprintf (config.map_file, "offset    section    offset   symbol\n");
433   bfd_link_hash_traverse (link_info.hash, print_symbol, (PTR) NULL);
434 }
435
436 /* Print information about a file.  */
437
438 static void
439 print_file_stuff (f)
440      lang_input_statement_type *f;
441 {
442   fprintf (config.map_file, "  %s\n", f->filename);
443   if (f->just_syms_flag)
444     {
445       fprintf (config.map_file, " symbols only\n");
446     }
447   else
448     {
449       asection *s;
450       if (true)
451         {
452           for (s = f->the_bfd->sections;
453                s != (asection *) NULL;
454                s = s->next)
455             {
456               print_address (s->output_offset);
457               if (s->reloc_done)
458                 {
459                   fprintf (config.map_file, " %08x 2**%2ud %s\n",
460                            (unsigned) bfd_get_section_size_after_reloc (s),
461                            s->alignment_power, s->name);
462                 }
463
464               else
465                 {
466                   fprintf (config.map_file, " %08x 2**%2ud %s\n",
467                            (unsigned) bfd_get_section_size_before_reloc (s),
468                            s->alignment_power, s->name);
469                 }
470             }
471         }
472       else
473         {
474           for (s = f->the_bfd->sections;
475                s != (asection *) NULL;
476                s = s->next)
477             {
478               fprintf (config.map_file, "%s ", s->name);
479               print_address (s->output_offset);
480               fprintf (config.map_file, "(%x)",
481                        (unsigned) bfd_get_section_size_after_reloc (s));
482             }
483           fprintf (config.map_file, "hex \n");
484         }
485     }
486   print_nl ();
487 }
488
489 /* Print a symbol.  */
490
491 /*ARGSUSED*/
492 static boolean
493 print_symbol (p, ignore)
494      struct bfd_link_hash_entry *p;
495      PTR ignore;
496 {
497   while (p->type == bfd_link_hash_indirect
498          || p->type == bfd_link_hash_warning)
499     p = p->u.i.link;
500
501   switch (p->type)
502     {
503     case bfd_link_hash_new:
504       abort ();
505
506     case bfd_link_hash_undefined:
507       fprintf (config.map_file, "undefined                     ");
508       fprintf (config.map_file, "%s ", p->root.string);
509       print_nl ();
510       break;
511
512     case bfd_link_hash_weak:
513       fprintf (config.map_file, "weak                          ");
514       fprintf (config.map_file, "%s ", p->root.string);
515       print_nl ();
516       break;
517
518     case bfd_link_hash_defined:
519       {
520         asection *defsec = p->u.def.section;
521
522         print_address (p->u.def.value);
523         if (defsec)
524           {
525             fprintf (config.map_file, "  %-10s",
526                      bfd_section_name (output_bfd, defsec));
527             print_space ();
528             print_address (p->u.def.value + defsec->vma);
529           }
530         else
531           {
532             fprintf (config.map_file, "         .......");
533           }
534         fprintf (config.map_file, " %s ", p->root.string);
535       }
536       print_nl ();
537       break;
538
539     case bfd_link_hash_common:
540       fprintf (config.map_file, "common               ");
541       print_address (p->u.c.size);
542       fprintf (config.map_file, " %s ", p->root.string);
543       print_nl ();
544       break;
545
546     default:
547       abort ();
548     }
549
550   return true;
551 }