X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf32-microblaze.c;h=7b839f8c9a0c6fa4f95937ca8539ad4d2fbf0917;hb=d16c467a501547e37b111f775396e28f8bf27c1e;hp=f1808bc4450d967eece94b18106ba3aafbfbbe4c;hpb=219d1afa89d0d53ca93a684cac341f16470f3ca0;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c index f1808bc445..7b839f8c9a 100644 --- a/bfd/elf32-microblaze.c +++ b/bfd/elf32-microblaze.c @@ -1,6 +1,6 @@ /* Xilinx MicroBlaze-specific support for 32-bit ELF - Copyright (C) 2009-2018 Free Software Foundation, Inc. + Copyright (C) 2009-2020 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -251,6 +251,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] = 0x0000ffff, /* Dest Mask. */ TRUE), /* PC relative offset? */ + /* A 64 bit TEXTPCREL relocation. Table-entry not really used. */ + HOWTO (R_MICROBLAZE_TEXTPCREL_64, /* Type. */ + 0, /* Rightshift. */ + 2, /* Size (0 = byte, 1 = short, 2 = long). */ + 16, /* Bitsize. */ + TRUE, /* PC_relative. */ + 0, /* Bitpos. */ + complain_overflow_dont, /* Complain on overflow. */ + bfd_elf_generic_reloc, /* Special Function. */ + "R_MICROBLAZE_TEXTPCREL_64", /* Name. */ + FALSE, /* Partial Inplace. */ + 0, /* Source Mask. */ + 0x0000ffff, /* Dest Mask. */ + TRUE), /* PC relative offset? */ + /* A 64 bit GOT relocation. Table-entry not really used. */ HOWTO (R_MICROBLAZE_GOT_64, /* Type. */ 0, /* Rightshift. */ @@ -266,6 +281,21 @@ static reloc_howto_type microblaze_elf_howto_raw[] = 0x0000ffff, /* Dest Mask. */ FALSE), /* PC relative offset? */ + /* A 64 bit TEXTREL relocation. Table-entry not really used. */ + HOWTO (R_MICROBLAZE_TEXTREL_64, /* 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_elf_generic_reloc,/* Special Function. */ + "R_MICROBLAZE_TEXTREL_64",/* Name. */ + FALSE, /* Partial Inplace. */ + 0, /* Source Mask. */ + 0x0000ffff, /* Dest Mask. */ + FALSE), /* PC relative offset? */ + /* A 64 bit PLT relocation. Table-entry not really used. */ HOWTO (R_MICROBLAZE_PLT_64, /* Type. */ 0, /* Rightshift. */ @@ -578,6 +608,12 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, case BFD_RELOC_MICROBLAZE_64_GOT: microblaze_reloc = R_MICROBLAZE_GOT_64; break; + case BFD_RELOC_MICROBLAZE_64_TEXTPCREL: + microblaze_reloc = R_MICROBLAZE_TEXTPCREL_64; + break; + case BFD_RELOC_MICROBLAZE_64_TEXTREL: + microblaze_reloc = R_MICROBLAZE_TEXTREL_64; + break; case BFD_RELOC_MICROBLAZE_64_PLT: microblaze_reloc = R_MICROBLAZE_PLT_64; break; @@ -638,8 +674,8 @@ microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, /* Set the howto pointer for a RCE ELF reloc. */ -static void -microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, +static bfd_boolean +microblaze_elf_info_to_howto (bfd * abfd, arelent * cache_ptr, Elf_Internal_Rela * dst) { @@ -653,13 +689,14 @@ microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, if (r_type >= R_MICROBLAZE_max) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: unrecognised MicroBlaze reloc number: %d"), + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type); bfd_set_error (bfd_error_bad_value); - r_type = R_MICROBLAZE_NONE; + return FALSE; } cache_ptr->howto = microblaze_elf_howto_table [r_type]; + return TRUE; } /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */ @@ -929,7 +966,7 @@ microblaze_elf_relocate_section (bfd *output_bfd, if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: unknown relocation type %d"), + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), input_bfd, (int) r_type); bfd_set_error (bfd_error_bad_value); ret = FALSE; @@ -1034,7 +1071,7 @@ microblaze_elf_relocate_section (bfd *output_bfd, /* Only relocate if the symbol is defined. */ if (sec) { - name = bfd_get_section_name (sec->owner, sec); + name = bfd_section_name (sec); if (strcmp (name, ".sdata2") == 0 || strcmp (name, ".sbss2") == 0) @@ -1061,8 +1098,8 @@ microblaze_elf_relocate_section (bfd *output_bfd, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: The target (%s) of an %s relocation" - " is in the wrong section (%A)"), + (_("%pB: the target (%s) of an %s relocation" + " is in the wrong section (%pA)"), input_bfd, sym_name, microblaze_elf_howto_table[(int) r_type]->name, @@ -1082,7 +1119,7 @@ microblaze_elf_relocate_section (bfd *output_bfd, /* Only relocate if the symbol is defined. */ if (sec) { - name = bfd_get_section_name (sec->owner, sec); + name = bfd_section_name (sec); if (strcmp (name, ".sdata") == 0 || strcmp (name, ".sbss") == 0) @@ -1109,8 +1146,8 @@ microblaze_elf_relocate_section (bfd *output_bfd, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: The target (%s) of an %s relocation" - " is in the wrong section (%A)"), + (_("%pB: the target (%s) of an %s relocation" + " is in the wrong section (%pA)"), input_bfd, sym_name, microblaze_elf_howto_table[(int) r_type]->name, @@ -1139,6 +1176,18 @@ microblaze_elf_relocate_section (bfd *output_bfd, contents + offset + endian + INST_WORD_SIZE); break; + case (int) R_MICROBLAZE_TEXTPCREL_64: + relocation = input_section->output_section->vma; + relocation -= (input_section->output_section->vma + + input_section->output_offset + + offset + INST_WORD_SIZE); + relocation += addend; + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, + contents + offset + endian); + bfd_put_16 (input_bfd, relocation & 0xffff, + contents + offset + endian + INST_WORD_SIZE); + break; + case (int) R_MICROBLAZE_PLT_64: { bfd_vma immediate; @@ -1389,6 +1438,8 @@ microblaze_elf_relocate_section (bfd *output_bfd, bfd_put_16 (input_bfd, relocation & 0xffff, contents + offset + 2 + INST_WORD_SIZE); break; + case (int) R_MICROBLAZE_TEXTREL_64: + case (int) R_MICROBLAZE_TEXTREL_32_LO: case (int) R_MICROBLAZE_64_PCREL : case (int) R_MICROBLAZE_64: case (int) R_MICROBLAZE_32: @@ -1407,11 +1458,22 @@ microblaze_elf_relocate_section (bfd *output_bfd, relocation -= (input_section->output_section->vma + input_section->output_offset + offset + INST_WORD_SIZE); - bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, + else if (r_type == R_MICROBLAZE_TEXTREL_64 + || r_type == R_MICROBLAZE_TEXTREL_32_LO) + relocation -= input_section->output_section->vma; + + if (r_type == R_MICROBLAZE_TEXTREL_32_LO) + bfd_put_16 (input_bfd, relocation & 0xffff, + contents + offset + endian); + + else + { + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, contents + offset + endian); - bfd_put_16 (input_bfd, relocation & 0xffff, + bfd_put_16 (input_bfd, relocation & 0xffff, contents + offset + endian + INST_WORD_SIZE); } + } break; } @@ -1479,7 +1541,7 @@ microblaze_elf_relocate_section (bfd *output_bfd, { BFD_FAIL (); _bfd_error_handler - (_("%B: probably compiled without -fPIC?"), + (_("%pB: probably compiled without -fPIC?"), input_bfd); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -1502,11 +1564,24 @@ microblaze_elf_relocate_section (bfd *output_bfd, relocation -= (input_section->output_section->vma + input_section->output_offset + offset + INST_WORD_SIZE); - bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, - contents + offset + endian); - bfd_put_16 (input_bfd, relocation & 0xffff, - contents + offset + endian + INST_WORD_SIZE); - } + else if (r_type == R_MICROBLAZE_TEXTREL_64 + || r_type == R_MICROBLAZE_TEXTREL_32_LO) + relocation -= input_section->output_section->vma; + + if (r_type == R_MICROBLAZE_TEXTREL_32_LO) + { + bfd_put_16 (input_bfd, relocation & 0xffff, + contents + offset + endian); + } + else + { + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, + contents + offset + endian); + bfd_put_16 (input_bfd, relocation & 0xffff, + contents + offset + endian + + INST_WORD_SIZE); + } + } break; } } @@ -1533,7 +1608,7 @@ microblaze_elf_relocate_section (bfd *output_bfd, name = (bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name)); if (name == NULL || *name == '\0') - name = bfd_section_name (input_bfd, sec); + name = bfd_section_name (sec); } if (errmsg != NULL) @@ -1699,7 +1774,8 @@ microblaze_elf_relax_section (bfd *abfd, { bfd_vma symval; if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL) - && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 )) + && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64) + && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_TEXTREL_64)) continue; /* Can't delete this reloc. */ /* Get the section contents. */ @@ -1769,6 +1845,10 @@ microblaze_elf_relax_section (bfd *abfd, + sec->output_section->vma + sec->output_offset); } + else if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_TEXTREL_64) + { + symval = symval + irel->r_addend - (sec->output_section->vma); + } else symval += irel->r_addend; @@ -1791,6 +1871,10 @@ microblaze_elf_relax_section (bfd *abfd, irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), (int) R_MICROBLAZE_32_LO); break; + case R_MICROBLAZE_TEXTREL_64: + irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), + (int) R_MICROBLAZE_TEXTREL_32_LO); + break; default: /* Cannot happen. */ BFD_ASSERT (FALSE); @@ -1817,6 +1901,8 @@ microblaze_elf_relax_section (bfd *abfd, break; case R_MICROBLAZE_64_PCREL: break; + case R_MICROBLAZE_TEXTREL_64: + case R_MICROBLAZE_TEXTREL_32_LO: case R_MICROBLAZE_64: case R_MICROBLAZE_32_LO: /* If this reloc is against a symbol defined in this @@ -1953,7 +2039,10 @@ microblaze_elf_relax_section (bfd *abfd, } } else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO) - || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO)) + || (ELF32_R_TYPE (irelscan->r_info) + == (int) R_MICROBLAZE_32_LO) + || (ELF32_R_TYPE (irelscan->r_info) + == (int) R_MICROBLAZE_TEXTREL_32_LO)) { isym = isymbuf + ELF32_R_SYM (irelscan->r_info); @@ -1997,7 +2086,9 @@ microblaze_elf_relax_section (bfd *abfd, } } - if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64) + if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64 + || (ELF32_R_TYPE (irelscan->r_info) + == (int) R_MICROBLAZE_TEXTREL_64)) { isym = isymbuf + ELF32_R_SYM (irelscan->r_info); @@ -2675,7 +2766,7 @@ microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info, s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two)); if (power_of_two > s->alignment_power) { - if (!bfd_set_section_alignment (s->owner, s, power_of_two)) + if (!bfd_set_section_alignment (s, power_of_two)) return FALSE; } @@ -3024,7 +3115,7 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* It's OK to base decisions on the section name, because none of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); + name = bfd_section_name (s); if (strncmp (name, ".rela", 5) == 0) { @@ -3364,9 +3455,10 @@ microblaze_elf_finish_dynamic_sections (bfd *output_bfd, memset (splt->contents, 0, PLT_ENTRY_SIZE); bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */, splt->contents + splt->size - 4); - } - elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4; + if (splt->output_section != bfd_abs_section_ptr) + elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4; + } } /* Set the first entry in the global offset table to the address of @@ -3409,7 +3501,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd, put into .sbss. */ *secp = bfd_make_section_old_way (abfd, ".sbss"); if (*secp == NULL - || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON)) + || !bfd_set_section_flags (*secp, SEC_IS_COMMON)) return FALSE; *valp = sym->st_size;