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