X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felfn32-mips.c;h=00ec8b0c9b6886d2ef9e9057ad955dc8d2d1401e;hb=6177242a84b9139f50d23a2b86ac68da6183e10c;hp=9052dfd7e342baa4b93e05347ad6103c2b5375c2;hpb=cd123cb70c845b890eed231a84e6e84c92c2ef92;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index 9052dfd7e3..00ec8b0c9b 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -1,6 +1,6 @@ /* MIPS-specific support for 32-bit ELF Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Most of the information added by Ian Lance Taylor, Cygnus Support, . @@ -1301,7 +1301,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_TLS_DTPMOD32", /* name */ - TRUE, /* partial_inplace */ + FALSE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ @@ -1315,7 +1315,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] = complain_overflow_dont, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS_TLS_DTPREL32", /* name */ - TRUE, /* partial_inplace */ + FALSE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ FALSE), /* pcrel_offset */ @@ -1323,115 +1323,768 @@ static reloc_howto_type elf_mips_howto_table_rela[] = EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64), EMPTY_HOWTO (R_MIPS_TLS_DTPREL64), - /* TLS general dynamic variable reference. */ - HOWTO (R_MIPS_TLS_GD, /* type */ - 0, /* rightshift */ + /* TLS general dynamic variable reference. */ + HOWTO (R_MIPS_TLS_GD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_GD", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS local dynamic variable reference. */ + HOWTO (R_MIPS_TLS_LDM, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_LDM", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS local dynamic offset. */ + HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS local dynamic offset. */ + HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_DTPREL_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_GOTTPREL", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS IE dynamic relocations. */ + HOWTO (R_MIPS_TLS_TPREL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL32", /* name */ + FALSE, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + EMPTY_HOWTO (R_MIPS_TLS_TPREL64), + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* TLS thread pointer offset. */ + HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_TLS_TPREL_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 32 bit relocation with no addend. */ + HOWTO (R_MIPS_GLOB_DAT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GLOB_DAT", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ +}; + +static reloc_howto_type elf_mips16_howto_table_rel[] = +{ + /* The reloc used for the mips16 jump instruction. */ + HOWTO (R_MIPS16_26, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_26", /* name */ + TRUE, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* The reloc used for the mips16 gprel instruction. */ + HOWTO (R_MIPS16_GPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips16_gprel_reloc, /* special_function */ + "R_MIPS16_GPREL", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A MIPS16 reference to the global offset table. */ + HOWTO (R_MIPS16_GOT16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_got16_reloc, /* special_function */ + "R_MIPS16_GOT16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A MIPS16 call through the global offset table. */ + HOWTO (R_MIPS16_CALL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_CALL16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 high 16 bits of symbol value. */ + HOWTO (R_MIPS16_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MIPS16_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 low 16 bits of symbol value. */ + HOWTO (R_MIPS16_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MIPS16_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ +}; + +static reloc_howto_type elf_mips16_howto_table_rela[] = +{ + /* The reloc used for the mips16 jump instruction. */ + HOWTO (R_MIPS16_26, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_26", /* name */ + FALSE, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* The reloc used for the mips16 gprel instruction. */ + HOWTO (R_MIPS16_GPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + mips16_gprel_reloc, /* special_function */ + "R_MIPS16_GPREL", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A MIPS16 reference to the global offset table. */ + HOWTO (R_MIPS16_GOT16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_got16_reloc, /* special_function */ + "R_MIPS16_GOT16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* A MIPS16 call through the global offset table. */ + HOWTO (R_MIPS16_CALL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_CALL16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 high 16 bits of symbol value. */ + HOWTO (R_MIPS16_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MIPS16_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 low 16 bits of symbol value. */ + HOWTO (R_MIPS16_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MIPS16_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ +}; + +static reloc_howto_type elf_micromips_howto_table_rel[] = +{ + EMPTY_HOWTO (130), + EMPTY_HOWTO (131), + EMPTY_HOWTO (132), + + /* 26 bit jump address. */ + HOWTO (R_MICROMIPS_26_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_26_S1", /* name */ + TRUE, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 16 bits of symbol value. */ + HOWTO (R_MICROMIPS_HI16, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MICROMIPS_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Low 16 bits of symbol value. */ + HOWTO (R_MICROMIPS_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MICROMIPS_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* GP relative reference. */ + HOWTO (R_MICROMIPS_GPREL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf32_gprel16_reloc, /* special_function */ + "R_MICROMIPS_GPREL16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Reference to literal section. */ + HOWTO (R_MICROMIPS_LITERAL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf32_gprel16_reloc, /* special_function */ + "R_MICROMIPS_LITERAL", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Reference to global offset table. */ + HOWTO (R_MICROMIPS_GOT16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_got16_reloc, /* special_function */ + "R_MICROMIPS_GOT16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* This is for microMIPS branches. */ + HOWTO (R_MICROMIPS_PC7_S1, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 7, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_PC7_S1", /* name */ + TRUE, /* partial_inplace */ + 0x0000007f, /* src_mask */ + 0x0000007f, /* dst_mask */ + TRUE), /* pcrel_offset */ + + HOWTO (R_MICROMIPS_PC10_S1, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 10, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_PC10_S1", /* name */ + TRUE, /* partial_inplace */ + 0x000003ff, /* src_mask */ + 0x000003ff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + HOWTO (R_MICROMIPS_PC16_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_PC16_S1", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + /* 16 bit call through global offset table. */ + HOWTO (R_MICROMIPS_CALL16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_CALL16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + EMPTY_HOWTO (143), + EMPTY_HOWTO (144), + + /* Displacement in the global offset table. */ + HOWTO (R_MICROMIPS_GOT_DISP, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_DISP",/* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Displacement to page pointer in the global offset table. */ + HOWTO (R_MICROMIPS_GOT_PAGE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_PAGE",/* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Offset from page pointer in the global offset table. */ + HOWTO (R_MICROMIPS_GOT_OFST, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_OFST",/* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_GOT_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_HI16",/* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Low 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_GOT_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_LO16",/* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* 64 bit subtraction. Used in the N32 ABI. */ + HOWTO (R_MICROMIPS_SUB, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_SUB", /* name */ + TRUE, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* We don't support these for REL relocations, because it means building + the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/ + R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering, + using fallable heuristics. */ + EMPTY_HOWTO (R_MICROMIPS_HIGHER), + EMPTY_HOWTO (R_MICROMIPS_HIGHEST), + + /* High 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_CALL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_CALL_HI16",/* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* Low 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_CALL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_CALL_LO16",/* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ +}; + +static reloc_howto_type elf_micromips_howto_table_rela[] = +{ + EMPTY_HOWTO (130), + EMPTY_HOWTO (131), + EMPTY_HOWTO (132), + + /* 26 bit jump address. */ + HOWTO (R_MICROMIPS_26_S1, /* type */ + 1, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 26, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + /* This needs complex overflow + detection, because the upper four + bits must match the PC. */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_26_S1", /* name */ + FALSE, /* partial_inplace */ + 0x3ffffff, /* src_mask */ + 0x3ffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* High 16 bits of symbol value. */ + HOWTO (R_MICROMIPS_HI16, /* type */ + 16, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS_TLS_GD", /* name */ - TRUE, /* partial_inplace */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_hi16_reloc, /* special_function */ + "R_MICROMIPS_HI16", /* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* TLS local dynamic variable reference. */ - HOWTO (R_MIPS_TLS_LDM, /* type */ + /* Low 16 bits of symbol value. */ + HOWTO (R_MICROMIPS_LO16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS_TLS_LDM", /* name */ - TRUE, /* partial_inplace */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_lo16_reloc, /* special_function */ + "R_MICROMIPS_LO16", /* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* TLS local dynamic offset. */ - HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */ + /* GP relative reference. */ + HOWTO (R_MICROMIPS_GPREL16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS_TLS_DTPREL_HI16", /* name */ - TRUE, /* partial_inplace */ + _bfd_mips_elf32_gprel16_reloc, /* special_function */ + "R_MICROMIPS_GPREL16", /* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* TLS local dynamic offset. */ - HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */ + /* Reference to literal section. */ + HOWTO (R_MICROMIPS_LITERAL, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS_TLS_DTPREL_LO16", /* name */ - TRUE, /* partial_inplace */ + _bfd_mips_elf32_gprel16_reloc, /* special_function */ + "R_MICROMIPS_LITERAL", /* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* TLS thread pointer offset. */ - HOWTO (R_MIPS_TLS_GOTTPREL, /* type */ + /* Reference to global offset table. */ + HOWTO (R_MICROMIPS_GOT16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS_TLS_GOTTPREL", /* name */ - TRUE, /* partial_inplace */ + _bfd_mips_elf_got16_reloc, /* special_function */ + "R_MICROMIPS_GOT16", /* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* TLS IE dynamic relocations. */ - HOWTO (R_MIPS_TLS_TPREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - FALSE, /* pc_relative */ + /* This is for microMIPS branches. */ + HOWTO (R_MICROMIPS_PC7_S1, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 7, /* bitsize */ + TRUE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ + complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS_TLS_TPREL32", /* name */ - TRUE, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - FALSE), /* pcrel_offset */ + "R_MICROMIPS_PC7_S1", /* name */ + FALSE, /* partial_inplace */ + 0x0000007f, /* src_mask */ + 0x0000007f, /* dst_mask */ + TRUE), /* pcrel_offset */ - EMPTY_HOWTO (R_MIPS_TLS_TPREL64), + HOWTO (R_MICROMIPS_PC10_S1, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 10, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_PC10_S1", /* name */ + FALSE, /* partial_inplace */ + 0x000003ff, /* src_mask */ + 0x000003ff, /* dst_mask */ + TRUE), /* pcrel_offset */ - /* TLS thread pointer offset. */ - HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */ - 0, /* rightshift */ + HOWTO (R_MICROMIPS_PC16_S1, /* type */ + 1, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ - FALSE, /* pc_relative */ + TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS_TLS_TPREL_HI16", /* name */ - TRUE, /* partial_inplace */ + "R_MICROMIPS_PC16_S1", /* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ - FALSE), /* pcrel_offset */ + TRUE), /* pcrel_offset */ - /* TLS thread pointer offset. */ - HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */ + /* 16 bit call through global offset table. */ + HOWTO (R_MICROMIPS_CALL16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ @@ -1439,166 +2092,160 @@ static reloc_howto_type elf_mips_howto_table_rela[] = 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS_TLS_TPREL_LO16", /* name */ - TRUE, /* partial_inplace */ + "R_MICROMIPS_CALL16", /* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* 32 bit relocation with no addend. */ - HOWTO (R_MIPS_GLOB_DAT, /* type */ + EMPTY_HOWTO (143), + EMPTY_HOWTO (144), + + /* Displacement in the global offset table. */ + HOWTO (R_MICROMIPS_GOT_DISP, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ + 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ + complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS_GLOB_DAT", /* name */ + "R_MICROMIPS_GOT_DISP",/* name */ FALSE, /* partial_inplace */ - 0x0, /* src_mask */ - 0xffffffff, /* dst_mask */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ -}; -static reloc_howto_type elf_mips16_howto_table_rel[] = -{ - /* The reloc used for the mips16 jump instruction. */ - HOWTO (R_MIPS16_26, /* type */ - 2, /* rightshift */ + /* Displacement to page pointer in the global offset table. */ + HOWTO (R_MICROMIPS_GOT_PAGE, /* type */ + 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ + 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - /* This needs complex overflow - detection, because the upper four - bits must match the PC. */ + complain_overflow_signed, /* complain_on_overflow */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS16_26", /* name */ - TRUE, /* partial_inplace */ - 0x3ffffff, /* src_mask */ - 0x3ffffff, /* dst_mask */ + "R_MICROMIPS_GOT_PAGE",/* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* The reloc used for the mips16 gprel instruction. */ - HOWTO (R_MIPS16_GPREL, /* type */ + /* Offset from page pointer in the global offset table. */ + HOWTO (R_MICROMIPS_GOT_OFST, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - mips16_gprel_reloc, /* special_function */ - "R_MIPS16_GPREL", /* name */ - TRUE, /* partial_inplace */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_OFST",/* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ + 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* A placeholder for MIPS16 reference to global offset table. */ - EMPTY_HOWTO (R_MIPS16_GOT16), - - /* A placeholder for MIPS16 16 bit call through global offset table. */ - EMPTY_HOWTO (R_MIPS16_CALL16), - - /* MIPS16 high 16 bits of symbol value. */ - HOWTO (R_MIPS16_HI16, /* type */ - 16, /* rightshift */ + /* High 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_GOT_HI16, /* type */ + 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_hi16_reloc, /* special_function */ - "R_MIPS16_HI16", /* name */ - TRUE, /* partial_inplace */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_HI16",/* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* MIPS16 low 16 bits of symbol value. */ - HOWTO (R_MIPS16_LO16, /* type */ + /* Low 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_GOT_LO16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_lo16_reloc, /* special_function */ - "R_MIPS16_LO16", /* name */ - TRUE, /* partial_inplace */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_GOT_LO16",/* name */ + FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ -}; -static reloc_howto_type elf_mips16_howto_table_rela[] = -{ - /* The reloc used for the mips16 jump instruction. */ - HOWTO (R_MIPS16_26, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ + /* 64 bit subtraction. Used in the N32 ABI. */ + HOWTO (R_MICROMIPS_SUB, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - /* This needs complex overflow - detection, because the upper four - bits must match the PC. */ _bfd_mips_elf_generic_reloc, /* special_function */ - "R_MIPS16_26", /* name */ + "R_MICROMIPS_SUB", /* name */ FALSE, /* partial_inplace */ - 0x3ffffff, /* src_mask */ - 0x3ffffff, /* dst_mask */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ FALSE), /* pcrel_offset */ - /* The reloc used for the mips16 gprel instruction. */ - HOWTO (R_MIPS16_GPREL, /* type */ + /* Get the higher value of a 64 bit addend. */ + HOWTO (R_MICROMIPS_HIGHER, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips16_gprel_reloc, /* special_function */ - "R_MIPS16_GPREL", /* name */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_HIGHER", /* name */ FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ + 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* A placeholder for MIPS16 reference to global offset table. */ - EMPTY_HOWTO (R_MIPS16_GOT16), - - /* A placeholder for MIPS16 16 bit call through global offset table. */ - EMPTY_HOWTO (R_MIPS16_CALL16), + /* Get the highest value of a 64 bit addend. */ + HOWTO (R_MICROMIPS_HIGHEST, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_HIGHEST", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ - /* MIPS16 high 16 bits of symbol value. */ - HOWTO (R_MIPS16_HI16, /* type */ - 16, /* rightshift */ + /* High 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_CALL_HI16, /* type */ + 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_hi16_reloc, /* special_function */ - "R_MIPS16_HI16", /* name */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_CALL_HI16",/* name */ FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* MIPS16 low 16 bits of symbol value. */ - HOWTO (R_MIPS16_LO16, /* type */ + /* Low 16 bits of displacement in global offset table. */ + HOWTO (R_MICROMIPS_CALL_LO16, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 16, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - _bfd_mips_elf_lo16_reloc, /* special_function */ - "R_MIPS16_LO16", /* name */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MICROMIPS_CALL_LO16",/* name */ FALSE, /* partial_inplace */ 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ @@ -1669,6 +2316,38 @@ static reloc_howto_type elf_mips_gnu_rela16_s2 = 0x0000ffff, /* dst_mask */ TRUE); /* pcrel_offset */ +/* Originally a VxWorks extension, but now used for other systems too. */ +static reloc_howto_type elf_mips_copy_howto = + HOWTO (R_MIPS_COPY, /* type */ + 0, /* rightshift */ + 0, /* this one is variable size */ + 0, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_COPY", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0x0, /* dst_mask */ + FALSE); /* pcrel_offset */ + +/* Originally a VxWorks extension, but now used for other systems too. */ +static reloc_howto_type elf_mips_jump_slot_howto = + HOWTO (R_MIPS_JUMP_SLOT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_MIPS_JUMP_SLOT", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0x0, /* dst_mask */ + FALSE); /* pcrel_offset */ + /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a dangerous relocation. */ @@ -1967,13 +2646,13 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, return ret; location = (bfd_byte *) data + reloc_entry->address; - _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE, - location); + _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE, + location); ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, input_section, relocatable, data, gp); - _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable, - location); + _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable, + location); return ret; } @@ -2041,10 +2720,36 @@ static const struct elf_reloc_map mips16_reloc_map[] = { { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min }, { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min }, + { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min }, }; +static const struct elf_reloc_map micromips_reloc_map[] = +{ + { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min }, + { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min }, +}; + /* Given a BFD reloc type, return a howto structure. */ static reloc_howto_type * @@ -2056,6 +2761,7 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, relocation variant. */ reloc_howto_type *howto_table = elf_mips_howto_table_rela; reloc_howto_type *howto16_table = elf_mips16_howto_table_rela; + reloc_howto_type *howto_micromips_table = elf_micromips_howto_table_rela; for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++) @@ -2071,12 +2777,23 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &howto16_table[(int) mips16_reloc_map[i].elf_val]; } + for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map); + i++) + { + if (micromips_reloc_map[i].bfd_val == code) + return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val]; + } + switch (code) { case BFD_RELOC_VTABLE_INHERIT: return &elf_mips_gnu_vtinherit_howto; case BFD_RELOC_VTABLE_ENTRY: return &elf_mips_gnu_vtentry_howto; + case BFD_RELOC_MIPS_COPY: + return &elf_mips_copy_howto; + case BFD_RELOC_MIPS_JUMP_SLOT: + return &elf_mips_jump_slot_howto; default: bfd_set_error (bfd_error_bad_value); return NULL; @@ -2105,6 +2822,14 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, && strcasecmp (elf_mips16_howto_table_rela[i].name, r_name) == 0) return &elf_mips16_howto_table_rela[i]; + for (i = 0; + i < (sizeof (elf_micromips_howto_table_rela) + / sizeof (elf_micromips_howto_table_rela[0])); + i++) + if (elf_micromips_howto_table_rela[i].name != NULL + && strcasecmp (elf_micromips_howto_table_rela[i].name, r_name) == 0) + return &elf_micromips_howto_table_rela[i]; + if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0) return &elf_mips_gnu_vtinherit_howto; if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0) @@ -2113,6 +2838,10 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &elf_mips_gnu_rel16_s2; if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0) return &elf_mips_gnu_rela16_s2; + if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0) + return &elf_mips_copy_howto; + if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0) + return &elf_mips_jump_slot_howto; return NULL; } @@ -2133,7 +2862,18 @@ mips_elf_n32_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p) return &elf_mips_gnu_rela16_s2; else return &elf_mips_gnu_rel16_s2; + case R_MIPS_COPY: + return &elf_mips_copy_howto; + case R_MIPS_JUMP_SLOT: + return &elf_mips_jump_slot_howto; default: + if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max) + { + if (rela_p) + return &elf_micromips_howto_table_rela[r_type - R_MICROMIPS_min]; + else + return &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min]; + } if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max) { if (rela_p) @@ -2165,8 +2905,7 @@ mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) when we do the relocation, because the symbol manipulations done by the linker may cause us to lose track of the input BFD. */ if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0 - && (r_type == (unsigned int) R_MIPS_GPREL16 - || r_type == (unsigned int) R_MIPS_LITERAL)) + && (gprel16_reloc_p (r_type) || r_type == (unsigned int) R_MIPS_LITERAL)) cache_ptr->addend = elf_gp (abfd); } @@ -2195,7 +2934,7 @@ mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym) if (SGI_COMPAT (abfd)) return (sym->flags & BSF_SECTION_SYM) == 0; else - return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0 + return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0 || bfd_is_und_section (bfd_get_section (sym)) || bfd_is_com_section (bfd_get_section (sym))); } @@ -2239,7 +2978,7 @@ elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12); /* pr_pid */ - elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24); + elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24); /* pr_reg */ offset = 72; @@ -2338,6 +3077,7 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { }; #define ELF_ARCH bfd_arch_mips +#define ELF_TARGET_ID MIPS_ELF_DATA #define ELF_MACHINE_CODE EM_MIPS #define elf_backend_collect TRUE @@ -2361,6 +3101,7 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { #define elf_backend_check_relocs _bfd_mips_elf_check_relocs #define elf_backend_merge_symbol_attribute \ _bfd_mips_elf_merge_symbol_attribute +#define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag #define elf_backend_adjust_dynamic_symbol \ _bfd_mips_elf_adjust_dynamic_symbol #define elf_backend_always_size_sections \ @@ -2382,7 +3123,6 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook #define elf_backend_copy_indirect_symbol \ _bfd_mips_elf_copy_indirect_symbol -#define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol #define elf_backend_grok_prstatus elf32_mips_grok_prstatus #define elf_backend_grok_psinfo elf32_mips_grok_psinfo #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap @@ -2394,7 +3134,10 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { #define elf_backend_may_use_rel_p 1 #define elf_backend_may_use_rela_p 1 #define elf_backend_default_use_rela_p 1 +#define elf_backend_rela_plts_and_copies_p 0 #define elf_backend_sign_extend_vma TRUE +#define elf_backend_plt_readonly 1 +#define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val #define elf_backend_discard_info _bfd_mips_elf_discard_info #define elf_backend_ignore_discarded_relocs \ @@ -2402,6 +3145,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { #define elf_backend_write_section _bfd_mips_elf_write_section #define elf_backend_mips_irix_compat elf_n32_mips_irix_compat #define elf_backend_mips_rtype_to_howto mips_elf_n32_rtype_to_howto +#define bfd_elf32_bfd_is_target_special_symbol \ + _bfd_mips_elf_is_target_special_symbol #define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line #define bfd_elf32_find_inliner_info _bfd_mips_elf_find_inliner_info #define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook @@ -2450,3 +3195,36 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { /* Include the target file again for this target. */ #include "elf32-target.h" + + +/* FreeBSD support. */ + +#undef TARGET_LITTLE_SYM +#undef TARGET_LITTLE_NAME +#undef TARGET_BIG_SYM +#undef TARGET_BIG_NAME + +#define TARGET_LITTLE_SYM bfd_elf32_ntradlittlemips_freebsd_vec +#define TARGET_LITTLE_NAME "elf32-ntradlittlemips-freebsd" +#define TARGET_BIG_SYM bfd_elf32_ntradbigmips_freebsd_vec +#define TARGET_BIG_NAME "elf32-ntradbigmips-freebsd" + +#undef ELF_OSABI +#define ELF_OSABI ELFOSABI_FREEBSD + +/* The kernel recognizes executables as valid only if they carry a + "FreeBSD" label in the ELF header. So we put this label on all + executables and (for simplicity) also all other object files. */ + +static void +elf_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) +{ + _bfd_elf_set_osabi (abfd, info); +} + +#undef elf_backend_post_process_headers +#define elf_backend_post_process_headers elf_fbsd_post_process_headers +#undef elf32_bed +#define elf32_bed elf32_fbsd_tradbed + +#include "elf32-target.h"