aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorMichael Eager <eager@eagercon.com>2018-04-17 14:47:13 -0700
committerMichael Eager <eager@eagercon.com>2018-04-17 14:47:13 -0700
commit3f0a5f17d7fe1f3d0911ad67a5993be59983fb00 (patch)
tree76261ae8c3c1153a62dc11d955eb7502ef6c8483 /bfd
parentbedda9aced2b3a8ab05e0fbf1372e394e32afbde (diff)
downloadgdb-3f0a5f17d7fe1f3d0911ad67a5993be59983fb00.zip
gdb-3f0a5f17d7fe1f3d0911ad67a5993be59983fb00.tar.gz
gdb-3f0a5f17d7fe1f3d0911ad67a5993be59983fb00.tar.bz2
[MicroBlaze] PIC data text relative
Andrew Sadek <andrew.sadek.se@gmail.com> A new implemented feature in GCC Microblaze that allows Position Independent Code to run using Data Text Relative addressing instead of using Global Offset Table. Its aim was to make 'PIC' more efficient and flexible as elf size excess performance overhead were noticed when using GOT due to the indirect addressing. include/ChangeLog: * bfdlink.h (Add flag): Add new flag @ 'bfd_link_info' struct. * elf/microblaze.h (Add 3 new relocations): R_MICROBLAZE_TEXTPCREL_64, R_MICROBLAZE_TEXTREL_64 and R_MICROBLAZE_TEXTREL_32_LO for relax function. bfd/ChangeLog: * bfd/reloc.c (2 new BFD relocations): BFD_RELOC_MICROBLAZE_64_TEXTPCREL & BFD_RELOC_MICROBLAZE_64_TEXTPCREL * bfd/bfd-in2.h: Regenerate * bfd/libbfd.h: Regenerate * bfd/elf32-microblaze.c (Handle new relocs): define 'HOWTO' of 3 new relocs and handle them in both relocate and relax functions. (microblaze_elf_reloc_type_lookup): add mapping between for new bfd relocs. (microblaze_elf_relocate_section): Handle new relocs in case of elf relocation. (microblaze_elf_relax_section): Handle new relocs for elf relaxation. gas/ChangeLog: * gas/config/tc-microblaze.c (Handle new relocs directives in assembler): Handle new relocs from compiler output. (imm_types): add new imm types for data text relative addressing TEXT_OFFSET, TEXT_PC_OFFSET (md_convert_frag): conversion for BFD_RELOC_MICROBLAZE_64_TEXTPCREL, BFD_RELOC_MICROBLAZE_64_TEXTPCREL (md_apply_fix): apply fix for BFD_RELOC_MICROBLAZE_64_TEXTPCREL, BFD_RELOC_MICROBLAZE_64_TEXTPCREL (md_estimate_size_before_relax): estimate size for BFD_RELOC_MICROBLAZE_64_TEXTPCREL, BFD_RELOC_MICROBLAZE_64_TEXTPCREL (tc_gen_reloc): generate relocations for BFD_RELOC_MICROBLAZE_64_TEXTPCREL, BFD_RELOC_MICROBLAZE_64_TEXTPCREL ld/ChangeLog: * ld/lexsup.c (Add 2 ld options): (ld_options): add disable-multiple-abs-defs @ 'ld_options' array (parse_args): parse new option and pass flag to 'link_info' struct. * ld/ldlex.h (Add enum): add new enum @ 'option_values' enum. * ld/ld.texinfo (Add new option): Add description for 'disable-multiple-abs-defs' * ld/main.c: Initialize flags with false @ 'main'. Handle disable-multiple-abs-defs @ 'mutiple_definition'.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog17
-rw-r--r--bfd/bfd-in2.h10
-rw-r--r--bfd/elf32-microblaze.c110
-rw-r--r--bfd/libbfd.h2
-rw-r--r--bfd/reloc.c12
5 files changed, 141 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 88365d0..6e76def 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,20 @@
+2018-04-09 Andrew Sadek <andrew.sadek.se@gmail.com>
+
+ Microblaze Target: PIC data text relative
+
+ * bfd/reloc.c (2 new BFD relocations):
+ BFD_RELOC_MICROBLAZE_64_TEXTPCREL &
+ BFD_RELOC_MICROBLAZE_64_TEXTPCREL
+ * bfd/bfd-in2.h: Regenerate
+ * bfd/libbfd.h: Regenerate
+ * bfd/elf32-microblaze.c (Handle new relocs): define 'HOWTO' of 3
+ new relocs and handle them in both relocate and relax functions.
+ (microblaze_elf_reloc_type_lookup): add mapping between for new
+ bfd relocs.
+ (microblaze_elf_relocate_section): Handle new relocs in case of
+ elf relocation.
+ (microblaze_elf_relax_section): Handle new relocs for elf relaxation.
+
2018-04-17 Nick Clifton <nickc@redhat.com>
PR 23055
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 041b3b1..97c37a0 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5831,6 +5831,16 @@ to two words (uses imm instruction). */
to two words (uses imm instruction). */
BFD_RELOC_MICROBLAZE_64_TLSTPREL,
+/* This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction). The relocation is
+PC-relative offset from start of TEXT. */
+ BFD_RELOC_MICROBLAZE_64_TEXTPCREL,
+
+/* This is a 64 bit reloc that stores the 32 bit offset
+value in two words (with an imm instruction). The relocation is
+relative offset from start of TEXT. */
+ BFD_RELOC_MICROBLAZE_64_TEXTREL,
+
/* AArch64 pseudo relocation code to mark the start of the AArch64
relocation enumerators. N.B. the order of the enumerators is
important as several tables in the AArch64 bfd backend are indexed
diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
index 3acf93a..3d131bc 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
@@ -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;
@@ -1140,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;
@@ -1390,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:
@@ -1408,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;
}
@@ -1503,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;
}
}
@@ -1700,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. */
@@ -1770,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;
@@ -1792,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);
@@ -1818,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
@@ -1954,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);
@@ -1998,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);
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index f50cc03..6263ec4 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2822,6 +2822,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_MICROBLAZE_64_TLSDTPREL",
"BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL",
"BFD_RELOC_MICROBLAZE_64_TLSTPREL",
+ "BFD_RELOC_MICROBLAZE_64_TEXTPCREL",
+ "BFD_RELOC_MICROBLAZE_64_TEXTREL",
"BFD_RELOC_AARCH64_RELOC_START",
"BFD_RELOC_AARCH64_NULL",
"BFD_RELOC_AARCH64_NONE",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 9d86dee..80db0c9 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -6906,6 +6906,18 @@ ENUM
ENUMDOC
This is a 64 bit reloc that stores 32-bit thread pointer relative offset
to two words (uses imm instruction).
+ENUM
+ BFD_RELOC_MICROBLAZE_64_TEXTPCREL
+ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). The relocation is
+ PC-relative offset from start of TEXT.
+ENUM
+ BFD_RELOC_MICROBLAZE_64_TEXTREL
+ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit offset
+ value in two words (with an imm instruction). The relocation is
+ relative offset from start of TEXT.
ENUM
BFD_RELOC_AARCH64_RELOC_START