binutils-2.22: Backport PR fixes from 2.22 branch
authorKhem Raj <raj.khem@gmail.com>
Thu, 13 Sep 2012 21:59:10 +0000 (14:59 -0700)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Fri, 14 Sep 2012 08:50:30 +0000 (09:50 +0100)
These are fixes mainly cherrypicks for mips/ppc/x86
mainly fixing PRs in ld and gold

(From OE-Core rev: f098cfc24bae8e0685bcae53ea4fdc3326ddc6c4)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
15 files changed:
meta/recipes-devtools/binutils/binutils-2.22.inc
meta/recipes-devtools/binutils/binutils/0006-mips-dis.c-print_insn_micromips-Rename-local-variabl.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0019-PR-ld-13468.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0028-Backport-from-mainline.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0035-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0037-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0039-emulparams-elf32bmip.sh-OTHER_SECTIONS-Put-.mdebug.-.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0052-gas.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0055-Remove-ABI_64_P-check-on-R_X86_64_PCXX.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0078-PR-binutils-13622.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0144-timer.cc-include-unistd.h.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0166-2012-04-27-Doug-Kwan-dougkwan-google.com.patch [new file with mode: 0644]
meta/recipes-devtools/binutils/binutils/0182-PR-ld-13991.patch [new file with mode: 0644]

index 821cc55..42dc6b7 100644 (file)
@@ -1,4 +1,4 @@
-PR = "r15"
+PR = "r16"
 
 LIC_FILES_CHKSUM="\
     file://src-release;endline=17;md5=4830a9ef968f3b18dd5e9f2c00db2d35\
@@ -32,6 +32,20 @@ SRC_URI = "\
      file://mips64-default-ld-emulation.patch \
      file://0001-PR-ld-13470.patch \
      file://rpath-sysroot.patch \
+     file://0006-mips-dis.c-print_insn_micromips-Rename-local-variabl.patch \
+     file://0019-PR-ld-13468.patch \
+     file://0028-Backport-from-mainline.patch \
+     file://0035-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \
+     file://0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \
+     file://0037-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch \
+     file://0038-Copy-from-mainline-to-binutils-2.22-branch.patch \
+     file://0039-emulparams-elf32bmip.sh-OTHER_SECTIONS-Put-.mdebug.-.patch \
+     file://0052-gas.patch \
+     file://0055-Remove-ABI_64_P-check-on-R_X86_64_PCXX.patch \
+     file://0078-PR-binutils-13622.patch \
+     file://0144-timer.cc-include-unistd.h.patch \
+     file://0166-2012-04-27-Doug-Kwan-dougkwan-google.com.patch \
+     file://0182-PR-ld-13991.patch \
      "
 
 SRC_URI[md5sum] = "ee0f10756c84979622b992a4a61ea3f5"
