diff options
author | Ken Raeburn <raeburn@cygnus> | 1994-05-27 16:58:05 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@cygnus> | 1994-05-27 16:58:05 +0000 |
commit | c06e55d99ac38bd32492481f46b69ec62ee1e433 (patch) | |
tree | 7567d7ea926780a1d5242d47399b3a267283bb3a /bfd/mipsbsd.c | |
parent | 60e8a534070c8dc181b2fb4971b8199597a168f1 (diff) | |
download | gdb-c06e55d99ac38bd32492481f46b69ec62ee1e433.zip gdb-c06e55d99ac38bd32492481f46b69ec62ee1e433.tar.gz gdb-c06e55d99ac38bd32492481f46b69ec62ee1e433.tar.bz2 |
changes from gas-2.3/binutils-2.4 dist (details in branch log msgs, changelogs)
Diffstat (limited to 'bfd/mipsbsd.c')
-rw-r--r-- | bfd/mipsbsd.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/bfd/mipsbsd.c b/bfd/mipsbsd.c index 020e5a2..29a41fb 100644 --- a/bfd/mipsbsd.c +++ b/bfd/mipsbsd.c @@ -178,6 +178,56 @@ MY(write_object_contents) (abfd) #define MIPS_RELOC_LO16 5 /* + * This is only called when performing a BFD_RELOC_MIPS_JMP relocation. + * The jump destination address is formed from the upper 4 bits of the + * "current" program counter concatenated with the jump instruction's + * 26 bit field and two trailing zeros. + * If the destination address is not in the same segment as the "current" + * program counter, then we need to signal an error. + */ +static bfd_reloc_status_type +mips_fix_jmp_addr (abfd,reloc_entry,symbol,data,input_section,output_bfd) + bfd *abfd; + arelent *reloc_entry; + struct symbol_cache_entry *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; +{ + bfd_vma relocation, pc; + + /* If this is a partial relocation, just continue. */ + if (output_bfd != (bfd *)NULL) + return bfd_reloc_continue; + + /* If this is an undefined symbol, return error */ + if (symbol->section == &bfd_und_section + && (symbol->flags & BSF_WEAK) == 0) + return bfd_reloc_undefined; + + /* + * Work out which section the relocation is targetted at and the + * initial relocation command value. + */ + if (bfd_is_com_section (symbol->section)) + relocation = 0; + else + relocation = symbol->value; + + relocation += symbol->section->output_section->vma; + relocation += symbol->section->output_offset; + relocation += reloc_entry->addend; + + pc = input_section->output_section->vma + input_section->output_offset + + reloc_entry->address + 4; + + if ((relocation & 0xF0000000) != (pc & 0xF0000000)) + return bfd_reloc_overflow; + + return bfd_reloc_continue; +} + +/* * This is only called when performing a BFD_RELOC_HI16_S relocation. * We need to see if bit 15 is set in the result. If it is, we add * 0x10000 and continue normally. This will compensate for the sign extension @@ -204,11 +254,16 @@ mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section, if (output_bfd != (bfd *)NULL) return bfd_reloc_continue; + /* If this is an undefined symbol, return error */ + if (symbol->section == &bfd_und_section + && (symbol->flags & BSF_WEAK) == 0) + return bfd_reloc_undefined; + /* * Work out which section the relocation is targetted at and the * initial relocation command value. */ - if (symbol->section == &bfd_com_section) + if (bfd_is_com_section (symbol->section)) relocation = 0; else relocation = symbol->value; @@ -226,7 +281,8 @@ mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section, static reloc_howto_type mips_howto_table_ext[] = { {MIPS_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", false, 0, 0xffffffff, false}, - {MIPS_RELOC_JMP, 2, 2, 26, false, 0, complain_overflow_bitfield, 0, + {MIPS_RELOC_JMP, 2, 2, 26, false, 0, complain_overflow_dont, + mips_fix_jmp_addr, "MIPS_JMP", false, 0, 0x03ffffff, false}, {MIPS_RELOC_WDISP16, 2, 1, 16, true, 0, complain_overflow_signed, 0, "WDISP16", false, 0, 0x0000ffff, false}, |