This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/binutils.git] / ld / ldwrite.c
1 /* Copyright (C) 1991 Free Software Foundation, Inc.
2    
3 This file is part of GLD, the Gnu Linker.
4
5 GLD is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 1, or (at your option)
8 any later version.
9
10 GLD is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GLD; see the file COPYING.  If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
18
19 /*
20  * $Id$ 
21  *
22  *  $Log$
23  *  Revision 1.3  1991/03/22 22:32:22  steve
24  *  *** empty log message ***
25  *
26  * Revision 1.2  1991/03/22  22:31:37  steve
27  * *** empty log message ***
28  *
29  * Revision 1.1.1.1  1991/03/21  21:29:05  gumby
30  * Back from Intel with Steve
31  *
32  * Revision 1.1  1991/03/21  21:29:04  gumby
33  * Initial revision
34  *
35  * Revision 1.2  1991/03/15  18:45:55  rich
36  * foo
37  *
38  * Revision 1.1  1991/03/13  00:48:37  chrisb
39  * Initial revision
40  *
41  * Revision 1.7  1991/03/10  19:15:03  sac
42  * Took out the abort() which had been put in the wrong place
43  * Updated the version #.
44  *
45  * Revision 1.6  1991/03/10  09:31:41  rich
46  *  Modified Files:
47  *      Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c
48  *      ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h
49  *      ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c
50  *      ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c
51  *      ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h
52  *
53  * As of this round of changes, ld now builds on all hosts of (Intel960)
54  * interest and copy passes my copy test on big endian hosts again.
55  *
56  * Revision 1.5  1991/03/09  03:25:08  sac
57  * Added support for LONG, SHORT and BYTE keywords in scripts
58  *
59  * Revision 1.4  1991/03/06  21:59:34  sac
60  * Completed G++ support
61  *
62  * Revision 1.3  1991/03/06  02:29:52  sac
63  * Added support for partial linking.
64  *
65  * Revision 1.2  1991/02/22  17:15:11  sac
66  * Added RCS keywords and copyrights
67  *
68 */
69
70 /* 
71    This module writes out the final image by reading sections from the
72    input files, relocating them and writing them out
73
74    There are two main paths through this module, one for normal
75    operation and one for partial linking. 
76
77    During  normal operation, raw section data is read along with the
78    associated relocation information, the relocation info applied and
79    the section data written out on a section by section basis.
80
81    When partially linking, all the relocation records are read to work
82    out how big the output relocation vector will be. Then raw data is
83    read, relocated and written section by section.
84
85    Written by Steve Chamberlain steve@cygnus.com
86
87 */
88
89
90 #include "sysdep.h"
91 #include "bfd.h"
92
93 #include "ldlang.h"
94 #include "ld.h"
95 #include "ldwrite.h"
96 #include "ldmisc.h"
97 #include "ldsym.h"
98 #include "ldgram.tab.h"
99
100
101
102 char *ldmalloc();
103 /* Static vars for do_warnings and subroutines of it */
104 int list_unresolved_refs;       /* List unresolved refs */
105 int list_warning_symbols;       /* List warning syms */
106 int list_multiple_defs;         /* List multiple definitions */
107 extern int errno;
108 extern char *sys_errlist[];
109
110 extern unsigned int undefined_global_sym_count;
111
112 extern bfd *output_bfd;
113
114 extern struct lang_output_section_statement_struct * create_object_symbols;
115
116 extern char lprefix;
117
118 #ifdef __STDC__
119 void lang_for_each_statement(void (*func)());
120 #else /* __STDC__ */
121 void lang_for_each_statement();
122 #endif /* __STDC__ */
123
124 extern size_t largest_section;
125 ld_config_type config;
126
127 extern unsigned int global_symbol_count;
128
129 boolean trace_files;
130
131 static void perform_relocation(input_bfd,
132                                input_section,
133                                data,
134                                symbols)
135 bfd *input_bfd;
136 asection *input_section;
137 void *data;
138 asymbol **symbols;
139 {
140   static asymbol *error_symbol = (asymbol *)NULL;
141   static unsigned int error_count = 0;
142 #define MAX_ERRORS_IN_A_ROW 5
143   size_t reloc_size = get_reloc_upper_bound(input_bfd, input_section);
144
145   arelent **reloc_vector = (arelent **)ldmalloc(reloc_size);
146   arelent **parent;
147   bfd *ob = output_bfd;
148   asection *os = input_section->output_section;
149   if (config.relocateable_output == false) ob = (bfd *)NULL;
150
151   if (bfd_canonicalize_reloc(input_bfd, 
152                              input_section,
153                              reloc_vector,
154                              symbols) )
155     {
156       for (parent = reloc_vector; *parent; parent++) 
157         {
158
159           bfd_reloc_status_enum_type r=
160             bfd_perform_relocation(input_bfd,
161                                    *parent,
162                                    data,
163                                    input_section, 
164                                    ob);
165
166           if (r == bfd_reloc_ok) {
167             if (ob != (bfd *)NULL) {
168               /* A parital link, so keep the relocs */
169               os->orelocation[os->reloc_count] = *parent;
170               os->reloc_count++;
171             }
172           }
173           else
174             {
175               asymbol *s;
176               arelent *p = *parent;
177
178               if (ob != (bfd *)NULL) {
179                 /* A parital link, so keep the relocs */
180                 os->orelocation[os->reloc_count] = *parent;
181                 os->reloc_count++;
182               }
183
184               if (p->sym_ptr_ptr != (asymbol **)NULL) {
185                 s = *(p->sym_ptr_ptr);
186               }
187               else {
188                 s = (asymbol *)NULL;
189               }
190               switch (r)
191                 {
192                 case bfd_reloc_undefined:
193                   /* We remember the symbol, and never print more than
194                      a reasonable number of them in a row */
195                   if (s == error_symbol) {
196                     error_count++;
197                   }
198                   else {
199                     error_count = 0;
200                     error_symbol = s;
201                   }
202                   if (error_count < MAX_ERRORS_IN_A_ROW) {
203                     info("%C: undefined reference to `%T'\n",
204                          input_bfd,
205                          input_section,
206                          symbols,
207                          (*parent)->address,
208                          s);
209                     config.make_executable = false;
210                   }
211                   else if (error_count == MAX_ERRORS_IN_A_ROW) {
212                     info("%C: more undefined references to `%T' follow\n",
213                          input_bfd,
214                          input_section,
215                          symbols,
216                          (*parent)->address,
217                          s);
218                   }                 
219                   else {
220                     /* Don't print any more */
221                   }
222                   break;
223                 case bfd_reloc_dangerous: 
224                   info("%B: relocation may be wrong `%T'\n",
225                        input_bfd,
226                        s);
227                   break;
228                 case bfd_reloc_outofrange:
229                   info("%B:%s relocation address out of range %T (%x)\n",
230                        input_bfd,
231                        input_section->name,
232                        s,
233                        p->address); 
234                   break;
235                 case bfd_reloc_overflow:
236                   info("%B:%s relocation overflow in %T reloc type %d\n",
237                        input_bfd,
238                        input_section->name,
239                        s,
240                        p->howto->type);
241                   break;
242                 default:
243                   info("%F%B: relocation error, symbol `%T'\n",
244                        input_bfd,
245                        s);
246                   break;
247                 }
248             }
249         }
250     }
251   free((char *)reloc_vector);
252 }
253
254
255
256
257
258
259 void  *data_area;
260
261 static void
262 copy_and_relocate(statement)
263 lang_statement_union_type *statement;
264 {
265   switch (statement->header.type) {
266   case lang_fill_statement_enum: 
267     {
268 #if 0
269       bfd_byte play_area[SHORT_SIZE];
270       unsigned int i;
271       bfd_putshort(output_bfd, statement->fill_statement.fill, play_area);
272       /* Write out all entire shorts */
273       for (i = 0;
274            i < statement->fill_statement.size - SHORT_SIZE + 1;
275            i+= SHORT_SIZE)
276         {
277           bfd_set_section_contents(output_bfd,
278                                    statement->fill_statement.output_section,
279                                    play_area,
280                                    statement->data_statement.output_offset +i,
281                                    SHORT_SIZE);
282
283         }
284
285       /* Now write any remaining byte */
286       if (i < statement->fill_statement.size) 
287         {
288           bfd_set_section_contents(output_bfd,
289                                    statement->fill_statement.output_section,
290                                    play_area,
291                                    statement->data_statement.output_offset +i,
292                                    1);
293
294         }
295 #endif
296     }
297     break;
298   case lang_data_statement_enum:
299     {
300       bfd_vma value = statement->data_statement.value;
301       bfd_byte play_area[LONG_SIZE];
302       unsigned int size;
303       switch (statement->data_statement.type) {
304       case LONG:
305         bfd_putlong(output_bfd, value,  play_area);
306         size = LONG_SIZE;
307         break;
308       case SHORT:
309         bfd_putshort(output_bfd, value,  play_area);
310         size = SHORT_SIZE;
311         break;
312       case BYTE:
313         bfd_putchar(output_bfd, value,  play_area);
314         size = BYTE_SIZE;
315         break;
316       }
317       
318       bfd_set_section_contents(output_bfd,
319                                statement->data_statement.output_section,
320                                play_area,
321                                statement->data_statement.output_vma,
322                                size);
323                                
324                                
325
326
327     }
328     break;
329   case lang_input_section_enum:
330     {
331     
332       asection *i  = statement->input_section.section;
333       asection *output_section = i->output_section;
334       lang_input_statement_type *ifile = statement->input_section.ifile;
335       bfd *inbfd = ifile->the_bfd;
336       if (output_section->flags & SEC_LOAD && i->size != 0) 
337         {
338           if(bfd_get_section_contents(inbfd,
339                                       i,
340                                       data_area,
341                                       0L,
342                                       i->size) == false) 
343             {
344               info("%F%B error reading section contents %E\n",
345                    inbfd);
346             }
347           perform_relocation (inbfd,  i,  data_area, ifile->asymbols);
348
349
350           if(bfd_set_section_contents(output_bfd,
351                                       output_section,
352                                       data_area,
353                                       (file_ptr)i->output_offset,
354                                       i->size) == false) 
355             {
356               info("%F%B error writing section contents of %E\n",
357                    output_bfd);
358             }
359
360         }
361     }
362     break;
363
364  default:
365     /* All the other ones fall through */
366     ;
367
368   }
369 }
370
371 void
372 write_norel()
373 {
374   /* Output the text and data segments, relocating as we go.  */
375   lang_for_each_statement(copy_and_relocate);
376 }
377
378
379 static void read_relocs(abfd, section, symbols)
380 bfd *abfd;
381 asection *section;
382 asymbol **symbols;
383 {
384   /* Work out the output section ascociated with this input section */
385   asection *output_section = section->output_section;
386
387   size_t reloc_size = get_reloc_upper_bound(abfd, section);
388   arelent **reloc_vector = (arelent **)ldmalloc(reloc_size);
389
390   if (bfd_canonicalize_reloc(abfd, 
391                              section,
392                              reloc_vector,
393                              symbols)) {
394     output_section->reloc_count   += section->reloc_count;
395   }
396 }
397
398
399 static void
400 write_rel()
401 {
402   /*
403      Run through each section of each file and work work out the total
404      number of relocation records which will finally be in each output
405      section 
406      */
407
408   LANG_FOR_EACH_INPUT_SECTION
409     (statement, abfd, section,
410      (read_relocs(abfd, section, statement->asymbols)));
411
412
413
414   /*
415      Now run though all the output sections and allocate the space for
416      all the relocations
417      */
418   LANG_FOR_EACH_OUTPUT_SECTION
419     (section, 
420      (section->orelocation =
421       (arelent **)ldmalloc((size_t)(sizeof(arelent **)*
422                                     section->reloc_count)),
423       section->reloc_count = 0,
424      section->flags |= SEC_HAS_CONTENTS));
425
426
427   /*
428      Copy the data, relocating as we go
429      */
430   lang_for_each_statement(copy_and_relocate);
431 }
432
433 void
434 ldwrite ()
435 {
436   data_area = (void*) ldmalloc(largest_section);
437   if (config.relocateable_output == true)
438     {
439       write_rel();
440     }
441   else 
442     {
443     write_norel();
444   }
445   free(data_area);
446   /* Output the symbol table (both globals and locals).  */
447   ldsym_write ();
448
449 }
450