diff --git a/meta/recipes-devtools/binutils/binutils/0006-mips-dis.c-print_insn_micromips-Rename-local-variabl.patch b/meta/recipes-devtools/binutils/binutils/0006-mips-dis.c-print_insn_micromips-Rename-local-variabl.patch
new file mode 100644 (file)
index 0000000..1baf1e8
--- /dev/null
@@ -0,0 +1,634 @@
+Upstream-Status: Backport
+
+From f72b2c498bc98f42048a3bf7f7d7891db9cabcfc Mon Sep 17 00:00:00 2001
+From: Pierre Muller <muller@ics.u-strasbg.fr>
+Date: Fri, 25 Nov 2011 16:57:32 +0000
+Subject: [PATCH 006/262]       * mips-dis.c (print_insn_micromips): Rename
+ local variable iprintf        to infprintf to
+ avoid shadow warning.
+
+---
+ opcodes/ChangeLog  |    5 ++
+ opcodes/mips-dis.c |  188 ++++++++++++++++++++++++++--------------------------
+ 2 files changed, 99 insertions(+), 94 deletions(-)
+
+2011-11-25  Pierre Muller  <muller@ics.u-strasbg.fr>
+
+       * mips-dis.c (print_insn_micromips): Rename local variable iprintf
+       to infprintf to avoid shadow warning.
+
+diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
+index 4e18d8a..72285de 100644
+--- a/opcodes/mips-dis.c
++++ b/opcodes/mips-dis.c
+@@ -2260,7 +2260,7 @@ print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
+ static int
+ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+ {
+-  const fprintf_ftype iprintf = info->fprintf_func;
++  const fprintf_ftype infprintf = info->fprintf_func;
+   const struct mips_opcode *op, *opend;
+   unsigned int lsb, msbd, msb;
+   void *is = info->stream;
+@@ -2307,7 +2307,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+       status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
+       if (status != 0)
+       {
+-        iprintf (is, "micromips 0x%x", higher);
++        infprintf (is, "micromips 0x%x", higher);
+         (*info->memory_error_func) (status, memaddr + 2, info);
+         return -1;
+       }
+@@ -2320,7 +2320,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+       status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
+       if (status != 0)
+       {
+-        iprintf (is, "micromips 0x%x", higher);
++        infprintf (is, "micromips 0x%x", higher);
+         (*info->memory_error_func) (status, memaddr + 4, info);
+         return -1;
+       }
+@@ -2328,7 +2328,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+       insn = bfd_getb16 (buffer);
+       else
+       insn = bfd_getl16 (buffer);
+-      iprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
++      infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
+       info->insn_type = dis_noninsn;
+       return 6;
+@@ -2341,7 +2341,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+       status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
+       if (status != 0)
+       {
+-        iprintf (is, "micromips 0x%x", higher);
++        infprintf (is, "micromips 0x%x", higher);
+         (*info->memory_error_func) (status, memaddr + 2, info);
+         return -1;
+       }
+@@ -2371,9 +2371,9 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+       {
+         const char *s;
+-        iprintf (is, "%s", op->name);
++        infprintf (is, "%s", op->name);
+         if (op->args[0] != '\0')
+-          iprintf (is, "\t");
++          infprintf (is, "\t");
+         for (s = op->args; *s != '\0'; s++)
+           {
+@@ -2382,37 +2382,37 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+               case ',':
+               case '(':
+               case ')':
+-                iprintf (is, "%c", *s);
++                infprintf (is, "%c", *s);
+                 break;
+               case '.':
+                 delta = GET_OP (insn, OFFSET10);
+                 if (delta & 0x200)
+                   delta |= ~0x3ff;
+-                iprintf (is, "%d", delta);
++                infprintf (is, "%d", delta);
+                 break;
+               case '1':
+-                iprintf (is, "0x%lx", GET_OP (insn, STYPE));
++                infprintf (is, "0x%lx", GET_OP (insn, STYPE));
+                 break;
+               case '<':
+-                iprintf (is, "0x%lx", GET_OP (insn, SHAMT));
++                infprintf (is, "0x%lx", GET_OP (insn, SHAMT));
+                 break;
+               case '\\':
+-                iprintf (is, "0x%lx", GET_OP (insn, 3BITPOS));
++                infprintf (is, "0x%lx", GET_OP (insn, 3BITPOS));
+                 break;
+               case '|':
+-                iprintf (is, "0x%lx", GET_OP (insn, TRAP));
++                infprintf (is, "0x%lx", GET_OP (insn, TRAP));
+                 break;
+               case '~':
+                 delta = GET_OP (insn, OFFSET12);
+                 if (delta & 0x800)
+                   delta |= ~0x7ff;
+-                iprintf (is, "%d", delta);
++                infprintf (is, "%d", delta);
+                 break;
+               case 'a':
+@@ -2433,34 +2433,34 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+               case 'r':
+               case 's':
+               case 'v':
+-                iprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]);
++                infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]);
+                 break;
+               case 'c':
+-                iprintf (is, "0x%lx", GET_OP (insn, CODE));
++                infprintf (is, "0x%lx", GET_OP (insn, CODE));
+                 break;
+               case 'd':
+-                iprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]);
++                infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]);
+                 break;
+               case 'h':
+-                iprintf (is, "0x%lx", GET_OP (insn, PREFX));
++                infprintf (is, "0x%lx", GET_OP (insn, PREFX));
+                 break;
+               case 'i':
+               case 'u':
+-                iprintf (is, "0x%lx", GET_OP (insn, IMMEDIATE));
++                infprintf (is, "0x%lx", GET_OP (insn, IMMEDIATE));
+                 break;
+               case 'j': /* Same as i, but sign-extended.  */
+               case 'o':
+                 delta = (GET_OP (insn, DELTA) ^ 0x8000) - 0x8000;
+-                iprintf (is, "%d", delta);
++                infprintf (is, "%d", delta);
+                 break;
+               case 'k':
+-                iprintf (is, "0x%x", GET_OP (insn, CACHE));
++                infprintf (is, "0x%x", GET_OP (insn, CACHE));
+                 break;
+               case 'n':
+@@ -2472,26 +2472,26 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                   if (s_reg_encode != 0)
+                     {
+                       if (s_reg_encode == 1)
+-                        iprintf (is, "%s", mips_gpr_names[16]);
++                        infprintf (is, "%s", mips_gpr_names[16]);
+                       else if (s_reg_encode < 9)
+-                        iprintf (is, "%s-%s",
++                        infprintf (is, "%s-%s",
+                                  mips_gpr_names[16],
+                                  mips_gpr_names[15 + s_reg_encode]);
+                       else if (s_reg_encode == 9)
+-                        iprintf (is, "%s-%s,%s",
++                        infprintf (is, "%s-%s,%s",
+                                  mips_gpr_names[16],
+                                  mips_gpr_names[23],
+                                  mips_gpr_names[30]);
+                       else
+-                        iprintf (is, "UNKNOWN");
++                        infprintf (is, "UNKNOWN");
+                     }
+                   if (immed & 0x10) /* For ra.  */
+                     {
+                       if (s_reg_encode == 0)
+-                        iprintf (is, "%s", mips_gpr_names[31]);
++                        infprintf (is, "%s", mips_gpr_names[31]);
+                       else
+-                        iprintf (is, ",%s", mips_gpr_names[31]);
++                        infprintf (is, ",%s", mips_gpr_names[31]);
+                     }
+                   break;
+                 }
+@@ -2504,32 +2504,32 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                 break;
+               case 'q':
+-                iprintf (is, "0x%lx", GET_OP (insn, CODE2));
++                infprintf (is, "0x%lx", GET_OP (insn, CODE2));
+                 break;
+               case 't':
+               case 'w':
+-                iprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]);
++                infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]);
+                 break;
+               case 'y':
+-                iprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]);
++                infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]);
+                 break;
+               case 'z':
+-                iprintf (is, "%s", mips_gpr_names[0]);
++                infprintf (is, "%s", mips_gpr_names[0]);
+                 break;
+               case 'B':
+-                iprintf (is, "0x%lx", GET_OP (insn, CODE10));
++                infprintf (is, "0x%lx", GET_OP (insn, CODE10));
+                 break;
+               case 'C':
+-                iprintf (is, "0x%lx", GET_OP (insn, COPZ));
++                infprintf (is, "0x%lx", GET_OP (insn, COPZ));
+                 break;
+               case 'D':
+-                iprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]);
++                infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]);
+                 break;
+               case 'E':
+@@ -2540,7 +2540,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                   'T' format.  Therefore, until we gain understanding of
+                   cp2 register names, we can simply print the register
+                   numbers.  */
+-                iprintf (is, "$%ld", GET_OP (insn, RT));
++                infprintf (is, "$%ld", GET_OP (insn, RT));
+                 break;
+               case 'G':
+@@ -2559,44 +2559,44 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                   case 0x000002fc:                            /* mtc0  */
+                   case 0x580000fc:                            /* dmfc0 */
+                   case 0x580002fc:                            /* dmtc0 */
+-                    iprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]);
++                    infprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]);
+                     break;
+                   default:
+-                    iprintf (is, "$%ld", GET_OP (insn, RS));
++                    infprintf (is, "$%ld", GET_OP (insn, RS));
+                     break;
+                   }
+                 break;
+               case 'H':
+-                iprintf (is, "%ld", GET_OP (insn, SEL));
++                infprintf (is, "%ld", GET_OP (insn, SEL));
+                 break;
+               case 'K':
+-                iprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]);
++                infprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]);
+                 break;
+               case 'M':
+-                iprintf (is, "$fcc%ld", GET_OP (insn, CCC));
++                infprintf (is, "$fcc%ld", GET_OP (insn, CCC));
+                 break;
+               case 'N':
+-                iprintf (is,
++                infprintf (is,
+                          (op->pinfo & (FP_D | FP_S)) != 0
+                          ? "$fcc%ld" : "$cc%ld",
+                          GET_OP (insn, BCC));
+                 break;
+               case 'R':
+-                iprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]);
++                infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]);
+                 break;
+               case 'S':
+               case 'V':
+-                iprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]);
++                infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]);
+                 break;
+               case 'T':
+-                iprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]);
++                infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]);
+                 break;
+               case '+':
+@@ -2606,18 +2606,18 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                   {
+                   case 'A':
+                     lsb = GET_OP (insn, EXTLSB);
+-                    iprintf (is, "0x%x", lsb);
++                    infprintf (is, "0x%x", lsb);
+                     break;
+                   case 'B':
+                     msb = GET_OP (insn, INSMSB);
+-                    iprintf (is, "0x%x", msb - lsb + 1);
++                    infprintf (is, "0x%x", msb - lsb + 1);
+                     break;
+                   case 'C':
+                   case 'H':
+                     msbd = GET_OP (insn, EXTMSBD);
+-                    iprintf (is, "0x%x", msbd + 1);
++                    infprintf (is, "0x%x", msbd + 1);
+                     break;
+                   case 'D':
+@@ -2637,30 +2637,30 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                                                    mips_cp0sel_names_len,
+                                                    cp0reg, sel);
+                       if (n != NULL)
+-                        iprintf (is, "%s", n->name);
++                        infprintf (is, "%s", n->name);
+                       else
+-                        iprintf (is, "$%d,%d", cp0reg, sel);
++                        infprintf (is, "$%d,%d", cp0reg, sel);
+                       break;
+                     }
+                   case 'E':
+                     lsb = GET_OP (insn, EXTLSB) + 32;
+-                    iprintf (is, "0x%x", lsb);
++                    infprintf (is, "0x%x", lsb);
+                     break;
+                   case 'F':
+                     msb = GET_OP (insn, INSMSB) + 32;
+-                    iprintf (is, "0x%x", msb - lsb + 1);
++                    infprintf (is, "0x%x", msb - lsb + 1);
+                     break;
+                   case 'G':
+                     msbd = GET_OP (insn, EXTMSBD) + 32;
+-                    iprintf (is, "0x%x", msbd + 1);
++                    infprintf (is, "0x%x", msbd + 1);
+                     break;
+                   default:
+                     /* xgettext:c-format */
+-                    iprintf (is,
++                    infprintf (is,
+                              _("# internal disassembler error, "
+                                "unrecognized modifier (+%c)"),
+                              *s);
+@@ -2674,111 +2674,111 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                 switch (*s)
+                   {
+                   case 'a':   /* global pointer.  */
+-                    iprintf (is, "%s", mips_gpr_names[28]);
++                    infprintf (is, "%s", mips_gpr_names[28]);
+                     break;
+                   case 'b':
+                     regno = micromips_to_32_reg_b_map[GET_OP (insn, MB)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'c':
+                     regno = micromips_to_32_reg_c_map[GET_OP (insn, MC)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'd':
+                     regno = micromips_to_32_reg_d_map[GET_OP (insn, MD)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'e':
+                     regno = micromips_to_32_reg_e_map[GET_OP (insn, ME)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'f':
+                     /* Save lastregno for "mt" to print out later.  */
+                     lastregno = micromips_to_32_reg_f_map[GET_OP (insn, MF)];
+-                    iprintf (is, "%s", mips_gpr_names[lastregno]);
++                    infprintf (is, "%s", mips_gpr_names[lastregno]);
+                     break;
+                   case 'g':
+                     regno = micromips_to_32_reg_g_map[GET_OP (insn, MG)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'h':
+                     regno = micromips_to_32_reg_h_map[GET_OP (insn, MH)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'i':
+                     regno = micromips_to_32_reg_i_map[GET_OP (insn, MI)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'j':
+-                    iprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]);
++                    infprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]);
+                     break;
+                   case 'l':
+                     regno = micromips_to_32_reg_l_map[GET_OP (insn, ML)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'm':
+                     regno = micromips_to_32_reg_m_map[GET_OP (insn, MM)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'n':
+                     regno = micromips_to_32_reg_n_map[GET_OP (insn, MN)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'p':
+                     /* Save lastregno for "mt" to print out later.  */
+                     lastregno = GET_OP (insn, MP);
+-                    iprintf (is, "%s", mips_gpr_names[lastregno]);
++                    infprintf (is, "%s", mips_gpr_names[lastregno]);
+                     break;
+                   case 'q':
+                     regno = micromips_to_32_reg_q_map[GET_OP (insn, MQ)];
+-                    iprintf (is, "%s", mips_gpr_names[regno]);
++                    infprintf (is, "%s", mips_gpr_names[regno]);
+                     break;
+                   case 'r':   /* program counter.  */
+-                    iprintf (is, "$pc");
++                    infprintf (is, "$pc");
+                     break;
+                   case 's':   /* stack pointer.  */
+                     lastregno = 29;
+-                    iprintf (is, "%s", mips_gpr_names[29]);
++                    infprintf (is, "%s", mips_gpr_names[29]);
+                     break;
+                   case 't':
+-                    iprintf (is, "%s", mips_gpr_names[lastregno]);
++                    infprintf (is, "%s", mips_gpr_names[lastregno]);
+                     break;
+                   case 'z':   /* $0.  */
+-                    iprintf (is, "%s", mips_gpr_names[0]);
++                    infprintf (is, "%s", mips_gpr_names[0]);
+                     break;
+                   case 'A':
+                     /* Sign-extend the immediate.  */
+                     immed = ((GET_OP (insn, IMMA) ^ 0x40) - 0x40) << 2;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'B':
+                     immed = micromips_imm_b_map[GET_OP (insn, IMMB)];
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'C':
+                     immed = micromips_imm_c_map[GET_OP (insn, IMMC)];
+-                    iprintf (is, "0x%lx", immed);
++                    infprintf (is, "0x%lx", immed);
+                     break;
+                   case 'D':
+@@ -2797,50 +2797,50 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                   case 'F':
+                     immed = GET_OP (insn, IMMF);
+-                    iprintf (is, "0x%x", immed);
++                    infprintf (is, "0x%x", immed);
+                     break;
+                   case 'G':
+                     immed = (insn >> MICROMIPSOP_SH_IMMG) + 1;
+                     immed = (immed & MICROMIPSOP_MASK_IMMG) - 1;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'H':
+                     immed = GET_OP (insn, IMMH) << 1;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'I':
+                     immed = (insn >> MICROMIPSOP_SH_IMMI) + 1;
+                     immed = (immed & MICROMIPSOP_MASK_IMMI) - 1;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'J':
+                     immed = GET_OP (insn, IMMJ) << 2;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'L':
+                     immed = GET_OP (insn, IMML);
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'M':
+                     immed = (insn >> MICROMIPSOP_SH_IMMM) - 1;
+                     immed = (immed & MICROMIPSOP_MASK_IMMM) + 1;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'N':
+                     immed = GET_OP (insn, IMMN);
+                     if (immed == 0)
+-                      iprintf (is, "%s,%s",
++                      infprintf (is, "%s,%s",
+                                mips_gpr_names[16],
+                                mips_gpr_names[31]);
+                     else
+-                      iprintf (is, "%s-%s,%s",
++                      infprintf (is, "%s-%s,%s",
+                                mips_gpr_names[16],
+                                mips_gpr_names[16 + immed],
+                                mips_gpr_names[31]);
+@@ -2848,35 +2848,35 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                   case 'O':
+                     immed = GET_OP (insn, IMMO);
+-                    iprintf (is, "0x%x", immed);
++                    infprintf (is, "0x%x", immed);
+                     break;
+                   case 'P':
+                     immed = GET_OP (insn, IMMP) << 2;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'Q':
+                     /* Sign-extend the immediate.  */
+                     immed = (GET_OP (insn, IMMQ) ^ 0x400000) - 0x400000;
+                     immed <<= 2;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'U':
+                     immed = GET_OP (insn, IMMU) << 2;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'W':
+                     immed = GET_OP (insn, IMMW) << 2;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'X':
+                     /* Sign-extend the immediate.  */
+                     immed = (GET_OP (insn, IMMX) ^ 0x8) - 0x8;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   case 'Y':
+@@ -2885,12 +2885,12 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+                     if (immed >= -2 && immed <= 1)
+                       immed ^= 0x100;
+                     immed = immed << 2;
+-                    iprintf (is, "%d", immed);
++                    infprintf (is, "%d", immed);
+                     break;
+                   default:
+                     /* xgettext:c-format */
+-                    iprintf (is,
++                    infprintf (is,
+                              _("# internal disassembler error, "
+                                "unrecognized modifier (m%c)"),
+                              *s);
+@@ -2900,7 +2900,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+               default:
+                 /* xgettext:c-format */
+-                iprintf (is,
++                infprintf (is,
+                          _("# internal disassembler error, "
+                            "unrecognized modifier (%c)"),
+                          *s);
+@@ -2937,7 +2937,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
+     }
+ #undef GET_OP
+-  iprintf (is, "0x%x", insn);
++  infprintf (is, "0x%x", insn);
+   info->insn_type = dis_noninsn;
+   return length;
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0019-PR-ld-13468.patch b/meta/recipes-devtools/binutils/binutils/0019-PR-ld-13468.patch
new file mode 100644 (file)
index 0000000..79d9f48
--- /dev/null
@@ -0,0 +1,46 @@
+Upstream-Status: Backport
+
+From 4c362e4511c4046e230fc9e330bf086753f04338 Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@bigpond.net.au>
+Date: Sat, 3 Dec 2011 10:29:17 +0000
+Subject: [PATCH 019/262]       PR ld/13468     * elflink.c
+ (bfd_elf_final_link): Don't segfault when checking 
+ for DT_TEXTREL and .dynamic does not exist.
+
+---
+ bfd/ChangeLog |    6 ++++++
+ bfd/elflink.c |    9 +++------
+ 2 files changed, 9 insertions(+), 6 deletions(-)
+
+ 2011-12-03  Alan Modra  <amodra@gmail.com>
+       PR ld/13468
+       * elflink.c (bfd_elf_final_link): Don't segfault when checking
+       for DT_TEXTREL and .dynamic does not exist.
+
+diff --git a/bfd/elflink.c b/bfd/elflink.c
+index fc4266b..8556cec 100644
+--- a/bfd/elflink.c
++++ b/bfd/elflink.c
+@@ -11188,15 +11188,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
+       goto error_return;
+       /* Check for DT_TEXTREL (late, in case the backend removes it).  */
+-      if ((info->warn_shared_textrel && info->shared)
+-        || info->error_textrel)
++      if (((info->warn_shared_textrel && info->shared)
++         || info->error_textrel)
++        && (o = bfd_get_section_by_name (dynobj, ".dynamic")) != NULL)
+       {
+         bfd_byte *dyncon, *dynconend;
+-        /* Fix up .dynamic entries.  */
+-        o = bfd_get_section_by_name (dynobj, ".dynamic");
+-        BFD_ASSERT (o != NULL);
+-
+         dyncon = o->contents;
+         dynconend = o->contents + o->size;
+         for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn)
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0028-Backport-from-mainline.patch b/meta/recipes-devtools/binutils/binutils/0028-Backport-from-mainline.patch
new file mode 100644 (file)
index 0000000..2b86b6b
--- /dev/null
@@ -0,0 +1,139 @@
+Upstream-Status: Backport
+
+From fbd07e4e15de7a81a2de7f9583fa3240302e2867 Mon Sep 17 00:00:00 2001
+From: David Daney <ddaney@avtrex.com>
+Date: Sun, 11 Dec 2011 02:28:10 +0000
+Subject: [PATCH 028/262] Backport from mainline:
+
+       2011-12-10  David Daney  <david.daney@cavium.com>
+
+       * elfxx-mips.c (mips_elf_link_hash_table.rld_value): Remove.
+       (mips_elf_link_hash_table.rld_symbol): New field;
+       (MIPS_ELF_RLD_MAP_SIZE): New macro.
+       (_bfd_mips_elf_add_symbol_hook): Remember __rld_obj_head symbol
+       in rld_symbol.
+       (_bfd_mips_elf_create_dynamic_sections): Remember __rld_map symbol
+       in rld_symbol.
+       (_bfd_mips_elf_size_dynamic_sections): Set correct size for .rld_map.
+       (_bfd_mips_elf_finish_dynamic_symbol): Remove .rld_map handling.
+       (_bfd_mips_elf_finish_dynamic_sections): Use rld_symbol to
+       calculate DT_MIPS_RLD_MAP value.
+       (_bfd_mips_elf_link_hash_table_create): Initialize rld_symbol,
+       quit initializing rld_value.
+
+diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
+index 33a454d..6b908ad 100644
+--- a/bfd/elfxx-mips.c
++++ b/bfd/elfxx-mips.c
+@@ -436,8 +436,8 @@ struct mips_elf_link_hash_table
+      entry is set to the address of __rld_obj_head as in IRIX5.  */
+   bfd_boolean use_rld_obj_head;
+-  /* This is the value of the __rld_map or __rld_obj_head symbol.  */
+-  bfd_vma rld_value;
++  /* The  __rld_map or __rld_obj_head symbol. */
++  struct elf_link_hash_entry *rld_symbol;
+   /* This is set if we see any mips16 stub sections.  */
+   bfd_boolean mips16_stubs_seen;
+@@ -768,6 +768,10 @@ static bfd *reldyn_sorting_bfd;
+ #define MIPS_ELF_GOT_SIZE(abfd) \
+   (get_elf_backend_data (abfd)->s->arch_size / 8)
++/* The size of the .rld_map section. */
++#define MIPS_ELF_RLD_MAP_SIZE(abfd) \
++  (get_elf_backend_data (abfd)->s->arch_size / 8)
++
+ /* The size of a symbol-table entry.  */
+ #define MIPS_ELF_SYM_SIZE(abfd) \
+   (get_elf_backend_data (abfd)->s->sizeof_sym)
+@@ -7081,6 +7085,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+       return FALSE;
+       mips_elf_hash_table (info)->use_rld_obj_head = TRUE;
++      mips_elf_hash_table (info)->rld_symbol = h;
+     }
+   /* If this is a mips16 text symbol, add 1 to the value to make it
+@@ -7266,6 +7271,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
+           return FALSE;
++        mips_elf_hash_table (info)->rld_symbol = h;
+       }
+     }
+@@ -9027,7 +9033,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
+       {
+         /* We add a room for __rld_map.  It will be filled in by the
+            rtld to contain a pointer to the _r_debug structure.  */
+-        s->size += 4;
++        s->size += MIPS_ELF_RLD_MAP_SIZE (output_bfd);
+       }
+       else if (SGI_COMPAT (output_bfd)
+              && CONST_STRNEQ (name, ".compact_rel"))
+@@ -10030,31 +10036,6 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
+   if (IRIX_COMPAT (output_bfd) == ict_irix6)
+     mips_elf_irix6_finish_dynamic_symbol (output_bfd, name, sym);
+-  if (! info->shared)
+-    {
+-      if (! mips_elf_hash_table (info)->use_rld_obj_head
+-        && (strcmp (name, "__rld_map") == 0
+-            || strcmp (name, "__RLD_MAP") == 0))
+-      {
+-        asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
+-        BFD_ASSERT (s != NULL);
+-        sym->st_value = s->output_section->vma + s->output_offset;
+-        bfd_put_32 (output_bfd, 0, s->contents);
+-        if (mips_elf_hash_table (info)->rld_value == 0)
+-          mips_elf_hash_table (info)->rld_value = sym->st_value;
+-      }
+-      else if (mips_elf_hash_table (info)->use_rld_obj_head
+-             && strcmp (name, "__rld_obj_head") == 0)
+-      {
+-        /* IRIX6 does not use a .rld_map section.  */
+-        if (IRIX_COMPAT (output_bfd) == ict_irix5
+-              || IRIX_COMPAT (output_bfd) == ict_none)
+-          BFD_ASSERT (bfd_get_section_by_name (dynobj, ".rld_map")
+-                      != NULL);
+-        mips_elf_hash_table (info)->rld_value = sym->st_value;
+-      }
+-    }
+-
+   /* Keep dynamic MIPS16 symbols odd.  This allows the dynamic linker to
+      treat MIPS16 symbols like any other.  */
+   if (ELF_ST_IS_MIPS16 (sym->st_other))
+@@ -10517,7 +10498,19 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
+             break;
+           case DT_MIPS_RLD_MAP:
+-            dyn.d_un.d_ptr = mips_elf_hash_table (info)->rld_value;
++            {
++              struct elf_link_hash_entry *h;
++              h = mips_elf_hash_table (info)->rld_symbol;
++              if (!h)
++                {
++                  dyn_to_skip = MIPS_ELF_DYN_SIZE (dynobj);
++                  swap_out_p = FALSE;
++                  break;
++                }
++              s = h->root.u.def.section;
++              dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
++                                + h->root.u.def.value);
++            }
+             break;
+           case DT_MIPS_OPTIONS:
+@@ -12794,7 +12787,7 @@ _bfd_mips_elf_link_hash_table_create (bfd *abfd)
+   ret->procedure_count = 0;
+   ret->compact_rel_size = 0;
+   ret->use_rld_obj_head = FALSE;
+-  ret->rld_value = 0;
++  ret->rld_symbol = NULL;
+   ret->mips16_stubs_seen = FALSE;
+   ret->use_plts_and_copy_relocs = FALSE;
+   ret->is_vxworks = FALSE;
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0035-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch b/meta/recipes-devtools/binutils/binutils/0035-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch
new file mode 100644 (file)
index 0000000..a83a597
--- /dev/null
@@ -0,0 +1,47 @@
+Upstream-Status: Backport
+
+From 97beee82f0e45e65308083a7e4cfaab57623733c Mon Sep 17 00:00:00 2001
+From: cltang <cltang>
+Date: Mon, 19 Dec 2011 10:34:15 +0000
+Subject: [PATCH 035/262] 2011-12-19  Chung-Lin Tang 
+ <cltang@codesourcery.com>
+
+       Backport from mainline:
+
+       2011-12-13  Chung-Lin Tang  <cltang@codesourcery.com>
+
+       * elfxx-mips.c (mips_elf_calculate_relocation): Correct
+       R_MIPS16_HI16/R_MIPS16_LO16 handling of two cleared lower bits,
+       update comments.
+
+diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
+index 6b908ad..3939183 100644
+--- a/bfd/elfxx-mips.c
++++ b/bfd/elfxx-mips.c
+@@ -5531,10 +5531,11 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+              12: addu    $v0,$v1
+              14: move    $gp,$v0
+            So the offsets of hi and lo relocs are the same, but the
+-           $pc is four higher than $t9 would be, so reduce
+-           both reloc addends by 4. */
++           base $pc is that used by the ADDIUPC instruction at $t9 + 4.
++           ADDIUPC clears the low two bits of the instruction address,
++           so the base is ($t9 + 4) & ~3.  */
+         if (r_type == R_MIPS16_HI16)
+-          value = mips_elf_high (addend + gp - p - 4);
++          value = mips_elf_high (addend + gp - ((p + 4) & ~(bfd_vma) 0x3));
+         /* The microMIPS .cpload sequence uses the same assembly
+            instructions as the traditional psABI version, but the
+            incoming $t9 has the low bit set.  */
+@@ -5557,7 +5558,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+         /* See the comment for R_MIPS16_HI16 above for the reason
+            for this conditional.  */
+         if (r_type == R_MIPS16_LO16)
+-          value = addend + gp - p;
++          value = addend + gp - (p & ~(bfd_vma) 0x3);
+         else if (r_type == R_MICROMIPS_LO16
+                  || r_type == R_MICROMIPS_HI0_LO16)
+           value = addend + gp - p + 3;
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch b/meta/recipes-devtools/binutils/binutils/0036-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch
new file mode 100644 (file)
index 0000000..9017c25
--- /dev/null
@@ -0,0 +1,214 @@
+Upstream-Status: Backport
+
+From 26e802720ccd055d70addadbc39f4119716f8573 Mon Sep 17 00:00:00 2001
+From: cltang <cltang>
+Date: Mon, 19 Dec 2011 10:39:27 +0000
+Subject: [PATCH 036/262] 2011-12-19  Chung-Lin Tang 
+ <cltang@codesourcery.com>
+
+       Backport from mainline:
+
+       2011-12-19  Chung-Lin Tang  <cltang@codesourcery.com>
+                   Catherine Moore  <clm@codesourcery.com>
+                   Sandra Loosemore  <sandra@codesourcery.com>
+                   Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * elfxx-mips.c (mips_elf_local_pic_function_p): Return true when
+       H is a MIPS16 function with a kept 32-bit stub. Update comments.
+       (mips_elf_get_la25_target): New function.
+       (mips_elf_add_la25_intro): Change to use mips_elf_get_la25_target().
+       (mips_elf_add_la25_stub): Move compute of use_trampoline_p down,
+       change to use mips_elf_get_la25_target().
+       (mips_elf_relocation_needs_la25_stub): Add target_is_16_bit_code_p
+       parameter, add switch case for R_MIPS16_26.
+       (mips_elf_calculate_relocation): Redirect relocation to point to the
+       LA25 stub if it exists, instead of the MIPS16 stub. Update arguments
+       of call to mips_elf_relocation_needs_la25_stub(), don't use la25 stub
+       for mips16->mips16 calls.
+       (_bfd_mips_elf_check_relocs): Update arguments of call to
+       mips_elf_relocation_needs_la25_stub().
+       (mips_elf_create_la25_stub): Change to use mips_elf_get_la25_target().
+
+diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
+index 3939183..9f3833b 100644
+--- a/bfd/elfxx-mips.c
++++ b/bfd/elfxx-mips.c
+@@ -1575,9 +1575,10 @@ _bfd_mips_elf_init_stubs (struct bfd_link_info *info,
+ }
+ /* Return true if H is a locally-defined PIC function, in the sense
+-   that it might need $25 to be valid on entry.  Note that MIPS16
+-   functions never need $25 to be valid on entry; they set up $gp
+-   using PC-relative instructions instead.  */
++   that it or its fn_stub might need $25 to be valid on entry.
++   Note that MIPS16 functions set up $gp using PC-relative instructions,
++   so they themselves never need $25 to be valid.  Only non-MIPS16
++   entry points are of interest here.  */
+ static bfd_boolean
+ mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
+@@ -1586,11 +1587,32 @@ mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
+          || h->root.root.type == bfd_link_hash_defweak)
+         && h->root.def_regular
+         && !bfd_is_abs_section (h->root.root.u.def.section)
+-        && !ELF_ST_IS_MIPS16 (h->root.other)
++        && (!ELF_ST_IS_MIPS16 (h->root.other)
++            || (h->fn_stub && h->need_fn_stub))
+         && (PIC_OBJECT_P (h->root.root.u.def.section->owner)
+             || ELF_ST_IS_MIPS_PIC (h->root.other)));
+ }
++/* Set *SEC to the input section that contains the target of STUB.
++   Return the offset of the target from the start of that section.  */
++
++static bfd_vma
++mips_elf_get_la25_target (struct mips_elf_la25_stub *stub,
++                        asection **sec)
++{
++  if (ELF_ST_IS_MIPS16 (stub->h->root.other))
++    {
++      BFD_ASSERT (stub->h->need_fn_stub);
++      *sec = stub->h->fn_stub;
++      return 0;
++    }
++  else
++    {
++      *sec = stub->h->root.root.u.def.section;
++      return stub->h->root.root.u.def.value;
++    }
++}
++
+ /* STUB describes an la25 stub that we have decided to implement
+    by inserting an LUI/ADDIU pair before the target function.
+    Create the section and redirect the function symbol to it.  */
+@@ -1615,7 +1637,7 @@ mips_elf_add_la25_intro (struct mips_elf_la25_stub *stub,
+   sprintf (name, ".text.stub.%d", (int) htab_elements (htab->la25_stubs));
+   /* Create the section.  */
+-  input_section = stub->h->root.root.u.def.section;
++  mips_elf_get_la25_target (stub, &input_section);
+   s = htab->add_stub_section (name, input_section,
+                             input_section->output_section);
+   if (s == NULL)
+@@ -1689,12 +1711,6 @@ mips_elf_add_la25_stub (struct bfd_link_info *info,
+   bfd_vma value;
+   void **slot;
+-  /* Prefer to use LUI/ADDIU stubs if the function is at the beginning
+-     of the section and if we would need no more than 2 nops.  */
+-  s = h->root.root.u.def.section;
+-  value = h->root.root.u.def.value;
+-  use_trampoline_p = (value != 0 || s->alignment_power > 4);
+-
+   /* Describe the stub we want.  */
+   search.stub_section = NULL;
+   search.offset = 0;
+@@ -1724,6 +1740,11 @@ mips_elf_add_la25_stub (struct bfd_link_info *info,
+   *stub = search;
+   *slot = stub;
++  /* Prefer to use LUI/ADDIU stubs if the function is at the beginning
++     of the section and if we would need no more than 2 nops.  */
++  value = mips_elf_get_la25_target (stub, &s);
++  use_trampoline_p = (value != 0 || s->alignment_power > 4);
++
+   h->la25_stub = stub;
+   return (use_trampoline_p
+         ? mips_elf_add_la25_trampoline (stub, info)
+@@ -4911,7 +4932,8 @@ is_gott_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h)
+    stub.  */
+ static bfd_boolean
+-mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
++mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type,
++                                   bfd_boolean target_is_16_bit_code_p)
+ {
+   /* We specifically ignore branches and jumps from EF_PIC objects,
+      where the onus is on the compiler or programmer to perform any
+@@ -4925,7 +4947,6 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
+     {
+     case R_MIPS_26:
+     case R_MIPS_PC16:
+-    case R_MIPS16_26:
+     case R_MICROMIPS_26_S1:
+     case R_MICROMIPS_PC7_S1:
+     case R_MICROMIPS_PC10_S1:
+@@ -4933,6 +4954,9 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
+     case R_MICROMIPS_PC23_S2:
+       return TRUE;
++    case R_MIPS16_26:
++      return !target_is_16_bit_code_p;
++
+     default:
+       return FALSE;
+     }
+@@ -5193,14 +5217,28 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+        have already noticed that we were going to need the
+        stub.  */
+       if (local_p)
+-      sec = elf_tdata (input_bfd)->local_stubs[r_symndx];
++      {
++        sec = elf_tdata (input_bfd)->local_stubs[r_symndx];
++        value = 0;
++      }
+       else
+       {
+         BFD_ASSERT (h->need_fn_stub);
+-        sec = h->fn_stub;
++        if (h->la25_stub)
++          {
++            /* If a LA25 header for the stub itself exists, point to the
++               prepended LUI/ADDIU sequence.  */
++            sec = h->la25_stub->stub_section;
++            value = h->la25_stub->offset;
++          }
++        else
++          {
++            sec = h->fn_stub;
++            value = 0;
++          }
+       }
+-      symbol = sec->output_section->vma + sec->output_offset;
++      symbol = sec->output_section->vma + sec->output_offset + value;
+       /* The target is 16-bit, but the stub isn't.  */
+       target_is_16_bit_code_p = FALSE;
+     }
+@@ -5250,7 +5288,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+   /* If this is a direct call to a PIC function, redirect to the
+      non-PIC stub.  */
+   else if (h != NULL && h->la25_stub
+-         && mips_elf_relocation_needs_la25_stub (input_bfd, r_type))
++         && mips_elf_relocation_needs_la25_stub (input_bfd, r_type,
++                                                 target_is_16_bit_code_p))
+     symbol = (h->la25_stub->stub_section->output_section->vma
+             + h->la25_stub->stub_section->output_offset
+             + h->la25_stub->offset);
+@@ -7925,7 +7964,9 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+           return FALSE;
+       }
+-      if (h != NULL && mips_elf_relocation_needs_la25_stub (abfd, r_type))
++      if (h != NULL
++        && mips_elf_relocation_needs_la25_stub (abfd, r_type,
++                                                ELF_ST_IS_MIPS16 (h->other)))
+       ((struct mips_elf_link_hash_entry *) h)->has_nonpic_branches = TRUE;
+       switch (r_type)
+@@ -9622,9 +9663,9 @@ mips_elf_create_la25_stub (void **slot, void *data)
+   offset = stub->offset;
+   /* Work out the target address.  */
+-  target = (stub->h->root.root.u.def.section->output_section->vma
+-          + stub->h->root.root.u.def.section->output_offset
+-          + stub->h->root.root.u.def.value);
++  target = mips_elf_get_la25_target (stub, &s);
++  target += s->output_section->vma + s->output_offset;
++
+   target_high = ((target + 0x8000) >> 16) & 0xffff;
+   target_low = (target & 0xffff);
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0037-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch b/meta/recipes-devtools/binutils/binutils/0037-2011-12-19-Chung-Lin-Tang-cltang-codesourcery.com.patch
new file mode 100644 (file)
index 0000000..4b0caaf
--- /dev/null
@@ -0,0 +1,1068 @@
+Upstream-Status: Backport
+
+From 7e2b7154b03e4c77233171eec5cba8d113e04fea Mon Sep 17 00:00:00 2001
+From: cltang <cltang>
+Date: Mon, 19 Dec 2011 10:49:24 +0000
+Subject: [PATCH 037/262] 2011-12-19  Chung-Lin Tang 
+ <cltang@codesourcery.com>
+
+       Backport from mainline:
+
+       2011-12-19  Chung-Lin Tang  <cltang@codesourcery.com>
+
+       gas/
+       * config/tc-mips.c (mips_pseudo_table): Add tprelword/tpreldword
+       entries.
+       (mips16_percent_op): Add MIPS16 TLS relocation ops.
+       (md_apply_fix): Add BFD_RELOC_MIPS16_TLS_* switch cases.
+       (s_tls_rel_directive): Rename from s_dtprel_internal(). Abstract out
+       directive string and reloc type as function parameters. Update
+       comments.
+       (s_dtprelword,s_dtpreldword): Change to use s_tls_rel_directive().
+       (s_tprelword,s_tpreldword): New functions.
+
+       include/
+       * elf/mips.h (elf_mips_reloc_type): Add R_MIPS16_TLS_* entries.
+
+       bfd/
+       * reloc.c (BFD_RELOC_MIPS16_TLS_GD,BFD_RELOC_MIPS16_TLS_LDM,
+       BFD_RELOC_MIPS16_TLS_DTPREL_HI16,BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
+       BFD_RELOC_MIPS16_TLS_GOTTPREL,BFD_RELOC_MIPS16_TLS_TPREL_HI16,
+       BFD_RELOC_MIPS16_TLS_TPREL_LO16): New relocations for MIPS16 TLS.
+       * bfd-in2.h (bfd_reloc_code_real): Regenerate.
+       * libbfd.h (bfd_reloc_code_real_names): Regenerate.
+       * elf32-mips.c (elf_mips16_howto_table_rel): Add R_MIPS16_TLS_*
+       entries.
+       (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_*
+       mappings.
+       * elfn32-mips.c (elf_mips16_howto_table_rel,
+       elf_mips16_howto_table_rela): Add R_MIPS16_TLS_* entries.
+       (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_*
+       mappings.
+       * elf64-mips.c (mips16_elf64_howto_table_rel,
+       mips16_elf64_howto_table_rela): Add R_MIPS16_TLS_* entries.
+       (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_*
+       mappings.
+       * elfxx-mips.c (TLS_RELOC_P,mips16_reloc_p,
+       _bfd_mips_elf_check_relocs): Add cases for R_MIPS16_TLS_* relocations.
+       (tls_gd_reloc_p): Add R_MIPS16_TLS_GD case.
+       (tls_ldm_reloc_p): Add R_MIPS16_TLS_LDM case.
+       (tls_gottprel_reloc_p): Add R_MIPS16_TLS_GOTTPREL case.
+       (mips_elf_calculate_relocation): Add cases for R_MIPS16_TLS_*,
+       R_MIPS_TLS_DTPREL32/64, and R_MIPS_TLS_TPREL32/64 relocations.
+---
+ bfd/ChangeLog        |   32 ++++++++
+ bfd/bfd-in2.h        |    9 +++
+ bfd/elf32-mips.c     |  114 ++++++++++++++++++++++++++
+ bfd/elf64-mips.c     |  219 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ bfd/elfn32-mips.c    |  219 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ bfd/elfxx-mips.c     |   48 +++++++++--
+ bfd/libbfd.h         |    7 ++
+ bfd/reloc.c          |   17 ++++
+ gas/ChangeLog        |   16 ++++
+ gas/config/tc-mips.c |   62 ++++++++++----
+ include/ChangeLog    |    8 ++
+ include/elf/mips.h   |    9 ++-
+ 12 files changed, 739 insertions(+), 21 deletions(-)
+
+diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
+index 22fcdf6..cd90740 100644
+--- a/bfd/bfd-in2.h
++++ b/bfd/bfd-in2.h
+@@ -2780,6 +2780,15 @@ to compensate for the borrow when the low bits are added.  */
+ /* MIPS16 low 16 bits.  */
+   BFD_RELOC_MIPS16_LO16,
++/* MIPS16 TLS relocations  */
++  BFD_RELOC_MIPS16_TLS_GD,
++  BFD_RELOC_MIPS16_TLS_LDM,
++  BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
++  BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
++  BFD_RELOC_MIPS16_TLS_GOTTPREL,
++  BFD_RELOC_MIPS16_TLS_TPREL_HI16,
++  BFD_RELOC_MIPS16_TLS_TPREL_LO16,
++
+ /* Relocation against a MIPS literal section.  */
+   BFD_RELOC_MIPS_LITERAL,
+   BFD_RELOC_MICROMIPS_LITERAL,
+diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
+index fd3d4ba..61e8b45 100644
+--- a/bfd/elf32-mips.c
++++ b/bfd/elf32-mips.c
+@@ -830,6 +830,111 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS general dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GD",     /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_LDM",    /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_HI16",    /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_LO16",    /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GOTTPREL",       /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_HI16", /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_LO16", /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
+ };
+ static reloc_howto_type elf_micromips_howto_table_rel[] =
+@@ -1796,6 +1901,15 @@ static const struct elf_reloc_map mips16_reloc_map[] =
+   { 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 },
++  { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
++    R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
++    R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
+ };
+ static const struct elf_reloc_map micromips_reloc_map[] =
+diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
+index 3feb1bb..bdd0c19 100644
+--- a/bfd/elf64-mips.c
++++ b/bfd/elf64-mips.c
+@@ -1590,6 +1590,111 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS general dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GD",     /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_LDM",    /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_HI16",    /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_LO16",    /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GOTTPREL",       /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_HI16", /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_LO16", /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
+ };
+ static reloc_howto_type mips16_elf64_howto_table_rela[] =
+@@ -1686,6 +1791,111 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS general dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GD",     /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_LDM",    /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_HI16",    /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_LO16",    /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GOTTPREL",       /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_HI16", /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_LO16", /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
+ };
+ static reloc_howto_type micromips_elf64_howto_table_rel[] =
+@@ -2908,6 +3118,15 @@ static const struct elf_reloc_map mips16_reloc_map[] =
+   { 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 },
++  { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
++    R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
++    R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
+ };
+ static const struct elf_reloc_map micromips_reloc_map[] =
+diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
+index 00ec8b0..2189566 100644
+--- a/bfd/elfn32-mips.c
++++ b/bfd/elfn32-mips.c
+@@ -1555,6 +1555,111 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS general dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GD",     /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_LDM",    /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_HI16",    /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_LO16",    /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GOTTPREL",       /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_HI16", /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_LO16", /* name */
++       TRUE,                  /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
+ };
+ static reloc_howto_type elf_mips16_howto_table_rela[] =
+@@ -1651,6 +1756,111 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS general dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GD",     /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic variable reference.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_LDM",    /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_HI16",    /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS local dynamic offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_DTPREL_LO16",    /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_GOTTPREL",       /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_HI16", /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
++
++  /* MIPS16 TLS thread pointer offset.  */
++  HOWTO (R_MIPS16_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_MIPS16_TLS_TPREL_LO16", /* name */
++       FALSE,                 /* partial_inplace */
++       0x0000ffff,            /* src_mask */
++       0x0000ffff,            /* dst_mask */
++       FALSE),                /* pcrel_offset */
+ };
+ static reloc_howto_type elf_micromips_howto_table_rel[] =
+@@ -2724,6 +2934,15 @@ static const struct elf_reloc_map mips16_reloc_map[] =
+   { 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 },
++  { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
++    R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
++    R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
++  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
+ };
+ static const struct elf_reloc_map micromips_reloc_map[] =
+diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
+index 9f3833b..fa906cd 100644
+--- a/bfd/elfxx-mips.c
++++ b/bfd/elfxx-mips.c
+@@ -529,6 +529,13 @@ struct mips_htab_traverse_info
+    || r_type == R_MIPS_TLS_TPREL64            \
+    || r_type == R_MIPS_TLS_TPREL_HI16         \
+    || r_type == R_MIPS_TLS_TPREL_LO16         \
++   || r_type == R_MIPS16_TLS_GD                       \
++   || r_type == R_MIPS16_TLS_LDM              \
++   || r_type == R_MIPS16_TLS_DTPREL_HI16      \
++   || r_type == R_MIPS16_TLS_DTPREL_LO16      \
++   || r_type == R_MIPS16_TLS_GOTTPREL         \
++   || r_type == R_MIPS16_TLS_TPREL_HI16               \
++   || r_type == R_MIPS16_TLS_TPREL_LO16               \
+    || r_type == R_MICROMIPS_TLS_GD            \
+    || r_type == R_MICROMIPS_TLS_LDM           \
+    || r_type == R_MICROMIPS_TLS_DTPREL_HI16   \
+@@ -1885,6 +1892,13 @@ mips16_reloc_p (int r_type)
+     case R_MIPS16_CALL16:
+     case R_MIPS16_HI16:
+     case R_MIPS16_LO16:
++    case R_MIPS16_TLS_GD:
++    case R_MIPS16_TLS_LDM:
++    case R_MIPS16_TLS_DTPREL_HI16:
++    case R_MIPS16_TLS_DTPREL_LO16:
++    case R_MIPS16_TLS_GOTTPREL:
++    case R_MIPS16_TLS_TPREL_HI16:
++    case R_MIPS16_TLS_TPREL_LO16:
+       return TRUE;
+     default:
+@@ -2012,19 +2026,25 @@ micromips_branch_reloc_p (int r_type)
+ static inline bfd_boolean
+ tls_gd_reloc_p (unsigned int r_type)
+ {
+-  return r_type == R_MIPS_TLS_GD || r_type == R_MICROMIPS_TLS_GD;
++  return (r_type == R_MIPS_TLS_GD
++        || r_type == R_MIPS16_TLS_GD
++        || r_type == R_MICROMIPS_TLS_GD);
+ }
+ static inline bfd_boolean
+ tls_ldm_reloc_p (unsigned int r_type)
+ {
+-  return r_type == R_MIPS_TLS_LDM || r_type == R_MICROMIPS_TLS_LDM;
++  return (r_type == R_MIPS_TLS_LDM
++        || r_type == R_MIPS16_TLS_LDM
++        || r_type == R_MICROMIPS_TLS_LDM);
+ }
+ static inline bfd_boolean
+ tls_gottprel_reloc_p (unsigned int r_type)
+ {
+-  return r_type == R_MIPS_TLS_GOTTPREL || r_type == R_MICROMIPS_TLS_GOTTPREL;
++  return (r_type == R_MIPS_TLS_GOTTPREL
++        || r_type == R_MIPS16_TLS_GOTTPREL
++        || r_type == R_MICROMIPS_TLS_GOTTPREL);
+ }
+ void
+@@ -5361,6 +5381,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+     case R_MIPS_TLS_GD:
+     case R_MIPS_TLS_GOTTPREL:
+     case R_MIPS_TLS_LDM:
++    case R_MIPS16_TLS_GD:
++    case R_MIPS16_TLS_GOTTPREL:
++    case R_MIPS16_TLS_LDM:
+     case R_MICROMIPS_TLS_GD:
+     case R_MICROMIPS_TLS_GOTTPREL:
+     case R_MICROMIPS_TLS_LDM:
+@@ -5530,6 +5553,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+       break;
+     case R_MIPS_TLS_DTPREL_HI16:
++    case R_MIPS16_TLS_DTPREL_HI16:
+     case R_MICROMIPS_TLS_DTPREL_HI16:
+       value = (mips_elf_high (addend + symbol - dtprel_base (info))
+              & howto->dst_mask);
+@@ -5538,17 +5562,22 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+     case R_MIPS_TLS_DTPREL_LO16:
+     case R_MIPS_TLS_DTPREL32:
+     case R_MIPS_TLS_DTPREL64:
++    case R_MIPS16_TLS_DTPREL_LO16:
+     case R_MICROMIPS_TLS_DTPREL_LO16:
+       value = (symbol + addend - dtprel_base (info)) & howto->dst_mask;
+       break;
+     case R_MIPS_TLS_TPREL_HI16:
++    case R_MIPS16_TLS_TPREL_HI16:
+     case R_MICROMIPS_TLS_TPREL_HI16:
+       value = (mips_elf_high (addend + symbol - tprel_base (info))
+              & howto->dst_mask);
+       break;
+     case R_MIPS_TLS_TPREL_LO16:
++    case R_MIPS_TLS_TPREL32:
++    case R_MIPS_TLS_TPREL64:
++    case R_MIPS16_TLS_TPREL_LO16:
+     case R_MICROMIPS_TLS_TPREL_LO16:
+       value = (symbol + addend - tprel_base (info)) & howto->dst_mask;
+       break;
+@@ -5681,6 +5710,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+     case R_MIPS_TLS_GOTTPREL:
+     case R_MIPS_TLS_LDM:
+     case R_MIPS_GOT_DISP:
++    case R_MIPS16_TLS_GD:
++    case R_MIPS16_TLS_GOTTPREL:
++    case R_MIPS16_TLS_LDM:
+     case R_MICROMIPS_TLS_GD:
+     case R_MICROMIPS_TLS_GOTTPREL:
+     case R_MICROMIPS_TLS_LDM:
+@@ -7813,8 +7845,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+       can_make_dynamic_p = FALSE;
+       switch (r_type)
+       {
+-      case R_MIPS16_GOT16:
+-      case R_MIPS16_CALL16:
+       case R_MIPS_GOT16:
+       case R_MIPS_CALL16:
+       case R_MIPS_CALL_HI16:
+@@ -7827,6 +7857,11 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+       case R_MIPS_TLS_GOTTPREL:
+       case R_MIPS_TLS_GD:
+       case R_MIPS_TLS_LDM:
++      case R_MIPS16_GOT16:
++      case R_MIPS16_CALL16:
++      case R_MIPS16_TLS_GOTTPREL:
++      case R_MIPS16_TLS_GD:
++      case R_MIPS16_TLS_LDM:
+       case R_MICROMIPS_GOT16:
+       case R_MICROMIPS_CALL16:
+       case R_MICROMIPS_CALL_HI16:
+@@ -8063,12 +8098,14 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+         break;
+       case R_MIPS_TLS_GOTTPREL:
++      case R_MIPS16_TLS_GOTTPREL:
+       case R_MICROMIPS_TLS_GOTTPREL:
+         if (info->shared)
+           info->flags |= DF_STATIC_TLS;
+         /* Fall through */
+       case R_MIPS_TLS_LDM:
++      case R_MIPS16_TLS_LDM:
+       case R_MICROMIPS_TLS_LDM:
+         if (tls_ldm_reloc_p (r_type))
+           {
+@@ -8078,6 +8115,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+         /* Fall through */
+       case R_MIPS_TLS_GD:
++      case R_MIPS16_TLS_GD:
+       case R_MICROMIPS_TLS_GD:
+         /* This symbol requires a global offset table entry, or two
+            for TLS GD relocations.  */
+diff --git a/bfd/libbfd.h b/bfd/libbfd.h
+index 200a6fa..0395ec2 100644
+--- a/bfd/libbfd.h
++++ b/bfd/libbfd.h
+@@ -1086,6 +1086,13 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
+   "BFD_RELOC_MIPS16_HI16",
+   "BFD_RELOC_MIPS16_HI16_S",
+   "BFD_RELOC_MIPS16_LO16",
++  "BFD_RELOC_MIPS16_TLS_GD",
++  "BFD_RELOC_MIPS16_TLS_LDM",
++  "BFD_RELOC_MIPS16_TLS_DTPREL_HI16",
++  "BFD_RELOC_MIPS16_TLS_DTPREL_LO16",
++  "BFD_RELOC_MIPS16_TLS_GOTTPREL",
++  "BFD_RELOC_MIPS16_TLS_TPREL_HI16",
++  "BFD_RELOC_MIPS16_TLS_TPREL_LO16",
+   "BFD_RELOC_MIPS_LITERAL",
+   "BFD_RELOC_MICROMIPS_LITERAL",
+   "BFD_RELOC_MICROMIPS_7_PCREL_S1",
+diff --git a/bfd/reloc.c b/bfd/reloc.c
+index 6ac7148..ef55cc3 100644
+--- a/bfd/reloc.c
++++ b/bfd/reloc.c
+@@ -2247,6 +2247,23 @@ ENUMDOC
+   MIPS16 low 16 bits.
+ ENUM
++  BFD_RELOC_MIPS16_TLS_GD
++ENUMX
++  BFD_RELOC_MIPS16_TLS_LDM
++ENUMX
++  BFD_RELOC_MIPS16_TLS_DTPREL_HI16
++ENUMX
++  BFD_RELOC_MIPS16_TLS_DTPREL_LO16
++ENUMX
++  BFD_RELOC_MIPS16_TLS_GOTTPREL
++ENUMX
++  BFD_RELOC_MIPS16_TLS_TPREL_HI16
++ENUMX
++  BFD_RELOC_MIPS16_TLS_TPREL_LO16
++ENUMDOC
++  MIPS16 TLS relocations
++
++ENUM
+   BFD_RELOC_MIPS_LITERAL
+ ENUMX
+   BFD_RELOC_MICROMIPS_LITERAL
+diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
+index 0e4c66e..0fb3a6e 100644
+--- a/gas/config/tc-mips.c
++++ b/gas/config/tc-mips.c
+@@ -1352,6 +1352,8 @@ static void s_cprestore (int);
+ static void s_cpreturn (int);
+ static void s_dtprelword (int);
+ static void s_dtpreldword (int);
++static void s_tprelword (int);
++static void s_tpreldword (int);
+ static void s_gpvalue (int);
+ static void s_gpword (int);
+ static void s_gpdword (int);
+@@ -1431,6 +1433,8 @@ static const pseudo_typeS mips_pseudo_table[] =
+   {"cpreturn", s_cpreturn, 0},
+   {"dtprelword", s_dtprelword, 0},
+   {"dtpreldword", s_dtpreldword, 0},
++  {"tprelword", s_tprelword, 0},
++  {"tpreldword", s_tpreldword, 0},
+   {"gpvalue", s_gpvalue, 0},
+   {"gpword", s_gpword, 0},
+   {"gpdword", s_gpdword, 0},
+@@ -14040,7 +14044,14 @@ static const struct percent_op_match mips16_percent_op[] =
+   {"%gprel", BFD_RELOC_MIPS16_GPREL},
+   {"%got", BFD_RELOC_MIPS16_GOT16},
+   {"%call16", BFD_RELOC_MIPS16_CALL16},
+-  {"%hi", BFD_RELOC_MIPS16_HI16_S}
++  {"%hi", BFD_RELOC_MIPS16_HI16_S},
++  {"%tlsgd", BFD_RELOC_MIPS16_TLS_GD},
++  {"%tlsldm", BFD_RELOC_MIPS16_TLS_LDM},
++  {"%dtprel_hi", BFD_RELOC_MIPS16_TLS_DTPREL_HI16},
++  {"%dtprel_lo", BFD_RELOC_MIPS16_TLS_DTPREL_LO16},
++  {"%tprel_hi", BFD_RELOC_MIPS16_TLS_TPREL_HI16},
++  {"%tprel_lo", BFD_RELOC_MIPS16_TLS_TPREL_LO16},
++  {"%gottprel", BFD_RELOC_MIPS16_TLS_GOTTPREL}
+ };
+@@ -15369,6 +15380,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+     case BFD_RELOC_MIPS_TLS_DTPREL_HI16:
+     case BFD_RELOC_MIPS_TLS_DTPREL_LO16:
+     case BFD_RELOC_MIPS_TLS_GOTTPREL:
++    case BFD_RELOC_MIPS_TLS_TPREL32:
++    case BFD_RELOC_MIPS_TLS_TPREL64:
+     case BFD_RELOC_MIPS_TLS_TPREL_HI16:
+     case BFD_RELOC_MIPS_TLS_TPREL_LO16:
+     case BFD_RELOC_MICROMIPS_TLS_GD:
+@@ -15378,6 +15391,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+     case BFD_RELOC_MICROMIPS_TLS_GOTTPREL:
+     case BFD_RELOC_MICROMIPS_TLS_TPREL_HI16:
+     case BFD_RELOC_MICROMIPS_TLS_TPREL_LO16:
++    case BFD_RELOC_MIPS16_TLS_GD:
++    case BFD_RELOC_MIPS16_TLS_LDM:
++    case BFD_RELOC_MIPS16_TLS_DTPREL_HI16:
++    case BFD_RELOC_MIPS16_TLS_DTPREL_LO16:
++    case BFD_RELOC_MIPS16_TLS_GOTTPREL:
++    case BFD_RELOC_MIPS16_TLS_TPREL_HI16:
++    case BFD_RELOC_MIPS16_TLS_TPREL_LO16:
+       S_SET_THREAD_LOCAL (fixP->fx_addsy);
+       /* fall through */
+@@ -16547,12 +16567,14 @@ s_cpreturn (int ignore ATTRIBUTE_UNUSED)
+   demand_empty_rest_of_line ();
+ }
+-/* Handle the .dtprelword and .dtpreldword pseudo-ops.  They generate
+-   a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
+-   use in DWARF debug information.  */
++/* Handle a .dtprelword, .dtpreldword, .tprelword, or .tpreldword
++   pseudo-op; DIRSTR says which. The pseudo-op generates a BYTES-size
++   DTP- or TP-relative relocation of type RTYPE, for use in either DWARF
++   debug information or MIPS16 TLS.  */
+ static void
+-s_dtprel_internal (size_t bytes)
++s_tls_rel_directive (const size_t bytes, const char *dirstr,
++                   bfd_reloc_code_real_type rtype)
+ {
+   expressionS ex;
+   char *p;
+@@ -16561,19 +16583,13 @@ s_dtprel_internal (size_t bytes)
+   if (ex.X_op != O_symbol)
+     {
+-      as_bad (_("Unsupported use of %s"), (bytes == 8
+-                                         ? ".dtpreldword"
+-                                         : ".dtprelword"));
++      as_bad (_("Unsupported use of %s"), dirstr);
+       ignore_rest_of_line ();
+     }
+   p = frag_more (bytes);
+   md_number_to_chars (p, 0, bytes);
+-  fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
+-             (bytes == 8
+-              ? BFD_RELOC_MIPS_TLS_DTPREL64
+-              : BFD_RELOC_MIPS_TLS_DTPREL32));
+-
++  fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE, rtype);
+   demand_empty_rest_of_line ();
+ }
+@@ -16582,7 +16598,7 @@ s_dtprel_internal (size_t bytes)
+ static void
+ s_dtprelword (int ignore ATTRIBUTE_UNUSED)
+ {
+-  s_dtprel_internal (4);
++  s_tls_rel_directive (4, ".dtprelword", BFD_RELOC_MIPS_TLS_DTPREL32);
+ }
+ /* Handle .dtpreldword.  */
+@@ -16590,7 +16606,23 @@ s_dtprelword (int ignore ATTRIBUTE_UNUSED)
+ static void
+ s_dtpreldword (int ignore ATTRIBUTE_UNUSED)
+ {
+-  s_dtprel_internal (8);
++  s_tls_rel_directive (8, ".dtpreldword", BFD_RELOC_MIPS_TLS_DTPREL64);
++}
++
++/* Handle .tprelword.  */
++
++static void
++s_tprelword (int ignore ATTRIBUTE_UNUSED)
++{
++  s_tls_rel_directive (4, ".tprelword", BFD_RELOC_MIPS_TLS_TPREL32);
++}
++
++/* Handle .tpreldword.  */
++
++static void
++s_tpreldword (int ignore ATTRIBUTE_UNUSED)
++{
++  s_tls_rel_directive (8, ".tpreldword", BFD_RELOC_MIPS_TLS_TPREL64);
+ }
+ /* Handle the .gpvalue pseudo-op.  This is used when generating NewABI PIC
+diff --git a/include/elf/mips.h b/include/elf/mips.h
+index db5fa54..c2c5922 100644
+--- a/include/elf/mips.h
++++ b/include/elf/mips.h
+@@ -98,7 +98,14 @@ START_RELOC_NUMBERS (elf_mips_reloc_type)
+   RELOC_NUMBER (R_MIPS16_CALL16, 103)
+   RELOC_NUMBER (R_MIPS16_HI16, 104)
+   RELOC_NUMBER (R_MIPS16_LO16, 105)
+-  FAKE_RELOC (R_MIPS16_max, 106)
++  RELOC_NUMBER (R_MIPS16_TLS_GD, 106)
++  RELOC_NUMBER (R_MIPS16_TLS_LDM, 107)
++  RELOC_NUMBER (R_MIPS16_TLS_DTPREL_HI16, 108)
++  RELOC_NUMBER (R_MIPS16_TLS_DTPREL_LO16, 109)
++  RELOC_NUMBER (R_MIPS16_TLS_GOTTPREL, 110)
++  RELOC_NUMBER (R_MIPS16_TLS_TPREL_HI16, 111)
++  RELOC_NUMBER (R_MIPS16_TLS_TPREL_LO16, 112)
++  FAKE_RELOC (R_MIPS16_max, 113)
+   /* These relocations are specific to VxWorks.  */
+   RELOC_NUMBER (R_MIPS_COPY, 126)
+   RELOC_NUMBER (R_MIPS_JUMP_SLOT, 127)
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch b/meta/recipes-devtools/binutils/binutils/0038-Copy-from-mainline-to-binutils-2.22-branch.patch
new file mode 100644 (file)
index 0000000..453ef22
--- /dev/null
@@ -0,0 +1,1944 @@
+Upstream-Status: Backport
+
+From 624da0376264205e399bc14fe2fa7b6fa659d0ee Mon Sep 17 00:00:00 2001
+From: Ian Lance Taylor <ian@airs.com>
+Date: Mon, 19 Dec 2011 21:14:39 +0000
+Subject: [PATCH 038/262]       Copy from mainline to binutils 2.22 branch:
+
+       2011-12-17  Cary Coutant  <ccoutant@google.com>
+
+       * dwarf_reader.cc (Sized_dwarf_line_info::read_lines): Add casts.
+       * resolve.cc (Symbol_table::resolve): Likewise.
+       * i386.cc (Target_i386::do_code_fill): Use char constants for nop
+       arrays.
+       * x86_64.cc (Target_x86_64::do_code_fill): Likewise.
+
+       2011-10-31  Cary Coutant  <ccoutant@google.com>
+
+       PR gold/13023
+       * expression.cc (Expression::eval_with_dot): Add
+       is_section_dot_assignment parameter.
+       (Expression::eval_maybe_dot): Likewise.  Adjust value when rhs is
+       absolute and assigning to dot within a section.
+       * script-sections.cc
+       (Output_section_element_assignment::set_section_addresses): Pass
+       dot_section to set_if_absolute.
+       (Output_section_element_dot_assignment::finalize_symbols): Pass TRUE
+       as is_section_dot_assignment flag to eval_with_dot.
+       (Output_section_element_dot_assignment::set_section_addresses):
+       Likewise.
+       * script.cc (Symbol_assignment::set_if_absolute): Add dot_section
+       parameter.  Also set value if relative to dot_section; set the
+       symbol's output_section.
+       * script.h (Expression::eval_with_dot): Add is_section_dot_assignment
+       parameter.  Adjust all callers.
+       (Expression::eval_maybe_dot): Likewise.
+       (Symbol_assignment::set_if_absolute): Add dot_section parameter.
+       Adjust all callers.
+       * testsuite/script_test_2.t: Test assignment of an absolute value
+       to dot within an output section element.
+
+       2011-10-31  Cary Coutant  <ccoutant@google.com>
+
+       * options.h (class General_options): Add --[no-]gnu-unique options.
+       * symtab.cc (Symbol_table::sized_write_globals): Convert
+       STB_GNU_UNIQUE to STB_GLOBAL if --no-gnu-unique.
+
+       2011-10-31  Cary Coutant  <ccoutant@google.com>
+
+       PR gold/13359
+       * i386.cc (Target_i386::Relocate::relocate_tls): Remove
+       unnecessary assertion.
+       * x86_64.cc (Target_x86_64::Relocate::relocate_tls): Likewise.
+
+       2011-10-31 Sriraman Tallam  <tmsriram@google.com>
+
+       * symtab.h (Symbol_table::gc_mark_symbol_for_shlib): Rename to
+       gc_mark_symbol.
+       * symtab.cc (Symbol_table::gc_mark_symbol_for_shlib): Rename to
+       gc_mark_symbol.
+       Change to just keep the section associated with symbol.
+       (Symbol_table::add_from_relobj): Mark symbols as not garbage when
+       they are externally visible and --export-dynamic is turned on.
+       (Symbol_table::gc_mark_dyn_syms): Call gc_mark_symbol.
+
+       2011-10-19  Ian Lance Taylor  <iant@google.com>
+
+       PR gold/13163
+       * script-sections.cc
+       (Output_section_element_dot_assignment::needs_output_section): New
+       function.
+
+       2011-10-19  Ian Lance Taylor  <iant@google.com>
+
+       PR gold/13204
+       * layout.cc (Layout::segment_precedes): Don't assert failure if a
+       --section-start option was seen.
+       * options.h (General_options::any_section_start): New function.
+
+       2011-10-18  Cary Coutant  <ccoutant@google.com>
+
+       * output.cc (posix_fallocate): Return 0 on success, errno on failure.
+       (Output_file::map_no_anonymous): Check for non-zero
+       return code from posix_fallocate.
+
+       2011-10-17  Cary Coutant  <ccoutant@google.com>
+
+       PR gold/13245
+       * plugin.cc (is_visible_from_outside): Check for symbols
+       referenced from dynamic objects.
+       * resolve.cc (Symbol_table::resolve): Don't count references
+       from dynamic objects as references from real ELF files.
+       * testsuite/plugin_test_2.sh: Adjust expected result.
+
+       2011-10-17  Cary Coutant  <ccoutant@google.com>
+
+       * readsyms.cc (Read_symbols::run): Don't queue an unblocker
+       task for members of lib groups.
+
+       2011-10-17  Cary Coutant  <ccoutant@google.com>
+
+       PR gold/13288
+       * fileread.cc (File_read::find_view): Add assert.
+       (File_read::make_view): Move bounds check (replace with assert)...
+       (File_read::find_or_make_view): ... to here.
+
+       2011-10-12  Cary Coutant  <ccoutant@google.com>
+
+       * output.cc (Output_file::open_base_file): Handle case where
+       ::read returns less than requested size.
+
+       2011-10-10  Cary Coutant  <ccoutant@google.com>
+
+       * incremental.cc (Sized_relobj_incr::Sized_relobj_incr):
+       Initialize defined_count_.
+       (Sized_relobj_incr::do_add_symbols): Count defined symbols.
+       (Sized_relobj_incr::do_get_global_symbol_counts): Rewrite.
+       (Sized_incr_dynobj::Sized_incr_dynobj): Initialize defined_count_.
+       (Sized_incr_dynobj::do_add_symbols): Count defined symbols.
+       (Sized_incr_dynobj::do_get_global_symbol_counts): Rewrite.
+       * incremental.h (Sized_relobj_incr::defined_count_): New data
+       member.
+       (Sized_incr_dynobj::defined_count_): New data member.
+       * plugin.cc (Sized_pluginobj::do_get_global_symbol_counts):
+       Return zeroes instead of internal error.
+
+       2011-10-10  Cary Coutant  <ccoutant@google.com>
+
+       PR gold/13249
+       * output.cc (Output_reloc::Output_reloc): Add use_plt_offset flag.
+       (Output_reloc::symbol_value): Return PLT offset if flag is set.
+       * output.h (class Output_reloc): Add use_plt_offset flag.
+       (Output_reloc::type_): Adjust size of bit field.
+       (Output_reloc::use_plt_offset_): New bit field.
+       (class Output_data_reloc): Adjust all calls to Output_reloc_type.
+       (Output_data_reloc::add_local_relative): (RELA only) Add use_plt_offset
+       flag.  Adjust all callers.
+       * x86_64.cc (Target_x86_64::Scan::local): Check for IFUNC when
+       creating RELATIVE relocations.
+
+       2011-10-03   Diego Novillo  <dnovillo@google.com>
+
+       * options.cc (parse_uint): Fix dereference of RETVAL.
+
+       2011-09-29  Cary Coutant  <ccoutant@google.com>
+
+       * incremental.cc (Sized_incremental_binary::do_process_got_plt):
+       Check for NULL.
+       * symtab.cc (Symbol_table::add_from_relobj): Ignore version
+       symbols during incremental update.
+       (Symbol_table::add_from_dynobj): Likewise.
+
+       2011-09-26  Cary Coutant  <ccoutant@google.com>
+
+       * gold.cc (queue_initial_tasks): Move option checks ...
+       * options.cc (General_options::finalize): ... to here. Disable
+       some options; make others fatal.
+
+       2011-09-23  Simon Baldwin  <simonb@google.com>
+
+       * configure.ac: Add new --with-gold-ldadd and --with-gold-ldflags
+       configuration options.
+       * configure: Regenerate.
+       * Makefile.am: Handle GOLD_LDADD and GOLD_LDFLAGS.
+       * Makefile.in: Regenerate.
+       * testsuite/Makefile.in: Regenerate.
+---
+ gold/ChangeLog                  |  163 +++++++++++++++++++++++++++++++++++++++
+ gold/dwarf_reader.cc            |    8 +-
+ gold/expression.cc              |   45 +++++++----
+ gold/fileread.cc                |   27 ++++---
+ gold/gold.cc                    |   55 +++++--------
+ gold/i386.cc                    |   87 +++++++++++----------
+ gold/incremental.cc             |   50 +++++++++---
+ gold/incremental.h              |    4 +
+ gold/layout.cc                  |    5 +-
+ gold/options.cc                 |   33 +++++++-
+ gold/options.h                  |    9 +++
+ gold/output.cc                  |   78 ++++++++++++-------
+ gold/output.h                   |   64 +++++++++------
+ gold/plugin.cc                  |   18 +++--
+ gold/powerpc.cc                 |    4 +-
+ gold/readsyms.cc                |    6 +-
+ gold/resolve.cc                 |    6 +-
+ gold/script-sections.cc         |   47 +++++++----
+ gold/script.cc                  |   17 ++--
+ gold/script.h                   |   24 ++++--
+ gold/sparc.cc                   |    4 +-
+ gold/symtab.cc                  |   65 +++++++++-------
+ gold/symtab.h                   |    5 +-
+ gold/testsuite/Makefile.in      |    2 +
+ gold/testsuite/plugin_test_2.sh |    2 +-
+ gold/testsuite/script_test_2.t  |    2 +-
+ gold/x86_64.cc                  |   99 ++++++++++++------------
+ 27 files changed, 636 insertions(+), 293 deletions(-)
+
+diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc
+index 3dc33e4..2b47a28 100644
+--- a/gold/dwarf_reader.cc
++++ b/gold/dwarf_reader.cc
+@@ -1,6 +1,6 @@
+ // dwarf_reader.cc -- parse dwarf2/3 debug information
+-// Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
++// Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ // Written by Ian Lance Taylor <iant@google.com>.
+ // This file is part of gold.
+@@ -491,8 +491,10 @@ Sized_dwarf_line_info<size, big_endian>::read_lines(unsigned const char* lineptr
+               && (shndx == -1U || lsm.shndx == -1U || shndx == lsm.shndx))
+             {
+               Offset_to_lineno_entry entry
+-                  = { lsm.address, this->current_header_index_,
+-                      lsm.file_num, true, lsm.line_num };
++                  = { static_cast<off_t>(lsm.address),
++                    this->current_header_index_,
++                    static_cast<unsigned int>(lsm.file_num),
++                    true, lsm.line_num };
+             std::vector<Offset_to_lineno_entry>&
+               map(this->line_number_map_[lsm.shndx]);
+             // If we see two consecutive entries with the same
+diff --git a/gold/expression.cc b/gold/expression.cc
+index e527b5e..e31c151 100644
+--- a/gold/expression.cc
++++ b/gold/expression.cc
+@@ -1,6 +1,6 @@
+ // expression.cc -- expressions in linker scripts for gold
+-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
++// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ // Written by Ian Lance Taylor <iant@google.com>.
+ // This file is part of gold.
+@@ -77,7 +77,7 @@ Expression::eval(const Symbol_table* symtab, const Layout* layout,
+                bool check_assertions)
+ {
+   return this->eval_maybe_dot(symtab, layout, check_assertions,
+-                            false, 0, NULL, NULL, NULL);
++                            false, 0, NULL, NULL, NULL, false);
+ }
+ // Evaluate an expression which may refer to the dot symbol.
+@@ -87,11 +87,13 @@ Expression::eval_with_dot(const Symbol_table* symtab, const Layout* layout,
+                         bool check_assertions, uint64_t dot_value,
+                         Output_section* dot_section,
+                         Output_section** result_section_pointer,
+-                        uint64_t* result_alignment_pointer)
++                        uint64_t* result_alignment_pointer,
++                        bool is_section_dot_assignment)
+ {
+   return this->eval_maybe_dot(symtab, layout, check_assertions, true,
+                             dot_value, dot_section, result_section_pointer,
+-                            result_alignment_pointer);
++                            result_alignment_pointer,
++                            is_section_dot_assignment);
+ }
+ // Evaluate an expression which may or may not refer to the dot
+@@ -102,7 +104,8 @@ Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout,
+                          bool check_assertions, bool is_dot_available,
+                          uint64_t dot_value, Output_section* dot_section,
+                          Output_section** result_section_pointer,
+-                         uint64_t* result_alignment_pointer)
++                         uint64_t* result_alignment_pointer,
++                         bool is_section_dot_assignment)
+ {
+   Expression_eval_info eei;
+   eei.symtab = symtab;
+@@ -113,14 +116,24 @@ Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout,
+   eei.dot_section = dot_section;
+   // We assume the value is absolute, and only set this to a section
+-  // if we find a section relative reference.
++  // if we find a section-relative reference.
+   if (result_section_pointer != NULL)
+     *result_section_pointer = NULL;
+   eei.result_section_pointer = result_section_pointer;
+   eei.result_alignment_pointer = result_alignment_pointer;
+-  return this->value(&eei);
++  uint64_t val = this->value(&eei);
++
++  // If this is an assignment to dot within a section, and the value
++  // is absolute, treat it as a section-relative offset.
++  if (is_section_dot_assignment && *result_section_pointer == NULL)
++    {
++      gold_assert(dot_section != NULL);
++      val += dot_section->address();
++      *result_section_pointer = dot_section;
++    }
++  return val;
+ }
+ // A number.
+@@ -257,7 +270,8 @@ class Unary_expression : public Expression
+                                     eei->dot_value,
+                                     eei->dot_section,
+                                     arg_section_pointer,
+-                                    eei->result_alignment_pointer);
++                                    eei->result_alignment_pointer,
++                                    false);
+   }
+   void
+@@ -336,7 +350,8 @@ class Binary_expression : public Expression
+                                      eei->dot_value,
+                                      eei->dot_section,
+                                      section_pointer,
+-                                     alignment_pointer);
++                                     alignment_pointer,
++                                     false);
+   }
+   uint64_t
+@@ -350,7 +365,8 @@ class Binary_expression : public Expression
+                                       eei->dot_value,
+                                       eei->dot_section,
+                                       section_pointer,
+-                                      alignment_pointer);
++                                      alignment_pointer,
++                                      false);
+   }
+   void
+@@ -500,7 +516,8 @@ class Trinary_expression : public Expression
+                                      eei->dot_value,
+                                      eei->dot_section,
+                                      section_pointer,
+-                                     NULL);
++                                     NULL,
++                                     false);
+   }
+   uint64_t
+@@ -514,7 +531,8 @@ class Trinary_expression : public Expression
+                                      eei->dot_value,
+                                      eei->dot_section,
+                                      section_pointer,
+-                                     alignment_pointer);
++                                     alignment_pointer,
++                                     false);
+   }
+   uint64_t
+@@ -528,7 +546,8 @@ class Trinary_expression : public Expression
+                                      eei->dot_value,
+                                      eei->dot_section,
+                                      section_pointer,
+-                                     alignment_pointer);
++                                     alignment_pointer,
++                                     false);
+   }
+   void
+diff --git a/gold/fileread.cc b/gold/fileread.cc
+index 80ddfbc..c5dc320 100644
+--- a/gold/fileread.cc
++++ b/gold/fileread.cc
+@@ -329,6 +329,10 @@ inline File_read::View*
+ File_read::find_view(off_t start, section_size_type size,
+                    unsigned int byteshift, File_read::View** vshifted) const
+ {
++  gold_assert(start <= this->size_
++            && (static_cast<unsigned long long>(size)
++                <= static_cast<unsigned long long>(this->size_ - start)));
++
+   if (vshifted != NULL)
+     *vshifted = NULL;
+@@ -456,16 +460,9 @@ File_read::make_view(off_t start, section_size_type size,
+                    unsigned int byteshift, bool cache)
+ {
+   gold_assert(size > 0);
+-
+-  // Check that start and end of the view are within the file.
+-  if (start > this->size_
+-      || (static_cast<unsigned long long>(size)
+-          > static_cast<unsigned long long>(this->size_ - start)))
+-    gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds "
+-                 "size of file; the file may be corrupt"),
+-                 this->filename().c_str(),
+-                 static_cast<long long>(size),
+-                 static_cast<long long>(start));
++  gold_assert(start <= this->size_
++            && (static_cast<unsigned long long>(size)
++                <= static_cast<unsigned long long>(this->size_ - start)));
+   off_t poff = File_read::page_offset(start);
+@@ -523,6 +520,16 @@ File_read::View*
+ File_read::find_or_make_view(off_t offset, off_t start,
+                            section_size_type size, bool aligned, bool cache)
+ {
++  // Check that start and end of the view are within the file.
++  if (start > this->size_
++      || (static_cast<unsigned long long>(size)
++          > static_cast<unsigned long long>(this->size_ - start)))
++    gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds "
++                 "size of file; the file may be corrupt"),
++                 this->filename().c_str(),
++                 static_cast<long long>(size),
++                 static_cast<long long>(start));
++
+   unsigned int byteshift;
+   if (offset == 0)
+     byteshift = 0;
+diff --git a/gold/gold.cc b/gold/gold.cc
+index 12f25b7..693ff79 100644
+--- a/gold/gold.cc
++++ b/gold/gold.cc
+@@ -197,46 +197,29 @@ queue_initial_tasks(const General_options& options,
+   // For incremental links, the base output file.
+   Incremental_binary* ibase = NULL;
+-  if (parameters->incremental())
+-    {
+-      if (options.relocatable())
+-      gold_error(_("incremental linking is incompatible with -r"));
+-      if (options.emit_relocs())
+-      gold_error(_("incremental linking is incompatible with --emit-relocs"));
+-      if (options.gc_sections())
+-      gold_error(_("incremental linking is incompatible with --gc-sections"));
+-      if (options.icf_enabled())
+-      gold_error(_("incremental linking is incompatible with --icf"));
+-      if (options.has_plugins())
+-      gold_error(_("incremental linking is incompatible with --plugin"));
+-      if (strcmp(options.compress_debug_sections(), "none") != 0)
+-      gold_error(_("incremental linking is incompatible with "
+-                   "--compress-debug-sections"));
+-
+-      if (parameters->incremental_update())
++  if (parameters->incremental_update())
++    {
++      Output_file* of = new Output_file(options.output_file_name());
++      if (of->open_base_file(options.incremental_base(), true))
+       {
+-        Output_file* of = new Output_file(options.output_file_name());
+-        if (of->open_base_file(options.incremental_base(), true))
+-          {
+-            ibase = open_incremental_binary(of);
+-            if (ibase != NULL
+-                && ibase->check_inputs(cmdline, layout->incremental_inputs()))
+-              ibase->init_layout(layout);
+-            else
+-              {
+-                delete ibase;
+-                ibase = NULL;
+-                of->close();
+-              }
+-          }
+-        if (ibase == NULL)
++        ibase = open_incremental_binary(of);
++        if (ibase != NULL
++            && ibase->check_inputs(cmdline, layout->incremental_inputs()))
++          ibase->init_layout(layout);
++        else
+           {
+-            if (set_parameters_incremental_full())
+-              gold_info(_("linking with --incremental-full"));
+-            else
+-              gold_fallback(_("restart link with --incremental-full"));
++            delete ibase;
++            ibase = NULL;
++            of->close();
+           }
+       }
++      if (ibase == NULL)
++      {
++        if (set_parameters_incremental_full())
++          gold_info(_("linking with --incremental-full"));
++        else
++          gold_fallback(_("restart link with --incremental-full"));
++      }
+     }
+   // Read the input files.  We have to add the symbols to the symbol
+diff --git a/gold/i386.cc b/gold/i386.cc
+index 445bc68..efb6248 100644
+--- a/gold/i386.cc
++++ b/gold/i386.cc
+@@ -2709,12 +2709,6 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
+             }
+           if (optimized_type == tls::TLSOPT_TO_IE)
+           {
+-            if (tls_segment == NULL)
+-              {
+-                gold_assert(parameters->errors()->error_count() > 0
+-                            || issue_undefined_symbol_error(gsym));
+-                return;
+-              }
+             this->tls_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type,
+                                  got_offset, view, view_size);
+               break;
+@@ -3480,42 +3474,51 @@ Target_i386::do_code_fill(section_size_type length) const
+     }
+   // Nop sequences of various lengths.
+-  const char nop1[1] = { 0x90 };                   // nop
+-  const char nop2[2] = { 0x66, 0x90 };             // xchg %ax %ax
+-  const char nop3[3] = { 0x8d, 0x76, 0x00 };       // leal 0(%esi),%esi
+-  const char nop4[4] = { 0x8d, 0x74, 0x26, 0x00};  // leal 0(%esi,1),%esi
+-  const char nop5[5] = { 0x90, 0x8d, 0x74, 0x26,   // nop
+-                         0x00 };                   // leal 0(%esi,1),%esi
+-  const char nop6[6] = { 0x8d, 0xb6, 0x00, 0x00,   // leal 0L(%esi),%esi
+-                         0x00, 0x00 };
+-  const char nop7[7] = { 0x8d, 0xb4, 0x26, 0x00,   // leal 0L(%esi,1),%esi
+-                         0x00, 0x00, 0x00 };
+-  const char nop8[8] = { 0x90, 0x8d, 0xb4, 0x26,   // nop
+-                         0x00, 0x00, 0x00, 0x00 }; // leal 0L(%esi,1),%esi
+-  const char nop9[9] = { 0x89, 0xf6, 0x8d, 0xbc,   // movl %esi,%esi
+-                         0x27, 0x00, 0x00, 0x00,   // leal 0L(%edi,1),%edi
+-                         0x00 };
+-  const char nop10[10] = { 0x8d, 0x76, 0x00, 0x8d, // leal 0(%esi),%esi
+-                           0xbc, 0x27, 0x00, 0x00, // leal 0L(%edi,1),%edi
+-                           0x00, 0x00 };
+-  const char nop11[11] = { 0x8d, 0x74, 0x26, 0x00, // leal 0(%esi,1),%esi
+-                           0x8d, 0xbc, 0x27, 0x00, // leal 0L(%edi,1),%edi
+-                           0x00, 0x00, 0x00 };
+-  const char nop12[12] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi
+-                           0x00, 0x00, 0x8d, 0xbf, // leal 0L(%edi),%edi
+-                           0x00, 0x00, 0x00, 0x00 };
+-  const char nop13[13] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi
+-                           0x00, 0x00, 0x8d, 0xbc, // leal 0L(%edi,1),%edi
+-                           0x27, 0x00, 0x00, 0x00,
+-                           0x00 };
+-  const char nop14[14] = { 0x8d, 0xb4, 0x26, 0x00, // leal 0L(%esi,1),%esi
+-                           0x00, 0x00, 0x00, 0x8d, // leal 0L(%edi,1),%edi
+-                           0xbc, 0x27, 0x00, 0x00,
+-                           0x00, 0x00 };
+-  const char nop15[15] = { 0xeb, 0x0d, 0x90, 0x90, // jmp .+15
+-                           0x90, 0x90, 0x90, 0x90, // nop,nop,nop,...
+-                           0x90, 0x90, 0x90, 0x90,
+-                           0x90, 0x90, 0x90 };
++  const char nop1[1] = { '\x90' };                   // nop
++  const char nop2[2] = { '\x66', '\x90' };           // xchg %ax %ax
++  const char nop3[3] = { '\x8d', '\x76', '\x00' };   // leal 0(%esi),%esi
++  const char nop4[4] = { '\x8d', '\x74', '\x26',     // leal 0(%esi,1),%esi
++                       '\x00'};
++  const char nop5[5] = { '\x90', '\x8d', '\x74',     // nop
++                       '\x26', '\x00' };           // leal 0(%esi,1),%esi
++  const char nop6[6] = { '\x8d', '\xb6', '\x00',     // leal 0L(%esi),%esi
++                       '\x00', '\x00', '\x00' };
++  const char nop7[7] = { '\x8d', '\xb4', '\x26',     // leal 0L(%esi,1),%esi
++                       '\x00', '\x00', '\x00',
++                       '\x00' };
++  const char nop8[8] = { '\x90', '\x8d', '\xb4',     // nop
++                       '\x26', '\x00', '\x00',     // leal 0L(%esi,1),%esi
++                       '\x00', '\x00' };
++  const char nop9[9] = { '\x89', '\xf6', '\x8d',     // movl %esi,%esi
++                       '\xbc', '\x27', '\x00',     // leal 0L(%edi,1),%edi
++                       '\x00', '\x00', '\x00' };
++  const char nop10[10] = { '\x8d', '\x76', '\x00',   // leal 0(%esi),%esi
++                         '\x8d', '\xbc', '\x27',   // leal 0L(%edi,1),%edi
++                         '\x00', '\x00', '\x00',
++                         '\x00' };
++  const char nop11[11] = { '\x8d', '\x74', '\x26',   // leal 0(%esi,1),%esi
++                         '\x00', '\x8d', '\xbc',   // leal 0L(%edi,1),%edi
++                         '\x27', '\x00', '\x00',
++                         '\x00', '\x00' };
++  const char nop12[12] = { '\x8d', '\xb6', '\x00',   // leal 0L(%esi),%esi
++                         '\x00', '\x00', '\x00',   // leal 0L(%edi),%edi
++                         '\x8d', '\xbf', '\x00',
++                         '\x00', '\x00', '\x00' };
++  const char nop13[13] = { '\x8d', '\xb6', '\x00',   // leal 0L(%esi),%esi
++                         '\x00', '\x00', '\x00',   // leal 0L(%edi,1),%edi
++                         '\x8d', '\xbc', '\x27',
++                         '\x00', '\x00', '\x00',
++                           '\x00' };
++  const char nop14[14] = { '\x8d', '\xb4', '\x26',   // leal 0L(%esi,1),%esi
++                         '\x00', '\x00', '\x00',   // leal 0L(%edi,1),%edi
++                         '\x00', '\x8d', '\xbc',
++                         '\x27', '\x00', '\x00',
++                           '\x00', '\x00' };
++  const char nop15[15] = { '\xeb', '\x0d', '\x90',   // jmp .+15
++                         '\x90', '\x90', '\x90',   // nop,nop,nop,...
++                         '\x90', '\x90', '\x90',
++                         '\x90', '\x90', '\x90',
++                           '\x90', '\x90', '\x90' };
+   const char* nops[16] = {
+     NULL,
+diff --git a/gold/incremental.cc b/gold/incremental.cc
+index b422827..75e44c5 100644
+--- a/gold/incremental.cc
++++ b/gold/incremental.cc
+@@ -685,7 +685,7 @@ Sized_incremental_binary<size, big_endian>::do_process_got_plt(
+       gold_assert(plt_desc >= first_global && plt_desc < symtab_count);
+       Symbol* sym = this->global_symbol(plt_desc - first_global);
+       // Add the PLT entry only if the symbol is still referenced.
+-      if (sym->in_reg())
++      if (sym != NULL && sym->in_reg())
+       {
+         gold_debug(DEBUG_INCREMENTAL,
+                    "PLT entry %d: %s",
+@@ -1966,8 +1966,9 @@ Sized_relobj_incr<size, big_endian>::Sized_relobj_incr(
+     input_reader_(ibase->inputs_reader().input_file(input_file_index)),
+     local_symbol_count_(0), output_local_dynsym_count_(0),
+     local_symbol_index_(0), local_symbol_offset_(0), local_dynsym_offset_(0),
+-    symbols_(), incr_reloc_offset_(-1U), incr_reloc_count_(0),
+-    incr_reloc_output_index_(0), incr_relocs_(NULL), local_symbols_()
++    symbols_(), defined_count_(0), incr_reloc_offset_(-1U),
++    incr_reloc_count_(0), incr_reloc_output_index_(0), incr_relocs_(NULL),
++    local_symbols_()
+ {
+   if (this->input_reader_.is_in_system_directory())
+     this->set_is_in_system_directory();
+@@ -2120,6 +2121,9 @@ Sized_relobj_incr<size, big_endian>::do_add_symbols(
+       Symbol* res = symtab->add_from_incrobj(this, name, NULL, &sym);
++      if (shndx != elfcpp::SHN_UNDEF)
++        ++this->defined_count_;
++
+       // If this is a linker-defined symbol that hasn't yet been defined,
+       // define it now.
+       if (input_shndx == -1U && !res->is_defined())
+@@ -2283,9 +2287,21 @@ Sized_relobj_incr<size, big_endian>::do_initialize_xindex()
+ template<int size, bool big_endian>
+ void
+ Sized_relobj_incr<size, big_endian>::do_get_global_symbol_counts(
+-    const Symbol_table*, size_t*, size_t*) const
+-{
+-  gold_unreachable();
++    const Symbol_table*,
++    size_t* defined,
++    size_t* used) const
++{
++  *defined = this->defined_count_;
++  size_t count = 0;
++  for (typename Symbols::const_iterator p = this->symbols_.begin();
++       p != this->symbols_.end();
++       ++p)
++    if (*p != NULL
++      && (*p)->source() == Symbol::FROM_OBJECT
++      && (*p)->object() == this
++      && (*p)->is_defined())
++      ++count;
++  *used = count;
+ }
+ // Read the relocs.
+@@ -2579,7 +2595,7 @@ Sized_incr_dynobj<size, big_endian>::Sized_incr_dynobj(
+   : Dynobj(name, NULL), ibase_(ibase),
+     input_file_index_(input_file_index),
+     input_reader_(ibase->inputs_reader().input_file(input_file_index)),
+-    symbols_()
++    symbols_(), defined_count_(0)
+ {
+   if (this->input_reader_.is_in_system_directory())
+     this->set_is_in_system_directory();
+@@ -2677,6 +2693,7 @@ Sized_incr_dynobj<size, big_endian>::do_add_symbols(
+         // is meaningless, as long as it's not SHN_UNDEF.
+         shndx = 1;
+         v = gsym.get_st_value();
++        ++this->defined_count_;
+       }
+       osym.put_st_name(0);
+@@ -2845,9 +2862,22 @@ Sized_incr_dynobj<size, big_endian>::do_initialize_xindex()
+ template<int size, bool big_endian>
+ void
+ Sized_incr_dynobj<size, big_endian>::do_get_global_symbol_counts(
+-    const Symbol_table*, size_t*, size_t*) const
+-{
+-  gold_unreachable();
++    const Symbol_table*,
++    size_t* defined,
++    size_t* used) const
++{
++  *defined = this->defined_count_;
++  size_t count = 0;
++  for (typename Symbols::const_iterator p = this->symbols_.begin();
++       p != this->symbols_.end();
++       ++p)
++    if (*p != NULL
++      && (*p)->source() == Symbol::FROM_OBJECT
++      && (*p)->object() == this
++      && (*p)->is_defined()
++      && (*p)->dynsym_index() != -1U)
++      ++count;
++  *used = count;
+ }
+ // Allocate an incremental object of the appropriate size and endianness.
+diff --git a/gold/incremental.h b/gold/incremental.h
+index e6732df..56fc52b 100644
+--- a/gold/incremental.h
++++ b/gold/incremental.h
+@@ -1996,6 +1996,8 @@ class Sized_relobj_incr : public Sized_relobj<size, big_endian>
+   unsigned int local_dynsym_offset_;
+   // The entries in the symbol table for the external symbols.
+   Symbols symbols_;
++  // Number of symbols defined in object file itself.
++  size_t defined_count_;
+   // The offset of the first incremental relocation for this object.
+   unsigned int incr_reloc_offset_;
+   // The number of incremental relocations for this object.
+@@ -2127,6 +2129,8 @@ class Sized_incr_dynobj : public Dynobj
+   Input_entry_reader input_reader_;
+   // The entries in the symbol table for the external symbols.
+   Symbols symbols_;
++  // Number of symbols defined in object file itself.
++  size_t defined_count_;
+ };
+ // Allocate an incremental object of the appropriate size and endianness.
+diff --git a/gold/layout.cc b/gold/layout.cc
+index 1c32bcf..9d8a43a 100644
+--- a/gold/layout.cc
++++ b/gold/layout.cc
+@@ -2975,8 +2975,9 @@ Layout::segment_precedes(const Output_segment* seg1,
+   // We shouldn't get here--we shouldn't create segments which we
+   // can't distinguish.  Unless of course we are using a weird linker
+-  // script.
+-  gold_assert(this->script_options_->saw_phdrs_clause());
++  // script or overlapping --section-start options.
++  gold_assert(this->script_options_->saw_phdrs_clause()
++            || parameters->options().any_section_start());
+   return false;
+ }
+diff --git a/gold/options.cc b/gold/options.cc
+index be32645..dcf6ba7 100644
+--- a/gold/options.cc
++++ b/gold/options.cc
+@@ -198,7 +198,7 @@ parse_uint(const char* option_name, const char* arg, int* retval)
+ {
+   char* endptr;
+   *retval = strtol(arg, &endptr, 0);
+-  if (*endptr != '\0' || retval < 0)
++  if (*endptr != '\0' || *retval < 0)
+     gold_fatal(_("%s: invalid option value (expected an integer): %s"),
+                option_name, arg);
+ }
+@@ -1224,6 +1224,37 @@ General_options::finalize()
+     gold_fatal(_("Options --incremental-changed, --incremental-unchanged, "
+                  "--incremental-unknown require the use of --incremental"));
++  // Check for options that are not compatible with incremental linking.
++  // Where an option can be disabled without seriously changing the semantics
++  // of the link, we turn the option off; otherwise, we issue a fatal error.
++
++  if (this->incremental_mode_ != INCREMENTAL_OFF)
++    {
++      if (this->relocatable())
++      gold_fatal(_("incremental linking is not compatible with -r"));
++      if (this->emit_relocs())
++      gold_fatal(_("incremental linking is not compatible with "
++                   "--emit-relocs"));
++      if (this->has_plugins())
++      gold_fatal(_("incremental linking is not compatible with --plugin"));
++      if (this->gc_sections())
++      {
++        gold_warning(_("ignoring --gc-sections for an incremental link"));
++        this->set_gc_sections(false);
++      }
++      if (this->icf_enabled())
++      {
++        gold_warning(_("ignoring --icf for an incremental link"));
++        this->set_icf_status(ICF_NONE);
++      }
++      if (strcmp(this->compress_debug_sections(), "none") != 0)
++      {
++        gold_warning(_("ignoring --compress-debug-sections for an "
++                       "incremental link"));
++        this->set_compress_debug_sections("none");
++      }
++    }
++
+   // FIXME: we can/should be doing a lot more sanity checking here.
+ }
+diff --git a/gold/options.h b/gold/options.h
+index 768df9c..8876a1e 100644
+--- a/gold/options.h
++++ b/gold/options.h
+@@ -791,6 +791,10 @@ class General_options
+   DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false,
+             N_("Ignored"), NULL);
++  DEFINE_bool(gnu_unique, options::TWO_DASHES, '\0', true,
++            N_("Enable STB_GNU_UNIQUE symbol binding (default)"),
++            N_("Disable STB_GNU_UNIQUE symbol binding"));
++
+   DEFINE_string(soname, options::ONE_DASH, 'h', NULL,
+                 N_("Set shared library name"), N_("FILENAME"));
+@@ -1385,6 +1389,11 @@ class General_options
+   bool
+   section_start(const char* secname, uint64_t* paddr) const;
++  // Return whether any --section-start option was used.
++  bool
++  any_section_start() const
++  { return !this->section_starts_.empty(); }
++
+   enum Fix_v4bx
+   {
+     // Leave original instruction.
+diff --git a/gold/output.cc b/gold/output.cc
+index 29d8e3d..a7e1e9a 100644
+--- a/gold/output.cc
++++ b/gold/output.cc
+@@ -119,7 +119,9 @@ extern "C" void *gold_mremap(void *, size_t, size_t, int);
+ static int
+ posix_fallocate(int o, off_t offset, off_t len)
+ {
+-  return ftruncate(o, offset + len);
++  if (ftruncate(o, offset + len) < 0)
++    return errno;
++  return 0;
+ }
+ #endif // !defined(HAVE_POSIX_FALLOCATE)
+@@ -706,7 +708,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     bool is_symbolless)
+   : address_(address), local_sym_index_(GSYM_CODE), type_(type),
+     is_relative_(is_relative), is_symbolless_(is_symbolless),
+-    is_section_symbol_(false), shndx_(INVALID_CODE)
++    is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE)
+ {
+   // this->type_ is a bitfield; make sure TYPE fits.
+   gold_assert(this->type_ == type);
+@@ -727,7 +729,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     bool is_symbolless)
+   : address_(address), local_sym_index_(GSYM_CODE), type_(type),
+     is_relative_(is_relative), is_symbolless_(is_symbolless),
+-    is_section_symbol_(false), shndx_(shndx)
++    is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx)
+ {
+   gold_assert(shndx != INVALID_CODE);
+   // this->type_ is a bitfield; make sure TYPE fits.
+@@ -749,10 +751,12 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     Address address,
+     bool is_relative,
+     bool is_symbolless,
+-    bool is_section_symbol)
++    bool is_section_symbol,
++    bool use_plt_offset)
+   : address_(address), local_sym_index_(local_sym_index), type_(type),
+     is_relative_(is_relative), is_symbolless_(is_symbolless),
+-    is_section_symbol_(is_section_symbol), shndx_(INVALID_CODE)
++    is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset),
++    shndx_(INVALID_CODE)
+ {
+   gold_assert(local_sym_index != GSYM_CODE
+               && local_sym_index != INVALID_CODE);
+@@ -773,10 +777,12 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     Address address,
+     bool is_relative,
+     bool is_symbolless,
+-    bool is_section_symbol)
++    bool is_section_symbol,
++    bool use_plt_offset)
+   : address_(address), local_sym_index_(local_sym_index), type_(type),
+     is_relative_(is_relative), is_symbolless_(is_symbolless),
+-    is_section_symbol_(is_section_symbol), shndx_(shndx)
++    is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset),
++    shndx_(shndx)
+ {
+   gold_assert(local_sym_index != GSYM_CODE
+               && local_sym_index != INVALID_CODE);
+@@ -799,7 +805,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     Address address)
+   : address_(address), local_sym_index_(SECTION_CODE), type_(type),
+     is_relative_(false), is_symbolless_(false),
+-    is_section_symbol_(true), shndx_(INVALID_CODE)
++    is_section_symbol_(true), use_plt_offset_(false), shndx_(INVALID_CODE)
+ {
+   // this->type_ is a bitfield; make sure TYPE fits.
+   gold_assert(this->type_ == type);
+@@ -820,7 +826,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     Address address)
+   : address_(address), local_sym_index_(SECTION_CODE), type_(type),
+     is_relative_(false), is_symbolless_(false),
+-    is_section_symbol_(true), shndx_(shndx)
++    is_section_symbol_(true), use_plt_offset_(false), shndx_(shndx)
+ {
+   gold_assert(shndx != INVALID_CODE);
+   // this->type_ is a bitfield; make sure TYPE fits.
+@@ -842,7 +848,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     Address address)
+   : address_(address), local_sym_index_(0), type_(type),
+     is_relative_(false), is_symbolless_(false),
+-    is_section_symbol_(false), shndx_(INVALID_CODE)
++    is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE)
+ {
+   // this->type_ is a bitfield; make sure TYPE fits.
+   gold_assert(this->type_ == type);
+@@ -858,7 +864,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     Address address)
+   : address_(address), local_sym_index_(0), type_(type),
+     is_relative_(false), is_symbolless_(false),
+-    is_section_symbol_(false), shndx_(shndx)
++    is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx)
+ {
+   gold_assert(shndx != INVALID_CODE);
+   // this->type_ is a bitfield; make sure TYPE fits.
+@@ -877,7 +883,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     Address address)
+   : address_(address), local_sym_index_(TARGET_CODE), type_(type),
+     is_relative_(false), is_symbolless_(false),
+-    is_section_symbol_(false), shndx_(INVALID_CODE)
++    is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE)
+ {
+   // this->type_ is a bitfield; make sure TYPE fits.
+   gold_assert(this->type_ == type);
+@@ -894,7 +900,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+     Address address)
+   : address_(address), local_sym_index_(TARGET_CODE), type_(type),
+     is_relative_(false), is_symbolless_(false),
+-    is_section_symbol_(false), shndx_(shndx)
++    is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx)
+ {
+   gold_assert(shndx != INVALID_CODE);
+   // this->type_ is a bitfield; make sure TYPE fits.
+@@ -1121,6 +1127,12 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::symbol_value(
+   Sized_relobj_file<size, big_endian>* relobj =
+       this->u1_.relobj->sized_relobj();
+   gold_assert(relobj != NULL);
++  if (this->use_plt_offset_)
++    {
++      uint64_t plt_address =
++        parameters->target().plt_address_for_local(relobj, lsi);
++      return plt_address + relobj->local_plt_offset(lsi);
++    }
+   const Symbol_value<size>* symval = relobj->local_symbol(lsi);
+   return symval->value(relobj, addend);
+ }
+@@ -4880,17 +4892,27 @@ Output_file::open_base_file(const char* base_name, bool writable)
+   if (use_base_file)
+     {
+       this->open(s.st_size);
+-      ssize_t len = ::read(o, this->base_, s.st_size);
+-      if (len < 0)
+-        {
+-        gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
+-        return false;
+-        }
+-      if (len < s.st_size)
+-        {
+-        gold_info(_("%s: file too short"), base_name);
+-        return false;
+-        }
++      ssize_t bytes_to_read = s.st_size;
++      unsigned char* p = this->base_;
++      while (bytes_to_read > 0)
++      {
++        ssize_t len = ::read(o, p, bytes_to_read);
++        if (len < 0)
++          {
++            gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
++            return false;
++          }
++        if (len == 0)
++          {
++            gold_info(_("%s: file too short: read only %lld of %lld bytes"),
++                      base_name,
++                      static_cast<long long>(s.st_size - bytes_to_read),
++                      static_cast<long long>(s.st_size));
++            return false;
++          }
++        p += len;
++        bytes_to_read -= len;
++      }
+       ::close(o);
+       return true;
+     }
+@@ -5052,8 +5074,12 @@ Output_file::map_no_anonymous(bool writable)
+   // output file will wind up incomplete, but we will have already
+   // exited.  The alternative to fallocate would be to use fdatasync,
+   // but that would be a more significant performance hit.
+-  if (writable && ::posix_fallocate(o, 0, this->file_size_) < 0)
+-    gold_fatal(_("%s: %s"), this->name_, strerror(errno));
++  if (writable)
++    {
++      int err = ::posix_fallocate(o, 0, this->file_size_);
++      if (err != 0)
++       gold_fatal(_("%s: %s"), this->name_, strerror(err));
++    }
+   // Map the file into memory.
+   int prot = PROT_READ;
+diff --git a/gold/output.h b/gold/output.h
+index 1bec2c0..e2d35e2 100644
+--- a/gold/output.h
++++ b/gold/output.h
+@@ -1033,12 +1033,14 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+   Output_reloc(Sized_relobj<size, big_endian>* relobj,
+              unsigned int local_sym_index, unsigned int type,
+              Output_data* od, Address address, bool is_relative,
+-               bool is_symbolless, bool is_section_symbol);
++               bool is_symbolless, bool is_section_symbol,
++               bool use_plt_offset);
+   Output_reloc(Sized_relobj<size, big_endian>* relobj,
+              unsigned int local_sym_index, unsigned int type,
+              unsigned int shndx, Address address, bool is_relative,
+-               bool is_symbolless, bool is_section_symbol);
++               bool is_symbolless, bool is_section_symbol,
++               bool use_plt_offset);
+   // A reloc against the STT_SECTION symbol of an output section.
+@@ -1216,7 +1218,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+   // input file.
+   unsigned int local_sym_index_;
+   // The reloc type--a processor specific code.
+-  unsigned int type_ : 29;
++  unsigned int type_ : 28;
+   // True if the relocation is a RELATIVE relocation.
+   bool is_relative_ : 1;
+   // True if the relocation is one which should not use
+@@ -1224,6 +1226,10 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+   bool is_symbolless_ : 1;
+   // True if the relocation is against a section symbol.
+   bool is_section_symbol_ : 1;
++  // True if the addend should be the PLT offset.  This is used only
++  // for RELATIVE relocations to local symbols.
++  // (Used only for RELA, but stored here for space.)
++  bool use_plt_offset_ : 1;
+   // If the reloc address is an input section in an object, the
+   // section index.  This is INVALID_CODE if the reloc address is
+   // specified in some other way.
+@@ -1268,9 +1274,10 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
+              unsigned int local_sym_index, unsigned int type,
+              Output_data* od, Address address,
+              Addend addend, bool is_relative,
+-             bool is_symbolless, bool is_section_symbol)
++             bool is_symbolless, bool is_section_symbol,
++             bool use_plt_offset)
+     : rel_(relobj, local_sym_index, type, od, address, is_relative,
+-           is_symbolless, is_section_symbol),
++           is_symbolless, is_section_symbol, use_plt_offset),
+       addend_(addend)
+   { }
+@@ -1278,9 +1285,10 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
+              unsigned int local_sym_index, unsigned int type,
+              unsigned int shndx, Address address,
+              Addend addend, bool is_relative,
+-             bool is_symbolless, bool is_section_symbol)
++             bool is_symbolless, bool is_section_symbol,
++             bool use_plt_offset)
+     : rel_(relobj, local_sym_index, type, shndx, address, is_relative,
+-           is_symbolless, is_section_symbol),
++           is_symbolless, is_section_symbol, use_plt_offset),
+       addend_(addend)
+   { }
+@@ -1571,7 +1579,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+           Output_data* od, Address address)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
+-                                    address, false, false, false));
++                                    address, false, false, false, false));
+   }
+   void
+@@ -1580,7 +1588,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+           Output_data* od, unsigned int shndx, Address address)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
+-                                  address, false, false, false));
++                                  address, false, false, false, false));
+   }
+   // Add a RELATIVE reloc against a local symbol.
+@@ -1591,7 +1599,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+                    Output_data* od, Address address)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
+-                                    address, true, true, false));
++                                    address, true, true, false, false));
+   }
+   void
+@@ -1600,7 +1608,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+                    Output_data* od, unsigned int shndx, Address address)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
+-                                  address, true, true, false));
++                                  address, true, true, false, false));
+   }
+   // Add a local relocation which does not use a symbol for the relocation,
+@@ -1612,7 +1620,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+                             Output_data* od, Address address)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
+-                                    address, false, true, false));
++                                    address, false, true, false, false));
+   }
+   void
+@@ -1622,7 +1630,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+                             Address address)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
+-                                  address, false, true, false));
++                                  address, false, true, false, false));
+   }
+   // Add a reloc against a local section symbol.  This will be
+@@ -1635,7 +1643,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+                     Output_data* od, Address address)
+   {
+     this->add(od, Output_reloc_type(relobj, input_shndx, type, od,
+-                                    address, false, false, true));
++                                    address, false, false, true, false));
+   }
+   void
+@@ -1644,7 +1652,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
+                     Output_data* od, unsigned int shndx, Address address)
+   {
+     this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx,
+-                                    address, false, false, true));
++                                    address, false, false, true, false));
+   }
+   // A reloc against the STT_SECTION symbol of an output section.
+@@ -1767,7 +1775,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
+           Output_data* od, Address address, Addend addend)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
+-                                  addend, false, false, false));
++                                  addend, false, false, false, false));
+   }
+   void
+@@ -1777,7 +1785,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
+           Addend addend)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
+-                                    address, addend, false, false, false));
++                                    address, addend, false, false, false,
++                                    false));
+   }
+   // Add a RELATIVE reloc against a local symbol.
+@@ -1785,20 +1794,23 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
+   void
+   add_local_relative(Sized_relobj<size, big_endian>* relobj,
+                    unsigned int local_sym_index, unsigned int type,
+-                   Output_data* od, Address address, Addend addend)
++                   Output_data* od, Address address, Addend addend,
++                   bool use_plt_offset)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
+-                                  addend, true, true, false));
++                                  addend, true, true, false,
++                                  use_plt_offset));
+   }
+   void
+   add_local_relative(Sized_relobj<size, big_endian>* relobj,
+                    unsigned int local_sym_index, unsigned int type,
+                    Output_data* od, unsigned int shndx, Address address,
+-                   Addend addend)
++                   Addend addend, bool use_plt_offset)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
+-                                    address, addend, true, true, false));
++                                    address, addend, true, true, false,
++                                    use_plt_offset));
+   }
+   // Add a local relocation which does not use a symbol for the relocation,
+@@ -1810,7 +1822,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
+                             Output_data* od, Address address, Addend addend)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
+-                                  addend, false, true, false));
++                                  addend, false, true, false, false));
+   }
+   void
+@@ -1820,7 +1832,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
+                             Address address, Addend addend)
+   {
+     this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
+-                                    address, addend, false, true, false));
++                                    address, addend, false, true, false,
++                                    false));
+   }
+   // Add a reloc against a local section symbol.  This will be
+@@ -1833,7 +1846,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
+                     Output_data* od, Address address, Addend addend)
+   {
+     this->add(od, Output_reloc_type(relobj, input_shndx, type, od, address,
+-                                  addend, false, false, true));
++                                  addend, false, false, true, false));
+   }
+   void
+@@ -1843,7 +1856,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
+                   Addend addend)
+   {
+     this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx,
+-                                    address, addend, false, false, true));
++                                    address, addend, false, false, true,
++                                    false));
+   }
+   // A reloc against the STT_SECTION symbol of an output section.
+diff --git a/gold/plugin.cc b/gold/plugin.cc
+index 3ccd8d0..b4e68f8 100644
+--- a/gold/plugin.cc
++++ b/gold/plugin.cc
+@@ -818,7 +818,9 @@ Pluginobj::Pluginobj(const std::string& name, Input_file* input_file,
+ }
+ // Return TRUE if a defined symbol is referenced from outside the
+-// universe of claimed objects.
++// universe of claimed objects.  Only references from relocatable,
++// non-IR (unclaimed) objects count as a reference.  References from
++// dynamic objects count only as "visible".
+ static inline bool
+ is_referenced_from_outside(Symbol* lsym)
+@@ -838,6 +840,8 @@ is_referenced_from_outside(Symbol* lsym)
+ static inline bool
+ is_visible_from_outside(Symbol* lsym)
+ {
++  if (lsym->in_dyn())
++    return true;
+   if (parameters->options().export_dynamic() || parameters->options().shared())
+     return lsym->is_externally_visible();
+   return false;
+@@ -1244,14 +1248,18 @@ Sized_pluginobj<size, big_endian>::do_initialize_xindex()
+   return NULL;
+ }
+-// Get symbol counts.  Not used for plugin objects.
++// Get symbol counts.  Don't count plugin objects; the replacement
++// files will provide the counts.
+ template<int size, bool big_endian>
+ void
+-Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(const Symbol_table*,
+-                                                   size_t*, size_t*) const
++Sized_pluginobj<size, big_endian>::do_get_global_symbol_counts(
++    const Symbol_table*,
++    size_t* defined,
++    size_t* used) const
+ {
+-  gold_unreachable();
++  *defined = 0;
++  *used = 0;
+ }
+ // Get symbols.  Not used for plugin objects.
+diff --git a/gold/powerpc.cc b/gold/powerpc.cc
+index 45783c3..62a17ca 100644
+--- a/gold/powerpc.cc
++++ b/gold/powerpc.cc
+@@ -1329,7 +1329,7 @@ Target_powerpc<size, big_endian>::Scan::local(
+               rela_dyn->add_local_relative(object, r_sym, r_type,
+                                          output_section, data_shndx,
+                                          reloc.get_r_offset(),
+-                                         reloc.get_r_addend());
++                                         reloc.get_r_addend(), false);
+             }
+         }
+       break;
+@@ -1372,7 +1372,7 @@ Target_powerpc<size, big_endian>::Scan::local(
+               object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
+               rela_dyn->add_local_relative(object, r_sym,
+                                            elfcpp::R_POWERPC_RELATIVE,
+-                                           got, off, 0);
++                                           got, off, 0, false);
+             }
+           }
+       else
+diff --git a/gold/readsyms.cc b/gold/readsyms.cc
+index 1e50942..9974722 100644
+--- a/gold/readsyms.cc
++++ b/gold/readsyms.cc
+@@ -161,8 +161,10 @@ void
+ Read_symbols::run(Workqueue* workqueue)
+ {
+   // If we didn't queue a new task, then we need to explicitly unblock
+-  // the token.
+-  if (!this->do_read_symbols(workqueue))
++  // the token. If the object is a member of a lib group, however,
++  // the token was already added to the list of locks for the task,
++  // and it will be unblocked automatically at the end of the task.
++  if (!this->do_read_symbols(workqueue) && this->member_ == NULL)
+     workqueue->queue_soon(new Unblock_token(this->this_blocker_,
+                                           this->next_blocker_));
+ }
+diff --git a/gold/resolve.cc b/gold/resolve.cc
+index 03288ec..780038a 100644
+--- a/gold/resolve.cc
++++ b/gold/resolve.cc
+@@ -296,7 +296,7 @@ Symbol_table::resolve(Sized_symbol<size>* to,
+   // Record if we've seen this symbol in a real ELF object (i.e., the
+   // symbol is referenced from outside the world known to the plugin).
+-  if (object->pluginobj() == NULL)
++  if (object->pluginobj() == NULL && !object->is_dynamic())
+     to->set_in_real_elf();
+   // If we're processing replacement files, allow new symbols to override
+@@ -336,9 +336,9 @@ Symbol_table::resolve(Sized_symbol<size>* to,
+       && to->name()[0] == '_' && to->name()[1] == 'Z')
+     {
+       Symbol_location fromloc
+-          = { object, orig_st_shndx, sym.get_st_value() };
++          = { object, orig_st_shndx, static_cast<off_t>(sym.get_st_value()) };
+       Symbol_location toloc = { to->object(), to->shndx(&to_is_ordinary),
+-                              to->value() };
++                              static_cast<off_t>(to->value()) };
+       this->candidate_odr_violations_[to->name()].insert(fromloc);
+       this->candidate_odr_violations_[to->name()].insert(toloc);
+     }
+diff --git a/gold/script-sections.cc b/gold/script-sections.cc
+index 1fad88d..f90c0b3 100644
+--- a/gold/script-sections.cc
++++ b/gold/script-sections.cc
+@@ -680,7 +680,7 @@ class Sections_element_assignment : public Sections_element
+   set_section_addresses(Symbol_table* symtab, Layout* layout,
+                       uint64_t* dot_value, uint64_t*, uint64_t*)
+   {
+-    this->assignment_.set_if_absolute(symtab, layout, true, *dot_value);
++    this->assignment_.set_if_absolute(symtab, layout, true, *dot_value, NULL);
+   }
+   // Print for debugging.
+@@ -714,7 +714,7 @@ class Sections_element_dot_assignment : public Sections_element
+     // output section definition the dot symbol is always considered
+     // to be absolute.
+     *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
+-                                         NULL, NULL, NULL);
++                                         NULL, NULL, NULL, false);
+   }
+   // Update the dot symbol while setting section addresses.
+@@ -724,7 +724,7 @@ class Sections_element_dot_assignment : public Sections_element
+                       uint64_t* load_address)
+   {
+     *dot_value = this->val_->eval_with_dot(symtab, layout, false, *dot_value,
+-                                         NULL, NULL, dot_alignment);
++                                         NULL, NULL, dot_alignment, false);
+     *load_address = *dot_value;
+   }
+@@ -866,9 +866,11 @@ class Output_section_element_assignment : public Output_section_element
+   void
+   set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
+                       uint64_t, uint64_t* dot_value, uint64_t*,
+-                      Output_section**, std::string*, Input_section_list*)
++                      Output_section** dot_section, std::string*,
++                      Input_section_list*)
+   {
+-    this->assignment_.set_if_absolute(symtab, layout, true, *dot_value);
++    this->assignment_.set_if_absolute(symtab, layout, true, *dot_value,
++                                    *dot_section);
+   }
+   // Print for debugging.
+@@ -892,20 +894,28 @@ class Output_section_element_dot_assignment : public Output_section_element
+     : val_(val)
+   { }
++  // An assignment to dot within an output section is enough to force
++  // the output section to exist.
++  bool
++  needs_output_section() const
++  { return true; }
++
+   // Finalize the symbol.
+   void
+   finalize_symbols(Symbol_table* symtab, const Layout* layout,
+                  uint64_t* dot_value, Output_section** dot_section)
+   {
+     *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
+-                                         *dot_section, dot_section, NULL);
++                                         *dot_section, dot_section, NULL,
++                                         true);
+   }
+   // Update the dot symbol while setting section addresses.
+   void
+   set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
+                       uint64_t, uint64_t* dot_value, uint64_t*,
+-                      Output_section**, std::string*, Input_section_list*);
++                      Output_section** dot_section, std::string*,
++                      Input_section_list*);
+   // Print for debugging.
+   void
+@@ -936,7 +946,8 @@ Output_section_element_dot_assignment::set_section_addresses(
+ {
+   uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, false,
+                                               *dot_value, *dot_section,
+-                                              dot_section, dot_alignment);
++                                              dot_section, dot_alignment,
++                                              true);
+   if (next_dot < *dot_value)
+     gold_error(_("dot may not move backward"));
+   if (next_dot > *dot_value && output_section != NULL)
+@@ -1037,7 +1048,8 @@ Output_data_expression::do_write_to_buffer(unsigned char* buf)
+ {
+   uint64_t val = this->val_->eval_with_dot(this->symtab_, this->layout_,
+                                          true, this->dot_value_,
+-                                         this->dot_section_, NULL, NULL);
++                                         this->dot_section_, NULL, NULL,
++                                         false);
+   if (parameters->target().is_big_endian())
+     this->endian_write_to_buffer<true>(val, buf);
+@@ -1187,7 +1199,7 @@ class Output_section_element_fill : public Output_section_element
+     Output_section* fill_section;
+     uint64_t fill_val = this->val_->eval_with_dot(symtab, layout, false,
+                                                 *dot_value, *dot_section,
+-                                                &fill_section, NULL);
++                                                &fill_section, NULL, false);
+     if (fill_section != NULL)
+       gold_warning(_("fill value is not absolute"));
+     // FIXME: The GNU linker supports fill values of arbitrary length.
+@@ -2108,13 +2120,13 @@ Output_section_definition::finalize_symbols(Symbol_table* symtab,
+       {
+         address = this->address_->eval_with_dot(symtab, layout, true,
+                                                 *dot_value, NULL,
+-                                                NULL, NULL);
++                                                NULL, NULL, false);
+       }
+       if (this->align_ != NULL)
+       {
+         uint64_t align = this->align_->eval_with_dot(symtab, layout, true,
+                                                      *dot_value, NULL,
+-                                                     NULL, NULL);
++                                                     NULL, NULL, false);
+         address = align_address(address, align);
+       }
+       *dot_value = address;
+@@ -2303,7 +2315,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
+   else
+     address = this->address_->eval_with_dot(symtab, layout, true,
+                                           *dot_value, NULL, NULL,
+-                                          dot_alignment);
++                                          dot_alignment, false);
+   uint64_t align;
+   if (this->align_ == NULL)
+     {
+@@ -2316,7 +2328,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
+     {
+       Output_section* align_section;
+       align = this->align_->eval_with_dot(symtab, layout, true, *dot_value,
+-                                        NULL, &align_section, NULL);
++                                        NULL, &align_section, NULL, false);
+       if (align_section != NULL)
+       gold_warning(_("alignment of section %s is not absolute"),
+                    this->name_.c_str());
+@@ -2401,7 +2413,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
+       laddr = this->load_address_->eval_with_dot(symtab, layout, true,
+                                                *dot_value,
+                                                this->output_section_,
+-                                               NULL, NULL);
++                                               NULL, NULL, false);
+       if (this->output_section_ != NULL)
+         this->output_section_->set_load_address(laddr);
+     }
+@@ -2416,7 +2428,8 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
+       Output_section* subalign_section;
+       subalign = this->subalign_->eval_with_dot(symtab, layout, true,
+                                               *dot_value, NULL,
+-                                              &subalign_section, NULL);
++                                              &subalign_section, NULL,
++                                              false);
+       if (subalign_section != NULL)
+       gold_warning(_("subalign of section %s is not absolute"),
+                    this->name_.c_str());
+@@ -2431,7 +2444,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
+       uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout, true,
+                                                    *dot_value,
+                                                    NULL, &fill_section,
+-                                                   NULL);
++                                                   NULL, false);
+       if (fill_section != NULL)
+       gold_warning(_("fill of section %s is not absolute"),
+                    this->name_.c_str());
+diff --git a/gold/script.cc b/gold/script.cc
+index 7df0c9e..b471cf9 100644
+--- a/gold/script.cc
++++ b/gold/script.cc
+@@ -983,18 +983,20 @@ Symbol_assignment::sized_finalize(Symbol_table* symtab, const Layout* layout,
+   uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout, true,
+                                                 is_dot_available,
+                                                 dot_value, dot_section,
+-                                                &section, NULL);
++                                                &section, NULL, false);
+   Sized_symbol<size>* ssym = symtab->get_sized_symbol<size>(this->sym_);
+   ssym->set_value(final_val);
+   if (section != NULL)
+     ssym->set_output_section(section);
+ }
+-// Set the symbol value if the expression yields an absolute value.
++// Set the symbol value if the expression yields an absolute value or
++// a value relative to DOT_SECTION.
+ void
+ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout,
+-                                 bool is_dot_available, uint64_t dot_value)
++                                 bool is_dot_available, uint64_t dot_value,
++                                 Output_section* dot_section)
+ {
+   if (this->sym_ == NULL)
+     return;
+@@ -1002,8 +1004,9 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout,
+   Output_section* val_section;
+   uint64_t val = this->val_->eval_maybe_dot(symtab, layout, false,
+                                           is_dot_available, dot_value,
+-                                          NULL, &val_section, NULL);
+-  if (val_section != NULL)
++                                          dot_section, &val_section, NULL,
++                                          false);
++  if (val_section != NULL && val_section != dot_section)
+     return;
+   if (parameters->target().get_size() == 32)
+@@ -1026,6 +1029,8 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout,
+     }
+   else
+     gold_unreachable();
++  if (val_section != NULL)
++    this->sym_->set_output_section(val_section);
+ }
+ // Print for debugging.
+@@ -1215,7 +1220,7 @@ Script_options::set_section_addresses(Symbol_table* symtab, Layout* layout)
+   for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
+        p != this->symbol_assignments_.end();
+        ++p)
+-    (*p)->set_if_absolute(symtab, layout, false, 0);
++    (*p)->set_if_absolute(symtab, layout, false, 0, NULL);
+   return this->script_sections_.set_section_addresses(symtab, layout);
+ }
+diff --git a/gold/script.h b/gold/script.h
+index 73079a4..f41f438 100644
+--- a/gold/script.h
++++ b/gold/script.h
+@@ -90,20 +90,28 @@ class Expression
+   // the section address.  If RESULT_ALIGNMENT is not NULL, this sets
+   // *RESULT_ALIGNMENT to the alignment of the value of that alignment
+   // is larger than *RESULT_ALIGNMENT; this will only be non-zero if
+-  // this is an ALIGN expression.
++  // this is an ALIGN expression.  If IS_SECTION_DOT_ASSIGMENT is true,
++  // we are evaluating an assignment to dot within an output section,
++  // and an absolute value should be interpreted as an offset within
++  // the section.
+   uint64_t
+   eval_with_dot(const Symbol_table*, const Layout*, bool check_assertions,
+               uint64_t dot_value, Output_section* dot_section,
+-              Output_section** result_section, uint64_t* result_alignment);
++              Output_section** result_section, uint64_t* result_alignment,
++              bool is_section_dot_assignment);
+   // Return the value of an expression which may or may not be
+   // permitted to refer to the dot symbol, depending on
+-  // is_dot_available.
++  // is_dot_available.  If IS_SECTION_DOT_ASSIGMENT is true,
++  // we are evaluating an assignment to dot within an output section,
++  // and an absolute value should be interpreted as an offset within
++  // the section.
+   uint64_t
+   eval_maybe_dot(const Symbol_table*, const Layout*, bool check_assertions,
+                bool is_dot_available, uint64_t dot_value,
+                Output_section* dot_section,
+-               Output_section** result_section, uint64_t* result_alignment);
++               Output_section** result_section, uint64_t* result_alignment,
++               bool is_section_dot_assignment);
+   // Print the expression to the FILE.  This is for debugging.
+   virtual void
+@@ -339,12 +347,12 @@ class Symbol_assignment
+   finalize_with_dot(Symbol_table*, const Layout*, uint64_t dot_value,
+                   Output_section* dot_section);
+-  // Set the symbol value, but only if the value is absolute.  This is
+-  // used while processing a SECTIONS clause.  We assume that dot is
+-  // an absolute value here.  We do not check assertions.
++  // Set the symbol value, but only if the value is absolute or relative to
++  // DOT_SECTION.  This is used while processing a SECTIONS clause.
++  // We assume that dot is an absolute value here.  We do not check assertions.
+   void
+   set_if_absolute(Symbol_table*, const Layout*, bool is_dot_available,
+-                uint64_t dot_value);
++                uint64_t dot_value, Output_section* dot_section);
+   const std::string&
+   name() const
+diff --git a/gold/sparc.cc b/gold/sparc.cc
+index 5f67a4e..12e1dee 100644
+--- a/gold/sparc.cc
++++ b/gold/sparc.cc
+@@ -1855,7 +1855,7 @@ Target_sparc<size, big_endian>::Scan::local(
+           rela_dyn->add_local_relative(object, r_sym, elfcpp::R_SPARC_RELATIVE,
+                                      output_section, data_shndx,
+                                      reloc.get_r_offset(),
+-                                     reloc.get_r_addend());
++                                     reloc.get_r_addend(), false);
+         }
+       break;
+@@ -1946,7 +1946,7 @@ Target_sparc<size, big_endian>::Scan::local(
+               object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
+               rela_dyn->add_local_relative(object, r_sym,
+                                            elfcpp::R_SPARC_RELATIVE,
+-                                           got, off, 0);
++                                           got, off, 0, false);
+             }
+         }
+       else
+diff --git a/gold/symtab.cc b/gold/symtab.cc
+index ff1b5ca..f0ba1d5 100644
+--- a/gold/symtab.cc
++++ b/gold/symtab.cc
+@@ -602,20 +602,16 @@ Symbol_table::gc_mark_undef_symbols(Layout* layout)
+ }
+ void
+-Symbol_table::gc_mark_symbol_for_shlib(Symbol* sym)
++Symbol_table::gc_mark_symbol(Symbol* sym)
+ {
+-  if (!sym->is_from_dynobj() 
+-      && sym->is_externally_visible())
++  // Add the object and section to the work list.
++  Relobj* obj = static_cast<Relobj*>(sym->object());
++  bool is_ordinary;
++  unsigned int shndx = sym->shndx(&is_ordinary);
++  if (is_ordinary && shndx != elfcpp::SHN_UNDEF)
+     {
+-      //Add the object and section to the work list.
+-      Relobj* obj = static_cast<Relobj*>(sym->object());
+-      bool is_ordinary;
+-      unsigned int shndx = sym->shndx(&is_ordinary);
+-      if (is_ordinary && shndx != elfcpp::SHN_UNDEF)
+-        {
+-          gold_assert(this->gc_!= NULL);
+-          this->gc_->worklist().push(Section_id(obj, shndx));
+-        }
++      gold_assert(this->gc_!= NULL);
++      this->gc_->worklist().push(Section_id(obj, shndx));
+     }
+ }
+@@ -626,16 +622,7 @@ Symbol_table::gc_mark_dyn_syms(Symbol* sym)
+ {
+   if (sym->in_dyn() && sym->source() == Symbol::FROM_OBJECT
+       && !sym->object()->is_dynamic())
+-    {
+-      Relobj* obj = static_cast<Relobj*>(sym->object()); 
+-      bool is_ordinary;
+-      unsigned int shndx = sym->shndx(&is_ordinary);
+-      if (is_ordinary && shndx != elfcpp::SHN_UNDEF)
+-        {
+-          gold_assert(this->gc_ != NULL);
+-          this->gc_->worklist().push(Section_id(obj, shndx));
+-        }
+-    }
++    this->gc_mark_symbol(sym);
+ }
+ // Make TO a symbol which forwards to FROM.
+@@ -1143,6 +1130,14 @@ Symbol_table::add_from_relobj(
+       bool is_default_version = false;
+       bool is_forced_local = false;
++      // FIXME: For incremental links, we don't store version information,
++      // so we need to ignore version symbols for now.
++      if (parameters->incremental_update() && ver != NULL)
++      {
++        namelen = ver - name;
++        ver = NULL;
++      }
++
+       if (ver != NULL)
+         {
+           // The symbol name is of the form foo@VERSION or foo@@VERSION
+@@ -1243,11 +1238,16 @@ Symbol_table::add_from_relobj(
+       if (is_forced_local)
+       this->force_local(res);
+-      // If building a shared library using garbage collection, do not 
+-      // treat externally visible symbols as garbage.
+-      if (parameters->options().gc_sections() 
+-          && parameters->options().shared())
+-        this->gc_mark_symbol_for_shlib(res);
++      // Do not treat this symbol as garbage if this symbol will be
++      // exported to the dynamic symbol table.  This is true when
++      // building a shared library or using --export-dynamic and
++      // the symbol is externally visible.
++      if (parameters->options().gc_sections()
++        && res->is_externally_visible()
++        && !res->is_from_dynobj()
++          && (parameters->options().shared()
++            || parameters->options().export_dynamic()))
++        this->gc_mark_symbol(res);
+       if (is_defined_in_discarded_section)
+       res->set_is_defined_in_discarded_section();
+@@ -1346,6 +1346,11 @@ Symbol_table::add_from_dynobj(
+       return;
+     }
++  // FIXME: For incremental links, we don't store version information,
++  // so we need to ignore version symbols for now.
++  if (parameters->incremental_update())
++    versym = NULL;
++
+   if (versym != NULL && versym_size / 2 < count)
+     {
+       dynobj->error(_("too few symbol versions"));
+@@ -2809,6 +2814,12 @@ Symbol_table::sized_write_globals(const Stringpool* sympool,
+       typename elfcpp::Elf_types<size>::Elf_Addr sym_value = sym->value();
+       typename elfcpp::Elf_types<size>::Elf_Addr dynsym_value = sym_value;
+       elfcpp::STB binding = sym->binding();
++
++      // If --no-gnu-unique is set, change STB_GNU_UNIQUE to STB_GLOBAL.
++      if (binding == elfcpp::STB_GNU_UNIQUE
++        && !parameters->options().gnu_unique())
++      binding = elfcpp::STB_GLOBAL;
++
+       switch (sym->source())
+       {
+       case Symbol::FROM_OBJECT:
+diff --git a/gold/symtab.h b/gold/symtab.h
+index b9b9e00..427f72f 100644
+--- a/gold/symtab.h
++++ b/gold/symtab.h
+@@ -1308,10 +1308,9 @@ class Symbol_table
+   void
+   gc_mark_undef_symbols(Layout*);
+-  // During garbage collection, this ensures externally visible symbols
+-  // are not treated as garbage while building shared objects.
++  // This tells garbage collection that this symbol is referenced.
+   void
+-  gc_mark_symbol_for_shlib(Symbol* sym);
++  gc_mark_symbol(Symbol* sym);
+   // During garbage collection, this keeps sections that correspond to 
+   // symbols seen in dynamic objects.
+diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
+index 67149fb..785dcdd 100644
+--- a/gold/testsuite/Makefile.in
++++ b/gold/testsuite/Makefile.in
+@@ -1844,6 +1844,8 @@ EGREP = @EGREP@
+ EXEEXT = @EXEEXT@
+ GENCAT = @GENCAT@
+ GMSGFMT = @GMSGFMT@
++GOLD_LDADD = @GOLD_LDADD@
++GOLD_LDFLAGS = @GOLD_LDFLAGS@
+ GREP = @GREP@
+ INCINTL = @INCINTL@
+ INSTALL = @INSTALL@
+diff --git a/gold/testsuite/plugin_test_2.sh b/gold/testsuite/plugin_test_2.sh
+index a47d22a..293b1f0 100755
+--- a/gold/testsuite/plugin_test_2.sh
++++ b/gold/testsuite/plugin_test_2.sh
+@@ -45,7 +45,7 @@ check plugin_test_2.err "two_file_test_main.o: claim file hook called"
+ check plugin_test_2.err "two_file_test_1.syms: claim file hook called"
+ check plugin_test_2.err "two_file_test_1b.syms: claim file hook called"
+ check plugin_test_2.err "two_file_shared_2.so: claim file hook called"
+-check plugin_test_2.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_REG"
++check plugin_test_2.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_IRONLY_EXP"
+ check plugin_test_2.err "two_file_test_1.syms: _Z2t2v: PREVAILING_DEF_REG"
+ check plugin_test_2.err "two_file_test_1.syms: v2: RESOLVED_DYN"
+ check plugin_test_2.err "two_file_test_1.syms: t17data: RESOLVED_DYN"
+diff --git a/gold/testsuite/script_test_2.t b/gold/testsuite/script_test_2.t
+index 73d39df..6a0188f 100644
+--- a/gold/testsuite/script_test_2.t
++++ b/gold/testsuite/script_test_2.t
+@@ -49,7 +49,7 @@ SECTIONS
+     /* This should match the remaining sections.  */
+     *(.gold_test)
+-    . = . + 4;
++    . = 60;
+     start_data = .;
+     BYTE(1)
+     SHORT(2)
+diff --git a/gold/x86_64.cc b/gold/x86_64.cc
+index e6b0021..e7c981b 100644
+--- a/gold/x86_64.cc
++++ b/gold/x86_64.cc
+@@ -1549,7 +1549,7 @@ Target_x86_64::reserve_local_got_entry(
+     case GOT_TYPE_STANDARD:
+       if (parameters->options().output_is_position_independent())
+       rela_dyn->add_local_relative(obj, r_sym, elfcpp::R_X86_64_RELATIVE,
+-                                   this->got_, got_offset, 0);
++                                   this->got_, got_offset, 0, false);
+       break;
+     case GOT_TYPE_TLS_OFFSET:
+       rela_dyn->add_local(obj, r_sym, elfcpp::R_X86_64_TPOFF64,
+@@ -1953,8 +1953,8 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
+                            const elfcpp::Sym<64, false>& lsym)
+ {
+   // A local STT_GNU_IFUNC symbol may require a PLT entry.
+-  if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC
+-      && this->reloc_needs_plt_for_ifunc(object, r_type))
++  bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC;
++  if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type))
+     {
+       unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info());
+       target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
+@@ -1982,7 +1982,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
+                                      elfcpp::R_X86_64_RELATIVE,
+                                      output_section, data_shndx,
+                                      reloc.get_r_offset(),
+-                                     reloc.get_r_addend());
++                                     reloc.get_r_addend(), is_ifunc);
+         }
+       break;
+@@ -2058,7 +2058,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
+       // lets function pointers compare correctly with shared
+       // libraries.  Otherwise we would need an IRELATIVE reloc.
+       bool is_new;
+-      if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC)
++      if (is_ifunc)
+         is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
+       else
+         is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
+@@ -2076,7 +2076,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
+                     object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
+                   rela_dyn->add_local_relative(object, r_sym,
+                                                elfcpp::R_X86_64_RELATIVE,
+-                                               got, got_offset, 0);
++                                               got, got_offset, 0, is_ifunc);
+                 }
+                 else
+                   {
+@@ -3181,12 +3181,6 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
+             }
+           if (optimized_type == tls::TLSOPT_TO_IE)
+             {
+-            if (tls_segment == NULL)
+-              {
+-                gold_assert(parameters->errors()->error_count() > 0
+-                            || issue_undefined_symbol_error(gsym));
+-                return;
+-              }
+               value = target->got_plt_section()->address() + got_offset;
+               this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type,
+                                  value, view, address, view_size);
+@@ -3867,42 +3861,51 @@ Target_x86_64::do_code_fill(section_size_type length) const
+     }
+   // Nop sequences of various lengths.
+-  const char nop1[1] = { 0x90 };                   // nop
+-  const char nop2[2] = { 0x66, 0x90 };             // xchg %ax %ax
+-  const char nop3[3] = { 0x0f, 0x1f, 0x00 };       // nop (%rax)
+-  const char nop4[4] = { 0x0f, 0x1f, 0x40, 0x00};  // nop 0(%rax)
+-  const char nop5[5] = { 0x0f, 0x1f, 0x44, 0x00,   // nop 0(%rax,%rax,1)
+-                         0x00 };
+-  const char nop6[6] = { 0x66, 0x0f, 0x1f, 0x44,   // nopw 0(%rax,%rax,1)
+-                         0x00, 0x00 };
+-  const char nop7[7] = { 0x0f, 0x1f, 0x80, 0x00,   // nopl 0L(%rax)
+-                         0x00, 0x00, 0x00 };
+-  const char nop8[8] = { 0x0f, 0x1f, 0x84, 0x00,   // nopl 0L(%rax,%rax,1)
+-                         0x00, 0x00, 0x00, 0x00 };
+-  const char nop9[9] = { 0x66, 0x0f, 0x1f, 0x84,   // nopw 0L(%rax,%rax,1)
+-                         0x00, 0x00, 0x00, 0x00,
+-                         0x00 };
+-  const char nop10[10] = { 0x66, 0x2e, 0x0f, 0x1f, // nopw %cs:0L(%rax,%rax,1)
+-                           0x84, 0x00, 0x00, 0x00,
+-                           0x00, 0x00 };
+-  const char nop11[11] = { 0x66, 0x66, 0x2e, 0x0f, // data16
+-                           0x1f, 0x84, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1)
+-                           0x00, 0x00, 0x00 };
+-  const char nop12[12] = { 0x66, 0x66, 0x66, 0x2e, // data16; data16
+-                           0x0f, 0x1f, 0x84, 0x00, // nopw %cs:0L(%rax,%rax,1)
+-                           0x00, 0x00, 0x00, 0x00 };
+-  const char nop13[13] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16
+-                           0x2e, 0x0f, 0x1f, 0x84, // nopw %cs:0L(%rax,%rax,1)
+-                           0x00, 0x00, 0x00, 0x00,
+-                           0x00 };
+-  const char nop14[14] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16
+-                           0x66, 0x2e, 0x0f, 0x1f, // data16
+-                           0x84, 0x00, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1)
+-                           0x00, 0x00 };
+-  const char nop15[15] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16
+-                           0x66, 0x66, 0x2e, 0x0f, // data16; data16
+-                           0x1f, 0x84, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1)
+-                           0x00, 0x00, 0x00 };
++  const char nop1[1] = { '\x90' };                 // nop
++  const char nop2[2] = { '\x66', '\x90' };         // xchg %ax %ax
++  const char nop3[3] = { '\x0f', '\x1f', '\x00' }; // nop (%rax)
++  const char nop4[4] = { '\x0f', '\x1f', '\x40',   // nop 0(%rax)
++                       '\x00'};
++  const char nop5[5] = { '\x0f', '\x1f', '\x44',   // nop 0(%rax,%rax,1)
++                       '\x00', '\x00' };
++  const char nop6[6] = { '\x66', '\x0f', '\x1f',   // nopw 0(%rax,%rax,1)
++                       '\x44', '\x00', '\x00' };
++  const char nop7[7] = { '\x0f', '\x1f', '\x80',   // nopl 0L(%rax)
++                       '\x00', '\x00', '\x00',
++                       '\x00' };
++  const char nop8[8] = { '\x0f', '\x1f', '\x84',   // nopl 0L(%rax,%rax,1)
++                       '\x00', '\x00', '\x00',
++                       '\x00', '\x00' };
++  const char nop9[9] = { '\x66', '\x0f', '\x1f',   // nopw 0L(%rax,%rax,1)
++                       '\x84', '\x00', '\x00',
++                       '\x00', '\x00', '\x00' };
++  const char nop10[10] = { '\x66', '\x2e', '\x0f', // nopw %cs:0L(%rax,%rax,1)
++                         '\x1f', '\x84', '\x00',
++                         '\x00', '\x00', '\x00',
++                         '\x00' };
++  const char nop11[11] = { '\x66', '\x66', '\x2e', // data16
++                         '\x0f', '\x1f', '\x84', // nopw %cs:0L(%rax,%rax,1)
++                         '\x00', '\x00', '\x00',
++                         '\x00', '\x00' };
++  const char nop12[12] = { '\x66', '\x66', '\x66', // data16; data16
++                         '\x2e', '\x0f', '\x1f', // nopw %cs:0L(%rax,%rax,1)
++                         '\x84', '\x00', '\x00',
++                         '\x00', '\x00', '\x00' };
++  const char nop13[13] = { '\x66', '\x66', '\x66', // data16; data16; data16
++                         '\x66', '\x2e', '\x0f', // nopw %cs:0L(%rax,%rax,1)
++                         '\x1f', '\x84', '\x00',
++                         '\x00', '\x00', '\x00',
++                           '\x00' };
++  const char nop14[14] = { '\x66', '\x66', '\x66', // data16; data16; data16
++                         '\x66', '\x66', '\x2e', // data16
++                         '\x0f', '\x1f', '\x84', // nopw %cs:0L(%rax,%rax,1)
++                         '\x00', '\x00', '\x00',
++                           '\x00', '\x00' };
++  const char nop15[15] = { '\x66', '\x66', '\x66', // data16; data16; data16
++                         '\x66', '\x66', '\x66', // data16; data16
++                         '\x2e', '\x0f', '\x1f', // nopw %cs:0L(%rax,%rax,1)
++                         '\x84', '\x00', '\x00',
++                           '\x00', '\x00', '\x00' };
+   const char* nops[16] = {
+     NULL,
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0039-emulparams-elf32bmip.sh-OTHER_SECTIONS-Put-.mdebug.-.patch b/meta/recipes-devtools/binutils/binutils/0039-emulparams-elf32bmip.sh-OTHER_SECTIONS-Put-.mdebug.-.patch
new file mode 100644 (file)
index 0000000..657d673
--- /dev/null
@@ -0,0 +1,49 @@
+Upstream-Status: Backport
+
+From 80041361bf80194da35c5efb842125f3ce1d2bf2 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Tue, 20 Dec 2011 18:00:03 +0000
+Subject: [PATCH 039/262]       * emulparams/elf32bmip.sh (OTHER_SECTIONS):
+ Put .mdebug.* and     .gcc_compiled_long* sections
+ at address 0.
+
+---
+ ld/ChangeLog               |    5 +++++
+ ld/emulparams/elf32bmip.sh |   16 ++++++++--------
+ 2 files changed, 13 insertions(+), 8 deletions(-)
+
+2011-12-20  Joseph Myers  <joseph@codesourcery.com>
+
+       * emulparams/elf32bmip.sh (OTHER_SECTIONS): Put .mdebug.* and
+       .gcc_compiled_long* sections at address 0.
+
+diff --git a/ld/emulparams/elf32bmip.sh b/ld/emulparams/elf32bmip.sh
+index 44a0b8a..f0fcd2c 100644
+--- a/ld/emulparams/elf32bmip.sh
++++ b/ld/emulparams/elf32bmip.sh
+@@ -64,14 +64,14 @@ OTHER_BSS_SYMBOLS='_fbss = .;'
+ OTHER_SECTIONS='
+   .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+   .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+-  .mdebug.abi32 : { KEEP(*(.mdebug.abi32)) }
+-  .mdebug.abiN32 : { KEEP(*(.mdebug.abiN32)) }
+-  .mdebug.abi64 : { KEEP(*(.mdebug.abi64)) }
+-  .mdebug.abiO64 : { KEEP(*(.mdebug.abiO64)) }
+-  .mdebug.eabi32 : { KEEP(*(.mdebug.eabi32)) }
+-  .mdebug.eabi64 : { KEEP(*(.mdebug.eabi64)) }
+-  .gcc_compiled_long32 : { KEEP(*(.gcc_compiled_long32)) }
+-  .gcc_compiled_long64 : { KEEP(*(.gcc_compiled_long64)) }
++  .mdebug.abi32 0 : { KEEP(*(.mdebug.abi32)) }
++  .mdebug.abiN32 0 : { KEEP(*(.mdebug.abiN32)) }
++  .mdebug.abi64 0 : { KEEP(*(.mdebug.abi64)) }
++  .mdebug.abiO64 0 : { KEEP(*(.mdebug.abiO64)) }
++  .mdebug.eabi32 0 : { KEEP(*(.mdebug.eabi32)) }
++  .mdebug.eabi64 0 : { KEEP(*(.mdebug.eabi64)) }
++  .gcc_compiled_long32 0 : { KEEP(*(.gcc_compiled_long32)) }
++  .gcc_compiled_long64 0 : { KEEP(*(.gcc_compiled_long64)) }
+ '
+ ARCH=mips
+ MACHINE=
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0052-gas.patch b/meta/recipes-devtools/binutils/binutils/0052-gas.patch
new file mode 100644 (file)
index 0000000..a9bb3ac
--- /dev/null
@@ -0,0 +1,83 @@
+Upstream-Status: Backport
+
+From e45a3a5695408d472e8f0ca6c21eb03e5fd42817 Mon Sep 17 00:00:00 2001
+From: Richard Sandiford <rsandifo@nildram.co.uk>
+Date: Sun, 8 Jan 2012 12:34:30 +0000
+Subject: [PATCH 052/262] gas/  * config/tc-mips.c (s_tls_rel_directive):
+ Call mips_clear_insn_labels.
+
+gas/testsuite/
+       * gas/mips/tls-relw.s, gas/mips/tls-relw.d: New test.
+       * gas/mips/mips.exp: Run it.
+---
+ gas/ChangeLog                     |    4 ++++
+ gas/config/tc-mips.c              |    1 +
+ gas/testsuite/ChangeLog           |    5 +++++
+ gas/testsuite/gas/mips/mips.exp   |    1 +
+ gas/testsuite/gas/mips/tls-relw.d |    8 ++++++++
+ gas/testsuite/gas/mips/tls-relw.s |   12 ++++++++++++
+ 6 files changed, 31 insertions(+)
+ create mode 100644 gas/testsuite/gas/mips/tls-relw.d
+ create mode 100644 gas/testsuite/gas/mips/tls-relw.s
+
+2012-01-08  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * config/tc-mips.c (s_tls_rel_directive): Call mips_clear_insn_labels.
+
+diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
+index 0fb3a6e..5324450 100644
+--- a/gas/config/tc-mips.c
++++ b/gas/config/tc-mips.c
+@@ -16591,6 +16591,7 @@ s_tls_rel_directive (const size_t bytes, const char *dirstr,
+   md_number_to_chars (p, 0, bytes);
+   fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE, rtype);
+   demand_empty_rest_of_line ();
++  mips_clear_insn_labels ();
+ }
+ /* Handle .dtprelword.  */
+--- a/gas/testsuite/gas/mips/mips.exp
++++ b/gas/testsuite/gas/mips/mips.exp
+@@ -878,6 +878,7 @@ if { [istarget mips*-*-vxworks*] } {
+       run_list_test "tls-ill" "-32"
+       run_dump_test "tls-o32"
++      run_dump_test "tls-relw"
+       run_dump_test "jalr2"
+       run_dump_test_arches "aent"     [mips_arch_list_matching mips1]
+diff --git a/gas/testsuite/gas/mips/tls-relw.d b/gas/testsuite/gas/mips/tls-relw.d
+new file mode 100644
+index 0000000..bc13b43
+--- /dev/null
++++ b/gas/testsuite/gas/mips/tls-relw.d
+@@ -0,0 +1,8 @@
++# as: -EB
++# objdump: -sj.data
++
++.*
++
++Contents of section \.data:
++ 0000 00000001 00000000 00000002 00000004  ................
++ 0010 00000000 00000003 00000010 00000000  ................
+diff --git a/gas/testsuite/gas/mips/tls-relw.s b/gas/testsuite/gas/mips/tls-relw.s
+new file mode 100644
+index 0000000..6890685
+--- /dev/null
++++ b/gas/testsuite/gas/mips/tls-relw.s
+@@ -0,0 +1,12 @@
++      .data
++start:
++      .word   1
++a:
++      .tprelword t1
++      .word   2
++      .word   a-start
++b:
++      .dtprelword t2
++      .word   3
++      .word   b-start
++      .word   0
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0055-Remove-ABI_64_P-check-on-R_X86_64_PCXX.patch b/meta/recipes-devtools/binutils/binutils/0055-Remove-ABI_64_P-check-on-R_X86_64_PCXX.patch
new file mode 100644 (file)
index 0000000..697d70e
--- /dev/null
@@ -0,0 +1,176 @@
+Upstream-Status: Backport
+
+From fee27086a7592c1812253e9c1c26f412dd87f3a2 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Tue, 10 Jan 2012 20:34:56 +0000
+Subject: [PATCH 055/262] Remove ABI_64_P check on R_X86_64_PCXX
+
+bfd/
+
+2012-01-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/13581
+       * elf64-x86-64.c (elf_x86_64_relocate_section): Remove ABI_64_P
+       check on R_X86_64_PCXX.
+
+ld/testsuite/
+
+2012-01-10  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/13581
+       * ld-x86-64/ilp32-4.s: New.
+       * ld-x86-64/ilp32-10.d: Likewise.
+       * ld-x86-64/ilp32-10.s: Likewise.
+
+       * ld-x86-64/ilp32-4.d: Adjusted.
+       * ld-x86-64/ilp32-5.d: Likewise.
+       * ld-x86-64/ilp32-5.s: Likewise.
+
+       * ld-x86-64/x86-64.exp: Run ilp32-10.
+---
+ bfd/ChangeLog                     |    7 +++++++
+ bfd/elf64-x86-64.c                |    1 -
+ ld/testsuite/ChangeLog            |   14 ++++++++++++++
+ ld/testsuite/ld-x86-64/ilp32-10.d |    3 +++
+ ld/testsuite/ld-x86-64/ilp32-10.s |    3 +++
+ ld/testsuite/ld-x86-64/ilp32-4.d  |   32 +++++++++++++-------------------
+ ld/testsuite/ld-x86-64/ilp32-4.s  |    3 +++
+ ld/testsuite/ld-x86-64/ilp32-5.d  |    2 +-
+ ld/testsuite/ld-x86-64/ilp32-5.s  |    2 +-
+ ld/testsuite/ld-x86-64/x86-64.exp |    1 +
+ 10 files changed, 46 insertions(+), 22 deletions(-)
+ create mode 100644 ld/testsuite/ld-x86-64/ilp32-10.d
+ create mode 100644 ld/testsuite/ld-x86-64/ilp32-10.s
+ create mode 100644 ld/testsuite/ld-x86-64/ilp32-4.s
+
+diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
+index 3a2444b..bdb3ae6 100644
+--- a/bfd/elf64-x86-64.c
++++ b/bfd/elf64-x86-64.c
+@@ -3460,7 +3460,6 @@ elf_x86_64_relocate_section (bfd *output_bfd,
+       case R_X86_64_PC16:
+       case R_X86_64_PC32:
+         if (info->shared
+-            && ABI_64_P (output_bfd)
+             && (input_section->flags & SEC_ALLOC) != 0
+             && (input_section->flags & SEC_READONLY) != 0
+             && h != NULL)
+diff --git a/ld/testsuite/ld-x86-64/ilp32-10.d b/ld/testsuite/ld-x86-64/ilp32-10.d
+new file mode 100644
+index 0000000..43d9fbd
+--- /dev/null
++++ b/ld/testsuite/ld-x86-64/ilp32-10.d
+@@ -0,0 +1,3 @@
++#as: --x32
++#ld: -shared -melf32_x86_64
++#error: .*relocation R_X86_64_PC32 against undefined symbol `bar' can not be used when making a shared object; recompile with -fPIC
+diff --git a/ld/testsuite/ld-x86-64/ilp32-10.s b/ld/testsuite/ld-x86-64/ilp32-10.s
+new file mode 100644
+index 0000000..70e4a90
+--- /dev/null
++++ b/ld/testsuite/ld-x86-64/ilp32-10.s
+@@ -0,0 +1,3 @@
++      .globl foo
++foo:
++      mov bar(%rip), %rax
+diff --git a/ld/testsuite/ld-x86-64/ilp32-4.d b/ld/testsuite/ld-x86-64/ilp32-4.d
+index 84dc7b2..92d8a67 100644
+--- a/ld/testsuite/ld-x86-64/ilp32-4.d
++++ b/ld/testsuite/ld-x86-64/ilp32-4.d
+@@ -1,36 +1,30 @@
+-#source: start.s
+ #as: --x32
+ #ld: -m elf32_x86_64 -shared --no-ld-generated-unwind-info
+ #readelf: -d -S --wide
+-There are 10 section headers, starting at offset 0x22c:
++There are 9 section headers, starting at offset 0x1d8:
+ Section Headers:
+   \[Nr\] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+   \[ 0\]                   NULL            00000000 000000 000000 00      0   0  0
+-  \[ 1\] .hash             HASH            00000094 000094 000030 04   A  2   0  4
+-  \[ 2\] .dynsym           DYNSYM          000000c4 0000c4 000070 10   A  3   2  4
+-  \[ 3\] .dynstr           STRTAB          00000134 000134 00001d 00   A  0   0  1
+-  \[ 4\] .rela.dyn         RELA            00000154 000154 00000c 0c   A  2   0  4
+-  \[ 5\] .text             PROGBITS        00000160 000160 000005 00  AX  0   0  4
+-  \[ 6\] .dynamic          DYNAMIC         00200168 000168 000078 08  WA  3   0  4
+-  \[ 7\] .shstrtab         STRTAB          00000000 0001e0 00004a 00      0   0  1
+-  \[ 8\] .symtab           SYMTAB          00000000 0003bc 0000e0 10      9   9  4
+-  \[ 9\] .strtab           STRTAB          00000000 00049c 000043 00      0   0  1
++  \[ 1\] .hash             HASH            00000094 000094 00002c 04   A  2   0  4
++  \[ 2\] .dynsym           DYNSYM          000000c0 0000c0 000060 10   A  3   2  4
++  \[ 3\] .dynstr           STRTAB          00000120 000120 000019 00   A  0   0  1
++  \[ 4\] .text             PROGBITS        0000013c 00013c 000001 00  AX  0   0  4
++  \[ 5\] .dynamic          DYNAMIC         00200140 000140 000058 08  WA  3   0  4
++  \[ 6\] .shstrtab         STRTAB          00000000 000198 000040 00      0   0  1
++  \[ 7\] .symtab           SYMTAB          00000000 000340 0000c0 10      8   8  4
++  \[ 8\] .strtab           STRTAB          00000000 000400 00003f 00      0   0  1
+ Key to Flags:
+   W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), l \(large\)
+   I \(info\), L \(link order\), G \(group\), T \(TLS\), E \(exclude\), x \(unknown\)
+   O \(extra OS processing required\) o \(OS specific\), p \(processor specific\)
+-Dynamic section at offset 0x168 contains 10 entries:
++Dynamic section at offset 0x140 contains 6 entries:
+   Tag        Type                         Name/Value
+  0x00000004 \(HASH\)                       0x94
+- 0x00000005 \(STRTAB\)                     0x134
+- 0x00000006 \(SYMTAB\)                     0xc4
+- 0x0000000a \(STRSZ\)                      29 \(bytes\)
++ 0x00000005 \(STRTAB\)                     0x120
++ 0x00000006 \(SYMTAB\)                     0xc0
++ 0x0000000a \(STRSZ\)                      25 \(bytes\)
+  0x0000000b \(SYMENT\)                     16 \(bytes\)
+- 0x00000007 \(RELA\)                       0x154
+- 0x00000008 \(RELASZ\)                     12 \(bytes\)
+- 0x00000009 \(RELAENT\)                    12 \(bytes\)
+- 0x00000016 \(TEXTREL\)                    0x0
+  0x00000000 \(NULL\)                       0x0
+diff --git a/ld/testsuite/ld-x86-64/ilp32-4.s b/ld/testsuite/ld-x86-64/ilp32-4.s
+new file mode 100644
+index 0000000..5f270c7
+--- /dev/null
++++ b/ld/testsuite/ld-x86-64/ilp32-4.s
+@@ -0,0 +1,3 @@
++      .globl _start
++_start:
++      ret
+diff --git a/ld/testsuite/ld-x86-64/ilp32-5.d b/ld/testsuite/ld-x86-64/ilp32-5.d
+index e4673e5..4870c2b 100644
+--- a/ld/testsuite/ld-x86-64/ilp32-5.d
++++ b/ld/testsuite/ld-x86-64/ilp32-5.d
+@@ -4,5 +4,5 @@
+ #...
+ [0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+
+-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_PC32 +[0-9a-f]+ +foo - 4
++[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +[0-9a-f]+ +foo \+ 0
+ [0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +[0-9a-f]+ +foo \+ 0
+diff --git a/ld/testsuite/ld-x86-64/ilp32-5.s b/ld/testsuite/ld-x86-64/ilp32-5.s
+index 0d97807..ef0c60e 100644
+--- a/ld/testsuite/ld-x86-64/ilp32-5.s
++++ b/ld/testsuite/ld-x86-64/ilp32-5.s
+@@ -1,6 +1,6 @@
+       .globl bar
+ bar:
+-      mov foo(%rip), %rax
++      mov foo@GOTPCREL(%rip), %rax
+       .data
+ xxx:
+diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
+index 77b081b..44d3e07 100644
+--- a/ld/testsuite/ld-x86-64/x86-64.exp
++++ b/ld/testsuite/ld-x86-64/x86-64.exp
+@@ -207,6 +207,7 @@ run_dump_test "ilp32-6"
+ run_dump_test "ilp32-7"
+ run_dump_test "ilp32-8"
+ run_dump_test "ilp32-9"
++run_dump_test "ilp32-10"
+ run_dump_test "ia32-1"
+ run_dump_test "ia32-2"
+ run_dump_test "ia32-3"
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0078-PR-binutils-13622.patch b/meta/recipes-devtools/binutils/binutils/0078-PR-binutils-13622.patch
new file mode 100644 (file)
index 0000000..a28fc9d
--- /dev/null
@@ -0,0 +1,48 @@
+Upstream-Status: Backport
+
+From dcf0cb6bb406708020efe2db44f53af0fe822773 Mon Sep 17 00:00:00 2001
+From: Nick Clifton <nickc@redhat.com>
+Date: Mon, 30 Jan 2012 11:35:37 +0000
+Subject: [PATCH 078/262]       PR binutils/13622       * readelf.c
+ (process_section_groups): If there are no section 
+ headers do not scan for section groups. 
+ (process_note_sections): Likewise for note
+ sections.
+
+---
+ binutils/ChangeLog |    7 +++++++
+ binutils/readelf.c |    5 +++--
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+2012-01-26  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/13622
+       * readelf.c (process_section_groups): If there are no section
+       headers do not scan for section groups.
+       (process_note_sections): Likewise for note sections.
+diff --git a/binutils/readelf.c b/binutils/readelf.c
+index 9e13190..bf053d9 100644
+--- a/binutils/readelf.c
++++ b/binutils/readelf.c
+@@ -4937,7 +4937,8 @@ process_section_groups (FILE * file)
+   if (section_headers == NULL)
+     {
+       error (_("Section headers are not available!\n"));
+-      abort ();
++      /* PR 13622: This can happen with a corrupt ELF header.  */
++      return 0;
+     }
+   section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
+@@ -12942,7 +12943,7 @@ process_note_sections (FILE * file)
+   int res = 1;
+   for (i = 0, section = section_headers;
+-       i < elf_header.e_shnum;
++       i < elf_header.e_shnum && section != NULL;
+        i++, section++)
+     if (section->sh_type == SHT_NOTE)
+       res &= process_corefile_note_segment (file,
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0144-timer.cc-include-unistd.h.patch b/meta/recipes-devtools/binutils/binutils/0144-timer.cc-include-unistd.h.patch
new file mode 100644 (file)
index 0000000..271c513
--- /dev/null
@@ -0,0 +1,32 @@
+Upstream-Status: Backport
+
+From b7578c6b7bd966b63ab1b2682fd90ed4f3a92e71 Mon Sep 17 00:00:00 2001
+From: Ian Lance Taylor <ian@airs.com>
+Date: Fri, 6 Apr 2012 17:23:58 +0000
+Subject: [PATCH 144/262]       * timer.cc: #include <unistd.h>.
+
+---
+ gold/ChangeLog |    4 ++++
+ gold/timer.cc  |    2 ++
+ 2 files changed, 6 insertions(+)
+
+2012-04-06  Ian Lance Taylor  <iant@google.com>
+
+       * timer.cc: #include <unistd.h>.
+
+diff --git a/gold/timer.cc b/gold/timer.cc
+index d9b8874..44e19f5 100644
+--- a/gold/timer.cc
++++ b/gold/timer.cc
+@@ -22,6 +22,8 @@
+ #include "gold.h"
++#include <unistd.h>
++
+ #ifdef HAVE_TIMES
+ #include <sys/times.h>
+ #endif
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0166-2012-04-27-Doug-Kwan-dougkwan-google.com.patch b/meta/recipes-devtools/binutils/binutils/0166-2012-04-27-Doug-Kwan-dougkwan-google.com.patch
new file mode 100644 (file)
index 0000000..bd1ff5b
--- /dev/null
@@ -0,0 +1,169 @@
+Upstream-Status: Backport
+
+From b6db4b7975d21ec53da5975ddac021098da13bf3 Mon Sep 17 00:00:00 2001
+From: Doug Kwan <dougkwan@google.com>
+Date: Thu, 26 Apr 2012 18:08:19 +0000
+Subject: [PATCH 166/262] 2012-04-27  Doug Kwan  <dougkwan@google.com>
+
+       Backport from mainline:
+
+       2012-03-16  Doug Kwan  <dougkwan@google.com>
+
+               * testsuite/Makefile.am: Disable test initpri3b.
+               * testsuite/Makefile.in: Regenerate.
+
+       2012-03-14  Doug Kwan  <dougkwan@google.com>
+
+               * gold/arm.cc (Target_arm::Scan::global): Generate
+                R_ARM_GLOB_DAT dynamic relocations for protected symbols in
+               shared objects.
+---
+ gold/ChangeLog             |   15 +++++++++++++++
+ gold/arm.cc                |    4 +++-
+ gold/testsuite/Makefile.am |   15 ++++++++++-----
+ gold/testsuite/Makefile.in |   32 +++++++++++++-------------------
+ 4 files changed, 41 insertions(+), 25 deletions(-)
+
+diff --git a/gold/arm.cc b/gold/arm.cc
+index 72c3670..a1e8e4c 100644
+--- a/gold/arm.cc
++++ b/gold/arm.cc
+@@ -8374,7 +8374,9 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
+           Reloc_section* rel_dyn = target->rel_dyn_section(layout);
+           if (gsym->is_from_dynobj()
+               || gsym->is_undefined()
+-              || gsym->is_preemptible())
++              || gsym->is_preemptible()
++              || (gsym->visibility() == elfcpp::STV_PROTECTED
++                  && parameters->options().shared()))
+             got->add_global_with_rel(gsym, GOT_TYPE_STANDARD,
+                                      rel_dyn, elfcpp::R_ARM_GLOB_DAT);
+           else
+diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
+index 9b8605b..97d6457 100644
+--- a/gold/testsuite/Makefile.am
++++ b/gold/testsuite/Makefile.am
+@@ -870,11 +870,16 @@ initpri3a_DEPENDENCIES = gcctestdir/ld
+ initpri3a_LDFLAGS = -Bgcctestdir/
+ initpri3a_LDADD =
+-check_PROGRAMS += initpri3b
+-initpri3b_SOURCES = initpri3.c
+-initpri3b_DEPENDENCIES = gcctestdir/ld
+-initpri3b_LDFLAGS = -Bgcctestdir/ -Wl,--no-ctors-in-init-array
+-initpri3b_LDADD =
++# This test fails on targets not using .ctors and .dtors sections (e.g. ARM
++# EABI). Given that gcc is moving towards using .init_array in all cases,
++# this test is commented out.  A better fix would be checking whether gcc
++# uses .ctors or .init_array sections in configure.
++
++# check_PROGRAMS += initpri3b
++# initpri3b_SOURCES = initpri3.c
++# initpri3b_DEPENDENCIES = gcctestdir/ld
++# initpri3b_LDFLAGS = -Bgcctestdir/ -Wl,--no-ctors-in-init-array
++# initpri3b_LDADD =
+ # Test --detect-odr-violations
+ check_SCRIPTS += debug_msg.sh
+diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
+index 785dcdd..518d32b 100644
+--- a/gold/testsuite/Makefile.in
++++ b/gold/testsuite/Makefile.in
+@@ -56,6 +56,17 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
+ @NATIVE_OR_CROSS_LINKER_TRUE@am__append_1 = object_unittest \
+ @NATIVE_OR_CROSS_LINKER_TRUE@ binary_unittest
++# This test fails on targets not using .ctors and .dtors sections (e.g. ARM
++# EABI). Given that gcc is moving towards using .init_array in all cases,
++# this test is commented out.  A better fix would be checking whether gcc
++# uses .ctors or .init_array sections in configure.
++
++# check_PROGRAMS += initpri3b
++# initpri3b_SOURCES = initpri3.c
++# initpri3b_DEPENDENCIES = gcctestdir/ld
++# initpri3b_LDFLAGS = -Bgcctestdir/ -Wl,--no-ctors-in-init-array
++# initpri3b_LDADD =
++
+ # Test --detect-odr-violations
+ # Similar to --detect-odr-violations: check for undefined symbols in .so's
+@@ -189,7 +200,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
+ # Test -o when emitting to a special file (such as something in /dev).
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_24 = many_sections_test \
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@        many_sections_r_test initpri1 \
+-@GCC_TRUE@@NATIVE_LINKER_TRUE@        initpri2 initpri3a initpri3b \
++@GCC_TRUE@@NATIVE_LINKER_TRUE@        initpri2 initpri3a \
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@        flagstest_o_specialfile
+ @GCC_FALSE@many_sections_test_DEPENDENCIES =
+ @NATIVE_LINKER_FALSE@many_sections_test_DEPENDENCIES =
+@@ -204,8 +215,6 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
+ @NATIVE_LINKER_FALSE@initpri2_DEPENDENCIES =
+ @GCC_FALSE@initpri3a_DEPENDENCIES =
+ @NATIVE_LINKER_FALSE@initpri3a_DEPENDENCIES =
+-@GCC_FALSE@initpri3b_DEPENDENCIES =
+-@NATIVE_LINKER_FALSE@initpri3b_DEPENDENCIES =
+ # Check that --detect-odr-violations works with compressed debug sections.
+ @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@am__append_27 = debug_msg_cdebug.err
+@@ -712,7 +721,6 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS)
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@        initpri1$(EXEEXT) \
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@        initpri2$(EXEEXT) \
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@        initpri3a$(EXEEXT) \
+-@GCC_TRUE@@NATIVE_LINKER_TRUE@        initpri3b$(EXEEXT) \
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@        flagstest_o_specialfile$(EXEEXT)
+ @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_21 = flagstest_compress_debug_sections$(EXEEXT) \
+ @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@        flagstest_o_specialfile_and_compress_debug_sections$(EXEEXT)
+@@ -1200,11 +1208,6 @@ initpri2_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(initpri2_LDFLAGS) \
+ initpri3a_OBJECTS = $(am_initpri3a_OBJECTS)
+ initpri3a_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(initpri3a_LDFLAGS) \
+       $(LDFLAGS) -o $@
+-@GCC_TRUE@@NATIVE_LINKER_TRUE@am_initpri3b_OBJECTS =  \
+-@GCC_TRUE@@NATIVE_LINKER_TRUE@        initpri3.$(OBJEXT)
+-initpri3b_OBJECTS = $(am_initpri3b_OBJECTS)
+-initpri3b_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(initpri3b_LDFLAGS) \
+-      $(LDFLAGS) -o $@
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@am_justsyms_OBJECTS =  \
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@        justsyms_1.$(OBJEXT)
+ justsyms_OBJECTS = $(am_justsyms_OBJECTS)
+@@ -1698,7 +1701,7 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c basic_pie_test.c \
+       incremental_copy_test.c incremental_test_2.c \
+       incremental_test_3.c incremental_test_4.c incremental_test_5.c \
+       incremental_test_6.c $(initpri1_SOURCES) $(initpri2_SOURCES) \
+-      $(initpri3a_SOURCES) $(initpri3b_SOURCES) $(justsyms_SOURCES) \
++      $(initpri3a_SOURCES) $(justsyms_SOURCES) \
+       $(justsyms_exec_SOURCES) $(large_SOURCES) local_labels_test.c \
+       many_sections_r_test.c $(many_sections_test_SOURCES) \
+       $(object_unittest_SOURCES) permission_test.c plugin_test_1.c \
+@@ -2281,10 +2284,6 @@ LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) \
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3a_DEPENDENCIES = gcctestdir/ld
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3a_LDFLAGS = -Bgcctestdir/
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3a_LDADD = 
+-@GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3b_SOURCES = initpri3.c
+-@GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3b_DEPENDENCIES = gcctestdir/ld
+-@GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3b_LDFLAGS = -Bgcctestdir/ -Wl,--no-ctors-in-init-array
+-@GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3b_LDADD = 
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_SOURCES = ver_test_main.cc
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_DEPENDENCIES = gcctestdir/ld ver_test_1.so ver_test_2.so ver_test_4.so
+ @GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
+@@ -2928,9 +2927,6 @@ initpri2$(EXEEXT): $(initpri2_OBJECTS) $(initpri2_DEPENDENCIES)
+ initpri3a$(EXEEXT): $(initpri3a_OBJECTS) $(initpri3a_DEPENDENCIES) 
+       @rm -f initpri3a$(EXEEXT)
+       $(initpri3a_LINK) $(initpri3a_OBJECTS) $(initpri3a_LDADD) $(LIBS)
+-initpri3b$(EXEEXT): $(initpri3b_OBJECTS) $(initpri3b_DEPENDENCIES) 
+-      @rm -f initpri3b$(EXEEXT)
+-      $(initpri3b_LINK) $(initpri3b_OBJECTS) $(initpri3b_LDADD) $(LIBS)
+ justsyms$(EXEEXT): $(justsyms_OBJECTS) $(justsyms_DEPENDENCIES) 
+       @rm -f justsyms$(EXEEXT)
+       $(justsyms_LINK) $(justsyms_OBJECTS) $(justsyms_LDADD) $(LIBS)
+@@ -3869,8 +3865,6 @@ initpri2.log: initpri2$(EXEEXT)
+       @p='initpri2$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+ initpri3a.log: initpri3a$(EXEEXT)
+       @p='initpri3a$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+-initpri3b.log: initpri3b$(EXEEXT)
+-      @p='initpri3b$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+ flagstest_o_specialfile.log: flagstest_o_specialfile$(EXEEXT)
+       @p='flagstest_o_specialfile$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+ flagstest_compress_debug_sections.log: flagstest_compress_debug_sections$(EXEEXT)
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/binutils/binutils/0182-PR-ld-13991.patch b/meta/recipes-devtools/binutils/binutils/0182-PR-ld-13991.patch
new file mode 100644 (file)
index 0000000..f4c9438
--- /dev/null
@@ -0,0 +1,1617 @@
+Upstream-Status: Backport
+
+From e827844b6119ff7e0c2de167f2b261c6c06226c8 Mon Sep 17 00:00:00 2001
+From: Nick Clifton <nickc@redhat.com>
+Date: Fri, 11 May 2012 12:24:12 +0000
+Subject: [PATCH 182/262]     PR ld/13991     bfd/     * bfd/elf-bfd.h
+ (_bfd_elf_link_just_syms): Define as    
+ _bfd_generic_link_just_syms.     * bfd/elflink.c
+ (_bfd_elf_link_just_syms): Delete.     *
+ bfd/linker.c (_bfd_generic_link_just_syms): Set
+ sec_info_type.
+
+    * bfd/bfd-in.h (discarded_section): Renamed from elf_discarded_section.
+    * bfd/section.c (SEC_INFO_TYPE_NONE, SEC_INFO_TYPE_STABS,
+    SEC_INFO_TYPE_MERGE, SEC_INFO_TYPE_EH_FRAME,
+    SEC_INFO_TYPE_JUST_SYMS): Renamed from corresponding ELF_INFO_TYPE.
+    * bfd/elf-eh-frame.c, * bfd/elf-m10200.c, * bfd/elf-m10300.c,
+    * bfd/elf.c, * bfd/elf32-arm.c, * bfd/elf32-avr.c, * bfd/elf32-bfin.c,
+    * bfd/elf32-cr16.c, * bfd/elf32-cr16c.c, * bfd/elf32-cris.c,
+    * bfd/elf32-crx.c, * bfd/elf32-d10v.c, * bfd/elf32-epiphany.c,
+    * bfd/elf32-fr30.c, * bfd/elf32-frv.c, * bfd/elf32-h8300.c,
+    * bfd/elf32-hppa.c, * bfd/elf32-i370.c, * bfd/elf32-i386.c,
+    * bfd/elf32-i860.c, * bfd/elf32-ip2k.c, * bfd/elf32-iq2000.c,
+    * bfd/elf32-lm32.c, * bfd/elf32-m32c.c, * bfd/elf32-m32r.c,
+    * bfd/elf32-m68hc1x.c, * bfd/elf32-m68k.c, * bfd/elf32-mcore.c,
+    * bfd/elf32-mep.c, * bfd/elf32-moxie.c, * bfd/elf32-msp430.c,
+    * bfd/elf32-mt.c, * bfd/elf32-openrisc.c, * bfd/elf32-ppc.c,
+    * bfd/elf32-rl78.c, * bfd/elf32-rx.c, * bfd/elf32-s390.c,
+    * bfd/elf32-score.c, * bfd/elf32-score7.c, * bfd/elf32-sh.c,
+    * bfd/elf32-spu.c, * bfd/elf32-tic6x.c, * bfd/elf32-tilepro.c,
+    * bfd/elf32-v850.c, * bfd/elf32-vax.c, * bfd/elf32-xc16x.c,
+    * bfd/elf32-xstormy16.c, * bfd/elf32-xtensa.c, * bfd/elf64-alpha.c,
+    * bfd/elf64-hppa.c, * bfd/elf64-ia64-vms.c, * bfd/elf64-mmix.c,
+    * bfd/elf64-ppc.c, * bfd/elf64-s390.c, * bfd/elf64-sh64.c,
+    * bfd/elf64-x86-64.c, * bfd/elflink.c, * bfd/elfnn-ia64.c,
+    * bfd/elfxx-mips.c, * bfd/elfxx-sparc.c, * bfd/elfxx-tilegx.c,
+    * bfd/reloc.c: Update all references.
+    * bfd/bfd-in2.h: Regenerate.
+    ld/
+    * ld/ldlang.c (size_input_section): Use sec_info_type rather than
+    usrdata->flags.just_syms.
+    * ld/ldwrite.c (build_link_order): Likewise.
+    * ld/emultempl/hppaelf.em (build_section_lists): Likewise.
+    * ld/emultempl/ppc64elf.em (build_toc_list): Likewise.
+    * ld/emultempl/armelf.em (build_section_lists): Likewise.
+    (after_allocation): Update for renamed sec_info_type value.
+    * ld/emultempl/tic6xdsbt.em: Likewise.
+---
+ bfd/ChangeLog             |   38 +++++++++++++++++++++++++++++++++
+ bfd/bfd-in.h              |    6 +++---
+ bfd/bfd-in2.h             |   16 +++++++-------
+ bfd/elf-bfd.h             |    3 +--
+ bfd/elf-eh-frame.c        |   10 ++++-----
+ bfd/elf-m10200.c          |    2 +-
+ bfd/elf-m10300.c          |    4 ++--
+ bfd/elf.c                 |   10 ++++-----
+ bfd/elf32-arm.c           |    6 +++---
+ bfd/elf32-avr.c           |    2 +-
+ bfd/elf32-bfin.c          |    6 +++---
+ bfd/elf32-cr16.c          |    2 +-
+ bfd/elf32-cr16c.c         |    2 +-
+ bfd/elf32-cris.c          |    2 +-
+ bfd/elf32-crx.c           |    2 +-
+ bfd/elf32-d10v.c          |    2 +-
+ bfd/elf32-fr30.c          |    2 +-
+ bfd/elf32-frv.c           |    4 ++--
+ bfd/elf32-h8300.c         |    2 +-
+ bfd/elf32-hppa.c          |    2 +-
+ bfd/elf32-i370.c          |    2 +-
+ bfd/elf32-i386.c          |    4 ++--
+ bfd/elf32-i860.c          |    2 +-
+ bfd/elf32-ip2k.c          |    2 +-
+ bfd/elf32-iq2000.c        |    2 +-
+ bfd/elf32-lm32.c          |    6 +++---
+ bfd/elf32-m32c.c          |    2 +-
+ bfd/elf32-m32r.c          |    2 +-
+ bfd/elf32-m68hc1x.c       |    2 +-
+ bfd/elf32-m68k.c          |    2 +-
+ bfd/elf32-mcore.c         |    2 +-
+ bfd/elf32-mep.c           |    2 +-
+ bfd/elf32-moxie.c         |    2 +-
+ bfd/elf32-msp430.c        |    2 +-
+ bfd/elf32-mt.c            |    2 +-
+ bfd/elf32-openrisc.c      |    2 +-
+ bfd/elf32-ppc.c           |    6 +++---
+ bfd/elf32-rx.c            |    4 ++--
+ bfd/elf32-s390.c          |    2 +-
+ bfd/elf32-score.c         |    2 +-
+ bfd/elf32-score7.c        |    2 +-
+ bfd/elf32-sh.c            |    4 ++--
+ bfd/elf32-spu.c           |    2 +-
+ bfd/elf32-tic6x.c         |    2 +-
+ bfd/elf32-tilepro.c       |    2 +-
+ bfd/elf32-v850.c          |    2 +-
+ bfd/elf32-vax.c           |    2 +-
+ bfd/elf32-xc16x.c         |    2 +-
+ bfd/elf32-xstormy16.c     |    2 +-
+ bfd/elf32-xtensa.c        |    8 +++----
+ bfd/elf64-alpha.c         |    8 +++----
+ bfd/elf64-hppa.c          |    2 +-
+ bfd/elf64-mmix.c          |    2 +-
+ bfd/elf64-ppc.c           |   20 +++++++++---------
+ bfd/elf64-s390.c          |    2 +-
+ bfd/elf64-sh64.c          |    4 ++--
+ bfd/elf64-x86-64.c        |    4 ++--
+ bfd/elflink.c             |   51 ++++++++++++++++++---------------------------
+ bfd/elfnn-ia64.c          |    6 +++---
+ bfd/elfxx-mips.c          |    2 +-
+ bfd/elfxx-sparc.c         |    2 +-
+ bfd/elfxx-tilegx.c        |    2 +-
+ bfd/linker.c              |    3 ++-
+ bfd/reloc.c               |    2 +-
+ bfd/section.c             |   10 ++++-----
+ ld/ChangeLog              |   15 +++++++++++++
+ ld/emultempl/armelf.em    |    4 ++--
+ ld/emultempl/hppaelf.em   |    2 +-
+ ld/emultempl/ppc64elf.em  |    4 ++--
+ ld/emultempl/tic6xdsbt.em |    2 +-
+ ld/ldlang.c               |    2 +-
+ ld/ldwrite.c              |    4 ++--
+ 72 files changed, 199 insertions(+), 157 deletions(-)
+
+diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
+index a477b49..7c5298a 100644
+--- a/bfd/bfd-in.h
++++ b/bfd/bfd-in.h
+@@ -295,11 +295,11 @@ typedef struct bfd_section *sec_ptr;
+     ? (sec)->rawsize : (sec)->size) / bfd_octets_per_byte (bfd))
+ /* Return TRUE if input section SEC has been discarded.  */
+-#define elf_discarded_section(sec)                            \
++#define discarded_section(sec)                                        \
+   (!bfd_is_abs_section (sec)                                  \
+    && bfd_is_abs_section ((sec)->output_section)              \
+-   && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE             \
+-   && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
++   && (sec)->sec_info_type != SEC_INFO_TYPE_MERGE             \
++   && (sec)->sec_info_type != SEC_INFO_TYPE_JUST_SYMS)
+ /* Forward define.  */
+ struct stat;
+diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
+index cd90740..34f9628 100644
+--- a/bfd/bfd-in2.h
++++ b/bfd/bfd-in2.h
+@@ -302,11 +302,11 @@ typedef struct bfd_section *sec_ptr;
+     ? (sec)->rawsize : (sec)->size) / bfd_octets_per_byte (bfd))
+ /* Return TRUE if input section SEC has been discarded.  */
+-#define elf_discarded_section(sec)                            \
++#define discarded_section(sec)                                        \
+   (!bfd_is_abs_section (sec)                                  \
+    && bfd_is_abs_section ((sec)->output_section)              \
+-   && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE             \
+-   && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
++   && (sec)->sec_info_type != SEC_INFO_TYPE_MERGE             \
++   && (sec)->sec_info_type != SEC_INFO_TYPE_JUST_SYMS)
+ /* Forward define.  */
+ struct stat;
+@@ -1384,11 +1384,11 @@ typedef struct bfd_section
+   /* Type of sec_info information.  */
+   unsigned int sec_info_type:3;
+-#define ELF_INFO_TYPE_NONE      0
+-#define ELF_INFO_TYPE_STABS     1
+-#define ELF_INFO_TYPE_MERGE     2
+-#define ELF_INFO_TYPE_EH_FRAME  3
+-#define ELF_INFO_TYPE_JUST_SYMS 4
++#define SEC_INFO_TYPE_NONE      0
++#define SEC_INFO_TYPE_STABS     1
++#define SEC_INFO_TYPE_MERGE     2
++#define SEC_INFO_TYPE_EH_FRAME  3
++#define SEC_INFO_TYPE_JUST_SYMS 4
+   /* Nonzero if this section uses RELA relocations, rather than REL.  */
+   unsigned int use_rela_p:1;
+diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
+index d6e2ab2..2cfe2ba 100644
+--- a/bfd/elf-bfd.h
++++ b/bfd/elf-bfd.h
+@@ -1807,8 +1807,7 @@ extern void bfd_elf_set_group_contents
+   (bfd *, asection *, void *);
+ extern asection *_bfd_elf_check_kept_section
+   (asection *, struct bfd_link_info *);
+-extern void _bfd_elf_link_just_syms
+-  (asection *, struct bfd_link_info *);
++#define _bfd_elf_link_just_syms _bfd_generic_link_just_syms
+ extern void _bfd_elf_copy_link_hash_symbol_type
+   (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
+ extern bfd_boolean _bfd_elf_size_group_sections
+diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
+index 54142b2..7b5cf7a 100644
+--- a/bfd/elf-eh-frame.c
++++ b/bfd/elf-eh-frame.c
+@@ -491,7 +491,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
+     return;
+   if (sec->size == 0
+-      || sec->sec_info_type != ELF_INFO_TYPE_NONE)
++      || sec->sec_info_type != SEC_INFO_TYPE_NONE)
+     {
+       /* This file does not contain .eh_frame information.  */
+       return;
+@@ -904,7 +904,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
+   BFD_ASSERT (cie_count == num_cies);
+   elf_section_data (sec)->sec_info = sec_info;
+-  sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
++  sec->sec_info_type = SEC_INFO_TYPE_EH_FRAME;
+   if (hdr_info->merge_cies)
+     {
+       sec_info->cies = local_cies;
+@@ -1137,7 +1137,7 @@ _bfd_elf_discard_section_eh_frame
+   struct eh_frame_hdr_info *hdr_info;
+   unsigned int ptr_size, offset;
+-  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
++  if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
+     return FALSE;
+   sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
+@@ -1307,7 +1307,7 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
+   struct eh_frame_sec_info *sec_info;
+   unsigned int lo, hi, mid;
+-  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
++  if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
+     return offset;
+   sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
+@@ -1395,7 +1395,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
+   unsigned int ptr_size;
+   struct eh_cie_fde *ent;
+-  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
++  if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
+     /* FIXME: octets_per_byte.  */
+     return bfd_set_section_contents (abfd, sec->output_section, contents,
+                                    sec->output_offset, sec->size);
+diff --git a/bfd/elf-m10200.c b/bfd/elf-m10200.c
+index a38f4db..d58c75c 100644
+--- a/bfd/elf-m10200.c
++++ b/bfd/elf-m10200.c
+@@ -401,7 +401,7 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c
+index 8276a2f..876ff4a 100644
+--- a/bfd/elf-m10300.c
++++ b/bfd/elf-m10300.c
+@@ -1509,7 +1509,7 @@ mn10300_elf_relocate_section (bfd *output_bfd,
+              h->root.root.root.string);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -2763,7 +2763,7 @@ mn10300_elf_relax_section (bfd *abfd,
+                                                     isym->st_name);
+         if ((sym_sec->flags & SEC_MERGE)
+-            && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
++            && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+           {
+             symval = isym->st_value;
+diff --git a/bfd/elf.c b/bfd/elf.c
+index aa40c33..9e23bee 100644
+--- a/bfd/elf.c
++++ b/bfd/elf.c
+@@ -3071,7 +3071,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
+             if (link_info != NULL)
+               {
+                 /* Check discarded linkonce section.  */
+-                if (elf_discarded_section (s))
++                if (discarded_section (s))
+                   {
+                     asection *kept;
+                     (*_bfd_error_handler)
+@@ -9390,7 +9390,7 @@ _bfd_elf_rela_local_sym (bfd *abfd,
+               + sym->st_value);
+   if ((sec->flags & SEC_MERGE)
+       && ELF_ST_TYPE (sym->st_info) == STT_SECTION
+-      && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
++      && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+     {
+       rel->r_addend =
+       _bfd_merged_section_offset (abfd, psec,
+@@ -9421,7 +9421,7 @@ _bfd_elf_rel_local_sym (bfd *abfd,
+ {
+   asection *sec = *psec;
+-  if (sec->sec_info_type != ELF_INFO_TYPE_MERGE)
++  if (sec->sec_info_type != SEC_INFO_TYPE_MERGE)
+     return sym->st_value + addend;
+   return _bfd_merged_section_offset (abfd, psec,
+@@ -9437,10 +9437,10 @@ _bfd_elf_section_offset (bfd *abfd,
+ {
+   switch (sec->sec_info_type)
+     {
+-    case ELF_INFO_TYPE_STABS:
++    case SEC_INFO_TYPE_STABS:
+       return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
+                                      offset);
+-    case ELF_INFO_TYPE_EH_FRAME:
++    case SEC_INFO_TYPE_EH_FRAME:
+       return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
+     default:
+       if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
+diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
+index 1f6c1a0..9355f66 100644
+--- a/bfd/elf32-arm.c
++++ b/bfd/elf32-arm.c
+@@ -4485,7 +4485,7 @@ cortex_a8_erratum_scan (bfd *input_bfd,
+       if (elf_section_type (section) != SHT_PROGBITS
+           || (elf_section_flags (section) & SHF_EXECINSTR) == 0
+           || (section->flags & SEC_EXCLUDE) != 0
+-          || (section->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
++          || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+           || (section->output_section == bfd_abs_section_ptr))
+         continue;
+@@ -6556,7 +6556,7 @@ bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info)
+       if (elf_section_type (sec) != SHT_PROGBITS
+           || (elf_section_flags (sec) & SHF_EXECINSTR) == 0
+           || (sec->flags & SEC_EXCLUDE) != 0
+-        || sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS
++        || sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS
+         || sec->output_section == bfd_abs_section_ptr
+           || strcmp (sec->name, VFP11_ERRATUM_VENEER_SECTION_NAME) == 0)
+         continue;
+@@ -10305,7 +10305,7 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
+         sym_type = h->type;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
+index a7f9217..97dc268 100644
+--- a/bfd/elf32-avr.c
++++ b/bfd/elf32-avr.c
+@@ -1189,7 +1189,7 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c
+index b112dfc..4941f40 100644
+--- a/bfd/elf32-bfin.c
++++ b/bfd/elf32-bfin.c
+@@ -1444,7 +1444,7 @@ bfin_relocate_section (bfd * output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -2663,7 +2663,7 @@ bfinfdpic_relocate_section (bfd * output_bfd,
+         osec = sec;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -4429,7 +4429,7 @@ bfinfdpic_elf_discard_info (bfd *ibfd,
+   /* Account for relaxation of .eh_frame section.  */
+   for (s = ibfd->sections; s; s = s->next)
+-    if (s->sec_info_type == ELF_INFO_TYPE_EH_FRAME)
++    if (s->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+       {
+       if (!_bfinfdpic_check_discarded_relocs (ibfd, s, info, &changed))
+         return FALSE;
+diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c
+index 0118131..38af05f 100644
+--- a/bfd/elf32-cr16.c
++++ b/bfd/elf32-cr16.c
+@@ -1431,7 +1431,7 @@ elf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+                                    unresolved_reloc, warned);
+         }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-cr16c.c b/bfd/elf32-cr16c.c
+index ca2d7cb..109936b 100644
+--- a/bfd/elf32-cr16c.c
++++ b/bfd/elf32-cr16c.c
+@@ -723,7 +723,7 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c
+index 310f6d1..ec23f03 100644
+--- a/bfd/elf32-cris.c
++++ b/bfd/elf32-cris.c
+@@ -1180,7 +1180,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+           }
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-crx.c b/bfd/elf32-crx.c
+index d48932d..fd13447 100644
+--- a/bfd/elf32-crx.c
++++ b/bfd/elf32-crx.c
+@@ -873,7 +873,7 @@ elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c
+index 7d65395..e39a9b5 100644
+--- a/bfd/elf32-d10v.c
++++ b/bfd/elf32-d10v.c
+@@ -463,7 +463,7 @@ elf32_d10v_relocate_section (bfd *output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c
+index 97b0d29..57be6ae 100644
+--- a/bfd/elf32-fr30.c
++++ b/bfd/elf32-fr30.c
+@@ -577,7 +577,7 @@ fr30_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c
+index 7f3c4dd..513f811 100644
+--- a/bfd/elf32-frv.c
++++ b/bfd/elf32-frv.c
+@@ -2812,7 +2812,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -5678,7 +5678,7 @@ frvfdpic_elf_discard_info (bfd *ibfd,
+   /* Account for relaxation of .eh_frame section.  */
+   for (s = ibfd->sections; s; s = s->next)
+-    if (s->sec_info_type == ELF_INFO_TYPE_EH_FRAME)
++    if (s->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+       {
+       if (!_frvfdpic_check_discarded_relocs (ibfd, s, info, &changed))
+         return FALSE;
+diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c
+index 95d3983..ff1ee70 100644
+--- a/bfd/elf32-h8300.c
++++ b/bfd/elf32-h8300.c
+@@ -460,7 +460,7 @@ elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
+index dcf6df0..044b6fa 100644
+--- a/bfd/elf32-hppa.c
++++ b/bfd/elf32-hppa.c
+@@ -3741,7 +3741,7 @@ elf32_hppa_relocate_section (bfd *output_bfd,
+         hh = hppa_elf_hash_entry (eh);
+       }
+-      if (sym_sec != NULL && elf_discarded_section (sym_sec))
++      if (sym_sec != NULL && discarded_section (sym_sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rela, relend,
+                                        elf_hppa_howto_table + r_type,
+diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c
+index 8082927..516511f 100644
+--- a/bfd/elf32-i370.c
++++ b/bfd/elf32-i370.c
+@@ -1138,7 +1138,7 @@ i370_elf_relocate_section (bfd *output_bfd,
+           }
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
+index d518d01..b925ca6 100644
+--- a/bfd/elf32-i386.c
++++ b/bfd/elf32-i386.c
+@@ -3178,7 +3178,7 @@ elf_i386_relocate_section (bfd *output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -4846,7 +4846,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
+                            + PLT_FDE_START_OFFSET);
+       }
+       if (htab->plt_eh_frame->sec_info_type
+-        == ELF_INFO_TYPE_EH_FRAME)
++        == SEC_INFO_TYPE_EH_FRAME)
+       {
+         if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
+                                                htab->plt_eh_frame,
+diff --git a/bfd/elf32-i860.c b/bfd/elf32-i860.c
+index 00c8ca7..88f4265 100644
+--- a/bfd/elf32-i860.c
++++ b/bfd/elf32-i860.c
+@@ -1128,7 +1128,7 @@ elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-ip2k.c b/bfd/elf32-ip2k.c
+index 0a251b8..43c7b1c 100644
+--- a/bfd/elf32-ip2k.c
++++ b/bfd/elf32-ip2k.c
+@@ -1436,7 +1436,7 @@ ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-iq2000.c b/bfd/elf32-iq2000.c
+index 63ef3dc..3954616 100644
+--- a/bfd/elf32-iq2000.c
++++ b/bfd/elf32-iq2000.c
+@@ -633,7 +633,7 @@ iq2000_elf_relocate_section (bfd *              output_bfd ATTRIBUTE_UNUSED,
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c
+index 07add20..a2b1003 100644
+--- a/bfd/elf32-lm32.c
++++ b/bfd/elf32-lm32.c
+@@ -893,7 +893,7 @@ lm32_elf_relocate_section (bfd *output_bfd,
+         name = h->root.root.string;
+         }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -2372,7 +2372,7 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd,
+                           /* Don't generate entries for weak symbols.  */
+                           if (!h || (h && h->root.type != bfd_link_hash_undefweak))
+                             {
+-                              if (!elf_discarded_section (s) && !((bfd_get_section_flags (ibfd, s) & SEC_ALLOC) == 0))
++                              if (!discarded_section (s) && !((bfd_get_section_flags (ibfd, s) & SEC_ALLOC) == 0))
+                                 {
+                                   switch (ELF32_R_TYPE (internal_relocs->r_info))
+                                     {
+@@ -2394,7 +2394,7 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd,
+                                   if (!strcmp (current->name, h->root.root.string))
+                                     break;
+                                 }
+-                              if (!current && !elf_discarded_section (s) && (bfd_get_section_flags (ibfd, s) & SEC_ALLOC))
++                              if (!current && !discarded_section (s) && (bfd_get_section_flags (ibfd, s) & SEC_ALLOC))
+                                 {
+                                   /* Will this have an entry in the GOT.  */
+                                   if (ELF32_R_TYPE (internal_relocs->r_info) == R_LM32_16_GOT)
+diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c
+index cf7ad99..bcdb55d 100644
+--- a/bfd/elf32-m32c.c
++++ b/bfd/elf32-m32c.c
+@@ -434,7 +434,7 @@ m32c_elf_relocate_section
+           }
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
+index 51ef61e..b151a8a 100644
+--- a/bfd/elf32-m32r.c
++++ b/bfd/elf32-m32r.c
+@@ -2616,7 +2616,7 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+           }
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c
+index 961dce4..4b9a1c0 100644
+--- a/bfd/elf32-m68hc1x.c
++++ b/bfd/elf32-m68hc1x.c
+@@ -970,7 +970,7 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+         is_far = (h && (h->other & STO_M68HC12_FAR));
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
+index 3e9ada9..518a41a 100644
+--- a/bfd/elf32-m68k.c
++++ b/bfd/elf32-m68k.c
+@@ -3717,7 +3717,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-mcore.c b/bfd/elf32-mcore.c
+index 31cc095..02aef53 100644
+--- a/bfd/elf32-mcore.c
++++ b/bfd/elf32-mcore.c
+@@ -466,7 +466,7 @@ mcore_elf_relocate_section (bfd * output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-mep.c b/bfd/elf32-mep.c
+index 6fecb25..e5104b3 100644
+--- a/bfd/elf32-mep.c
++++ b/bfd/elf32-mep.c
+@@ -500,7 +500,7 @@ mep_elf_relocate_section
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-moxie.c b/bfd/elf32-moxie.c
+index 8463599..c340826 100644
+--- a/bfd/elf32-moxie.c
++++ b/bfd/elf32-moxie.c
+@@ -250,7 +250,7 @@ moxie_elf_relocate_section (bfd *output_bfd,
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c
+index 9a5fb2a..2fa70d9 100644
+--- a/bfd/elf32-msp430.c
++++ b/bfd/elf32-msp430.c
+@@ -454,7 +454,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-mt.c b/bfd/elf32-mt.c
+index 1be5d00..b87995e 100644
+--- a/bfd/elf32-mt.c
++++ b/bfd/elf32-mt.c
+@@ -354,7 +354,7 @@ mt_elf_relocate_section
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-openrisc.c b/bfd/elf32-openrisc.c
+index ada738e..e441f4d 100644
+--- a/bfd/elf32-openrisc.c
++++ b/bfd/elf32-openrisc.c
+@@ -373,7 +373,7 @@ openrisc_elf_relocate_section (bfd *output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
+index 574cd98..d3925af 100644
+--- a/bfd/elf32-ppc.c
++++ b/bfd/elf32-ppc.c
+@@ -6231,7 +6231,7 @@ ppc_elf_relax_section (bfd *abfd,
+        attribute for a code section, and we are only looking at
+        branches.  However, implement it correctly here as a
+        reference for other target relax_section functions.  */
+-      if (0 && tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
++      if (0 && tsec->sec_info_type == SEC_INFO_TYPE_MERGE)
+       {
+         /* At this stage in linking, no SEC_MERGE symbol has been
+            adjusted, so all references to such symbols need to be
+@@ -6886,7 +6886,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
+         sym_name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       {
+         /* For relocs against symbols from removed linkonce sections,
+            or sections discarded by a linker script, we just want the
+@@ -9054,7 +9054,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
+       BFD_ASSERT ((bfd_vma) ((p + 3 - htab->glink_eh_frame->contents) & -4)
+                 == htab->glink_eh_frame->size);
+-      if (htab->glink_eh_frame->sec_info_type == ELF_INFO_TYPE_EH_FRAME
++      if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
+         && !_bfd_elf_write_section_eh_frame (output_bfd, info,
+                                              htab->glink_eh_frame,
+                                              htab->glink_eh_frame->contents))
+diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c
+index f049f6e..32820b4 100644
+--- a/bfd/elf32-rx.c
++++ b/bfd/elf32-rx.c
+@@ -510,7 +510,7 @@ rx_elf_relocate_section
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -1588,7 +1588,7 @@ rx_offset_for_reloc (bfd *                    abfd,
+         if (ssec)
+           {
+             if ((ssec->flags & SEC_MERGE)
+-                && ssec->sec_info_type == ELF_INFO_TYPE_MERGE)
++                && ssec->sec_info_type == SEC_INFO_TYPE_MERGE)
+               symval = _bfd_merged_section_offset (abfd, & ssec,
+                                                    elf_section_data (ssec)->sec_info,
+                                                    symval);
+diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
+index 98437d0..11fb072 100644
+--- a/bfd/elf32-s390.c
++++ b/bfd/elf32-s390.c
+@@ -2282,7 +2282,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c
+index b437624..ef849aa 100644
+--- a/bfd/elf32-score.c
++++ b/bfd/elf32-score.c
+@@ -2672,7 +2672,7 @@ s3_bfd_score_elf_relocate_section (bfd *output_bfd,
+             }
+         }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-score7.c b/bfd/elf32-score7.c
+index 3e98bfc..3d228f3 100644
+--- a/bfd/elf32-score7.c
++++ b/bfd/elf32-score7.c
+@@ -2443,7 +2443,7 @@ s7_bfd_score_elf_relocate_section (bfd *output_bfd,
+             }
+         }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
+index ca2c4af..e56c3b5 100644
+--- a/bfd/elf32-sh.c
++++ b/bfd/elf32-sh.c
+@@ -4048,7 +4048,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+             _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
+             input_bfd, input_section, rel->r_offset));
+-        if (sec != NULL && elf_discarded_section (sec))
++        if (sec != NULL && discarded_section (sec))
+           /* Handled below.  */
+           ;
+         else if (info->relocatable)
+@@ -4236,7 +4236,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+           }
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
+index ae3ed10..40a9da2 100644
+--- a/bfd/elf32-spu.c
++++ b/bfd/elf32-spu.c
+@@ -4895,7 +4895,7 @@ spu_elf_relocate_section (bfd *output_bfd,
+         sym_name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c
+index 44042eb..a879d3c 100644
+--- a/bfd/elf32-tic6x.c
++++ b/bfd/elf32-tic6x.c
+@@ -2334,7 +2334,7 @@ elf32_tic6x_relocate_section (bfd *output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c
+index f2aed9c..a4e565d 100644
+--- a/bfd/elf32-tilepro.c
++++ b/bfd/elf32-tilepro.c
+@@ -2594,7 +2594,7 @@ tilepro_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+           }
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c
+index 9e6f77d..0fbe080 100644
+--- a/bfd/elf32-v850.c
++++ b/bfd/elf32-v850.c
+@@ -2093,7 +2093,7 @@ v850_elf_relocate_section (bfd *output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c
+index 643381c..fc3cb7c 100644
+--- a/bfd/elf32-vax.c
++++ b/bfd/elf32-vax.c
+@@ -1450,7 +1450,7 @@ elf_vax_relocate_section (bfd *output_bfd,
+           relocation = 0;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-xc16x.c b/bfd/elf32-xc16x.c
+index 11d9840..00c7841 100644
+--- a/bfd/elf32-xc16x.c
++++ b/bfd/elf32-xc16x.c
+@@ -381,7 +381,7 @@ elf32_xc16x_relocate_section (bfd *output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       {
+         /* For relocs against symbols from removed linkonce sections,
+            or sections discarded by a linker script, we just want the
+diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c
+index 6141783..86e1d5b 100644
+--- a/bfd/elf32-xstormy16.c
++++ b/bfd/elf32-xstormy16.c
+@@ -825,7 +825,7 @@ xstormy16_elf_relocate_section (bfd *                   output_bfd ATTRIBUTE_UNU
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
+index c6e4fb4..5a51eae 100644
+--- a/bfd/elf32-xtensa.c
++++ b/bfd/elf32-xtensa.c
+@@ -1712,7 +1712,7 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+           continue;
+         for (s = abfd->sections; s != NULL; s = s->next)
+           {
+-            if (! elf_discarded_section (s)
++            if (! discarded_section (s)
+                 && xtensa_is_littable_section (s)
+                 && s != spltlittbl)
+               sgotloc->size += s->size;
+@@ -2656,7 +2656,7 @@ elf_xtensa_relocate_section (bfd *output_bfd,
+         sym_type = h->type;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -8960,9 +8960,9 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
+            that here and adjust things accordingly.  */
+         if (! elf_xtensa_ignore_discarded_relocs (sec)
+             && elf_xtensa_action_discarded (sec) == PRETEND
+-            && sec->sec_info_type != ELF_INFO_TYPE_STABS
++            && sec->sec_info_type != SEC_INFO_TYPE_STABS
+             && target_sec != NULL
+-            && elf_discarded_section (target_sec))
++            && discarded_section (target_sec))
+           {
+             /* It would be natural to call _bfd_elf_check_kept_section
+                here, but it's not exported from elflink.c.  It's also a
+diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
+index 6076709..ddb1cd7 100644
+--- a/bfd/elf64-alpha.c
++++ b/bfd/elf64-alpha.c
+@@ -4106,7 +4106,7 @@ elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED,
+         sec = h->root.u.def.section;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend,
+                                        elf64_alpha_howto_table + r_type,
+@@ -4263,7 +4263,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+            unless it has been done already.  */
+         if ((sec->flags & SEC_MERGE)
+             && ELF_ST_TYPE (sym->st_info) == STT_SECTION
+-            && sec->sec_info_type == ELF_INFO_TYPE_MERGE
++            && sec->sec_info_type == SEC_INFO_TYPE_MERGE
+             && gotent
+             && !gotent->reloc_xlated)
+           {
+@@ -4315,7 +4315,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+         gotent = h->got_entries;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -4717,7 +4717,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+           if (r_symndx < symtab_hdr->sh_info
+               && sec != NULL && howto->pc_relative
+-              && elf_discarded_section (sec))
++              && discarded_section (sec))
+             break;
+           if (h != NULL)
+diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c
+index 057a92d..9d2dfcf 100644
+--- a/bfd/elf64-hppa.c
++++ b/bfd/elf64-hppa.c
+@@ -3919,7 +3919,7 @@ elf64_hppa_relocate_section (bfd *output_bfd,
+             }
+       }
+-      if (sym_sec != NULL && elf_discarded_section (sym_sec))
++      if (sym_sec != NULL && discarded_section (sym_sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c
+index ecc9ad0..9cc407f 100644
+--- a/bfd/elf64-mmix.c
++++ b/bfd/elf64-mmix.c
+@@ -1475,7 +1475,7 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+         name = h->root.root.string;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
+index 32a3430..52e9ce9 100644
+--- a/bfd/elf64-ppc.c
++++ b/bfd/elf64-ppc.c
+@@ -6852,7 +6852,7 @@ adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
+         if (dsec == NULL)
+           {
+             for (dsec = sym_sec->owner->sections; dsec; dsec = dsec->next)
+-              if (elf_discarded_section (dsec))
++              if (discarded_section (dsec))
+                 {
+                   ppc64_elf_tdata (sym_sec->owner)->deleted_section = dsec;
+                   break;
+@@ -7033,7 +7033,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping)
+       if (sec == NULL || sec->size == 0)
+       continue;
+-      if (sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
++      if (sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+       continue;
+       if (sec->output_section == bfd_abs_section_ptr)
+@@ -8077,8 +8077,8 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
+       toc = bfd_get_section_by_name (ibfd, ".toc");
+       if (toc == NULL
+         || toc->size == 0
+-        || toc->sec_info_type == ELF_INFO_TYPE_JUST_SYMS
+-        || elf_discarded_section (toc))
++        || toc->sec_info_type == SEC_INFO_TYPE_JUST_SYMS
++        || discarded_section (toc))
+       continue;
+       toc_relocs = NULL;
+@@ -8091,7 +8091,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
+       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+       {
+         if (sec->reloc_count == 0
+-            || !elf_discarded_section (sec)
++            || !discarded_section (sec)
+             || get_opd_info (sec)
+             || (sec->flags & SEC_ALLOC) == 0
+             || (sec->flags & SEC_DEBUGGING) != 0)
+@@ -8201,7 +8201,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
+               goto error_ret;
+             if (sym_sec == NULL
+-                || elf_discarded_section (sym_sec))
++                || discarded_section (sym_sec))
+               continue;
+             if (!SYMBOL_CALLS_LOCAL (info, h))
+@@ -8281,7 +8281,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
+         int repeat;
+         if (sec->reloc_count == 0
+-            || elf_discarded_section (sec)
++            || discarded_section (sec)
+             || get_opd_info (sec)
+             || (sec->flags & SEC_ALLOC) == 0
+             || (sec->flags & SEC_DEBUGGING) != 0)
+@@ -8503,7 +8503,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
+         for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+           {
+             if (sec->reloc_count == 0
+-                || elf_discarded_section (sec))
++                || discarded_section (sec))
+               continue;
+             relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
+@@ -12036,7 +12036,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
+       }
+       h = (struct ppc_link_hash_entry *) h_elf;
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend,
+                                        ppc64_elf_howto_table[r_type],
+@@ -13865,7 +13865,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
+   if (htab->glink_eh_frame != NULL
+-      && htab->glink_eh_frame->sec_info_type == ELF_INFO_TYPE_EH_FRAME
++      && htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
+       && !_bfd_elf_write_section_eh_frame (output_bfd, info,
+                                          htab->glink_eh_frame,
+                                          htab->glink_eh_frame->contents))
+diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
+index 9884da0..e9138a6 100644
+--- a/bfd/elf64-s390.c
++++ b/bfd/elf64-s390.c
+@@ -2270,7 +2270,7 @@ elf_s390_relocate_section (bfd *output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c
+index bbef2a2..d8f2120 100644
+--- a/bfd/elf64-sh64.c
++++ b/bfd/elf64-sh64.c
+@@ -1514,7 +1514,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+             _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
+             input_bfd, input_section, rel->r_offset));
+-        if (sec != NULL && elf_discarded_section (sec))
++        if (sec != NULL && discarded_section (sec))
+           /* Handled below.  */
+           ;
+         else if (info->relocatable)
+@@ -1657,7 +1657,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+           }
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
+index bdb3ae6..9d826e7 100644
+--- a/bfd/elf64-x86-64.c
++++ b/bfd/elf64-x86-64.c
+@@ -3062,7 +3062,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
+                                  unresolved_reloc, warned);
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+@@ -4625,7 +4625,7 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
+                            + PLT_FDE_START_OFFSET);
+       }
+       if (htab->plt_eh_frame->sec_info_type
+-        == ELF_INFO_TYPE_EH_FRAME)
++        == SEC_INFO_TYPE_EH_FRAME)
+       {
+         if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
+                                                htab->plt_eh_frame,
+diff --git a/bfd/elflink.c b/bfd/elflink.c
+index 8556cec..da6be48 100644
+--- a/bfd/elflink.c
++++ b/bfd/elflink.c
+@@ -1,6 +1,6 @@
+ /* ELF linking support for BFD.
+    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+-   2005, 2006, 2007, 2008, 2009, 2010, 2011
++   2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+    Free Software Foundation, Inc.
+    This file is part of BFD, the Binary File Descriptor library.
+@@ -937,7 +937,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
+   /* Silently discard TLS symbols from --just-syms.  There's no way to
+      combine a static TLS block with a new TLS block for this executable.  */
+   if (ELF_ST_TYPE (sym->st_info) == STT_TLS
+-      && sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
++      && sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+     {
+       *skip = TRUE;
+       return TRUE;
+@@ -2708,7 +2708,7 @@ _bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data)
+   if ((h->root.type == bfd_link_hash_defined
+        || h->root.type == bfd_link_hash_defweak)
+       && ((sec = h->root.u.def.section)->flags & SEC_MERGE)
+-      && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
++      && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+     {
+       bfd *output_bfd = (bfd *) data;
+@@ -3499,7 +3499,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+       /* ld --just-symbols and dynamic objects don't mix very well.
+        ld shouldn't allow it.  */
+       if ((s = abfd->sections) != NULL
+-        && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
++        && s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+       abort ();
+       /* If this dynamic lib was specified on the command line with
+@@ -3896,7 +3896,7 @@ error_free_dyn:
+         sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+         if (sec == NULL)
+           sec = bfd_abs_section_ptr;
+-        else if (elf_discarded_section (sec))
++        else if (discarded_section (sec))
+           {
+             /* Symbols from discarded section are undefined.  We keep
+                its visibility.  */
+@@ -4861,7 +4861,7 @@ error_free_dyn:
+                                              &string_offset))
+                 goto error_return;
+               if (secdata->sec_info)
+-                stab->sec_info_type = ELF_INFO_TYPE_STABS;
++                stab->sec_info_type = SEC_INFO_TYPE_STABS;
+           }
+       }
+     }
+@@ -6644,25 +6644,14 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
+   return TRUE;
+ }
\f
+-/* Indicate that we are only retrieving symbol values from this
+-   section.  */
+-
+-void
+-_bfd_elf_link_just_syms (asection *sec, struct bfd_link_info *info)
+-{
+-  if (is_elf_hash_table (info->hash))
+-    sec->sec_info_type = ELF_INFO_TYPE_JUST_SYMS;
+-  _bfd_generic_link_just_syms (sec, info);
+-}
+-
+ /* Make sure sec_info_type is cleared if sec_info is cleared too.  */
+ static void
+ merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED,
+                           asection *sec)
+ {
+-  BFD_ASSERT (sec->sec_info_type == ELF_INFO_TYPE_MERGE);
+-  sec->sec_info_type = ELF_INFO_TYPE_NONE;
++  BFD_ASSERT (sec->sec_info_type == SEC_INFO_TYPE_MERGE);
++  sec->sec_info_type = SEC_INFO_TYPE_NONE;
+ }
+ /* Finish SHF_MERGE section merging.  */
+@@ -6690,7 +6679,7 @@ _bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info)
+                                         sec, &secdata->sec_info))
+             return FALSE;
+           else if (secdata->sec_info)
+-            sec->sec_info_type = ELF_INFO_TYPE_MERGE;
++            sec->sec_info_type = SEC_INFO_TYPE_MERGE;
+         }
+   if (elf_hash_table (info)->merge_info != NULL)
+@@ -8708,7 +8697,7 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
+   else if ((h->root.type == bfd_link_hash_defined
+           || h->root.type == bfd_link_hash_defweak)
+          && ((finfo->info->strip_discarded
+-              && elf_discarded_section (h->root.u.def.section))
++              && discarded_section (h->root.u.def.section))
+              || (h->root.u.def.section->owner != NULL
+                  && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0)))
+     strip = TRUE;
+@@ -9007,8 +8996,8 @@ elf_section_ignore_discarded_relocs (asection *sec)
+   switch (sec->sec_info_type)
+     {
+-    case ELF_INFO_TYPE_STABS:
+-    case ELF_INFO_TYPE_EH_FRAME:
++    case SEC_INFO_TYPE_STABS:
++    case SEC_INFO_TYPE_EH_FRAME:
+       return TRUE;
+     default:
+       break;
+@@ -9193,7 +9182,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
+             *ppsection = NULL;
+             continue;
+           }
+-        else if (isec->sec_info_type == ELF_INFO_TYPE_MERGE
++        else if (isec->sec_info_type == SEC_INFO_TYPE_MERGE
+                  && ELF_ST_TYPE (isym->st_info) != STT_SECTION)
+           isym->st_value =
+             _bfd_merged_section_offset (output_bfd, &isec,
+@@ -9537,7 +9526,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
+               {
+                 /* Complain if the definition comes from a
+                    discarded section.  */
+-                if ((sec = *ps) != NULL && elf_discarded_section (sec))
++                if ((sec = *ps) != NULL && discarded_section (sec))
+                   {
+                     BFD_ASSERT (r_symndx != STN_UNDEF);
+                     if (action_discarded & COMPLAIN)
+@@ -9874,19 +9863,19 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
+       }
+       else switch (o->sec_info_type)
+       {
+-      case ELF_INFO_TYPE_STABS:
++      case SEC_INFO_TYPE_STABS:
+         if (! (_bfd_write_section_stabs
+                (output_bfd,
+                 &elf_hash_table (finfo->info)->stab_info,
+                 o, &elf_section_data (o)->sec_info, contents)))
+           return FALSE;
+         break;
+-      case ELF_INFO_TYPE_MERGE:
++      case SEC_INFO_TYPE_MERGE:
+         if (! _bfd_write_merged_section (output_bfd, o,
+                                          elf_section_data (o)->sec_info))
+           return FALSE;
+         break;
+-      case ELF_INFO_TYPE_EH_FRAME:
++      case SEC_INFO_TYPE_EH_FRAME:
+         {
+           if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info,
+                                                  o, contents))
+@@ -12415,7 +12404,7 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
+         if ((h->root.type == bfd_link_hash_defined
+              || h->root.type == bfd_link_hash_defweak)
+-            && elf_discarded_section (h->root.u.def.section))
++            && discarded_section (h->root.u.def.section))
+           return TRUE;
+         else
+           return FALSE;
+@@ -12431,7 +12420,7 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
+         /* Need to: get the symbol; get the section.  */
+         isym = &rcookie->locsyms[r_symndx];
+         isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx);
+-        if (isec != NULL && elf_discarded_section (isec))
++        if (isec != NULL && discarded_section (isec))
+           return TRUE;
+       }
+       return FALSE;
+@@ -12482,7 +12471,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
+       if (stab != NULL
+         && (stab->size == 0
+             || bfd_is_abs_section (stab->output_section)
+-            || stab->sec_info_type != ELF_INFO_TYPE_STABS))
++            || stab->sec_info_type != SEC_INFO_TYPE_STABS))
+       stab = NULL;
+       if (stab == NULL
+diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c
+index 3e2ee0b..0f6b720 100644
+--- a/bfd/elfnn-ia64.c
++++ b/bfd/elfnn-ia64.c
+@@ -530,7 +530,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
+         symtype = h->type;
+       }
+-      if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
++      if (tsec->sec_info_type == SEC_INFO_TYPE_MERGE)
+       {
+         /* At this stage in linking, no SEC_MERGE symbol has been
+            adjusted, so all references to such symbols need to be
+@@ -3861,7 +3861,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
+         if (!info->relocatable
+             && (sym_sec->flags & SEC_MERGE) != 0
+             && ELF_ST_TYPE (sym->st_info) == STT_SECTION
+-            && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
++            && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+           {
+             struct elfNN_ia64_local_hash_entry *loc_h;
+@@ -3919,7 +3919,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
+           continue;
+       }
+-      if (sym_sec != NULL && elf_discarded_section (sym_sec))
++      if (sym_sec != NULL && discarded_section (sym_sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
+index fa906cd..7911050 100644
+--- a/bfd/elfxx-mips.c
++++ b/bfd/elfxx-mips.c
+@@ -9385,7 +9385,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+           sec = h->root.u.def.section;
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
+index 9a15124..f3c631e 100644
+--- a/bfd/elfxx-sparc.c
++++ b/bfd/elfxx-sparc.c
+@@ -2970,7 +2970,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
+           }
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c
+index c484562..e1c8946 100644
+--- a/bfd/elfxx-tilegx.c
++++ b/bfd/elfxx-tilegx.c
+@@ -2908,7 +2908,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+           }
+       }
+-      if (sec != NULL && elf_discarded_section (sec))
++      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
+diff --git a/bfd/linker.c b/bfd/linker.c
+index 7a01e11..e5d20b2 100644
+--- a/bfd/linker.c
++++ b/bfd/linker.c
+@@ -1,6 +1,6 @@
+ /* linker.c -- BFD linker routines
+    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+-   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
++   2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+    Free Software Foundation, Inc.
+    Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
+@@ -810,6 +810,7 @@ void
+ _bfd_generic_link_just_syms (asection *sec,
+                            struct bfd_link_info *info ATTRIBUTE_UNUSED)
+ {
++  sec->sec_info_type = SEC_INFO_TYPE_JUST_SYMS;
+   sec->output_section = bfd_abs_section_ptr;
+   sec->output_offset = sec->vma;
+ }
+diff --git a/bfd/reloc.c b/bfd/reloc.c
+index ef55cc3..e3f0343 100644
+--- a/bfd/reloc.c
++++ b/bfd/reloc.c
+@@ -6235,7 +6235,7 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
+         bfd_reloc_status_type r;
+         symbol = *(*parent)->sym_ptr_ptr;
+-        if (symbol->section && elf_discarded_section (symbol->section))
++        if (symbol->section && discarded_section (symbol->section))
+           {
+             bfd_byte *p;
+             static reloc_howto_type none_howto
+diff --git a/bfd/section.c b/bfd/section.c
+index 7c1f750..e60f247 100644
+--- a/bfd/section.c
++++ b/bfd/section.c
+@@ -382,11 +382,11 @@ CODE_FRAGMENT
+ .
+ .  {* Type of sec_info information.  *}
+ .  unsigned int sec_info_type:3;
+-.#define ELF_INFO_TYPE_NONE      0
+-.#define ELF_INFO_TYPE_STABS     1
+-.#define ELF_INFO_TYPE_MERGE     2
+-.#define ELF_INFO_TYPE_EH_FRAME  3
+-.#define ELF_INFO_TYPE_JUST_SYMS 4
++.#define SEC_INFO_TYPE_NONE      0
++.#define SEC_INFO_TYPE_STABS     1
++.#define SEC_INFO_TYPE_MERGE     2
++.#define SEC_INFO_TYPE_EH_FRAME  3
++.#define SEC_INFO_TYPE_JUST_SYMS 4
+ .
+ .  {* Nonzero if this section uses RELA relocations, rather than REL.  *}
+ .  unsigned int use_rela_p:1;
+diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
+index d29da59..7631474 100644
+--- a/ld/emultempl/armelf.em
++++ b/ld/emultempl/armelf.em
+@@ -240,7 +240,7 @@ build_section_lists (lang_statement_union_type *statement)
+     {
+       asection *i = statement->input_section.section;
+-      if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
++      if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+         && (i->flags & SEC_EXCLUDE) == 0
+         && i->output_section != NULL
+         && i->output_section->owner == link_info.output_bfd)
+@@ -299,7 +299,7 @@ gld${EMULATION_NAME}_after_allocation (void)
+                 && elf_section_type (sec) == SHT_PROGBITS
+                 && (elf_section_flags (sec) & SHF_EXECINSTR) != 0
+                 && (sec->flags & SEC_EXCLUDE) == 0
+-                && sec->sec_info_type != ELF_INFO_TYPE_JUST_SYMS
++                && sec->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+                 && out_sec != bfd_abs_section_ptr)
+               {
+                 if (sec_count == list_size)
+diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em
+index 1137ba2..6258bf4 100644
+--- a/ld/emultempl/hppaelf.em
++++ b/ld/emultempl/hppaelf.em
+@@ -229,7 +229,7 @@ build_section_lists (lang_statement_union_type *statement)
+     {
+       asection *i = statement->input_section.section;
+-      if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
++      if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+         && (i->flags & SEC_EXCLUDE) == 0
+         && i->output_section != NULL
+         && i->output_section->owner == link_info.output_bfd)
+diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
+index 92a468f..52b9f05 100644
+--- a/ld/emultempl/ppc64elf.em
++++ b/ld/emultempl/ppc64elf.em
+@@ -428,7 +428,7 @@ build_toc_list (lang_statement_union_type *statement)
+     {
+       asection *i = statement->input_section.section;
+-      if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
++      if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+         && (i->flags & SEC_EXCLUDE) == 0
+         && i->output_section == toc_section)
+       {
+@@ -446,7 +446,7 @@ build_section_lists (lang_statement_union_type *statement)
+     {
+       asection *i = statement->input_section.section;
+-      if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
++      if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+         && (i->flags & SEC_EXCLUDE) == 0
+         && i->output_section != NULL
+         && i->output_section->owner == link_info.output_bfd)
+diff --git a/ld/emultempl/tic6xdsbt.em b/ld/emultempl/tic6xdsbt.em
+index e287005..fd7a12b 100644
+--- a/ld/emultempl/tic6xdsbt.em
++++ b/ld/emultempl/tic6xdsbt.em
+@@ -122,7 +122,7 @@ gld${EMULATION_NAME}_after_allocation (void)
+                 && elf_section_type (sec) == SHT_PROGBITS
+                 && (elf_section_flags (sec) & SHF_EXECINSTR) != 0
+                 && (sec->flags & SEC_EXCLUDE) == 0
+-                && sec->sec_info_type != ELF_INFO_TYPE_JUST_SYMS
++                && sec->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+                 && out_sec != bfd_abs_section_ptr)
+               {
+                 if (sec_count == list_size)
+diff --git a/ld/ldlang.c b/ld/ldlang.c
+index 2c56b56..7ecbae2 100644
+--- a/ld/ldlang.c
++++ b/ld/ldlang.c
+@@ -4648,7 +4648,7 @@ size_input_section
+   lang_input_section_type *is = &((*this_ptr)->input_section);
+   asection *i = is->section;
+-  if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
++  if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+       && (i->flags & SEC_EXCLUDE) == 0)
+     {
+       unsigned int alignment_needed;
+diff --git a/ld/ldwrite.c b/ld/ldwrite.c
+index b7a1469..2503d1f 100644
+--- a/ld/ldwrite.c
++++ b/ld/ldwrite.c
+@@ -1,6 +1,6 @@
+ /* ldwrite.c -- write out the linked file
+    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002,
+-   2003, 2004, 2005, 2006, 2007, 2008, 2010
++   2003, 2004, 2005, 2006, 2007, 2008, 2010, 2012
+    Free Software Foundation, Inc.
+    Written by Steve Chamberlain sac@cygnus.com
+@@ -240,7 +240,7 @@ build_link_order (lang_statement_union_type *statement)
+          attached */
+       asection *i = statement->input_section.section;
+-      if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
++      if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
+           && (i->flags & SEC_EXCLUDE) == 0)
+         {
+           asection *output_section = i->output_section;
+-- 
+1.7.9.5
+