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