-y support
[platform/upstream/binutils.git] / ld / relax.c
1
2
3 /* 
4  
5 new age linking
6
7
8 Tie together all the interseting blocks 
9
10 */
11
12
13 #include "bfd.h"
14 #include "../bfd/seclet.h"
15 #include "coff/internal.h"
16 #include "sysdep.h"
17
18 #include "ldlang.h"
19 #include "ld.h"
20 #include "ldwrite.h"
21 #include "ldmisc.h"
22 #include "ldsym.h"
23 #include "ldgram.h"
24 #include "relax.h"
25 static void
26 DEFUN(build_it,(statement),
27       lang_statement_union_type *statement)
28 {
29   switch (statement->header.type) {
30 #if 0
31    {
32
33      bfd_byte play_area[SHORT_SIZE];
34      unsigned int i;
35      bfd_putshort(output_bfd, statement->fill_statement.fill, play_area);
36      /* Write out all entire shorts */
37      for (i = 0;
38           i < statement->fill_statement.size - SHORT_SIZE + 1;
39           i+= SHORT_SIZE)
40      {
41        bfd_set_section_contents(output_bfd,
42                                 statement->fill_statement.output_section,
43                                 play_area,
44                                 statement->data_statement.output_offset +i,
45                                 SHORT_SIZE);
46
47      }
48
49      /* Now write any remaining byte */
50      if (i < statement->fill_statement.size) 
51      {
52        bfd_set_section_contents(output_bfd,
53                                 statement->fill_statement.output_section,
54                                 play_area,
55                                 statement->data_statement.output_offset +i,
56                                 1);
57
58      }
59
60      abort();
61    }
62     break;
63 #endif
64    case lang_data_statement_enum:
65
66    {
67
68      bfd_vma value = statement->data_statement.value;
69      bfd_byte play_area[LONG_SIZE];
70      unsigned int size = 0;
71      asection * output_section = statement->data_statement.output_section;
72      switch (statement->data_statement.type) {
73       case LONG:
74        bfd_put_32(output_section->owner, value,  play_area);
75        size = LONG_SIZE;
76        break;
77       case SHORT:
78        bfd_put_16(output_section->owner, value,  play_area);
79        size = SHORT_SIZE;
80        break;
81       case BYTE:
82        bfd_put_8(output_section->owner, value,  play_area);
83        size = BYTE_SIZE;
84        break;
85      }
86       
87      bfd_set_section_contents(output_section->owner,
88                               statement->data_statement.output_section,
89                               play_area,
90                               statement->data_statement.output_vma,
91                               size);
92                                
93                                
94
95    }
96
97     break;
98    case lang_input_section_enum:
99    {
100      /* Create a new seclet in the output section with this
101         attached */
102      if (statement->input_section.ifile->just_syms_flag == false) 
103      {
104        asection *i  = statement->input_section.section;
105
106        asection *output_section = i->output_section;
107         
108        bfd_seclet_type *seclet  = bfd_new_seclet(output_section->owner,output_section);
109         
110        seclet->type = bfd_indirect_seclet;
111        seclet->u.indirect.section = i;
112        seclet->u.indirect.symbols = statement->input_section.ifile->asymbols;
113        seclet->size = i->_cooked_size;
114        seclet->offset = i->output_offset;
115        seclet->next = 0;
116      }
117         
118    }
119     break;
120    case lang_padding_statement_enum:
121     /* Make a new seclet with the right filler */
122    {
123      /* Create a new seclet in the output section with this
124         attached */
125
126      bfd_seclet_type *seclet  =
127       bfd_new_seclet(statement->padding_statement.output_section->owner,
128                      statement->padding_statement.output_section);
129         
130      seclet->type = bfd_fill_seclet;
131      seclet->size = statement->padding_statement.size;
132      seclet->offset = statement->padding_statement.output_offset;
133      seclet->u.fill.value = statement->padding_statement.fill;
134      seclet->next = 0;
135    }
136     break;
137
138
139
140     break;
141    default:
142     /* All the other ones fall through */
143     ;
144
145   }
146
147
148
149 }
150
151
152 void 
153 DEFUN(write_relaxnorel,(output_bfd, data),
154       bfd *output_bfd AND
155       PTR data)
156 {
157 /* Tie up all the statements to generate an output bfd structure which
158    bfd can mull over */
159
160
161   lang_for_each_statement(build_it);
162
163   seclet_dump(output_bfd, data);
164
165 }
166
167
168     
169
170
171 /* See if we can change the size of this section by shrinking the
172    relocations in it. If this happens, then we'll have to renumber the
173    symbols in it, and shift around the data too.
174  */
175 boolean
176 DEFUN(relax_section,(this_ptr),
177       lang_statement_union_type **this_ptr)
178 {
179
180   lang_input_section_type *is = &((*this_ptr)->input_section);
181   asection *i = is->section;
182   if (!(i->owner->flags & BFD_IS_RELAXABLE)) 
183   {
184     einfo("%B: not assembled with -linkrelax\n", i->owner);    
185   }
186
187   return bfd_relax_section(i->owner, i, is->ifile->asymbols);
188   
189 }
190