bfd: add experimental support for SHT_RELR sections.

This change adds experimental support for SHT_RELR sections, proposed
here: https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg

This is a subset of the change that was merged into the aosp/binutils
repo (https://android-review.googlesource.com/572669). It contains the
definitions for the new section type / dynamic tags, and support in bfd
for recognizing the new section type. Gdb uses bfd to read the program
binary, and without this support, it fails to detect some architecture
related settings.

Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=836845
Test: Built gdb inside a Chrome OS chroot. Verified that architecture
      auto-detection works for an x86_64 binary containing a '.relr.dyn'
      section. The message "don't know how to handle section `.relr.dyn'"
      is no longer printed.

Change-Id: Id199a7201d4750d2c6cb41a0c1a811777c322621
diff --git a/gdb-8.0.1/bfd/elf-bfd.h b/gdb-8.0.1/bfd/elf-bfd.h
index af377ee..b5c7567 100644
--- a/gdb-8.0.1/bfd/elf-bfd.h
+++ b/gdb-8.0.1/bfd/elf-bfd.h
@@ -650,7 +650,7 @@
 
 struct elf_size_info {
   unsigned char sizeof_ehdr, sizeof_phdr, sizeof_shdr;
-  unsigned char sizeof_rel, sizeof_rela, sizeof_sym, sizeof_dyn, sizeof_note;
+  unsigned char sizeof_rel, sizeof_rela, sizeof_relr, sizeof_sym, sizeof_dyn, sizeof_note;
 
   /* The size of entries in the .hash section.  */
   unsigned char sizeof_hash_entry;
diff --git a/gdb-8.0.1/bfd/elf.c b/gdb-8.0.1/bfd/elf.c
index 18b4bbe..569bb2c 100644
--- a/gdb-8.0.1/bfd/elf.c
+++ b/gdb-8.0.1/bfd/elf.c
@@ -1668,6 +1668,9 @@
 	    case DT_RELA: name = "RELA"; break;
 	    case DT_RELASZ: name = "RELASZ"; break;
 	    case DT_RELAENT: name = "RELAENT"; break;
+	    case DT_RELR: name = "RELR"; break;
+	    case DT_RELRSZ: name = "RELRSZ"; break;
+	    case DT_RELRENT: name = "RELRENT"; break;
 	    case DT_STRSZ: name = "STRSZ"; break;
 	    case DT_SYMENT: name = "SYMENT"; break;
 	    case DT_INIT: name = "INIT"; break;
@@ -1705,6 +1708,7 @@
 	    case DT_PLTPAD: name = "PLTPAD"; break;
 	    case DT_MOVETAB: name = "MOVETAB"; break;
 	    case DT_SYMINFO: name = "SYMINFO"; break;
+	    case DT_RELRCOUNT: name = "RELRCOUNT"; break;
 	    case DT_RELACOUNT: name = "RELACOUNT"; break;
 	    case DT_RELCOUNT: name = "RELCOUNT"; break;
 	    case DT_FLAGS_1: name = "FLAGS_1"; break;
@@ -2269,16 +2273,30 @@
 
     case SHT_REL:
     case SHT_RELA:
+    case SHT_RELR:
       /* *These* do a lot of work -- but build no sections!  */
       {
 	asection *target_sect;
 	Elf_Internal_Shdr *hdr2, **p_hdr;
 	unsigned int num_sec = elf_numsections (abfd);
 	struct bfd_elf_section_data *esdt;
+	bfd_size_type size;
 
-	if (hdr->sh_entsize
-	    != (bfd_size_type) (hdr->sh_type == SHT_REL
-				? bed->s->sizeof_rel : bed->s->sizeof_rela))
+	switch (hdr->sh_type)
+	{
+        case SHT_REL:
+	  size = bed->s->sizeof_rel;
+	  break;
+        case SHT_RELA:
+	  size = bed->s->sizeof_rela;
+	  break;
+        case SHT_RELR:
+	  size = bed->s->sizeof_relr;
+	  break;
+        default:
+	  goto fail;
+        }
+	if (hdr->sh_entsize  != size)
 	  goto fail;
 
 	/* Check for a bogus link to avoid crashing.  */
@@ -2345,7 +2363,8 @@
 	    || hdr->sh_info == SHN_UNDEF
 	    || hdr->sh_info >= num_sec
 	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
-	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
+	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA
+	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELR)
 	  {
 	    ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
 						   shindex);
diff --git a/gdb-8.0.1/bfd/elf32-arm.c b/gdb-8.0.1/bfd/elf32-arm.c
index 434649f..cd693d1 100644
--- a/gdb-8.0.1/bfd/elf32-arm.c
+++ b/gdb-8.0.1/bfd/elf32-arm.c
@@ -18954,6 +18954,7 @@
   sizeof (Elf32_External_Shdr),
   sizeof (Elf32_External_Rel),
   sizeof (Elf32_External_Rela),
+  sizeof (Elf32_External_Relr),
   sizeof (Elf32_External_Sym),
   sizeof (Elf32_External_Dyn),
   sizeof (Elf_External_Note),
diff --git a/gdb-8.0.1/bfd/elfcode.h b/gdb-8.0.1/bfd/elfcode.h
index ef097f7..cedf82e 100644
--- a/gdb-8.0.1/bfd/elfcode.h
+++ b/gdb-8.0.1/bfd/elfcode.h
@@ -80,6 +80,7 @@
 #define Elf_External_Phdr	NAME(Elf,External_Phdr)
 #define Elf_External_Rel	NAME(Elf,External_Rel)
 #define Elf_External_Rela	NAME(Elf,External_Rela)
+#define Elf_External_Relr	NAME(Elf,External_Relr)
 #define Elf_External_Dyn	NAME(Elf,External_Dyn)
 
 #define elf_core_file_failing_command	NAME(bfd_elf,core_file_failing_command)
@@ -1886,6 +1887,7 @@
   sizeof (Elf_External_Shdr),
   sizeof (Elf_External_Rel),
   sizeof (Elf_External_Rela),
+  sizeof (Elf_External_Relr),
   sizeof (Elf_External_Sym),
   sizeof (Elf_External_Dyn),
   sizeof (Elf_External_Note),
diff --git a/gdb-8.0.1/bfd/elfnn-aarch64.c b/gdb-8.0.1/bfd/elfnn-aarch64.c
index 00f19e9..e366ddf 100644
--- a/gdb-8.0.1/bfd/elfnn-aarch64.c
+++ b/gdb-8.0.1/bfd/elfnn-aarch64.c
@@ -9311,6 +9311,7 @@
   sizeof (ElfNN_External_Shdr),
   sizeof (ElfNN_External_Rel),
   sizeof (ElfNN_External_Rela),
+  sizeof (ElfNN_External_Relr),
   sizeof (ElfNN_External_Sym),
   sizeof (ElfNN_External_Dyn),
   sizeof (Elf_External_Note),
diff --git a/gdb-8.0.1/include/elf/common.h b/gdb-8.0.1/include/elf/common.h
index 484cb48..61ca209 100644
--- a/gdb-8.0.1/include/elf/common.h
+++ b/gdb-8.0.1/include/elf/common.h
@@ -514,6 +514,10 @@
 #define SHT_GNU_verneed	SHT_SUNW_verneed
 #define SHT_GNU_versym	SHT_SUNW_versym
 
+/* Experimental support for SHT_RELR sections. For details, see proposal
+   at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg */
+#define SHT_RELR	0x6fffff00	/* Relative relocations, only offsets */
+
 #define SHT_LOPROC	0x70000000	/* Processor-specific semantics, lo */
 #define SHT_HIPROC	0x7FFFFFFF	/* Processor-specific semantics, hi */
 #define SHT_LOUSER	0x80000000	/* Application-specific semantics */
@@ -917,6 +921,13 @@
 /* This tag is a GNU extension to the Solaris version scheme.  */
 #define DT_VERSYM	0x6ffffff0
 
+/* Experimental support for SHT_RELR sections. For details, see proposal
+   at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg */
+#define DT_RELR		0x6fffe000
+#define DT_RELRSZ	0x6fffe001
+#define DT_RELRENT	0x6fffe003
+#define DT_RELRCOUNT	0x6fffe005
+
 #define DT_LOPROC	0x70000000
 #define DT_HIPROC	0x7fffffff
 
diff --git a/gdb-8.0.1/include/elf/external.h b/gdb-8.0.1/include/elf/external.h
index d65bae0..c9e0e58 100644
--- a/gdb-8.0.1/include/elf/external.h
+++ b/gdb-8.0.1/include/elf/external.h
@@ -196,6 +196,10 @@
 } Elf32_External_Rela;
 
 typedef struct {
+  unsigned char r_data[4];	/* jump and bitmap for relative relocations */
+} Elf32_External_Relr;
+
+typedef struct {
   unsigned char r_offset[8];	/* Location at which to apply the action */
   unsigned char	r_info[8];	/* index and type of relocation */
 } Elf64_External_Rel;
@@ -206,6 +210,10 @@
   unsigned char	r_addend[8];	/* Constant addend used to compute value */
 } Elf64_External_Rela;
 
+typedef struct {
+  unsigned char r_data[8];	/* jump and bitmap for relative relocations */
+} Elf64_External_Relr;
+
 /* dynamic section structure */
 
 typedef struct {