mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 06:45:56 +08:00
Wed Mar 30 16:25:41 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
Changes to let BFD return an error indication from get_symtab_upper_bound, bfd_canonicalize_symtab, bfd_get_reloc_upper_bound, and bfd_canonicalize_reloc. They now return long instead of unsigned int, and use -1 to indicate an error. Along the way, rename get_symtab_upper_bound to bfd_get_symtab_upper_bound. * bfd.c (bfd_get_reloc_upper_bound): Return long, and -1 on errors. (bfd_canonicalize_reloc): Likewise. * syms.c (bfd_get_symtab_upper_bound): Renamed from get_symtab_upper_bound. * targets.c (bfd_target): Renamed _get_symtab_upper_bound to _bfd_get_symtab_upper_bound, and changed it and _bfd_canonicalize_symtab and _get_reloc_upper_bound and _bfd_canonicalize_reloc to all return long. * aoutx.h (NAME(aout,get_symtab)): Return long, and -1 on errors. (NAME(aout,canonicalize_reloc)): Likewise. (NAME(aout,get_reloc_upper_bound)): Likewise. (NAME(aout,get_symtab_upper_bound)): Likewise. * bout.c (b_out_canonicalize_reloc): Likewise. (b_out_get_reloc_upper_bound): Likewise. * coffcode.h (coff_canonicalize_reloc): Likewise. * coffgen.c (coff_get_symtab_upper_bound): Likewise. (coff_get_symtab): Likewise. (coff_get_reloc_upper_bound): Likewise. * ecoff.c (ecoff_get_symtab_upper_bound): Likewise. (ecoff_get_symtab): Likewise. (ecoff_canonicalize_reloc): Likewise. * elfcode.h (elf_get_symtab_upper_bound): Likewise. (elf_get_reloc_upper_bound): Likewise. (elf_canonicalize_reloc): Likewise. (elf_get_symtab): Likewise. * hp300hpux.c (MY(get_symtab)): Likewise. (MY(get_symtab_upper_bound)): Likewise. (MY(canonicalize_reloc)): Likewise. * i386lynx.c (NAME(lynx,canonicalize_reloc)): Likewise. * ieee.c (ieee_slurp_external_symbols): Change return type to boolean. Check for errors from get_symbol. (ieee_slurp_symbol_table): Change return type to boolean. Check for errors from ieee_slurp_external_symbols. (ieee_get_symtab_upper_bound): Return long, and -1 on errors. (ieee_get_symtab): Likewise. (ieee_get_reloc_upper_bound): Likewise. (ieee_canonicalize_reloc): Likewise. * mipsbsd.c (MY(canonicalize_reloc)): Likewise. * nlmcode.h (nlm_get_symtab_upper_bound): Likewise. (nlm_get_symtab): Likewise. (nlm_get_reloc_upper_bound): Likewise. (nlm_canonicalize_reloc): Likewise. * oasys.c (oasys_get_symtab_upper_bound): Likewise. (oasys_get_symtab): Likewise. (oasys_get_reloc_upper_bound): Likewise. (oasys_canonicalize_reloc): Likewise. * som.c (som_get_symtab_upper_bound): Likewise. (som_get_symtab): Likewise. (som_get_reloc_upper_bound): Likewise. (som_canonicalize_reloc): Likewise. * srec.c (srec_get_symtab_upper_bound): Likewise. (srec_get_symtab): Likewise. (srec_get_reloc_upper_bound): Define as bfd_0l. (srec_canonicalize_reloc): Likewise. * tekhex.c (tekhex_get_symtab): Return long, and -1 on errors. (tekhex_get_symtab_upper_bound): Likewise. (tekhex_get_reloc_upper_bound): Define as bfd_0l. (tekhex_canonicalize_reloc): Likewise. * libaout.h (NAME(aout,get_symtab_upper_bound)): Change declaration to return long. (NAME(aout,get_symtab)): Likewise. (NAME(aout,canonicalize_reloc)): Likewise. (NAME(aout,get_reloc_upper_bound)): Likewise. * libcoff-in.h (coff_get_symtab_upper_bound): Likewise. (coff_get_symtab): Likewise. (coff_get_reloc_upper_bound): Likewise. * libecoff.h (ecoff_get_symtab_upper_bound): Likewise. (ecoff_get_symtab): Likewise. (ecoff_canonicalize_reloc): Likewise. * libelf.h (bfd_elf32_get_symtab_upper_bound): Likewise. (bfd_elf32_get_symtab): Likewise. (bfd_elf32_get_reloc_upper_bound): Likewise. (bfd_elf32_canonicalize_reloc): Likewise. (bfd_elf64_get_symtab_upper_bound): Likewise. (bfd_elf64_get_symtab): Likewise. (bfd_elf64_get_reloc_upper_bound): Likewise. (bfd_elf64_canonicalize_reloc): Likewise. * libnlm.h (nlmNAME(get_symtab_upper_bound)): Likewise. (nlmNAME(get_symtab)): Likewise. (nlmNAME(get_reloc_upper_bound)): Likewise. (nlmNAME(canonicalize_reloc)): Likewise. * archive.c (compute_and_write_armap): Use error_return and no_memory_return labels rather than freeing information in various places. Change storage, symcount and src_count to long. Check errors from bfd_get_symtab_upper_bound and bfd_canonicalize_symtab. * bout.c (b_out_relax_section): Change reloc_size to long. Check for errors from bfd_get_reloc_upper_bound and bfd_canonicalize_reloc. (b_out_get_relocated_section_contents): Likewise. * coff-alpha.c (alpha_ecoff_get_relocated_section_contents): Likewise. * elf32-mips.c: Likewise. * elf32-hppa.c (hppa_elf_stub_finish): Likewise. (hppa_look_for_stubs_in_section): Check for errors from bfd_get_symtab_upper_bound, bfd_canonicalize_symtab, and bfd_canonicalize_reloc. * ecofflink.c (bfd_ecoff_debug_accumulate_other): Check for errors from bfd_get_symtab_upper_bound and bfd_canonicalize_symtab. * linker.c (generic_link_read_symbols): Likewise. (_bfd_generic_final_link): Check for errors from bfd_get_reloc_upper_bound and bfd_canonicalize_reloc. * reloc.c (bfd_generic_get_relocated_section_contents): Likewise. * reloc16.c (bfd_coff_reloc16_relax_section): Likewise. (bfd_coff_reloc16_get_relocated_section_contents): Likewise. * libbfd.c (bfd_0l): New function. * libbfd-in.h (bfd_0l): Declare. * aix386-core.c: Change get_symtab_upper_bound, get_symtab, get_reloc_upper_bound, and canonicalize_reloc to use bfd_0l rather than bfd_0u. * cisco-core.c, hppabsd-core.c, hpux-core.c: Likewise. * irix-core.c, osf-core.c, ptrace-core.c, trad-core.c: Likewise. * bfd-in2.h: Rebuilt. * libbfd.h: Rebuilt. * libcoff.h: Rebuilt. * nlm32-sparc.c (nlm_sparc_read_reloc): Remove unused variables temp and name.
This commit is contained in:
432
bfd/reloc.c
432
bfd/reloc.c
@ -57,7 +57,7 @@ SUBSECTION
|
||||
|
||||
CODE_FRAGMENT
|
||||
.
|
||||
.typedef enum bfd_reloc_status
|
||||
.typedef enum bfd_reloc_status
|
||||
.{
|
||||
. {* No errors detected *}
|
||||
. bfd_reloc_ok,
|
||||
@ -89,7 +89,7 @@ CODE_FRAGMENT
|
||||
. bfd_reloc_status_type;
|
||||
.
|
||||
.
|
||||
.typedef struct reloc_cache_entry
|
||||
.typedef struct reloc_cache_entry
|
||||
.{
|
||||
. {* A pointer into the canonical table of pointers *}
|
||||
. struct symbol_cache_entry **sym_ptr_ptr;
|
||||
@ -98,7 +98,7 @@ CODE_FRAGMENT
|
||||
. bfd_size_type address;
|
||||
.
|
||||
. {* addend for relocation value *}
|
||||
. bfd_vma addend;
|
||||
. bfd_vma addend;
|
||||
.
|
||||
. {* Pointer to how to perform the required relocation *}
|
||||
. const struct reloc_howto_struct *howto;
|
||||
@ -162,7 +162,7 @@ DESCRIPTION
|
||||
|
||||
|
||||
|RELOCATION RECORDS FOR [.text]:
|
||||
|offset type value
|
||||
|offset type value
|
||||
|00000006 32 _foo
|
||||
|
|
||||
|00000000 4e56 fffc ; linkw fp,#-4
|
||||
@ -187,7 +187,7 @@ DESCRIPTION
|
||||
|
||||
|
||||
|RELOCATION RECORDS FOR [.text]:
|
||||
|offset type value
|
||||
|offset type value
|
||||
|00000002 HVRT16 _foo+0x12340000
|
||||
|00000006 LVRT16 _foo+0x12340000
|
||||
|
|
||||
@ -207,7 +207,7 @@ DESCRIPTION
|
||||
sparc the parts are created in odd sized lumps. The designers of
|
||||
the a.out format chose to not use the data within the section
|
||||
for storing part of the offset; all the offset is kept within
|
||||
the reloc. Anything in the data should be ignored.
|
||||
the reloc. Anything in the data should be ignored.
|
||||
|
||||
| save %sp,-112,%sp
|
||||
| sethi %hi(_foo+0x12345678),%g2
|
||||
@ -220,7 +220,7 @@ DESCRIPTION
|
||||
|
||||
|
||||
|RELOCATION RECORDS FOR [.text]:
|
||||
|offset type value
|
||||
|offset type value
|
||||
|00000004 HI22 _foo+0x12345678
|
||||
|00000008 LO10 _foo+0x12345678
|
||||
|
|
||||
@ -240,7 +240,7 @@ DESCRIPTION
|
||||
would normally have a relocation instruction set and turn
|
||||
relocations into pointers to the correct structure on input -
|
||||
but it would be possible to create each howto field on demand.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -273,7 +273,7 @@ CODE_FRAGMENT
|
||||
*/
|
||||
|
||||
/*
|
||||
SUBSUBSECTION
|
||||
SUBSUBSECTION
|
||||
<<reloc_howto_type>>
|
||||
|
||||
The <<reloc_howto_type>> is a structure which contains all the
|
||||
@ -282,8 +282,8 @@ SUBSUBSECTION
|
||||
CODE_FRAGMENT
|
||||
.struct symbol_cache_entry; {* Forward declaration *}
|
||||
.
|
||||
.typedef struct reloc_howto_struct
|
||||
.{
|
||||
.typedef struct reloc_howto_struct
|
||||
.{
|
||||
. {* The type field has mainly a documetary use - the back end can
|
||||
. do what it wants with it, though normally the back end's
|
||||
. external idea of what a reloc number is stored
|
||||
@ -323,12 +323,12 @@ CODE_FRAGMENT
|
||||
. called rather than the normal function. This allows really
|
||||
. strange relocation methods to be accomodated (e.g., i960 callj
|
||||
. instructions). *}
|
||||
. bfd_reloc_status_type (*special_function)
|
||||
. bfd_reloc_status_type (*special_function)
|
||||
. PARAMS ((bfd *abfd,
|
||||
. arelent *reloc_entry,
|
||||
. struct symbol_cache_entry *symbol,
|
||||
. PTR data,
|
||||
. asection *input_section,
|
||||
. asection *input_section,
|
||||
. bfd *output_bfd,
|
||||
. char **error_message));
|
||||
.
|
||||
@ -352,7 +352,7 @@ CODE_FRAGMENT
|
||||
. into the instruction. In most cases src_mask == dst_mask,
|
||||
. except in the above special case, where dst_mask would be
|
||||
. 0x000000ff, and src_mask would be 0x00000000. *}
|
||||
. bfd_vma dst_mask;
|
||||
. bfd_vma dst_mask;
|
||||
.
|
||||
. {* When some formats create PC relative instructions, they leave
|
||||
. the value of the pc of the place being relocated in the offset
|
||||
@ -397,7 +397,7 @@ DESCRIPTION
|
||||
. relocation = symbol->value; \
|
||||
. } \
|
||||
. } \
|
||||
.}
|
||||
.}
|
||||
|
||||
*/
|
||||
|
||||
@ -417,15 +417,16 @@ int
|
||||
bfd_get_reloc_size (howto)
|
||||
const reloc_howto_type *howto;
|
||||
{
|
||||
switch (howto->size) {
|
||||
case 0: return 1;
|
||||
case 1: return 2;
|
||||
case 2: return 4;
|
||||
case 3: return 0;
|
||||
case 4: return 8;
|
||||
case -2: return 4;
|
||||
default: abort ();
|
||||
}
|
||||
switch (howto->size)
|
||||
{
|
||||
case 0: return 1;
|
||||
case 1: return 2;
|
||||
case 2: return 4;
|
||||
case 3: return 0;
|
||||
case 4: return 8;
|
||||
case -2: return 4;
|
||||
default: abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -448,7 +449,7 @@ DESCRIPTION
|
||||
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
FUNCTION
|
||||
bfd_perform_relocation
|
||||
|
||||
SYNOPSIS
|
||||
@ -492,15 +493,15 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
|
||||
{
|
||||
bfd_vma relocation;
|
||||
bfd_reloc_status_type flag = bfd_reloc_ok;
|
||||
bfd_size_type addr = reloc_entry->address ;
|
||||
bfd_size_type addr = reloc_entry->address;
|
||||
bfd_vma output_base = 0;
|
||||
const reloc_howto_type *howto = reloc_entry->howto;
|
||||
asection *reloc_target_output_section;
|
||||
asymbol *symbol;
|
||||
|
||||
symbol = *(reloc_entry->sym_ptr_ptr);
|
||||
if ((symbol->section == &bfd_abs_section)
|
||||
&& output_bfd != (bfd *)NULL)
|
||||
if ((symbol->section == &bfd_abs_section)
|
||||
&& output_bfd != (bfd *) NULL)
|
||||
{
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
return bfd_reloc_ok;
|
||||
@ -544,7 +545,7 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
|
||||
reloc_target_output_section = symbol->section->output_section;
|
||||
|
||||
/* Convert input-section-relative symbol value to absolute. */
|
||||
if (output_bfd && howto->partial_inplace==false)
|
||||
if (output_bfd && howto->partial_inplace == false)
|
||||
output_base = 0;
|
||||
else
|
||||
output_base = reloc_target_output_section->vma;
|
||||
@ -587,28 +588,28 @@ bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
|
||||
actually does. I don't want to change it, because it seems
|
||||
far too likely that something will break. */
|
||||
|
||||
relocation -=
|
||||
relocation -=
|
||||
input_section->output_section->vma + input_section->output_offset;
|
||||
|
||||
if (howto->pcrel_offset == true)
|
||||
relocation -= reloc_entry->address;
|
||||
}
|
||||
|
||||
if (output_bfd!= (bfd *)NULL)
|
||||
if (output_bfd != (bfd *) NULL)
|
||||
{
|
||||
if ( howto->partial_inplace == false)
|
||||
if (howto->partial_inplace == false)
|
||||
{
|
||||
/* This is a partial relocation, and we want to apply the relocation
|
||||
to the reloc entry rather than the raw data. Modify the reloc
|
||||
inplace to reflect what we now know. */
|
||||
reloc_entry->addend = relocation;
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
return flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is a partial relocation, but inplace, so modify the
|
||||
reloc record a bit.
|
||||
reloc record a bit.
|
||||
|
||||
If we've relocated with a symbol with a section, change
|
||||
into a ref to the section belonging to the symbol. */
|
||||
@ -699,7 +700,7 @@ space consuming. For each target:
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
reloc_entry->addend = 0;
|
||||
}
|
||||
@ -727,14 +728,14 @@ space consuming. For each target:
|
||||
{
|
||||
/* Assumes two's complement. */
|
||||
bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
|
||||
bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
|
||||
bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
|
||||
|
||||
/* The above right shift is incorrect for a signed value.
|
||||
Fix it up by forcing on the upper bits. */
|
||||
if (howto->rightshift > howto->bitpos
|
||||
&& (bfd_signed_vma) relocation < 0)
|
||||
check |= ((bfd_vma) -1
|
||||
&~ ((bfd_vma) -1
|
||||
check |= ((bfd_vma) - 1
|
||||
& ~((bfd_vma) - 1
|
||||
>> (howto->rightshift - howto->bitpos)));
|
||||
if ((bfd_signed_vma) check > reloc_signed_max
|
||||
|| (bfd_signed_vma) check < reloc_signed_min)
|
||||
@ -747,7 +748,7 @@ space consuming. For each target:
|
||||
overflow if howto->bitsize is the number of bits in
|
||||
bfd_vma. */
|
||||
bfd_vma reloc_unsigned_max =
|
||||
(((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
|
||||
(((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
|
||||
|
||||
if ((bfd_vma) check > reloc_unsigned_max)
|
||||
flag = bfd_reloc_overflow;
|
||||
@ -760,8 +761,8 @@ space consuming. For each target:
|
||||
bfd_vma. */
|
||||
bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
|
||||
|
||||
if (((bfd_vma) check &~ reloc_bits) != 0
|
||||
&& ((bfd_vma) check &~ reloc_bits) != (-1 &~ reloc_bits))
|
||||
if (((bfd_vma) check & ~reloc_bits) != 0
|
||||
&& ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
|
||||
{
|
||||
/* The above right shift is incorrect for a signed
|
||||
value. See if turning on the upper bits fixes the
|
||||
@ -769,10 +770,10 @@ space consuming. For each target:
|
||||
if (howto->rightshift > howto->bitpos
|
||||
&& (bfd_signed_vma) relocation < 0)
|
||||
{
|
||||
check |= ((bfd_vma) -1
|
||||
&~ ((bfd_vma) -1
|
||||
check |= ((bfd_vma) - 1
|
||||
& ~((bfd_vma) - 1
|
||||
>> (howto->rightshift - howto->bitpos)));
|
||||
if (((bfd_vma) check &~ reloc_bits) != (-1 &~ reloc_bits))
|
||||
if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
|
||||
flag = bfd_reloc_overflow;
|
||||
}
|
||||
else
|
||||
@ -784,8 +785,8 @@ space consuming. For each target:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
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
|
||||
any room in the output format to describe addends to relocs)
|
||||
@ -817,7 +818,7 @@ space consuming. For each target:
|
||||
relocation >>= (bfd_vma) howto->rightshift;
|
||||
|
||||
/* Shift everything up to where it's going to be used */
|
||||
|
||||
|
||||
relocation <<= (bfd_vma) howto->bitpos;
|
||||
|
||||
/* Wait for the day when all have the mask in them */
|
||||
@ -832,23 +833,23 @@ space consuming. For each target:
|
||||
A part 1
|
||||
B part 2
|
||||
R result
|
||||
|
||||
|
||||
Do this:
|
||||
i i i i i o o o o o from bfd_get<size>
|
||||
and S S S S S to get the size offset we want
|
||||
+ r r r r r r r r r r to get the final value to place
|
||||
and D D D D D to chop to right size
|
||||
-----------------------
|
||||
A A A A A
|
||||
A A A A A
|
||||
And this:
|
||||
... i i i i i o o o o o from bfd_get<size>
|
||||
and N N N N N get instruction
|
||||
-----------------------
|
||||
... B B B B B
|
||||
|
||||
And then:
|
||||
B B B B B
|
||||
or A A A A A
|
||||
|
||||
And then:
|
||||
B B B B B
|
||||
or A A A A A
|
||||
-----------------------
|
||||
R R R R R R R R R R put into bfd_put<size>
|
||||
*/
|
||||
@ -856,60 +857,60 @@ space consuming. For each target:
|
||||
#define DOIT(x) \
|
||||
x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
|
||||
|
||||
switch (howto->size)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
char x = bfd_get_8(abfd, (char *)data + addr);
|
||||
DOIT(x);
|
||||
bfd_put_8(abfd,x, (unsigned char *) data + addr);
|
||||
}
|
||||
break;
|
||||
switch (howto->size)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
char x = bfd_get_8 (abfd, (char *) data + addr);
|
||||
DOIT (x);
|
||||
bfd_put_8 (abfd, x, (unsigned char *) data + addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (relocation)
|
||||
{
|
||||
short x = bfd_get_16(abfd, (bfd_byte *)data + addr);
|
||||
DOIT(x);
|
||||
bfd_put_16(abfd, x, (unsigned char *)data + addr);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (relocation)
|
||||
{
|
||||
long x = bfd_get_32 (abfd, (bfd_byte *) data + addr);
|
||||
DOIT (x);
|
||||
bfd_put_32 (abfd, x, (bfd_byte *)data + addr);
|
||||
}
|
||||
break;
|
||||
case -2:
|
||||
{
|
||||
long x = bfd_get_32(abfd, (bfd_byte *) data + addr);
|
||||
relocation = -relocation;
|
||||
DOIT(x);
|
||||
bfd_put_32(abfd,x, (bfd_byte *)data + addr);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (relocation)
|
||||
{
|
||||
short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
|
||||
DOIT (x);
|
||||
bfd_put_16 (abfd, x, (unsigned char *) data + addr);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (relocation)
|
||||
{
|
||||
long x = bfd_get_32 (abfd, (bfd_byte *) data + addr);
|
||||
DOIT (x);
|
||||
bfd_put_32 (abfd, x, (bfd_byte *) data + addr);
|
||||
}
|
||||
break;
|
||||
case -2:
|
||||
{
|
||||
long x = bfd_get_32 (abfd, (bfd_byte *) data + addr);
|
||||
relocation = -relocation;
|
||||
DOIT (x);
|
||||
bfd_put_32 (abfd, x, (bfd_byte *) data + addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* Do nothing */
|
||||
break;
|
||||
case 3:
|
||||
/* Do nothing */
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 4:
|
||||
#ifdef BFD64
|
||||
if (relocation)
|
||||
{
|
||||
bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + addr);
|
||||
DOIT (x);
|
||||
bfd_put_64 (abfd, x, (bfd_byte *) data + addr);
|
||||
}
|
||||
if (relocation)
|
||||
{
|
||||
bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + addr);
|
||||
DOIT (x);
|
||||
bfd_put_64 (abfd, x, (bfd_byte *) data + addr);
|
||||
}
|
||||
#else
|
||||
abort ();
|
||||
abort ();
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return bfd_reloc_other;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return bfd_reloc_other;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
@ -937,7 +938,7 @@ space consuming. For each target:
|
||||
|
||||
bfd_reloc_status_type
|
||||
_bfd_final_link_relocate (howto, input_bfd, input_section, contents, address,
|
||||
value, addend)
|
||||
value, addend)
|
||||
const reloc_howto_type *howto;
|
||||
bfd *input_bfd;
|
||||
asection *input_section;
|
||||
@ -975,7 +976,7 @@ _bfd_final_link_relocate (howto, input_bfd, input_section, contents, address,
|
||||
if (howto->pcrel_offset)
|
||||
relocation -= address;
|
||||
}
|
||||
|
||||
|
||||
return _bfd_relocate_contents (howto, input_bfd, relocation,
|
||||
contents + address);
|
||||
}
|
||||
@ -996,7 +997,7 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
|
||||
/* If the size is negative, negate RELOCATION. This isn't very
|
||||
general. */
|
||||
if (howto->size < 0)
|
||||
relocation = - relocation;
|
||||
relocation = -relocation;
|
||||
|
||||
/* Get the value we are going to relocate. */
|
||||
size = bfd_get_reloc_size (howto);
|
||||
@ -1051,8 +1052,8 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
|
||||
signed_check = check;
|
||||
else
|
||||
signed_check = (check
|
||||
| ((bfd_vma) -1
|
||||
&~ ((bfd_vma) -1 >> howto->rightshift)));
|
||||
| ((bfd_vma) - 1
|
||||
& ~((bfd_vma) - 1 >> howto->rightshift)));
|
||||
}
|
||||
|
||||
/* Get the value from the object file. */
|
||||
@ -1067,8 +1068,8 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
|
||||
signed_add needs no adjustment to become negative in that
|
||||
case. */
|
||||
signed_add = add;
|
||||
if ((add & (((~ howto->src_mask) >> 1) & howto->src_mask)) != 0)
|
||||
signed_add -= (((~ howto->src_mask) >> 1) & howto->src_mask) << 1;
|
||||
if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
|
||||
signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
|
||||
|
||||
/* Add the value from the object file, shifted so that it is a
|
||||
straight number. */
|
||||
@ -1088,8 +1089,8 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
|
||||
signed_check += add >> howto->bitpos;
|
||||
else
|
||||
signed_check += ((add >> howto->bitpos)
|
||||
| ((bfd_vma) -1
|
||||
&~ ((bfd_vma) -1 >> howto->bitpos)));
|
||||
| ((bfd_vma) - 1
|
||||
& ~((bfd_vma) - 1 >> howto->bitpos)));
|
||||
}
|
||||
|
||||
switch (howto->complain_on_overflow)
|
||||
@ -1098,7 +1099,7 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
|
||||
{
|
||||
/* Assumes two's complement. */
|
||||
bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
|
||||
bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
|
||||
bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
|
||||
|
||||
if (signed_check > reloc_signed_max
|
||||
|| signed_check < reloc_signed_min)
|
||||
@ -1111,7 +1112,7 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
|
||||
overflow if howto->bitsize is the number of bits in
|
||||
bfd_vma. */
|
||||
bfd_vma reloc_unsigned_max =
|
||||
(((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
|
||||
(((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
|
||||
|
||||
if (check > reloc_unsigned_max)
|
||||
overflow = true;
|
||||
@ -1124,9 +1125,9 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
|
||||
bfd_vma. */
|
||||
bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
|
||||
|
||||
if ((check &~ reloc_bits) != 0
|
||||
&& (((bfd_vma) signed_check &~ reloc_bits)
|
||||
!= (-1 &~ reloc_bits)))
|
||||
if ((check & ~reloc_bits) != 0
|
||||
&& (((bfd_vma) signed_check & ~reloc_bits)
|
||||
!= (-1 & ~reloc_bits)))
|
||||
overflow = true;
|
||||
}
|
||||
break;
|
||||
@ -1140,7 +1141,7 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location)
|
||||
relocation <<= (bfd_vma) howto->bitpos;
|
||||
|
||||
/* Add RELOCATION to the right bits of X. */
|
||||
x = ((x &~ howto->dst_mask)
|
||||
x = ((x & ~howto->dst_mask)
|
||||
| (((x & howto->src_mask) + relocation) & howto->dst_mask));
|
||||
|
||||
/* Put the relocated value back in the object file. */
|
||||
@ -1176,7 +1177,7 @@ INODE
|
||||
howto manager, , typedef arelent, Relocations
|
||||
|
||||
SECTION
|
||||
The howto manager
|
||||
The howto manager
|
||||
|
||||
When an application wants to create a relocation, but doesn't
|
||||
know what the target machine might call it, it can find out by
|
||||
@ -1200,12 +1201,12 @@ DESCRIPTION
|
||||
|
||||
CODE_FRAGMENT
|
||||
.
|
||||
.typedef enum bfd_reloc_code_real
|
||||
.typedef enum bfd_reloc_code_real
|
||||
.{
|
||||
. {* Basic absolute relocations *}
|
||||
. BFD_RELOC_64,
|
||||
. BFD_RELOC_32,
|
||||
. BFD_RELOC_16,
|
||||
. BFD_RELOC_16,
|
||||
. BFD_RELOC_14,
|
||||
. BFD_RELOC_8,
|
||||
.
|
||||
@ -1494,15 +1495,15 @@ DESCRIPTION
|
||||
|
||||
|
||||
const struct reloc_howto_struct *
|
||||
DEFUN(bfd_reloc_type_lookup,(abfd, code),
|
||||
bfd *abfd AND
|
||||
bfd_reloc_code_real_type code)
|
||||
bfd_reloc_type_lookup (abfd, code)
|
||||
bfd *abfd;
|
||||
bfd_reloc_code_real_type code;
|
||||
{
|
||||
return BFD_SEND (abfd, reloc_type_lookup, (abfd, code));
|
||||
}
|
||||
|
||||
static reloc_howto_type bfd_howto_32 =
|
||||
HOWTO(0, 00,2,32,false,0,complain_overflow_bitfield,0,"VRT32", false,0xffffffff,0xffffffff,true);
|
||||
HOWTO (0, 00, 2, 32, false, 0, complain_overflow_bitfield, 0, "VRT32", false, 0xffffffff, 0xffffffff, true);
|
||||
|
||||
|
||||
/*
|
||||
@ -1511,8 +1512,7 @@ INTERNAL_FUNCTION
|
||||
|
||||
SYNOPSIS
|
||||
const struct reloc_howto_struct *bfd_default_reloc_type_lookup
|
||||
(bfd *abfd AND
|
||||
bfd_reloc_code_real_type code);
|
||||
(bfd *abfd, bfd_reloc_code_real_type code);
|
||||
|
||||
DESCRIPTION
|
||||
Provides a default relocation lookup routine for any architecture.
|
||||
@ -1521,29 +1521,30 @@ DESCRIPTION
|
||||
*/
|
||||
|
||||
const struct reloc_howto_struct *
|
||||
DEFUN(bfd_default_reloc_type_lookup, (abfd, code),
|
||||
bfd *abfd AND
|
||||
bfd_reloc_code_real_type code)
|
||||
bfd_default_reloc_type_lookup (abfd, code)
|
||||
bfd *abfd;
|
||||
bfd_reloc_code_real_type code;
|
||||
{
|
||||
switch (code)
|
||||
switch (code)
|
||||
{
|
||||
case BFD_RELOC_CTOR:
|
||||
/* The type of reloc used in a ctor, which will be as wide as the
|
||||
address - so either a 64, 32, or 16 bitter. */
|
||||
switch (bfd_get_arch_info (abfd)->bits_per_address) {
|
||||
case 64:
|
||||
BFD_FAIL();
|
||||
case 32:
|
||||
return &bfd_howto_32;
|
||||
case 16:
|
||||
BFD_FAIL();
|
||||
default:
|
||||
BFD_FAIL();
|
||||
}
|
||||
switch (bfd_get_arch_info (abfd)->bits_per_address)
|
||||
{
|
||||
case 64:
|
||||
BFD_FAIL ();
|
||||
case 32:
|
||||
return &bfd_howto_32;
|
||||
case 16:
|
||||
BFD_FAIL ();
|
||||
default:
|
||||
BFD_FAIL ();
|
||||
}
|
||||
default:
|
||||
BFD_FAIL();
|
||||
BFD_FAIL ();
|
||||
}
|
||||
return (const struct reloc_howto_struct *)NULL;
|
||||
return (const struct reloc_howto_struct *) NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1556,7 +1557,7 @@ SYNOPSIS
|
||||
(bfd *abfd,
|
||||
asection *section,
|
||||
struct bfd_link_info *,
|
||||
asymbol **symbols);
|
||||
boolean *);
|
||||
|
||||
DESCRIPTION
|
||||
Provides default handling for relaxing for back ends which
|
||||
@ -1565,15 +1566,16 @@ DESCRIPTION
|
||||
|
||||
/*ARGSUSED*/
|
||||
boolean
|
||||
bfd_generic_relax_section (abfd, section, link_info, symbols)
|
||||
bfd_generic_relax_section (abfd, section, link_info, again)
|
||||
bfd *abfd;
|
||||
asection *section;
|
||||
struct bfd_link_info *link_info;
|
||||
asymbol **symbols;
|
||||
boolean *again;
|
||||
{
|
||||
return false;
|
||||
*again = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_generic_get_relocated_section_contents
|
||||
@ -1607,95 +1609,101 @@ bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data,
|
||||
bfd *input_bfd = link_order->u.indirect.section->owner;
|
||||
asection *input_section = link_order->u.indirect.section;
|
||||
|
||||
size_t reloc_size = bfd_get_reloc_upper_bound(input_bfd, input_section);
|
||||
long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
|
||||
arelent **reloc_vector = NULL;
|
||||
long reloc_count;
|
||||
|
||||
if (reloc_size < 0)
|
||||
goto error_return;
|
||||
|
||||
reloc_vector = (arelent **) malloc (reloc_size);
|
||||
if (reloc_vector == NULL)
|
||||
if (reloc_vector == NULL && reloc_size != 0)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
|
||||
/* read in the section */
|
||||
if (!bfd_get_section_contents(input_bfd,
|
||||
input_section,
|
||||
(PTR) data,
|
||||
0,
|
||||
input_section->_raw_size))
|
||||
if (!bfd_get_section_contents (input_bfd,
|
||||
input_section,
|
||||
(PTR) data,
|
||||
0,
|
||||
input_section->_raw_size))
|
||||
goto error_return;
|
||||
|
||||
/* We're not relaxing the section, so just copy the size info */
|
||||
input_section->_cooked_size = input_section->_raw_size;
|
||||
input_section->reloc_done = true;
|
||||
|
||||
if (!bfd_canonicalize_reloc (input_bfd,
|
||||
input_section,
|
||||
reloc_vector,
|
||||
symbols))
|
||||
reloc_count = bfd_canonicalize_reloc (input_bfd,
|
||||
input_section,
|
||||
reloc_vector,
|
||||
symbols);
|
||||
if (reloc_count < 0)
|
||||
goto error_return;
|
||||
|
||||
{
|
||||
arelent **parent;
|
||||
for (parent = reloc_vector; * parent != (arelent *)NULL;
|
||||
parent++)
|
||||
{
|
||||
char *error_message = (char *) NULL;
|
||||
bfd_reloc_status_type r=
|
||||
bfd_perform_relocation(input_bfd,
|
||||
*parent,
|
||||
(PTR) data,
|
||||
input_section,
|
||||
relocateable ? abfd : (bfd *) NULL,
|
||||
&error_message);
|
||||
|
||||
if (relocateable)
|
||||
if (reloc_count > 0)
|
||||
{
|
||||
arelent **parent;
|
||||
for (parent = reloc_vector; *parent != (arelent *) NULL;
|
||||
parent++)
|
||||
{
|
||||
asection *os = input_section->output_section;
|
||||
char *error_message = (char *) NULL;
|
||||
bfd_reloc_status_type r =
|
||||
bfd_perform_relocation (input_bfd,
|
||||
*parent,
|
||||
(PTR) data,
|
||||
input_section,
|
||||
relocateable ? abfd : (bfd *) NULL,
|
||||
&error_message);
|
||||
|
||||
/* A partial link, so keep the relocs */
|
||||
os->orelocation[os->reloc_count] = *parent;
|
||||
os->reloc_count++;
|
||||
if (relocateable)
|
||||
{
|
||||
asection *os = input_section->output_section;
|
||||
|
||||
/* A partial link, so keep the relocs */
|
||||
os->orelocation[os->reloc_count] = *parent;
|
||||
os->reloc_count++;
|
||||
}
|
||||
|
||||
if (r != bfd_reloc_ok)
|
||||
{
|
||||
switch (r)
|
||||
{
|
||||
case bfd_reloc_undefined:
|
||||
if (!((*link_info->callbacks->undefined_symbol)
|
||||
(link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
|
||||
input_bfd, input_section, (*parent)->address)))
|
||||
goto error_return;
|
||||
break;
|
||||
case bfd_reloc_dangerous:
|
||||
BFD_ASSERT (error_message != (char *) NULL);
|
||||
if (!((*link_info->callbacks->reloc_dangerous)
|
||||
(link_info, error_message, input_bfd, input_section,
|
||||
(*parent)->address)))
|
||||
goto error_return;
|
||||
break;
|
||||
case bfd_reloc_overflow:
|
||||
if (!((*link_info->callbacks->reloc_overflow)
|
||||
(link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
|
||||
(*parent)->howto->name, (*parent)->addend,
|
||||
input_bfd, input_section, (*parent)->address)))
|
||||
goto error_return;
|
||||
break;
|
||||
case bfd_reloc_outofrange:
|
||||
default:
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (r != bfd_reloc_ok)
|
||||
{
|
||||
switch (r)
|
||||
{
|
||||
case bfd_reloc_undefined:
|
||||
if (! ((*link_info->callbacks->undefined_symbol)
|
||||
(link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
|
||||
input_bfd, input_section, (*parent)->address)))
|
||||
goto error_return;
|
||||
break;
|
||||
case bfd_reloc_dangerous:
|
||||
BFD_ASSERT (error_message != (char *) NULL);
|
||||
if (! ((*link_info->callbacks->reloc_dangerous)
|
||||
(link_info, error_message, input_bfd, input_section,
|
||||
(*parent)->address)))
|
||||
goto error_return;
|
||||
break;
|
||||
case bfd_reloc_overflow:
|
||||
if (! ((*link_info->callbacks->reloc_overflow)
|
||||
(link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
|
||||
(*parent)->howto->name, (*parent)->addend,
|
||||
input_bfd, input_section, (*parent)->address)))
|
||||
goto error_return;
|
||||
break;
|
||||
case bfd_reloc_outofrange:
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reloc_vector != NULL)
|
||||
free (reloc_vector);
|
||||
return data;
|
||||
|
||||
error_return:
|
||||
error_return:
|
||||
if (reloc_vector != NULL)
|
||||
free (reloc_vector);
|
||||
return NULL;
|
||||
|
Reference in New Issue
Block a user