Enable dosrel for special dos installation (appending of .exe to
[deliverable/binutils-gdb.git] / bfd / reloc16.c
CommitLineData
075caafd 1/* 8 and 16 bit COFF relocation functions, for BFD.
1cedfe03 2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
075caafd
ILT
3 Written by Cygnus Support.
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/*
22Most of this hacked by Steve Chamberlain,
23 sac@cygnus.com
24*/
25
26/* These routines are used by coff-h8300 and coff-z8k to do
27 relocation. */
28
29#include "bfd.h"
30#include "sysdep.h"
075caafd 31#include "obstack.h"
1cedfe03
ILT
32#include "libbfd.h"
33#include "bfdlink.h"
075caafd
ILT
34#include "coff/internal.h"
35#include "libcoff.h"
36
1cedfe03
ILT
37bfd_vma
38bfd_coff_reloc16_get_value (reloc, link_info, input_section)
39 arelent *reloc;
40 struct bfd_link_info *link_info;
41 asection *input_section;
075caafd
ILT
42{
43 bfd_vma value;
44 asymbol *symbol = *(reloc->sym_ptr_ptr);
45 /* A symbol holds a pointer to a section, and an offset from the
46 base of the section. To relocate, we find where the section will
47 live in the output and add that in */
48
49 if (symbol->section == &bfd_und_section)
1cedfe03
ILT
50 {
51 struct bfd_link_hash_entry *h;
52
53 /* The symbol is undefined in this BFD. Look it up in the
54 global linker hash table. FIXME: This should be changed when
55 we convert this stuff to use a specific final_link function
56 and change the interface to bfd_relax_section to not require
57 the generic symbols. */
58 h = bfd_link_hash_lookup (link_info->hash, bfd_asymbol_name (symbol),
59 false, false, true);
60 if (h != (struct bfd_link_hash_entry *) NULL
61 && h->type == bfd_link_hash_defined)
62 value = (h->u.def.value
63 + h->u.def.section->output_section->vma
64 + h->u.def.section->output_offset);
65 else if (h != (struct bfd_link_hash_entry *) NULL
66 && h->type == bfd_link_hash_common)
67 value = h->u.c.size;
68 else
69 {
70 if (! ((*link_info->callbacks->undefined_symbol)
71 (link_info, bfd_asymbol_name (symbol),
72 input_section->owner, input_section, reloc->address)))
73 abort ();
74 value = 0;
75 }
76 }
075caafd 77 else
1cedfe03
ILT
78 {
79 value = symbol->value +
80 symbol->section->output_offset +
81 symbol->section->output_section->vma;
82 }
075caafd
ILT
83
84 /* Add the value contained in the relocation */
85 value += reloc->addend;
86
87 return value;
88}
89
1cedfe03
ILT
90void
91bfd_perform_slip(s, slip, input_section, value)
92 asymbol **s;
93 unsigned int slip;
94 asection *input_section;
95 bfd_vma value;
075caafd 96{
075caafd
ILT
97 /* Find all symbols past this point, and make them know
98 what's happened */
99 while (*s)
075caafd 100 {
1cedfe03
ILT
101 asymbol *p = *s;
102 if (p->section == input_section)
103 {
104 /* This was pointing into this section, so mangle it */
105 if (p->value > value)
106 {
107 p->value -= slip;
108 }
109 }
110 s++;
111 }
075caafd
ILT
112}
113
114boolean
1cedfe03
ILT
115bfd_coff_reloc16_relax_section (abfd, i, link_info, symbols)
116 bfd *abfd;
117 asection *i;
118 struct bfd_link_info *link_info;
119 asymbol **symbols;
075caafd 120{
075caafd
ILT
121 /* Get enough memory to hold the stuff */
122 bfd *input_bfd = i->owner;
123 asection *input_section = i;
124 int shrink = 0 ;
125 boolean new = false;
126
127 bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
128 input_section);
129 arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size);
130
131 /* Get the relocs and think about them */
132 if (bfd_canonicalize_reloc(input_bfd,
133 input_section,
134 reloc_vector,
135 symbols))
075caafd 136 {
1cedfe03
ILT
137 arelent **parent;
138 for (parent = reloc_vector; *parent; parent++)
139 {
140 shrink = bfd_coff_reloc16_estimate (abfd, input_section, symbols,
141 *parent, shrink, link_info);
075caafd
ILT
142 }
143 }
144
075caafd
ILT
145 input_section->_cooked_size -= shrink;
146 free((char *)reloc_vector);
147 return new;
148}
149
150bfd_byte *
1cedfe03
ILT
151bfd_coff_reloc16_get_relocated_section_contents(in_abfd,
152 link_info,
153 link_order,
154 data,
155 relocateable,
156 symbols)
157 bfd *in_abfd;
158 struct bfd_link_info *link_info;
159 struct bfd_link_order *link_order;
160 bfd_byte *data;
161 boolean relocateable;
162 asymbol **symbols;
075caafd
ILT
163{
164 /* Get enough memory to hold the stuff */
1cedfe03
ILT
165 bfd *input_bfd = link_order->u.indirect.section->owner;
166 asection *input_section = link_order->u.indirect.section;
075caafd
ILT
167 bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
168 input_section);
169 arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size);
170
1cedfe03
ILT
171 /* If producing relocateable output, don't bother to relax. */
172 if (relocateable)
173 return bfd_generic_get_relocated_section_contents (in_abfd, link_info,
174 link_order,
175 data, relocateable,
176 symbols);
177
075caafd
ILT
178 /* read in the section */
179 bfd_get_section_contents(input_bfd,
180 input_section,
181 data,
182 0,
183 input_section->_raw_size);
184
185
186 if (bfd_canonicalize_reloc(input_bfd,
187 input_section,
188 reloc_vector,
1cedfe03
ILT
189 symbols) )
190 {
191 arelent **parent = reloc_vector;
192 arelent *reloc ;
075caafd
ILT
193
194
195
1cedfe03
ILT
196 unsigned int dst_address = 0;
197 unsigned int src_address = 0;
198 unsigned int run;
199 unsigned int idx;
075caafd 200
1cedfe03
ILT
201 /* Find how long a run we can do */
202 while (dst_address < link_order->size)
203 {
075caafd 204
1cedfe03
ILT
205 reloc = *parent;
206 if (reloc)
207 {
208 /* Note that the relaxing didn't tie up the addresses in the
209 relocation, so we use the original address to work out the
210 run of non-relocated data */
211 run = reloc->address - src_address;
212 parent++;
075caafd 213
1cedfe03
ILT
214 }
215 else
216 {
217 run = link_order->size - dst_address;
218 }
219 /* Copy the bytes */
220 for (idx = 0; idx < run; idx++)
221 {
222 data[dst_address++] = data[src_address++];
223 }
075caafd 224
1cedfe03 225 /* Now do the relocation */
075caafd 226
1cedfe03
ILT
227 if (reloc)
228 {
229 bfd_coff_reloc16_extra_cases (in_abfd, link_info, link_order,
230 reloc, data, &src_address,
231 &dst_address);
232 }
075caafd 233 }
075caafd 234 }
075caafd
ILT
235 free((char *)reloc_vector);
236 return data;
075caafd
ILT
237}
238
This page took 0.148014 seconds and 4 git commands to generate.