1 |
/* BFD support for the ns32k architecture. |
/* BFD support for the ns32k architecture. |
2 |
Copyright 1990, 1991, 1994, 1995, 1998, 2000, 2001, 2002 |
Copyright 1990, 1991, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, |
3 |
Free Software Foundation, Inc. |
2004, 2005 Free Software Foundation, Inc. |
4 |
Almost totally rewritten by Ian Dall from initial work |
Almost totally rewritten by Ian Dall from initial work |
5 |
by Andrew Cagney. |
by Andrew Cagney. |
6 |
|
|
7 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
8 |
|
|
9 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
10 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
11 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
12 |
(at your option) any later version. |
(at your option) any later version. |
13 |
|
|
14 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
15 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 |
GNU General Public License for more details. |
GNU General Public License for more details. |
18 |
|
|
19 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
20 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
21 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
22 |
|
|
23 |
#include "bfd.h" |
#include "bfd.h" |
24 |
#include "sysdep.h" |
#include "sysdep.h" |
30 |
|
|
31 |
static const bfd_arch_info_type arch_info_struct[] = |
static const bfd_arch_info_type arch_info_struct[] = |
32 |
{ |
{ |
33 |
N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */ |
N(32532,"ns32k:32532",TRUE, 0), /* The word ns32k will match this too. */ |
34 |
}; |
}; |
35 |
|
|
36 |
const bfd_arch_info_type bfd_ns32k_arch = |
const bfd_arch_info_type bfd_ns32k_arch = |
37 |
N(32032,"ns32k:32032",false, &arch_info_struct[0]); |
N(32032,"ns32k:32032",FALSE, &arch_info_struct[0]); |
38 |
|
|
39 |
static bfd_reloc_status_type do_ns32k_reloc |
static bfd_reloc_status_type do_ns32k_reloc |
40 |
PARAMS ((bfd *, arelent *, struct symbol_cache_entry *, PTR, asection *, |
PARAMS ((bfd *, arelent *, struct bfd_symbol *, PTR, asection *, |
41 |
bfd *, char **, |
bfd *, char **, |
42 |
bfd_vma (*) (bfd_byte *, int), |
bfd_vma (*) (bfd_byte *, int), |
43 |
int (*) (bfd_vma, bfd_byte *, int))); |
void (*) (bfd_vma, bfd_byte *, int))); |
44 |
|
|
45 |
bfd_vma |
bfd_vma |
46 |
_bfd_ns32k_get_displacement (buffer, size) |
_bfd_ns32k_get_displacement (buffer, size) |
48 |
int size; |
int size; |
49 |
{ |
{ |
50 |
bfd_signed_vma value; |
bfd_signed_vma value; |
51 |
|
|
52 |
switch (size) |
switch (size) |
53 |
{ |
{ |
54 |
case 1: |
case 1: |
71 |
abort (); |
abort (); |
72 |
return 0; |
return 0; |
73 |
} |
} |
74 |
|
|
75 |
return value; |
return value; |
76 |
} |
} |
77 |
|
|
78 |
int |
void |
79 |
_bfd_ns32k_put_displacement (value, buffer, size) |
_bfd_ns32k_put_displacement (value, buffer, size) |
80 |
bfd_vma value; |
bfd_vma value; |
81 |
bfd_byte *buffer; |
bfd_byte *buffer; |
84 |
switch (size) |
switch (size) |
85 |
{ |
{ |
86 |
case 1: |
case 1: |
|
if (value + 0x40 > 0x7f) |
|
|
return -1; |
|
87 |
value &= 0x7f; |
value &= 0x7f; |
88 |
*buffer++ = value; |
*buffer++ = value; |
89 |
break; |
break; |
90 |
|
|
91 |
case 2: |
case 2: |
|
if (value + 0x2000 > 0x3fff) |
|
|
return -1; |
|
92 |
value &= 0x3fff; |
value &= 0x3fff; |
93 |
value |= 0x8000; |
value |= 0x8000; |
94 |
*buffer++ = (value >> 8); |
*buffer++ = (value >> 8); |
96 |
break; |
break; |
97 |
|
|
98 |
case 4: |
case 4: |
|
/* FIXME: is this correct? -0x1f000000 <= value < 0x2000000 */ |
|
|
if (value + 0x1f000000 > 0x3effffff) |
|
|
return -1; |
|
99 |
value |= (bfd_vma) 0xc0000000; |
value |= (bfd_vma) 0xc0000000; |
100 |
*buffer++ = (value >> 24); |
*buffer++ = (value >> 24); |
101 |
*buffer++ = (value >> 16); |
*buffer++ = (value >> 16); |
102 |
*buffer++ = (value >> 8); |
*buffer++ = (value >> 8); |
103 |
*buffer++ = value; |
*buffer++ = value; |
104 |
break; |
break; |
|
default: |
|
|
return -1; |
|
105 |
} |
} |
106 |
return 0; |
return; |
107 |
} |
} |
108 |
|
|
109 |
bfd_vma |
bfd_vma |
112 |
int size; |
int size; |
113 |
{ |
{ |
114 |
bfd_vma value = 0; |
bfd_vma value = 0; |
115 |
|
|
116 |
switch (size) |
switch (size) |
117 |
{ |
{ |
|
case 8: |
|
|
value = (value << 8) | (*buffer++ & 0xff); |
|
|
value = (value << 8) | (*buffer++ & 0xff); |
|
|
value = (value << 8) | (*buffer++ & 0xff); |
|
|
value = (value << 8) | (*buffer++ & 0xff); |
|
118 |
case 4: |
case 4: |
119 |
value = (value << 8) | (*buffer++ & 0xff); |
value = (value << 8) | (*buffer++ & 0xff); |
120 |
value = (value << 8) | (*buffer++ & 0xff); |
value = (value << 8) | (*buffer++ & 0xff); |
122 |
value = (value << 8) | (*buffer++ & 0xff); |
value = (value << 8) | (*buffer++ & 0xff); |
123 |
case 1: |
case 1: |
124 |
value = (value << 8) | (*buffer++ & 0xff); |
value = (value << 8) | (*buffer++ & 0xff); |
125 |
|
break; |
126 |
|
default: |
127 |
|
abort (); |
128 |
} |
} |
129 |
return value; |
return value; |
130 |
} |
} |
131 |
|
|
132 |
int |
void |
133 |
_bfd_ns32k_put_immediate (value, buffer, size) |
_bfd_ns32k_put_immediate (value, buffer, size) |
134 |
bfd_vma value; |
bfd_vma value; |
135 |
bfd_byte *buffer; |
bfd_byte *buffer; |
138 |
buffer += size - 1; |
buffer += size - 1; |
139 |
switch (size) |
switch (size) |
140 |
{ |
{ |
|
case 8: |
|
|
*buffer-- = (value & 0xff); value >>= 8; |
|
|
*buffer-- = (value & 0xff); value >>= 8; |
|
|
*buffer-- = (value & 0xff); value >>= 8; |
|
|
*buffer-- = (value & 0xff); value >>= 8; |
|
141 |
case 4: |
case 4: |
142 |
*buffer-- = (value & 0xff); value >>= 8; |
*buffer-- = (value & 0xff); value >>= 8; |
143 |
*buffer-- = (value & 0xff); value >>= 8; |
*buffer-- = (value & 0xff); value >>= 8; |
146 |
case 1: |
case 1: |
147 |
*buffer-- = (value & 0xff); value >>= 8; |
*buffer-- = (value & 0xff); value >>= 8; |
148 |
} |
} |
|
return 0; |
|
149 |
} |
} |
150 |
|
|
151 |
/* This is just like the standard perform_relocation except we |
/* This is just like the standard perform_relocation except we |
152 |
* use get_data and put_data which know about the ns32k |
use get_data and put_data which know about the ns32k storage |
153 |
* storage methods. |
methods. This is probably a lot more complicated than it |
154 |
* This is probably a lot more complicated than it needs to be! |
needs to be! */ |
155 |
*/ |
|
156 |
static bfd_reloc_status_type |
static bfd_reloc_status_type |
157 |
do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, |
do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, |
158 |
error_message, get_data, put_data) |
error_message, get_data, put_data) |
159 |
bfd *abfd; |
bfd *abfd; |
160 |
arelent *reloc_entry; |
arelent *reloc_entry; |
161 |
struct symbol_cache_entry *symbol; |
struct bfd_symbol *symbol; |
162 |
PTR data; |
PTR data; |
163 |
asection *input_section; |
asection *input_section; |
164 |
bfd *output_bfd; |
bfd *output_bfd; |
165 |
char **error_message ATTRIBUTE_UNUSED; |
char **error_message ATTRIBUTE_UNUSED; |
166 |
bfd_vma (*get_data) PARAMS ((bfd_byte *, int)); |
bfd_vma (*get_data) PARAMS ((bfd_byte *, int)); |
167 |
int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int)); |
void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int)); |
168 |
{ |
{ |
169 |
int overflow = 0; |
int overflow = 0; |
170 |
bfd_vma relocation; |
bfd_vma relocation; |
182 |
return bfd_reloc_ok; |
return bfd_reloc_ok; |
183 |
} |
} |
184 |
|
|
185 |
/* If we are not producing relocateable output, return an error if |
/* If we are not producing relocatable output, return an error if |
186 |
the symbol is not defined. An undefined weak symbol is |
the symbol is not defined. An undefined weak symbol is |
187 |
considered to have a value of zero (SVR4 ABI, p. 4-27). */ |
considered to have a value of zero (SVR4 ABI, p. 4-27). */ |
188 |
if (symbol->section == &bfd_und_section |
if (symbol->section == &bfd_und_section |
191 |
flag = bfd_reloc_undefined; |
flag = bfd_reloc_undefined; |
192 |
|
|
193 |
/* Is the address of the relocation really within the section? */ |
/* Is the address of the relocation really within the section? */ |
194 |
if (reloc_entry->address > input_section->_cooked_size) |
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) |
195 |
return bfd_reloc_outofrange; |
return bfd_reloc_outofrange; |
196 |
|
|
197 |
/* Work out which section the relocation is targetted at and the |
/* Work out which section the relocation is targeted at and the |
198 |
initial relocation command value. */ |
initial relocation command value. */ |
199 |
|
|
200 |
/* Get symbol value. (Common symbols are special.) */ |
/* Get symbol value. (Common symbols are special.) */ |
232 |
of the location within the section. Some targets arrange for |
of the location within the section. Some targets arrange for |
233 |
the addend to be the negative of the position of the location |
the addend to be the negative of the position of the location |
234 |
within the section; for example, i386-aout does this. For |
within the section; for example, i386-aout does this. For |
235 |
i386-aout, pcrel_offset is false. Some other targets do not |
i386-aout, pcrel_offset is FALSE. Some other targets do not |
236 |
include the position of the location; for example, m88kbcs, |
include the position of the location; for example, m88kbcs, |
237 |
or ELF. For those targets, pcrel_offset is true. |
or ELF. For those targets, pcrel_offset is TRUE. |
238 |
|
|
239 |
If we are producing relocateable output, then we must ensure |
If we are producing relocatable output, then we must ensure |
240 |
that this reloc will be correctly computed when the final |
that this reloc will be correctly computed when the final |
241 |
relocation is done. If pcrel_offset is false we want to wind |
relocation is done. If pcrel_offset is FALSE we want to wind |
242 |
up with the negative of the location within the section, |
up with the negative of the location within the section, |
243 |
which means we must adjust the existing addend by the change |
which means we must adjust the existing addend by the change |
244 |
in the location within the section. If pcrel_offset is true |
in the location within the section. If pcrel_offset is TRUE |
245 |
we do not want to adjust the existing addend at all. |
we do not want to adjust the existing addend at all. |
246 |
|
|
247 |
FIXME: This seems logical to me, but for the case of |
FIXME: This seems logical to me, but for the case of |
248 |
producing relocateable output it is not what the code |
producing relocatable output it is not what the code |
249 |
actually does. I don't want to change it, because it seems |
actually does. I don't want to change it, because it seems |
250 |
far too likely that something will break. */ |
far too likely that something will break. */ |
|
|
|
251 |
relocation -= |
relocation -= |
252 |
input_section->output_section->vma + input_section->output_offset; |
input_section->output_section->vma + input_section->output_offset; |
253 |
|
|
279 |
/* WTF?? */ |
/* WTF?? */ |
280 |
if (abfd->xvec->flavour == bfd_target_coff_flavour) |
if (abfd->xvec->flavour == bfd_target_coff_flavour) |
281 |
{ |
{ |
|
#if 1 |
|
282 |
/* For m68k-coff, the addend was being subtracted twice during |
/* For m68k-coff, the addend was being subtracted twice during |
283 |
relocation with -r. Removing the line below this comment |
relocation with -r. Removing the line below this comment |
284 |
fixes that problem; see PR 2953. |
fixes that problem; see PR 2953. |
285 |
|
|
286 |
However, Ian wrote the following, regarding removing the line below, |
However, Ian wrote the following, regarding removing the line |
287 |
which explains why it is still enabled: --djm |
below, which explains why it is still enabled: --djm |
288 |
|
|
289 |
If you put a patch like that into BFD you need to check all the COFF |
If you put a patch like that into BFD you need to check all |
290 |
linkers. I am fairly certain that patch will break coff-i386 (e.g., |
the COFF linkers. I am fairly certain that patch will break |
291 |
SCO); see coff_i386_reloc in coff-i386.c where I worked around the |
coff-i386 (e.g., SCO); see coff_i386_reloc in coff-i386.c |
292 |
problem in a different way. There may very well be a reason that the |
where I worked around the problem in a different way. There |
293 |
code works as it does. |
may very well be a reason that the code works as it does. |
294 |
|
|
295 |
Hmmm. The first obvious point is that bfd_perform_relocation should |
Hmmm. The first obvious point is that bfd_perform_relocation |
296 |
not have any tests that depend upon the flavour. It's seem like |
should not have any tests that depend upon the flavour. It's |
297 |
entirely the wrong place for such a thing. The second obvious point |
seem like entirely the wrong place for such a thing. The |
298 |
is that the current code ignores the reloc addend when producing |
second obvious point is that the current code ignores the |
299 |
relocateable output for COFF. That's peculiar. In fact, I really |
reloc addend when producing relocatable output for COFF. |
300 |
have no idea what the point of the line you want to remove is. |
That's peculiar. In fact, I really have no idea what the |
301 |
|
point of the line you want to remove is. |
302 |
A typical COFF reloc subtracts the old value of the symbol and adds in |
|
303 |
the new value to the location in the object file (if it's a pc |
A typical COFF reloc subtracts the old value of the symbol |
304 |
relative reloc it adds the difference between the symbol value and the |
and adds in the new value to the location in the object file |
305 |
location). When relocating we need to preserve that property. |
(if it's a pc relative reloc it adds the difference between |
306 |
|
the symbol value and the location). When relocating we need |
307 |
BFD handles this by setting the addend to the negative of the old |
to preserve that property. |
308 |
value of the symbol. Unfortunately it handles common symbols in a |
|
309 |
non-standard way (it doesn't subtract the old value) but that's a |
BFD handles this by setting the addend to the negative of the |
310 |
different story (we can't change it without losing backward |
old value of the symbol. Unfortunately it handles common |
311 |
compatibility with old object files) (coff-i386 does subtract the old |
symbols in a non-standard way (it doesn't subtract the old |
312 |
value, to be compatible with existing coff-i386 targets, like SCO). |
value) but that's a different story (we can't change it |
313 |
|
without losing backward compatibility with old object files) |
314 |
So everything works fine when not producing relocateable output. When |
(coff-i386 does subtract the old value, to be compatible with |
315 |
we are producing relocateable output, logically we should do exactly |
existing coff-i386 targets, like SCO). |
316 |
what we do when not producing relocateable output. Therefore, your |
|
317 |
patch is correct. In fact, it should probably always just set |
So everything works fine when not producing relocatable |
318 |
reloc_entry->addend to 0 for all cases, since it is, in fact, going to |
output. When we are producing relocatable output, logically |
319 |
add the value into the object file. This won't hurt the COFF code, |
we should do exactly what we do when not producing |
320 |
which doesn't use the addend; I'm not sure what it will do to other |
relocatable output. Therefore, your patch is correct. In |
321 |
formats (the thing to check for would be whether any formats both use |
fact, it should probably always just set reloc_entry->addend |
322 |
the addend and set partial_inplace). |
to 0 for all cases, since it is, in fact, going to add the |
323 |
|
value into the object file. This won't hurt the COFF code, |
324 |
When I wanted to make coff-i386 produce relocateable output, I ran |
which doesn't use the addend; I'm not sure what it will do |
325 |
into the problem that you are running into: I wanted to remove that |
to other formats (the thing to check for would be whether |
326 |
line. Rather than risk it, I made the coff-i386 relocs use a special |
any formats both use the addend and set partial_inplace). |
327 |
function; it's coff_i386_reloc in coff-i386.c. The function |
|
328 |
specifically adds the addend field into the object file, knowing that |
When I wanted to make coff-i386 produce relocatable output, |
329 |
bfd_perform_relocation is not going to. If you remove that line, then |
I ran into the problem that you are running into: I wanted |
330 |
coff-i386.c will wind up adding the addend field in twice. It's |
to remove that line. Rather than risk it, I made the |
331 |
trivial to fix; it just needs to be done. |
coff-i386 relocs use a special function; it's coff_i386_reloc |
332 |
|
in coff-i386.c. The function specifically adds the addend |
333 |
The problem with removing the line is just that it may break some |
field into the object file, knowing that bfd_perform_relocation |
334 |
working code. With BFD it's hard to be sure of anything. The right |
is not going to. If you remove that line, then coff-i386.c |
335 |
way to deal with this is simply to build and test at least all the |
will wind up adding the addend field in twice. It's trivial |
336 |
supported COFF targets. It should be straightforward if time and disk |
to fix; it just needs to be done. |
337 |
space consuming. For each target: |
|
338 |
1) build the linker |
The problem with removing the line is just that it may break |
339 |
2) generate some executable, and link it using -r (I would |
some working code. With BFD it's hard to be sure of anything. |
340 |
probably use paranoia.o and link against newlib/libc.a, which |
The right way to deal with this is simply to build and test at |
341 |
for all the supported targets would be available in |
least all the supported COFF targets. It should be |
342 |
/usr/cygnus/progressive/H-host/target/lib/libc.a). |
straightforward if time and disk space consuming. For each |
343 |
3) make the change to reloc.c |
target: |
344 |
4) rebuild the linker |
1) build the linker |
345 |
5) repeat step 2 |
2) generate some executable, and link it using -r (I would |
346 |
6) if the resulting object files are the same, you have at least |
probably use paranoia.o and link against newlib/libc.a, |
347 |
made it no worse |
which for all the supported targets would be available in |
348 |
7) if they are different you have to figure out which version is |
/usr/cygnus/progressive/H-host/target/lib/libc.a). |
349 |
right |
3) make the change to reloc.c |
350 |
*/ |
4) rebuild the linker |
351 |
|
5) repeat step 2 |
352 |
|
6) if the resulting object files are the same, you have at |
353 |
|
least made it no worse |
354 |
|
7) if they are different you have to figure out which |
355 |
|
version is right. */ |
356 |
relocation -= reloc_entry->addend; |
relocation -= reloc_entry->addend; |
|
#endif |
|
357 |
reloc_entry->addend = 0; |
reloc_entry->addend = 0; |
358 |
} |
} |
359 |
else |
else |
450 |
} |
} |
451 |
} |
} |
452 |
|
|
453 |
/* |
/* Either we are relocating all the way, or we don't want to apply |
454 |
Either we are relocating all the way, or we don't want to apply |
the relocation to the reloc entry (probably because there isn't |
455 |
the relocation to the reloc entry (probably because there isn't |
any room in the output format to describe addends to relocs). */ |
|
any room in the output format to describe addends to relocs) |
|
|
*/ |
|
456 |
|
|
457 |
/* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler |
/* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler |
458 |
(OSF version 1.3, compiler version 3.11). It miscompiles the |
(OSF version 1.3, compiler version 3.11). It miscompiles the |
479 |
|
|
480 |
relocation >>= (bfd_vma) howto->rightshift; |
relocation >>= (bfd_vma) howto->rightshift; |
481 |
|
|
482 |
/* Shift everything up to where it's going to be used */ |
/* Shift everything up to where it's going to be used. */ |
|
|
|
483 |
relocation <<= (bfd_vma) howto->bitpos; |
relocation <<= (bfd_vma) howto->bitpos; |
484 |
|
|
485 |
/* Wait for the day when all have the mask in them */ |
/* Wait for the day when all have the mask in them. */ |
486 |
|
|
487 |
/* What we do: |
/* What we do: |
488 |
i instruction to be left alone |
i instruction to be left alone |
512 |
B B B B B |
B B B B B |
513 |
or A A A A A |
or A A A A A |
514 |
----------------------- |
----------------------- |
515 |
R R R R R R R R R R put into bfd_put<size> |
R R R R R R R R R R put into bfd_put<size>. */ |
|
*/ |
|
516 |
|
|
517 |
#define DOIT(x) \ |
#define DOIT(x) \ |
518 |
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) |
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) |
522 |
{ |
{ |
523 |
case 0: |
case 0: |
524 |
{ |
{ |
525 |
char x = get_data (location, 1); |
bfd_vma x = get_data (location, 1); |
526 |
DOIT (x); |
DOIT (x); |
527 |
overflow = put_data ((bfd_vma) x, location, 1); |
put_data ((bfd_vma) x, location, 1); |
528 |
} |
} |
529 |
break; |
break; |
530 |
|
|
531 |
case 1: |
case 1: |
532 |
if (relocation) |
if (relocation) |
533 |
{ |
{ |
534 |
short x = get_data (location, 2); |
bfd_vma x = get_data (location, 2); |
535 |
DOIT (x); |
DOIT (x); |
536 |
overflow = put_data ((bfd_vma) x, location, 2); |
put_data ((bfd_vma) x, location, 2); |
537 |
} |
} |
538 |
break; |
break; |
539 |
case 2: |
case 2: |
540 |
if (relocation) |
if (relocation) |
541 |
{ |
{ |
542 |
long x = get_data (location, 4); |
bfd_vma x = get_data (location, 4); |
543 |
DOIT (x); |
DOIT (x); |
544 |
overflow = put_data ((bfd_vma) x, location, 4); |
put_data ((bfd_vma) x, location, 4); |
545 |
} |
} |
546 |
break; |
break; |
547 |
case -2: |
case -2: |
548 |
{ |
{ |
549 |
long x = get_data (location, 4); |
bfd_vma x = get_data (location, 4); |
550 |
relocation = -relocation; |
relocation = -relocation; |
551 |
DOIT(x); |
DOIT(x); |
552 |
overflow = put_data ((bfd_vma) x, location, 4); |
put_data ((bfd_vma) x, location, 4); |
553 |
} |
} |
554 |
break; |
break; |
555 |
|
|
556 |
case 3: |
case 3: |
557 |
/* Do nothing */ |
/* Do nothing. */ |
558 |
break; |
break; |
559 |
|
|
560 |
case 4: |
case 4: |
563 |
{ |
{ |
564 |
bfd_vma x = get_data (location, 8); |
bfd_vma x = get_data (location, 8); |
565 |
DOIT (x); |
DOIT (x); |
566 |
overflow = put_data (x, location, 8); |
put_data (x, location, 8); |
567 |
} |
} |
568 |
#else |
#else |
569 |
abort (); |
abort (); |
588 |
bfd_vma relocation; |
bfd_vma relocation; |
589 |
bfd_byte *location; |
bfd_byte *location; |
590 |
bfd_vma (*get_data) PARAMS ((bfd_byte *, int)); |
bfd_vma (*get_data) PARAMS ((bfd_byte *, int)); |
591 |
int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int)); |
void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int)); |
592 |
{ |
{ |
593 |
int size; |
int size; |
594 |
bfd_vma x; |
bfd_vma x; |
595 |
boolean overflow; |
bfd_boolean overflow; |
596 |
|
|
597 |
/* If the size is negative, negate RELOCATION. This isn't very |
/* If the size is negative, negate RELOCATION. This isn't very |
598 |
general. */ |
general. */ |
620 |
which we don't check for. We must either check at every single |
which we don't check for. We must either check at every single |
621 |
operation, which would be tedious, or we must do the computations |
operation, which would be tedious, or we must do the computations |
622 |
in a type larger than bfd_vma, which would be inefficient. */ |
in a type larger than bfd_vma, which would be inefficient. */ |
623 |
overflow = false; |
overflow = FALSE; |
624 |
if (howto->complain_on_overflow != complain_overflow_dont) |
if (howto->complain_on_overflow != complain_overflow_dont) |
625 |
{ |
{ |
626 |
bfd_vma check; |
bfd_vma check; |
676 |
|
|
677 |
/* For the signed case we use ADD, rather than SIGNED_ADD, |
/* For the signed case we use ADD, rather than SIGNED_ADD, |
678 |
to avoid warnings from SVR4 cc. This is OK since we |
to avoid warnings from SVR4 cc. This is OK since we |
679 |
explictly handle the sign bits. */ |
explicitly handle the sign bits. */ |
680 |
if (signed_add >= 0) |
if (signed_add >= 0) |
681 |
signed_check += add >> howto->bitpos; |
signed_check += add >> howto->bitpos; |
682 |
else |
else |
695 |
|
|
696 |
if (signed_check > reloc_signed_max |
if (signed_check > reloc_signed_max |
697 |
|| signed_check < reloc_signed_min) |
|| signed_check < reloc_signed_min) |
698 |
overflow = true; |
overflow = TRUE; |
699 |
} |
} |
700 |
break; |
break; |
701 |
case complain_overflow_unsigned: |
case complain_overflow_unsigned: |
707 |
(((1 << (howto->bitsize - 1)) - 1) << 1) | 1; |
(((1 << (howto->bitsize - 1)) - 1) << 1) | 1; |
708 |
|
|
709 |
if (check > reloc_unsigned_max) |
if (check > reloc_unsigned_max) |
710 |
overflow = true; |
overflow = TRUE; |
711 |
} |
} |
712 |
break; |
break; |
713 |
case complain_overflow_bitfield: |
case complain_overflow_bitfield: |
720 |
if ((check & ~reloc_bits) != 0 |
if ((check & ~reloc_bits) != 0 |
721 |
&& (((bfd_vma) signed_check & ~reloc_bits) |
&& (((bfd_vma) signed_check & ~reloc_bits) |
722 |
!= (-(bfd_vma) 1 & ~reloc_bits))) |
!= (-(bfd_vma) 1 & ~reloc_bits))) |
723 |
overflow = true; |
overflow = TRUE; |
724 |
} |
} |
725 |
break; |
break; |
726 |
default: |
default: |
760 |
output_bfd, error_message) |
output_bfd, error_message) |
761 |
bfd *abfd; |
bfd *abfd; |
762 |
arelent *reloc_entry; |
arelent *reloc_entry; |
763 |
struct symbol_cache_entry *symbol; |
struct bfd_symbol *symbol; |
764 |
PTR data; |
PTR data; |
765 |
asection *input_section; |
asection *input_section; |
766 |
bfd *output_bfd; |
bfd *output_bfd; |
777 |
output_bfd, error_message) |
output_bfd, error_message) |
778 |
bfd *abfd; |
bfd *abfd; |
779 |
arelent *reloc_entry; |
arelent *reloc_entry; |
780 |
struct symbol_cache_entry *symbol; |
struct bfd_symbol *symbol; |
781 |
PTR data; |
PTR data; |
782 |
asection *input_section; |
asection *input_section; |
783 |
bfd *output_bfd; |
bfd *output_bfd; |
802 |
bfd_vma relocation; |
bfd_vma relocation; |
803 |
|
|
804 |
/* Sanity check the address. */ |
/* Sanity check the address. */ |
805 |
if (address > input_section->_cooked_size) |
if (address > bfd_get_section_limit (input_bfd, input_section)) |
806 |
return bfd_reloc_outofrange; |
return bfd_reloc_outofrange; |
807 |
|
|
808 |
/* This function assumes that we are dealing with a basic relocation |
/* This function assumes that we are dealing with a basic relocation |
816 |
location we are relocating. Some targets (e.g., i386-aout) |
location we are relocating. Some targets (e.g., i386-aout) |
817 |
arrange for the contents of the section to be the negative of the |
arrange for the contents of the section to be the negative of the |
818 |
offset of the location within the section; for such targets |
offset of the location within the section; for such targets |
819 |
pcrel_offset is false. Other targets (e.g., m88kbcs or ELF) |
pcrel_offset is FALSE. Other targets (e.g., m88kbcs or ELF) |
820 |
simply leave the contents of the section as zero; for such |
simply leave the contents of the section as zero; for such |
821 |
targets pcrel_offset is true. If pcrel_offset is false we do not |
targets pcrel_offset is TRUE. If pcrel_offset is FALSE we do not |
822 |
need to subtract out the offset of the location within the |
need to subtract out the offset of the location within the |
823 |
section (which is just ADDRESS). */ |
section (which is just ADDRESS). */ |
824 |
if (howto->pc_relative) |
if (howto->pc_relative) |