QNX MIPS Support Patch

Jeff Baker jbaker@qnx.com
Tue Sep 21 18:09:00 GMT 2004


Ping.

Jeff Baker wrote:
> Sorry it took so long to reply.  I got onto something else for a while. 
>   I've attached updated versions of all but the ugly mips patch.  I 
> separated the ChangeLog entries in each patch by dir and included 
> qnx_changelog.patch, which is all of the ChangeLogs merged together.
> 
> Thiemo Seufer wrote:
> 
> 
>>Jeff Baker wrote:
>>[snip]
>>
>>
>>>>>qnx_shared_textrel.patch - This patch adds the --warn-shared-textrel
>>
>>
>>>>>option to the linker.  This option, oddly enough, warns when a 
>>>>>DT_TEXTREL is being added to a shared object.
>>>>
>>>>I can't approve this one.
>>>
>>>Can't because it's not your area or can't because it's no good? 
>>
>>
>>It looks good IMHO, but it is outside the mips area.
>>
>>[snip]
>>
>>
>>>- A patch to add support for QNX MIPS PIC to the BFD.
>>>
>>>What is the accepted way of switching on our modifications without
>>
>>using 
>>
>>
>>>the ifdefs (they were never meant to be permanent, I just don't know
>>
>>how 
>>
>>
>>>else to do it yet)?
>>
>>
>>The object files should have some identification as being QNX PIC
>>specific (probably a .note section?), and BFD should switch
>>behaviour accordingly.
>>
>>[snip]
>>
>>
>>>2004-08-26  Jeff Baker  <jbaker@qnx.com>
>>>
>>>	* bfd/libbfd.h: Add new reloc: R_MIPS_QNX_COPY.
>>>	* bfd/elf32-mips.c: Likewise.
>>>	* bfd/bfd-in2.h: Likewise.
>>>	* bfd/reloc.c: Likewise.
>>>	* include/elf/mips.h: Likewise.
>>
>>
>>Ok, but note that bfd/ChangeLog and include/elf/ChangeLog are in
>>different subdirectories. When you commit, add the entry to the
> 
> nearest
> 
>>ChangeLog in the tree, with proper relative paths. E.g. for bfd:
>>
>>2004-08-26  Jeff Baker  <jbaker@qnx.com>
>>
>>	* libbfd.h: Add new reloc: R_MIPS_QNX_COPY.
>>	* elf32-mips.c: Likewise.
>>	* bfd-in2.h: Likewise.
>>	* reloc.c: Likewise.
>>
>>[snip]
>>
>>
>>>2004-08-26  Jeff Baker  <jbaker@qnx.com>
>>>	* config/tc-mips.c (QNX_GP_REG): Define.
>>>	(load_address): Added code to handle QNX_PIC pic level.
>>>	(macro): Likewise.
>>>	(mips_validate_fix): Likewise.
>>>	(mips_fix_adjustable): Likewise.
>>>	(s_cpsetup): Likewise.
>>>	(s_cplocal): Likewise.
>>>	(s_cprestore): Likewise.
>>>	(s_cpreturn): Likewise.
>>>	(s_cpadd): Likewise.
>>>	(s_gpvalue): Likewise.
>>>	(s_gpword): Likewise.
>>>	(s_gpdword): Likewise.
>>>	(md_longopts): Define qnx_pic command line argument.
>>>	(md_parse_option): Handle qnx_pic command line argument. 
>>>	(s_qnxpiccalls): New function.
>>>	(s_noqnxpiccalls): New function.
>>>	* config/tc-mips.h (mips_pic_level): Add QNX_PIC pic
>>>	level.
>>
>>[snip]
>>
>>
>>>@@ -3877,21 +3882,21 @@ load_address (int reg, expressionS *ep, 
>>>			   mips_gp_register, BFD_RELOC_GPREL16);
>>>	      relax_switch ();
>>>	    }
>>>	  macro_build_lui (ep, reg);
>>>	  macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j",
>>>		       reg, reg, BFD_RELOC_LO16);
>>>	  if (mips_relax.sequence)
>>>	    relax_end ();
>>>	}
>>>    }
>>>-  else if (mips_pic == SVR4_PIC && ! mips_big_got)
>>>+  else if ((mips_pic == SVR4_PIC || mips_pic == QNX_PIC) && !
>>
>>mips_big_got)
>>
>>A common mips_pic_p macro would be nicer.
>>
>>[snip]
>>
>>
>>>@@ -5062,21 +5067,21 @@ macro (struct mips_cl_insn *ip)
>>>		  load_delay_nop ();
>>>		  macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
>>>			       treg, AT, breg);
>>>		  breg = 0;
>>>		  tempreg = treg;
>>>		}
>>>	      add_got_offset_hilo (tempreg, &offset_expr, AT);
>>>	      used_at = 1;
>>>	    }
>>>	}
>>>-      else if (mips_pic == SVR4_PIC && ! mips_big_got && HAVE_NEWABI)
>>>+      else if ((mips_pic == SVR4_PIC || mips_pic == QNX_PIC) && !
>>
>>mips_big_got && HAVE_NEWABI)
>>
>>Is there some plan to implement a NewABI variant as well? If yes,
>>add at least a TODO comment to the relevant s_cp*/s_gp* functions.
>>If no, don't check for QNX_PIC in NewABI code.
>>
>>[snip]
>>
>>
>>>@@ -5467,61 +5472,64 @@ macro (struct mips_cl_insn *ip)
>>>
>>>      /* The jal instructions must be handled as macros because when
>>>	 generating PIC code they expand to multi-instruction
>>>	 sequences.  Normally they are simple instructions.  */
>>>    case M_JAL_1:
>>>      dreg = RA;
>>>      /* Fall through.  */
>>>    case M_JAL_2:
>>>      if (mips_pic == NO_PIC)
>>>	macro_build (NULL, "jalr", "d,s", dreg, sreg);
>>>-      else if (mips_pic == SVR4_PIC)
>>>+      else if (mips_pic == SVR4_PIC || mips_pic == QNX_PIC)
>>>	{
>>>-	  if (sreg != PIC_CALL_REG)
>>>+	  if ((sreg != PIC_CALL_REG) && (mips_pic != QNX_PIC))
>>>	    as_warn (_("MIPS PIC call to register other than $25"));
>>
>>
>>Does QNX PIC use different registers for calls?
>>
>>[snip]
>>
>>
>>>@@ -5578,20 +5586,28 @@ macro (struct mips_cl_insn *ip)
>>>		  relax_end ();
>>>		}
>>>
>>>	      macro_build_jalr (&offset_expr);
>>>	    }
>>>	  else
>>>	    {
>>>	      relax_start (offset_expr.X_add_symbol);
>>>	      if (! mips_big_got)
>>>		{
>>>+	      if(mips_pic != QNX_PIC)
>>>+                macro_build (&offset_expr,
>>>+                     ((bfd_arch_bits_per_address (stdoutput) == 32
>>>+                           || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
>>>+                          ? "lw" : "ld"),
>>>+                     "t,o(b)", PIC_CALL_REG,
>>>+                     (int) BFD_RELOC_MIPS_CALL16, mips_gp_register);
>>>+	      else
>>>		  macro_build (&offset_expr, ADDRESS_LOAD_INSN,
>>
>>"t,o(b)",
>>
>>
>>>			       PIC_CALL_REG, BFD_RELOC_MIPS_CALL16,
>>>			       mips_gp_register);
>>
>>
>>This chunk is apparently some old code, and completely superfluous.
>>
>>[snip]
>>
>>
>>>@@ -10120,20 +10138,22 @@ struct option md_longopts[] =
>>>#define OPTION_64          (OPTION_ELF_BASE + 6)
>>>  {"64",          no_argument, NULL, OPTION_64},
>>>#define OPTION_MDEBUG      (OPTION_ELF_BASE + 7)
>>>  {"mdebug", no_argument, NULL, OPTION_MDEBUG},
>>>#define OPTION_NO_MDEBUG   (OPTION_ELF_BASE + 8)
>>>  {"no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG},
>>>#define OPTION_PDR	   (OPTION_ELF_BASE + 9)
>>>  {"mpdr", no_argument, NULL, OPTION_PDR},
>>>#define OPTION_NO_PDR	   (OPTION_ELF_BASE + 10)
>>>  {"mno-pdr", no_argument, NULL, OPTION_NO_PDR},
>>>+#define OPTION_QNX_PIC	   (OPTION_ELF_BASE + 11)
>>>+  {"qnx_pic", no_argument, NULL, OPTION_QNX_PIC},
>>>#endif /* OBJ_ELF */
>>
>>[snip]
>>
>>
>>>+    case OPTION_QNX_PIC:
>>>+      if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
>>>+        {
>>>+          as_bad ("-qnx_pic is supported only for ELF format");
>>>+          return 0;
>>>+        }
>>
>>
>>I would prefer more gcc-like options, with an inverse, and probably
>>without underscore. E.g:
>>
>>-mqnx-pic
>>-mno-qnx-pic
>>
>>If that causes a problem with backward compatibility, -qnx_pic could
> 
> be
> 
>>retained as alias for -mqnx-pic.
>>
>>[snip]
>>
>>
>>>/* Handle the .cpload pseudo-op.  This is used when generating SVR4
>>>   PIC code.  It sets the $gp register for the function based on the
>>>   function address, which is in the register named in the argument.
>>>   This uses a relocation against _gp_disp, which is handled
>>
>>specially
>>
>>
>>>   by the linker.  The result is:
>>>	lui	$gp,%hi(_gp_disp)
>>>	addiu	$gp,$gp,%lo(_gp_disp)
>>>	addu	$gp,$gp,.cpload argument
>>>-   The .cpload argument is normally $25 == $t9.  */
>>>+   The .cpload argument is normally $25 == $t9. 
>>>+
>>>+   In the case of QNX pic code, we always compute the full address
>>>+   of the GOT, therefore we do:
>>>+        bltzal 0, 0f
>>>+        nop
>>>+    0:  lui     $23, %hi(_gp_disp)
>>>+        addiu   $23, $23, %lo(_gp_disp)
>>>+        addu    $23, $23, $31
>>>+    One possible optimization would be to move the opcode
>>>+    right before the bltzal into the nop slot. */
>>
>>
>>Below, this optimization is done, so the comment should reflect that.
>>Out of curiosity: Why isn't simply the lui moved into the branch delay
>>slot? At least it would always be a valid optimization.
>>
>>
>>
>>>static void
>>>s_cpload (int ignore ATTRIBUTE_UNUSED)
>>>{
>>>  expressionS ex;
>>>
>>>  /* If we are not generating SVR4 PIC code, or if this is NewABI
>>
>>code,
>>
>>
>>>     .cpload is ignored.  */
>>>-  if (mips_pic != SVR4_PIC || HAVE_NEWABI)
>>>+  if ((mips_pic != SVR4_PIC && mips_pic != QNX_PIC) || HAVE_NEWABI)
>>>    {
>>>      s_ignore (0);
>>>      return;
>>>    }
>>>
>>>  /* .cpload should be in a .set noreorder section.  */
>>>-  if (mips_opts.noreorder == 0)
>>>+  if ((mips_opts.noreorder == 0) && (mips_pic != QNX_PIC))
>>>    as_warn (_(".cpload not in noreorder section"));
>>>
>>>  ex.X_op = O_symbol;
>>>  ex.X_add_symbol = symbol_find_or_make ("_gp_disp");
>>>  ex.X_op_symbol = NULL;
>>>  ex.X_add_number = 0;
>>>
>>>  /* In ELF, this symbol is implicitly an STT_OBJECT symbol.  */
>>>  symbol_get_bfdsym (ex.X_add_symbol)->flags |= BSF_OBJECT;
>>>
>>>+  if (mips_pic == QNX_PIC) {
>>>+        expressionS ep;
>>>+        /* In our case, we do a bltzal first to get the current IP,
>>
>>and
>>
>>In MIPS lingua, it is "PC", not "IP". :-)
>>
>>
>>
>>>+         * then add the offset to the got... Thus, we always do
>>
>>"cpload $31"
>>
>>
>>>+         */
>>>+        ep.X_op = O_constant;
>>>+        ep.X_add_number = 4;
>>>+        tc_get_register(0);  // Flush any arg to cpload...
>>
>>
>>No C99 comments, please.
>>
>>
>>
>>>+        /* See if we can swap the bltzal with the previous insn and
>>
>>save
>>
>>
>>>+         * the nop...
>>>+         * For simplicity, we only check that the insn is a move or
>>
>>sw,
>>
>>
>>>+         * which are really the only two we should encounter.
>>>+         * If it is anything else, we don't swap for now.
>>>+         */
>>>+        if(0 && (mips_optimize > 1)
>>>+                && prev_insn_valid
>>>+                && (mips_opts.isa > 1)
>>>+                && !(mips_opts.noreorder)
>>>+                && (((prev_insn.insn_opcode & 0xfc1f07ff) ==
>>
>>0x00000021)
>>
>>
>>>+                  || ((prev_insn.insn_opcode & 0xfc000000) ==
>>
>>0xac000000)))
>>
>>
>>>+          {
>>>+                  char *prev_f;
>>>+                  char temp[4];
>>>+
>>>+                  prev_f = prev_insn_frag->fr_literal +
>>
>>prev_insn_where;
>>
>>
>>>+                  memcpy (temp, prev_f, 4);
>>>+                  *(unsigned long *)(prev_f) = 0x04100001;
>>>+                  macro_build (&ep,
>>>+                       "bltzal", "s,p", 0);
>>
>>
>>Formatting, ...
>>
>>
>>
>>>+                  prev_f = prev_insn_frag->fr_literal +
>>
>>prev_insn_where;
>>
>>
>>>+                  memcpy (prev_f, temp, 4);
>>>+                  mips_opts.noreorder ++;
>>
>>                                        ^
>>..., formatting, ...
>>
>>
>>
>>>+          }
>>>+        else
>>>+          {     /* We need a NOP... */
>>>+                mips_opts.noreorder ++;
>>>+                macro_build (&ep,
>>>+                       "bltzal", "s,p", 0);
>>>+                macro_build ((expressionS *) NULL, "nop", "");
>>
>>
>>..., old K&R casts, ...
>>
>>
>>
>>>+          }
>>>+        macro_build_lui (&ex, 23);
>>>+        macro_build (&ex, "addiu", "t,r,j", 23, 23,
>>>+                       (int) BFD_RELOC_LO16);
>>
>>
>>..., and magic constants instead of QNX_GP_REG aka mips_gp_register,
> 
> ...
> 
>>
>>>+        mips_opts.noreorder --;
>>>+
>>>+        macro_build ((expressionS *) NULL, "addu", "d,v,t",
>>>+                       23, 23, RA);
>>>+  } else
>>>+  {
>>>+
>>>  macro_start ();
>>>  macro_build_lui (&ex, mips_gp_register);
>>>  macro_build (&ex, "addiu", "t,r,j", mips_gp_register,
>>>	       mips_gp_register, BFD_RELOC_LO16);
>>>  macro_build (NULL, "addu", "d,v,t", mips_gp_register,
>>>	       mips_gp_register, tc_get_register (0));
>>>  macro_end ();
>>>+}
>>
>>
>>... and a suspiciously absent macro_start()/macro_end() pair.
>>
>>[snip]
>>
>>
>>>@@ -12743,20 +12869,28 @@ mips_fix_adjustable (fixS *fixp)
>>>  if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
>>>    return 0;
>>>
>>>  if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
>>>      || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
>>>    return 0;
>>>
>>>  if (fixp->fx_addsy == NULL)
>>>    return 1;
>>>
>>>+  if ((mips_pic == QNX_PIC) &&
>>>+        (fixp->fx_r_type == BFD_RELOC_MIPS_GOT16 || fixp->fx_r_type
>>
>>== BFD_RELOC_32))
>>
>>Line length formatting.
>>
>>[snip]
>>
>>
>>>2004-08-26  Jeff Baker <jbaker@qnx.com>
>>>	* ltconfig (nto-qnx*): Add support for QNX OS suffix.
>>>	* bfd/config.bfd (mips*eb-*-nto*): New target.
>>>	(mips*-*-nto*): New target.
>>>	* gas/configure (mips*-*-nto*): New target.
>>>	* gas/configure.in: Likewise.
>>>	* ld/Makefile.am: Add targets for QNX MIPS emulation files.
>>>	* ld/Makefile.in: Likewise.
>>>	* ld/configure.tgt(mips*-*-nto*): New target.
>>>	* ld/emulparams/elf32bmipnto.sh: New file. QNX MIPS
>>>	emulation.
>>>	* ld/emulparams/elf32lmipnto.sh: New file. QNX MIPS
>>>	emulation.
>>
>>
>>This also needs to be split in the respective subdirectory's
> 
> ChangeLogs.
> 
>>[snip]
>>
>>
>>>--- bfd/config.bfd	19 Aug 2004 18:09:44 -0000	1.169
>>>+++ bfd/config.bfd	26 Aug 2004 19:45:29 -0000
>>>@@ -829,20 +829,30 @@ case "${targ}" in
>>>    targ_selvecs=ecoff_little_vec
>>>    ;;
>>>  mips*el-*-elf* | mips*el-*-rtems* | mips*el-*-vxworks* |
>>
>>mips*-*-chorus*)
>>
>>
>>>    targ_defvec=bfd_elf32_littlemips_vec
>>>    targ_selvecs="bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec
>>
>>bfd_elf64_littlemips_vec"
>>
>>
>>>    ;;
>>>  mips*-*-elf* | mips*-*-rtems* | mips*-*-vxworks | mips*-*-windiss)
>>>    targ_defvec=bfd_elf32_bigmips_vec
>>>    targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec
>>
>>bfd_elf64_littlemips_vec"
>>
>>
>>>    ;;
>>>+  mips*eb-*-nto*)
>>>+    targ_defvec=bfd_elf32_bigmips_vec
>>>+    targ_selvecs="bfd_elf32_littlemips_vec"
>>>+    targ_cflags=-D__QNXTARGET__
>>>+    ;;
>>>+  mips*-*-nto*)
>>>+    targ_defvec=bfd_elf32_littlemips_vec
>>>+    targ_selvecs="bfd_elf32_bigmips_vec"
>>>+    targ_cflags=-D__QNXTARGET__
>>>+    ;;
>>
>>
>>Please don't define __QNXTARGET__. :-)
>>
>>[snip]
>>
>>
>>>Index: ld/configure.tgt
>>>===================================================================
>>>RCS file: /cvs/src/src/ld/configure.tgt,v
>>>retrieving revision 1.154
>>>diff -w -u -1 -0 -p -r1.154 configure.tgt
>>>--- ld/configure.tgt	19 Aug 2004 18:11:42 -0000	1.154
>>>+++ ld/configure.tgt	26 Aug 2004 19:45:35 -0000
>>>@@ -421,20 +421,23 @@ mips*-*-netbsd*)	targ_emul=elf32bmip
>>>			;;
>>>mips*-*-bsd*)		targ_emul=mipsbig ;;
>>>mips*vr4300el-*-elf*)	targ_emul=elf32l4300 ;;
>>>mips*vr4300-*-elf*)	targ_emul=elf32b4300 ;;
>>>mips*vr4100el-*-elf*)	targ_emul=elf32l4300 ;;
>>>mips*vr4100-*-elf*)	targ_emul=elf32b4300 ;;
>>>mips*vr5000el-*-elf*)	targ_emul=elf32l4300 ;;
>>>mips*vr5000-*-elf*)	targ_emul=elf32b4300 ;;
>>>mips*el-*-elf*)		targ_emul=elf32elmip ;;
>>>mips*-*-elf*)		targ_emul=elf32ebmip ;;
>>>+mips*-*-nto*)		targ_emul=elf32lmipnto
>>>+			targ_extra_emuls="elf32bmipnto"
>>>+			;;
>>
>>
>>I think this wants an additional mips*eb*-*-nto* with the big endian
>>emulation as default.
>>
>>
>>Thiemo
> 
> 
> 
> ------------------------------------------------------------------------
> 
> (/)
> 2004-09-13  Jeff Baker <jbaker@qnx.com>
> 	* ltconfig (nto-qnx*): Add support for QNX OS suffix.
> 
> (/bfd)
> 2004-09-13  Jeff Baker  <jbaker@qnx.com>
> 	* config.bfd (mips*eb-*-nto*): New target.
> 	(mips*-*-nto*): New target.	
> 	* libbfd.h: Add new reloc: R_MIPS_QNX_COPY.
> 	* elf32-mips.c: Likewise.
> 	* bfd-in2.h: Likewise.
> 	* reloc.c: Likewise.
> 	* elflink.c (_bfd_elf_add_dynamic_entry): Add code to
> 	warn if adding a DT_TEXTREL to a shared object and
> 	--warn-shared-textrel was specified
> 
> (/include)
> 2004-09-13  Jeff Baker  <jbaker@qnx.com>
> 	* bfdlink.h (bfd_link_info): Add boolean
> 	warn_shared_textrel.
> 
> (/include/elf)
> 2004-09-13  Jeff Baker  <jbaker@qnx.com>
> 	* mips.h: Add new reloc: R_MIPS_QNX_COPY
> 
> (/gas)
> 2004-08-26  Jeff Baker  <jbaker@qnx.com>
> 	* configure (mips*-*-nto*): New target.
> 	* configure.in: Likewise.
> 	* config/tc-mips.c (QNX_GP_REG): Define.
> 	(mips_pic_p): Define.
> 	(load_address): Added code to handle QNX_PIC pic level.
> 	(macro): Likewise.
> 	(mips_validate_fix): Likewise.
> 	(mips_fix_adjustable): Likewise.
> 	(s_cpsetup): Likewise.
> 	(s_cplocal): Likewise.
> 	(s_cprestore): Likewise.
> 	(s_cpreturn): Likewise.
> 	(s_cpadd): Likewise.
> 	(s_gpvalue): Likewise.
> 	(s_gpword): Likewise.
> 	(s_gpdword): Likewise.
> 	(md_estimate_size_before_relax): Likewise.
> 	(md_longopts): Define qnx_pic command line argument.
> 	(md_parse_option): Handle qnx_pic command line argument. 
> 	(s_qnxpiccalls): New function.
> 	(s_noqnxpiccalls): New function.
> 	* config/tc-mips.h (mips_pic_level): Add QNX_PIC pic
> 	level.
> 
> (/ld)
> 2004-09-13  Jeff Baker <jbaker@qnx.com>
> 	* Makefile.am: Add targets for QNX MIPS emulation files.
> 	* Makefile.in: Likewise.
> 	* configure.tgt(mips*-*-nto*): New target.
> 	(mips*eb*-*-nto*): New target. 
> 	* emulparams/elf32bmipnto.sh: New file. QNX MIPS
> 	emulation.
> 	* emulparams/elf32lmipnto.sh: New file. QNX MIPS
> 	emulation
> 	* lexsup.c: Handle --warn-shared-textrel option.
> 
> 
> ------------------------------------------------------------------------
> 
> 2004-09-13  Jeff Baker  <jbaker@qnx.com>
> 	* libbfd.h: Add new reloc: R_MIPS_QNX_COPY.
> 	* elf32-mips.c: Likewise.
> 	* bfd-in2.h: Likewise.
> 	* reloc.c: Likewise.
> 
> 2004-09-13  Jeff Baker  <jbaker@qnx.com>
> 	* mips.h: Add new reloc: R_MIPS_QNX_COPY.
> 
> Index: bfd/libbfd.h
> ===================================================================
> RCS file: /cvs/src/src/bfd/libbfd.h,v
> retrieving revision 1.123
> diff -w -u -1 -0 -p -r1.123 libbfd.h
> --- bfd/libbfd.h	28 Aug 2004 03:05:18 -0000	1.123
> +++ bfd/libbfd.h	13 Sep 2004 18:27:28 -0000
> @@ -912,21 +912,21 @@ static const char *const bfd_reloc_code_
>    "BFD_RELOC_MIPS_SHIFT6",
>    "BFD_RELOC_MIPS_INSERT_A",
>    "BFD_RELOC_MIPS_INSERT_B",
>    "BFD_RELOC_MIPS_DELETE",
>    "BFD_RELOC_MIPS_HIGHEST",
>    "BFD_RELOC_MIPS_HIGHER",
>    "BFD_RELOC_MIPS_SCN_DISP",
>    "BFD_RELOC_MIPS_REL16",
>    "BFD_RELOC_MIPS_RELGOT",
>    "BFD_RELOC_MIPS_JALR",
> -
> +  "BFD_RELOC_MIPS_QNX_COPY",
>    "BFD_RELOC_FRV_LABEL16",
>    "BFD_RELOC_FRV_LABEL24",
>    "BFD_RELOC_FRV_LO16",
>    "BFD_RELOC_FRV_HI16",
>    "BFD_RELOC_FRV_GPREL12",
>    "BFD_RELOC_FRV_GPRELU12",
>    "BFD_RELOC_FRV_GPREL32",
>    "BFD_RELOC_FRV_GPRELHI",
>    "BFD_RELOC_FRV_GPRELLO",
>    "BFD_RELOC_FRV_GOT12",
> Index: bfd/elf32-mips.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/elf32-mips.c,v
> retrieving revision 1.178
> diff -w -u -1 -0 -p -r1.178 elf32-mips.c
> --- bfd/elf32-mips.c	29 Jun 2004 13:46:30 -0000	1.178
> +++ bfd/elf32-mips.c	13 Sep 2004 18:27:36 -0000
> @@ -592,20 +592,41 @@ static reloc_howto_type elf_mips16_gprel
>  	 FALSE,			/* pc_relative */
>  	 0,			/* bitpos */
>  	 complain_overflow_signed, /* complain_on_overflow */
>  	 mips16_gprel_reloc,	/* special_function */
>  	 "R_MIPS16_GPREL",	/* name */
>  	 TRUE,			/* partial_inplace */
>  	 0x07ff001f,		/* src_mask */
>  	 0x07ff001f,	        /* dst_mask */
>  	 FALSE);		/* pcrel_offset */
>  
> +/* Do a QNX pic copy relocation. This is used only with dynamic linking.
> +   This works in the same way as copy relocs on other platforms: the data
> +   object must exist both in the object and in the shared lib. The dynamic
> +   linker copies the data from the shared object to the executable at runtime.
> +   This is needed because the exec. does not access the data through the GOT.
> +   */
> +static reloc_howto_type elf_mips_qnx_copy_howto =
> +  HOWTO (R_MIPS_QNX_COPY,       /* type */
> +         0,                     /* rightshift */
> +         2,                     /* size (0 = byte, 1 = short, 2 = long) */
> +         32,                    /* bitsize */
> +         FALSE,                 /* pc_relative */
> +         0,                     /* bitpos */
> +         complain_overflow_bitfield, /* complain_on_overflow */
> +         bfd_elf_generic_reloc, /* special_function */
> +         "R_MIPS_QNX_COPY",     /* name */
> +         FALSE,                 /* partial_inplace */
> +         0,                     /* src_mask */
> +         0,                     /* dst_mask */
> +         FALSE);                /* pcrel_offset */
> +
>  /* 16 bit offset for pc-relative branches.  */
>  static reloc_howto_type elf_mips_gnu_rel16_s2 =
>    HOWTO (R_MIPS_GNU_REL16_S2,	/* type */
>  	 2,			/* rightshift */
>  	 2,			/* size (0 = byte, 1 = short, 2 = long) */
>  	 16,			/* bitsize */
>  	 TRUE,			/* pc_relative */
>  	 0,			/* bitpos */
>  	 complain_overflow_signed, /* complain_on_overflow */
>  	 _bfd_mips_elf_generic_reloc, /* special_function */
> @@ -1039,21 +1060,22 @@ static const struct elf_reloc_map mips_r
>    { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
>    { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
>    { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
>    { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
>    { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
>    { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
>    { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
>    { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
>    { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
>    { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
> -  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP }
> +  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
> +  { BFD_RELOC_MIPS_QNX_COPY, R_MIPS_QNX_COPY }
>  };
>  
>  /* Given a BFD reloc type, return a howto structure.  */
>  
>  static reloc_howto_type *
>  bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
>  {
>    unsigned int i;
>    reloc_howto_type *howto_table = elf_mips_howto_table_rel;
> Index: bfd/bfd-in2.h
> ===================================================================
> RCS file: /cvs/src/src/bfd/bfd-in2.h,v
> retrieving revision 1.298
> diff -w -u -1 -0 -p -r1.298 bfd-in2.h
> --- bfd/bfd-in2.h	28 Aug 2004 03:05:18 -0000	1.298
> +++ bfd/bfd-in2.h	13 Sep 2004 18:27:44 -0000
> @@ -2361,20 +2361,21 @@ to compensate for the borrow when the lo
>    BFD_RELOC_MIPS_SHIFT6,
>    BFD_RELOC_MIPS_INSERT_A,
>    BFD_RELOC_MIPS_INSERT_B,
>    BFD_RELOC_MIPS_DELETE,
>    BFD_RELOC_MIPS_HIGHEST,
>    BFD_RELOC_MIPS_HIGHER,
>    BFD_RELOC_MIPS_SCN_DISP,
>    BFD_RELOC_MIPS_REL16,
>    BFD_RELOC_MIPS_RELGOT,
>    BFD_RELOC_MIPS_JALR,
> +  BFD_RELOC_MIPS_QNX_COPY,
>  
>  
>  /* Fujitsu Frv Relocations.  */
>    BFD_RELOC_FRV_LABEL16,
>    BFD_RELOC_FRV_LABEL24,
>    BFD_RELOC_FRV_LO16,
>    BFD_RELOC_FRV_HI16,
>    BFD_RELOC_FRV_GPREL12,
>    BFD_RELOC_FRV_GPRELU12,
>    BFD_RELOC_FRV_GPREL32,
> Index: bfd/reloc.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/reloc.c,v
> retrieving revision 1.111
> diff -w -u -1 -0 -p -r1.111 reloc.c
> --- bfd/reloc.c	25 Aug 2004 12:54:14 -0000	1.111
> +++ bfd/reloc.c	13 Sep 2004 18:27:51 -0000
> @@ -2105,20 +2105,22 @@ ENUMX
>  ENUMX
>    BFD_RELOC_MIPS_HIGHER
>  ENUMX
>    BFD_RELOC_MIPS_SCN_DISP
>  ENUMX
>    BFD_RELOC_MIPS_REL16
>  ENUMX
>    BFD_RELOC_MIPS_RELGOT
>  ENUMX
>    BFD_RELOC_MIPS_JALR
> +ENUMX
> +  BFD_RELOC_MIPS_QNX_COPY
>  ENUMDOC
>    MIPS ELF relocations.
>  COMMENT
>  
>  ENUM
>    BFD_RELOC_FRV_LABEL16
>  ENUMX
>    BFD_RELOC_FRV_LABEL24
>  ENUMX
>    BFD_RELOC_FRV_LO16
> Index: include/elf/mips.h
> ===================================================================
> RCS file: /cvs/src/src/include/elf/mips.h,v
> retrieving revision 1.23
> diff -w -u -1 -0 -p -r1.23 mips.h
> --- include/elf/mips.h	14 Jun 2004 18:25:10 -0000	1.23
> +++ include/elf/mips.h	13 Sep 2004 18:28:08 -0000
> @@ -69,20 +69,22 @@ START_RELOC_NUMBERS (elf_mips_reloc_type
>    RELOC_NUMBER (R_MIPS_SCN_DISP, 32)
>    RELOC_NUMBER (R_MIPS_REL16, 33)
>    RELOC_NUMBER (R_MIPS_ADD_IMMEDIATE, 34)
>    RELOC_NUMBER (R_MIPS_PJUMP, 35)
>    RELOC_NUMBER (R_MIPS_RELGOT, 36)
>    RELOC_NUMBER (R_MIPS_JALR, 37)
>    RELOC_NUMBER (R_MIPS_max, 38)
>    /* These relocs are used for the mips16.  */
>    RELOC_NUMBER (R_MIPS16_26, 100)
>    RELOC_NUMBER (R_MIPS16_GPREL, 101)
> +  /* And this is used with QNX pic for data copy relocs */
> +  RELOC_NUMBER (R_MIPS_QNX_COPY, 126)
>    /* This was a GNU extension used by embedded-PIC.  It was co-opted by
>       mips-linux for exception-handling data.  It is no longer used, but
>       should continue to be supported by the linker for backward
>       compatibility.  (GCC stopped using it in May, 2004.)  */
>    RELOC_NUMBER (R_MIPS_PC32, 248)
>    /* FIXME: this relocation is used internally by gas.  */
>    RELOC_NUMBER (R_MIPS_GNU_REL16_S2, 250)
>    /* These are GNU extensions to enable C++ vtable garbage collection.  */
>    RELOC_NUMBER (R_MIPS_GNU_VTINHERIT, 253)
>    RELOC_NUMBER (R_MIPS_GNU_VTENTRY, 254)
> 
> 
> ------------------------------------------------------------------------
> 
> 2004-08-26  Jeff Baker  <jbaker@qnx.com>
> 	* config/tc-mips.c (QNX_GP_REG): Define.
> 	(mips_pic_p): Define.
> 	(load_address): Added code to handle QNX_PIC pic level.
> 	(macro): Likewise.
> 	(mips_validate_fix): Likewise.
> 	(mips_fix_adjustable): Likewise.
> 	(s_cpsetup): Likewise.
> 	(s_cplocal): Likewise.
> 	(s_cprestore): Likewise.
> 	(s_cpreturn): Likewise.
> 	(s_cpadd): Likewise.
> 	(s_gpvalue): Likewise.
> 	(s_gpword): Likewise.
> 	(s_gpdword): Likewise.
> 	(md_estimate_size_before_relax): Likewise.
> 	(md_longopts): Define qnx_pic command line argument.
> 	(md_parse_option): Handle qnx_pic command line argument. 
> 	(s_qnxpiccalls): New function.
> 	(s_noqnxpiccalls): New function.
> 	* config/tc-mips.h (mips_pic_level): Add QNX_PIC pic
> 	level
> 
> Index: gas/config/tc-mips.c
> ===================================================================
> RCS file: /cvs/src/src/gas/config/tc-mips.c,v
> retrieving revision 1.270
> diff -w -u -1 -0 -p -r1.270 tc-mips.c
> --- gas/config/tc-mips.c	18 Aug 2004 15:58:11 -0000	1.270
> +++ gas/config/tc-mips.c	13 Sep 2004 18:37:52 -0000
> @@ -84,20 +84,21 @@ int mips_flag_pdr = TRUE;
>  #endif
>  
>  #include "ecoff.h"
>  
>  #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
>  static char *mips_regmask_frag;
>  #endif
>  
>  #define ZERO 0
>  #define AT  1
> +#define QNX_GP_REG 23
>  #define TREG 24
>  #define PIC_CALL_REG 25
>  #define KT0 26
>  #define KT1 27
>  #define GP  28
>  #define SP  29
>  #define FP  30
>  #define RA  31
>  
>  #define ILLEGAL_REG (32)
> @@ -376,20 +377,22 @@ static int mips_32bitmode = 0;
>     from coprocessor registers after they are loaded from memory, and
>     thus does not require nops to be inserted.  This applies to
>     instructions marked INSN_COPROC_MEMORY_DELAY.  These nops are only
>     requires at MIPS ISA level I.  */
>  #define cop_mem_interlocks (mips_opts.isa != ISA_MIPS1)
>  
>  /* Is this a mfhi or mflo instruction?  */
>  #define MF_HILO_INSN(PINFO) \
>            ((PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO))
>  
> +#define mips_pic_p (mips_pic == SVR4_PIC || mips_pic == QNX_PIC)
> +
>  /* MIPS PIC level.  */
>  
>  enum mips_pic_level mips_pic;
>  
>  /* 1 if we should generate 32 bit offsets from the $gp register in
>     SVR4_PIC mode.  Currently has no meaning in other modes.  */
>  static int mips_big_got = 0;
>  
>  /* 1 if trap instructions should used for overflow rather than break
>     instructions.  */
> @@ -877,20 +880,22 @@ static size_t my_getSmallExpression
>  static void my_getExpression (expressionS *, char *);
>  static void s_align (int);
>  static void s_change_sec (int);
>  static void s_change_section (int);
>  static void s_cons (int);
>  static void s_float_cons (int);
>  static void s_mips_globl (int);
>  static void s_option (int);
>  static void s_mipsset (int);
>  static void s_abicalls (int);
> +static void s_qnxpiccalls PARAMS ((int));
> +static void s_noqnxpiccalls PARAMS ((int));
>  static void s_cpload (int);
>  static void s_cpsetup (int);
>  static void s_cplocal (int);
>  static void s_cprestore (int);
>  static void s_cpreturn (int);
>  static void s_gpvalue (int);
>  static void s_gpword (int);
>  static void s_gpdword (int);
>  static void s_cpadd (int);
>  static void s_insn (int);
> @@ -943,20 +948,22 @@ static const struct mips_cpu_info *mips_
>  
>  static const pseudo_typeS mips_pseudo_table[] =
>  {
>    /* MIPS specific pseudo-ops.  */
>    {"option", s_option, 0},
>    {"set", s_mipsset, 0},
>    {"rdata", s_change_sec, 'r'},
>    {"sdata", s_change_sec, 's'},
>    {"livereg", s_ignore, 0},
>    {"abicalls", s_abicalls, 0},
> +  {"qnxpiccalls", s_qnxpiccalls, 0},
> +  {"noqnxpiccalls", s_noqnxpiccalls, 0},
>    {"cpload", s_cpload, 0},
>    {"cpsetup", s_cpsetup, 0},
>    {"cplocal", s_cplocal, 0},
>    {"cprestore", s_cprestore, 0},
>    {"cpreturn", s_cpreturn, 0},
>    {"gpvalue", s_gpvalue, 0},
>    {"gpword", s_gpword, 0},
>    {"gpdword", s_gpdword, 0},
>    {"cpadd", s_cpadd, 0},
>    {"insn", s_insn, 0},
> @@ -3877,21 +3884,21 @@ load_address (int reg, expressionS *ep, 
>  			   mips_gp_register, BFD_RELOC_GPREL16);
>  	      relax_switch ();
>  	    }
>  	  macro_build_lui (ep, reg);
>  	  macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j",
>  		       reg, reg, BFD_RELOC_LO16);
>  	  if (mips_relax.sequence)
>  	    relax_end ();
>  	}
>      }
> -  else if (mips_pic == SVR4_PIC && ! mips_big_got)
> +  else if ((mips_pic_p) && ! mips_big_got)
>      {
>        expressionS ex;
>  
>        /* If this is a reference to an external symbol, we want
>  	   lw		$reg,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)
>  	 Otherwise we want
>  	   lw		$reg,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)
>  	   nop
>  	   addiu	$reg,$reg,<sym>		(BFD_RELOC_LO16)
>  	 If there is a constant, it must be added in after.
> @@ -3938,21 +3945,21 @@ load_address (int reg, expressionS *ep, 
>  	  if (ex.X_add_number != 0)
>  	    {
>  	      if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)
>  		as_bad (_("PIC code offset overflow (max 16 signed bits)"));
>  	      ex.X_op = O_constant;
>  	      macro_build (&ex, ADDRESS_ADDI_INSN, "t,r,j",
>  			   reg, reg, BFD_RELOC_LO16);
>  	    }
>  	}
>      }
> -  else if (mips_pic == SVR4_PIC)
> +  else if (mips_pic_p)
>      {
>        expressionS ex;
>  
>        /* This is the large GOT case.  If this is a reference to an
>  	 external symbol, we want
>  	   lui		$reg,<sym>		(BFD_RELOC_MIPS_GOT_HI16)
>  	   addu		$reg,$reg,$gp
>  	   lw		$reg,<sym>($reg)	(BFD_RELOC_MIPS_GOT_LO16)
>  
>  	 Otherwise, for a reference to a local symbol in old ABI, we want
> @@ -4969,21 +4976,21 @@ macro (struct mips_cl_insn *ip)
>  			       tempreg, mips_gp_register, BFD_RELOC_GPREL16);
>  		  relax_switch ();
>  		}
>  	      macro_build_lui (&offset_expr, tempreg);
>  	      macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
>  			   tempreg, tempreg, BFD_RELOC_LO16);
>  	      if (mips_relax.sequence)
>  		relax_end ();
>  	    }
>  	}
> -      else if (mips_pic == SVR4_PIC && ! mips_big_got && ! HAVE_NEWABI)
> +      else if ((mips_pic_p) && ! mips_big_got && ! HAVE_NEWABI)
>  	{
>  	  int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT16;
>  
>  	  /* If this is a reference to an external symbol, and there
>  	     is no constant, we want
>  	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)
>  	     or for lca or if tempreg is PIC_CALL_REG
>  	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_CALL16)
>  	     For a local symbol, we want
>  	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)
> @@ -5165,21 +5172,21 @@ macro (struct mips_cl_insn *ip)
>  	      macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
>  			   BFD_RELOC_MIPS_GOT_DISP, mips_gp_register);
>  	      relax_end ();
>  	    }
>  	  else
>  	    {
>  	      macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
>  			   BFD_RELOC_MIPS_GOT_DISP, mips_gp_register);
>  	    }
>  	}
> -      else if (mips_pic == SVR4_PIC && ! HAVE_NEWABI)
> +      else if ((mips_pic_p) && ! HAVE_NEWABI)
>  	{
>  	  int gpdelay;
>  	  int lui_reloc_type = (int) BFD_RELOC_MIPS_GOT_HI16;
>  	  int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT_LO16;
>  	  int local_reloc_type = (int) BFD_RELOC_MIPS_GOT16;
>  
>  	  /* This is the large GOT case.  If this is a reference to an
>  	     external symbol, and there is no constant, we want
>  	       lui	$tempreg,<sym>		(BFD_RELOC_MIPS_GOT_HI16)
>  	       addu	$tempreg,$tempreg,$gp
> @@ -5467,61 +5474,64 @@ macro (struct mips_cl_insn *ip)
>  
>        /* The jal instructions must be handled as macros because when
>  	 generating PIC code they expand to multi-instruction
>  	 sequences.  Normally they are simple instructions.  */
>      case M_JAL_1:
>        dreg = RA;
>        /* Fall through.  */
>      case M_JAL_2:
>        if (mips_pic == NO_PIC)
>  	macro_build (NULL, "jalr", "d,s", dreg, sreg);
> -      else if (mips_pic == SVR4_PIC)
> +      else if (mips_pic_p)
>  	{
> -	  if (sreg != PIC_CALL_REG)
> +	  if ((sreg != PIC_CALL_REG) && (mips_pic != QNX_PIC))
>  	    as_warn (_("MIPS PIC call to register other than $25"));
>  
>  	  macro_build (NULL, "jalr", "d,s", dreg, sreg);
>  	  if (! HAVE_NEWABI)
>  	    {
> -	      if (mips_cprestore_offset < 0)
> +	      if (mips_cprestore_offset < 0){
> +		      if (mips_pic != QNX_PIC)
>  		as_warn (_("No .cprestore pseudo-op used in PIC code"));
> +	      }
>  	      else
>  		{
>  		  if (! mips_frame_reg_valid)
>  		    {
>  		      as_warn (_("No .frame pseudo-op used in PIC code"));
>  		      /* Quiet this warning.  */
>  		      mips_frame_reg_valid = 1;
>  		    }
>  		  if (! mips_cprestore_valid)
>  		    {
> +			    if (mips_pic != QNX_PIC)
>  		      as_warn (_("No .cprestore pseudo-op used in PIC code"));
>  		      /* Quiet this warning.  */
>  		      mips_cprestore_valid = 1;
>  		    }
>  		  expr1.X_add_number = mips_cprestore_offset;
>    		  macro_build_ldst_constoffset (&expr1, ADDRESS_LOAD_INSN,
>  						mips_gp_register,
>  						mips_frame_reg,
>  						HAVE_64BIT_ADDRESSES);
>  		}
>  	    }
>  	}
>        else
>  	abort ();
>  
>        return;
>  
>      case M_JAL_A:
>        if (mips_pic == NO_PIC)
>  	macro_build (&offset_expr, "jal", "a");
> -      else if (mips_pic == SVR4_PIC)
> +      else if (mips_pic_p)
>  	{
>  	  /* If this is a reference to an external symbol, and we are
>  	     using a small GOT, we want
>  	       lw	$25,<sym>($gp)		(BFD_RELOC_MIPS_CALL16)
>  	       nop
>  	       jalr	$ra,$25
>  	       nop
>  	       lw	$gp,cprestore($sp)
>  	     The cprestore value is set using the .cprestore
>  	     pseudo-op.  If we are using a big GOT, we want
> @@ -5610,22 +5620,24 @@ macro (struct mips_cl_insn *ip)
>  		}
>  	      macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
>  			   PIC_CALL_REG, BFD_RELOC_MIPS_GOT16,
>  			   mips_gp_register);
>  	      load_delay_nop ();
>  	      macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
>  			   PIC_CALL_REG, PIC_CALL_REG, BFD_RELOC_LO16);
>  	      relax_end ();
>  	      macro_build_jalr (&offset_expr);
>  
> -	      if (mips_cprestore_offset < 0)
> +	      if (mips_cprestore_offset < 0) {
> +		      if (mips_pic != QNX_PIC)
>  		as_warn (_("No .cprestore pseudo-op used in PIC code"));
> +		}
>  	      else
>  		{
>  		  if (! mips_frame_reg_valid)
>  		    {
>  		      as_warn (_("No .frame pseudo-op used in PIC code"));
>  		      /* Quiet this warning.  */
>  		      mips_frame_reg_valid = 1;
>  		    }
>  		  if (! mips_cprestore_valid)
>  		    {
> @@ -6010,21 +6022,21 @@ macro (struct mips_cl_insn *ip)
>  		}
>  	      macro_build_lui (&offset_expr, tempreg);
>  	      macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
>  			   tempreg, tempreg, breg);
>  	      macro_build (&offset_expr, s, fmt, treg,
>  			   BFD_RELOC_LO16, tempreg);
>  	      if (mips_relax.sequence)
>  		relax_end ();
>  	    }
>  	}
> -      else if (mips_pic == SVR4_PIC && ! mips_big_got)
> +      else if ((mips_pic_p) && ! mips_big_got)
>  	{
>  	  int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT16;
>  
>  	  /* If this is a reference to an external symbol, we want
>  	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)
>  	       nop
>  	       <op>	$treg,0($tempreg)
>  	     Otherwise we want
>  	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)
>  	       nop
> @@ -6068,21 +6080,21 @@ macro (struct mips_cl_insn *ip)
>  	  relax_start (offset_expr.X_add_symbol);
>  	  relax_switch ();
>  	  macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j", tempreg,
>  		       tempreg, BFD_RELOC_LO16);
>  	  relax_end ();
>  	  if (breg != 0)
>  	    macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
>  			 tempreg, tempreg, breg);
>  	  macro_build (&expr1, s, fmt, treg, BFD_RELOC_LO16, tempreg);
>  	}
> -      else if (mips_pic == SVR4_PIC && ! HAVE_NEWABI)
> +      else if ((mips_pic_p) && ! HAVE_NEWABI)
>  	{
>  	  int gpdelay;
>  
>  	  /* If this is a reference to an external symbol, we want
>  	       lui	$tempreg,<sym>		(BFD_RELOC_MIPS_GOT_HI16)
>  	       addu	$tempreg,$tempreg,$gp
>  	       lw	$tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
>  	       <op>	$treg,0($tempreg)
>  	     Otherwise we want
>  	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)
> @@ -6238,21 +6250,21 @@ macro (struct mips_cl_insn *ip)
>  	    }
>  	  return;
>  	}
>  
>        /* We know that sym is in the .rdata section.  First we get the
>  	 upper 16 bits of the address.  */
>        if (mips_pic == NO_PIC)
>  	{
>  	  macro_build_lui (&offset_expr, AT);
>  	}
> -      else if (mips_pic == SVR4_PIC)
> +      else if (mips_pic_p)
>  	{
>  	  macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", AT,
>  		       BFD_RELOC_MIPS_GOT16, mips_gp_register);
>  	}
>        else
>  	abort ();
>  
>        /* Now we load the register(s).  */
>        if (HAVE_64BIT_GPRS)
>  	macro_build (&offset_expr, "ld", "t,o(b)", treg, BFD_RELOC_LO16, AT);
> @@ -6310,21 +6322,21 @@ macro (struct mips_cl_insn *ip)
>  			   BFD_RELOC_MIPS_LITERAL, mips_gp_register);
>  	      return;
>  	    }
>  	  breg = mips_gp_register;
>  	  r = BFD_RELOC_MIPS_LITERAL;
>  	  goto dob;
>  	}
>        else
>  	{
>  	  assert (strcmp (s, RDATA_SECTION_NAME) == 0);
> -	  if (mips_pic == SVR4_PIC)
> +	  if (mips_pic_p)
>  	    macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", AT,
>  			 BFD_RELOC_MIPS_GOT16, mips_gp_register);
>  	  else
>  	    {
>  	      /* FIXME: This won't work for a 64 bit address.  */
>  	      macro_build_lui (&offset_expr, AT);
>  	    }
>  
>  	  if (mips_opts.isa != ISA_MIPS1)
>  	    {
> @@ -6524,21 +6536,21 @@ macro (struct mips_cl_insn *ip)
>  	  macro_build (&offset_expr, s, fmt, coproc ? treg + 1 : treg,
>  		       BFD_RELOC_LO16, AT);
>  	  /* FIXME: How do we handle overflow here?  */
>  	  offset_expr.X_add_number += 4;
>  	  /* Itbl support may require additional care here.  */
>  	  macro_build (&offset_expr, s, fmt, coproc ? treg : treg + 1,
>  		       BFD_RELOC_LO16, AT);
>  	  if (mips_relax.sequence)
>  	    relax_end ();
>  	}
> -      else if (mips_pic == SVR4_PIC && ! mips_big_got)
> +      else if ((mips_pic_p) && ! mips_big_got)
>  	{
>  	  /* If this is a reference to an external symbol, we want
>  	       lw	$at,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)
>  	       nop
>  	       <op>	$treg,0($at)
>  	       <op>	$treg+1,4($at)
>  	     Otherwise we want
>  	       lw	$at,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)
>  	       nop
>  	       <op>	$treg,<sym>($at)	(BFD_RELOC_LO16)
> @@ -6571,21 +6583,21 @@ macro (struct mips_cl_insn *ip)
>  	  relax_switch ();
>  	  macro_build (&offset_expr, s, fmt, coproc ? treg + 1 : treg,
>  		       BFD_RELOC_LO16, AT);
>  	  offset_expr.X_add_number += 4;
>  	  macro_build (&offset_expr, s, fmt, coproc ? treg : treg + 1,
>  		       BFD_RELOC_LO16, AT);
>  	  relax_end ();
>  
>  	  mips_optimize = hold_mips_optimize;
>  	}
> -      else if (mips_pic == SVR4_PIC)
> +      else if (mips_pic_p)
>  	{
>  	  int gpdelay;
>  
>  	  /* If this is a reference to an external symbol, we want
>  	       lui	$at,<sym>		(BFD_RELOC_MIPS_GOT_HI16)
>  	       addu	$at,$at,$gp
>  	       lw	$at,<sym>($at)		(BFD_RELOC_MIPS_GOT_LO16)
>  	       nop
>  	       <op>	$treg,0($at)
>  	       <op>	$treg+1,4($at)
> @@ -10120,20 +10132,25 @@ struct option md_longopts[] =
>  #define OPTION_64          (OPTION_ELF_BASE + 6)
>    {"64",          no_argument, NULL, OPTION_64},
>  #define OPTION_MDEBUG      (OPTION_ELF_BASE + 7)
>    {"mdebug", no_argument, NULL, OPTION_MDEBUG},
>  #define OPTION_NO_MDEBUG   (OPTION_ELF_BASE + 8)
>    {"no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG},
>  #define OPTION_PDR	   (OPTION_ELF_BASE + 9)
>    {"mpdr", no_argument, NULL, OPTION_PDR},
>  #define OPTION_NO_PDR	   (OPTION_ELF_BASE + 10)
>    {"mno-pdr", no_argument, NULL, OPTION_NO_PDR},
> +#define OPTION_QNX_PIC	   (OPTION_ELF_BASE + 11)
> +  {"qnx_pic", no_argument, NULL, OPTION_QNX_PIC},
> +  {"mqnx-pic", no_argument, NULL, OPTION_QNX_PIC},
> +#define OPTION_NO_QNX_PIC	   (OPTION_ELF_BASE + 12)
> +  {"mno-qnx-pic", no_argument, NULL, OPTION_NO_QNX_PIC},
>  #endif /* OBJ_ELF */
>  
>    {NULL, no_argument, NULL, 0}
>  };
>  size_t md_longopts_size = sizeof (md_longopts);
>  
>  /* Set STRING_PTR (either &mips_arch_string or &mips_tune_string) to
>     NEW_VALUE.  Warn if another value was already specified.  Note:
>     we have to defer parsing the -march and -mtune arguments in order
>     to handle 'from-abi' correctly, since the ABI might be specified
> @@ -10461,20 +10478,42 @@ md_parse_option (int c, char *arg)
>        mips_flag_mdebug = FALSE;
>        break;
>  
>      case OPTION_PDR:
>        mips_flag_pdr = TRUE;
>        break;
>  
>      case OPTION_NO_PDR:
>        mips_flag_pdr = FALSE;
>        break;
> +
> +    case OPTION_QNX_PIC:
> +      if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
> +        {
> +          as_bad ("QNX PIC is supported only for ELF format");
> +          return 0;
> +        }
> +      mips_pic = QNX_PIC;
> +      mips_gp_register = QNX_GP_REG;
> +      if (g_switch_seen && g_switch_value != 0)
> +        {
> +          as_bad ("-G may not be used with QNX PIC code");
> +          return 0;
> +        }
> +      g_switch_value = 0;
> +      break;
> +
> +     case OPTION_NO_QNX_PIC:
> +      mips_pic = NO_PIC;
> +      mips_gp_register = GP;
> +      break;
> +      
>  #endif /* OBJ_ELF */
>  
>      default:
>        return 0;
>      }
>  
>    return 1;
>  }
>  

>  /* Set up globals to generate code for the ISA or processor
> @@ -10865,21 +10904,21 @@ mips_validate_fix (struct fix *fixP, ase
>        else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
>  	{
>  	  as_bad_where (fixP->fx_file, fixP->fx_line,
>  			_("Cannot branch to symbol in another section."));
>  	  fixP->fx_done = 1;
>  	}
>        else if (S_IS_EXTERNAL (fixP->fx_addsy))
>  	{
>  	  symbolS *sym = fixP->fx_addsy;
>  
> -	  if (mips_pic == SVR4_PIC)
> +	  if (mips_pic_p)
>  	    as_warn_where (fixP->fx_file, fixP->fx_line,
>  			   _("Pretending global symbol used as branch target is local."));
>  
>  	  fixP->fx_addsy = symbol_create (S_GET_NAME (sym),
>  					  S_GET_SEGMENT (sym),
>  					  S_GET_VALUE (sym),
>  					  symbol_get_frag (sym));
>  	  copy_symbol_attributes (fixP->fx_addsy, sym);
>  	  S_CLEAR_EXTERNAL (fixP->fx_addsy);
>  	  assert (symbol_resolved_p (sym));
> @@ -11759,62 +11798,150 @@ s_abicalls (int ignore ATTRIBUTE_UNUSED)
>    mips_abicalls = TRUE;
>  
>    if (g_switch_seen && g_switch_value != 0)
>      as_warn (_("-G may not be used with SVR4 PIC code"));
>    g_switch_value = 0;
>  
>    bfd_set_gp_size (stdoutput, 0);
>    demand_empty_rest_of_line ();
>  }
>  
> +/* This handles the .qnxpiccalls pseudo-op.i */
> +
> +static void
> +s_qnxpiccalls (ignore)
> +     int ignore ATTRIBUTE_UNUSED;
> +{
> +  mips_pic = QNX_PIC;
> +  mips_gp_register = QNX_GP_REG;
> +  if (g_switch_seen && g_switch_value != 0)
> +      as_warn ("-G may not be used with QNX PIC code");
> +  g_switch_value = 0;
> +  bfd_set_gp_size (stdoutput, 0);
> +  demand_empty_rest_of_line ();
> +}
> +
> +/* Allows us to turn off PIC code gen, in case that is needed */
> +
> +static void
> +s_noqnxpiccalls (ignore)
> +     int ignore ATTRIBUTE_UNUSED;
> +{
> +  mips_pic = NO_PIC;
> +  mips_gp_register = GP;
> +  demand_empty_rest_of_line ();
> +}
> +
> +
>  /* Handle the .cpload pseudo-op.  This is used when generating SVR4
>     PIC code.  It sets the $gp register for the function based on the
>     function address, which is in the register named in the argument.
>     This uses a relocation against _gp_disp, which is handled specially
>     by the linker.  The result is:
>  	lui	$gp,%hi(_gp_disp)
>  	addiu	$gp,$gp,%lo(_gp_disp)
>  	addu	$gp,$gp,.cpload argument
> -   The .cpload argument is normally $25 == $t9.  */
> +   The .cpload argument is normally $25 == $t9. 
> +
> +   In the case of QNX pic code, we always compute the full address
> +   of the GOT, therefore we do:
> +        bltzal 0, 0f
> +    0:  lui     $23, %hi(_gp_disp)
> +        addiu   $23, $23, %lo(_gp_disp)
> +        addu    $23, $23, $31
> +*/
>  
>  static void
>  s_cpload (int ignore ATTRIBUTE_UNUSED)
>  {
>    expressionS ex;
>  
>    /* If we are not generating SVR4 PIC code, or if this is NewABI code,
>       .cpload is ignored.  */
>    if (mips_pic != SVR4_PIC || HAVE_NEWABI)
>      {
>        s_ignore (0);
>        return;
>      }
>  
>    /* .cpload should be in a .set noreorder section.  */
> -  if (mips_opts.noreorder == 0)
> +  if ((mips_opts.noreorder == 0) && (mips_pic != QNX_PIC))
>      as_warn (_(".cpload not in noreorder section"));
>  
>    ex.X_op = O_symbol;
>    ex.X_add_symbol = symbol_find_or_make ("_gp_disp");
>    ex.X_op_symbol = NULL;
>    ex.X_add_number = 0;
>  
>    /* In ELF, this symbol is implicitly an STT_OBJECT symbol.  */
>    symbol_get_bfdsym (ex.X_add_symbol)->flags |= BSF_OBJECT;
>  
> +  if (mips_pic == QNX_PIC) {
> +        expressionS ep;
> +        /* In our case, we do a bltzal first to get the current PC, and
> +         * then add the offset to the got... Thus, we always do "cpload $31"
> +         */
> +        ep.X_op = O_constant;
> +        ep.X_add_number = 4;
> +        tc_get_register(0); 
> +
> +        /* See if we can swap the bltzal with the previous insn and save
> +         * the nop...
> +         * For simplicity, we only check that the insn is a move or sw,
> +         * which are really the only two we should encounter.
> +         * If it is anything else, we don't swap for now.
> +         */
> +        if(0 && (mips_optimize > 1)
> +                && prev_insn_valid
> +                && (mips_opts.isa > 1)
> +                && !(mips_opts.noreorder)
> +                && (((prev_insn.insn_opcode & 0xfc1f07ff) == 0x00000021)
> +                  || ((prev_insn.insn_opcode & 0xfc000000) == 0xac000000)))
> +          {
> +                  char *prev_f;
> +                  char temp[4];
> +
> +                  prev_f = prev_insn_frag->fr_literal + prev_insn_where;
> +                  memcpy (temp, prev_f, 4);
> +                  *(unsigned long *)(prev_f) = 0x04100001;
> +                  macro_build (&ep, "bltzal", "s,p", 0);
> +
> +                  prev_f = prev_insn_frag->fr_literal + prev_insn_where;
> +                  memcpy (prev_f, temp, 4);
> +                  mips_opts.noreorder ++;
> +          }
> +        else
> +          {     /* We need a NOP... */
> +                mips_opts.noreorder ++;
> +                macro_build (&ep, "bltzal", "s,p", 0);
> +                macro_build (NULL, "nop", "");
> +          }
> +	macro_start ();
> +        macro_build_lui (&ex, QNX_GP_REG);
> +        macro_build (&ex, "addiu", "t,r,j", QNX_GP_REG, QNX_GP_REG,
> +                       (int) BFD_RELOC_LO16);
> +        mips_opts.noreorder --;
> +
> +        macro_build ((expressionS *) NULL, "addu", "d,v,t",
> +                       QNX_GP_REG, QNX_GP_REG, RA);
> +	macro_end ();
> +  } else
> +  {
> +
>    macro_start ();
>    macro_build_lui (&ex, mips_gp_register);
>    macro_build (&ex, "addiu", "t,r,j", mips_gp_register,
>  	       mips_gp_register, BFD_RELOC_LO16);
>    macro_build (NULL, "addu", "d,v,t", mips_gp_register,
>  	       mips_gp_register, tc_get_register (0));
>    macro_end ();
> +}
>  
>    demand_empty_rest_of_line ();
>  }
>  
>  /* Handle the .cpsetup pseudo-op defined for NewABI PIC code.  The syntax is:
>       .cpsetup $reg1, offset|$reg2, label
>  
>     If offset is given, this results in:
>       sd		$gp, offset($sp)
>       lui	$gp, %hi(%neg(%gp_rel(label)))
> @@ -11830,21 +11957,21 @@ s_cpload (int ignore ATTRIBUTE_UNUSED)
>  static void
>  s_cpsetup (int ignore ATTRIBUTE_UNUSED)
>  {
>    expressionS ex_off;
>    expressionS ex_sym;
>    int reg1;
>    char *f;
>  
>    /* If we are not generating SVR4 PIC code, .cpsetup is ignored.
>       We also need NewABI support.  */
> -  if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
> +  if ((mips_pic != SVR4_PIC && mips_pic != QNX_PIC)|| ! HAVE_NEWABI)
>      {
>        s_ignore (0);
>        return;
>      }
>  
>    reg1 = tc_get_register (0);
>    SKIP_WHITESPACE ();
>    if (*input_line_pointer != ',')
>      {
>        as_bad (_("missing argument separator ',' for .cpsetup"));
> @@ -11912,21 +12039,21 @@ s_cpsetup (int ignore ATTRIBUTE_UNUSED)
>    macro_end ();
>  
>    demand_empty_rest_of_line ();
>  }
>  
>  static void
>  s_cplocal (int ignore ATTRIBUTE_UNUSED)
>  {
>    /* If we are not generating SVR4 PIC code, or if this is not NewABI code,
>     .cplocal is ignored.  */
> -  if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
> +  if ((mips_pic != SVR4_PIC && mips_pic != QNX_PIC) || ! HAVE_NEWABI)
>      {
>        s_ignore (0);
>        return;
>      }
>  
>    mips_gp_register = tc_get_register (0);
>    demand_empty_rest_of_line ();
>  }
>  
>  /* Handle the .cprestore pseudo-op.  This stores $gp into a given
> @@ -11969,21 +12096,21 @@ s_cprestore (int ignore ATTRIBUTE_UNUSED
>     If a register $reg2 was given there, it results in:
>       daddu	$gp, $reg2, $0
>   */
>  static void
>  s_cpreturn (int ignore ATTRIBUTE_UNUSED)
>  {
>    expressionS ex;
>  
>    /* If we are not generating SVR4 PIC code, .cpreturn is ignored.
>       We also need NewABI support.  */
> -  if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
> +  if ((mips_pic != SVR4_PIC && mips_pic != QNX_PIC) || ! HAVE_NEWABI)
>      {
>        s_ignore (0);
>        return;
>      }
>  
>    macro_start ();
>    if (mips_cpreturn_register == -1)
>      {
>        ex.X_op = O_constant;
>        ex.X_add_symbol = NULL;
> @@ -12001,21 +12128,21 @@ s_cpreturn (int ignore ATTRIBUTE_UNUSED)
>  }
>  
>  /* Handle the .gpvalue pseudo-op.  This is used when generating NewABI PIC
>     code.  It sets the offset to use in gp_rel relocations.  */
>  
>  static void
>  s_gpvalue (int ignore ATTRIBUTE_UNUSED)
>  {
>    /* If we are not generating SVR4 PIC code, .gpvalue is ignored.
>       We also need NewABI support.  */
> -  if (mips_pic != SVR4_PIC || ! HAVE_NEWABI)
> +  if ((mips_pic != SVR4_PIC && mips_pic != QNX_PIC) || ! HAVE_NEWABI)
>      {
>        s_ignore (0);
>        return;
>      }
>  
>    mips_gprel_offset = get_absolute_expression ();
>  
>    demand_empty_rest_of_line ();
>  }
>  
> @@ -12023,21 +12150,21 @@ s_gpvalue (int ignore ATTRIBUTE_UNUSED)
>     code.  It generates a 32 bit GP relative reloc.  */
>  
>  static void
>  s_gpword (int ignore ATTRIBUTE_UNUSED)
>  {
>    symbolS *label;
>    expressionS ex;
>    char *p;
>  
>    /* When not generating PIC code, this is treated as .word.  */
> -  if (mips_pic != SVR4_PIC)
> +  if (mips_pic != SVR4_PIC && mips_pic != QNX_PIC)
>      {
>        s_cons (2);
>        return;
>      }
>  
>    label = insn_labels != NULL ? insn_labels->label : NULL;
>    mips_emit_delays (TRUE);
>    if (auto_align)
>      mips_align (2, 0, label);
>    mips_clear_insn_labels ();
> @@ -12059,21 +12186,21 @@ s_gpword (int ignore ATTRIBUTE_UNUSED)
>  }
>  
>  static void
>  s_gpdword (int ignore ATTRIBUTE_UNUSED)
>  {
>    symbolS *label;
>    expressionS ex;
>    char *p;
>  
>    /* When not generating PIC code, this is treated as .dword.  */
> -  if (mips_pic != SVR4_PIC)
> +  if (mips_pic != SVR4_PIC && mips_pic != QNX_PIC)
>      {
>        s_cons (3);
>        return;
>      }
>  
>    label = insn_labels != NULL ? insn_labels->label : NULL;
>    mips_emit_delays (TRUE);
>    if (auto_align)
>      mips_align (3, 0, label);
>    mips_clear_insn_labels ();
> @@ -12103,21 +12230,21 @@ s_gpdword (int ignore ATTRIBUTE_UNUSED)
>  
>  /* Handle the .cpadd pseudo-op.  This is used when dealing with switch
>     tables in SVR4 PIC code.  */
>  
>  static void
>  s_cpadd (int ignore ATTRIBUTE_UNUSED)
>  {
>    int reg;
>  
>    /* This is ignored when not generating SVR4 PIC code.  */
> -  if (mips_pic != SVR4_PIC)
> +  if (mips_pic != SVR4_PIC && mips_pic != QNX_PIC)
>      {
>        s_ignore (0);
>        return;
>      }
>  
>    /* Add $gp to the register named as an argument.  */
>    macro_start ();
>    reg = tc_get_register (0);
>    macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", reg, reg, mips_gp_register);
>    macro_end ();
> @@ -12698,34 +12825,33 @@ relaxed_branch_length (fragS *fragp, ase
>     encoded in the subtype information.  For the mips16, we have to
>     decide whether we are using an extended opcode or not.  */
>  
>  int
>  md_estimate_size_before_relax (fragS *fragp, asection *segtype)
>  {
>    int change;
>  
>    if (RELAX_BRANCH_P (fragp->fr_subtype))
>      {
> -
>        fragp->fr_var = relaxed_branch_length (fragp, segtype, FALSE);
>  
>        return fragp->fr_var;
>      }
>  
>    if (RELAX_MIPS16_P (fragp->fr_subtype))
>      /* We don't want to modify the EXTENDED bit here; it might get us
>         into infinite loops.  We change it only in mips_relax_frag().  */
>      return (RELAX_MIPS16_EXTENDED (fragp->fr_subtype) ? 4 : 2);
>  
>    if (mips_pic == NO_PIC)
>      change = nopic_need_relax (fragp->fr_symbol, 0);
> -  else if (mips_pic == SVR4_PIC)
> +  else if (mips_pic_p)
>      change = pic_need_relax (fragp->fr_symbol, segtype);
>    else
>      abort ();
>  
>    if (change)
>      {
>        fragp->fr_subtype |= RELAX_USE_SECOND;
>        return -RELAX_FIRST (fragp->fr_subtype);
>      }
>    else
> @@ -12743,20 +12869,29 @@ mips_fix_adjustable (fixS *fixp)
>    if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
>      return 0;
>  
>    if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
>        || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
>      return 0;
>  
>    if (fixp->fx_addsy == NULL)
>      return 1;
>  
> +  if ((mips_pic == QNX_PIC) &&
> +      (fixp->fx_r_type == BFD_RELOC_MIPS_GOT16 
> +      || fixp->fx_r_type == BFD_RELOC_32))
> +    {
> +      symbolS * sym = fixp->fx_addsy;
> +      if (S_IS_EXTERN(sym) || S_IS_WEAK(sym)) return 0;
> +    }
> +    
> +  
>    /* If symbol SYM is in a mergeable section, relocations of the form
>       SYM + 0 can usually be made section-relative.  The mergeable data
>       is then identified by the section offset rather than by the symbol.
>  
>       However, if we're generating REL LO16 relocations, the offset is split
>       between the LO16 and parterning high part relocation.  The linker will
>       need to recalculate the complete offset in order to correctly identify
>       the merge data.
>  
>       The linker has traditionally not looked for the parterning high part
> Index: gas/config/tc-mips.h
> ===================================================================
> RCS file: /cvs/src/src/gas/config/tc-mips.h,v
> retrieving revision 1.35
> diff -w -u -1 -0 -p -r1.35 tc-mips.h
> --- gas/config/tc-mips.h	29 Apr 2004 05:14:22 -0000	1.35
> +++ gas/config/tc-mips.h	13 Sep 2004 18:38:03 -0000
> @@ -68,20 +68,23 @@ extern const char *mips_target_format (v
>  
>  /* MIPS PIC level.  */
>  
>  enum mips_pic_level
>  {
>    /* Do not generate PIC code.  */
>    NO_PIC,
>  
>    /* Generate PIC code as in the SVR4 MIPS ABI.  */
>    SVR4_PIC,
> +
> +  /* Generate QNX PIC code.  */
> +  QNX_PIC,
>  };
>  
>  extern enum mips_pic_level mips_pic;
>  
>  struct mips_cl_insn
>  {
>    unsigned long insn_opcode;
>    const struct mips_opcode *insn_mo;
>    /* The next two fields are used when generating mips16 code.  */
>    bfd_boolean use_extend;
> 
> 
> ------------------------------------------------------------------------
> 
> 2004-09-13  Jeff Baker <jbaker@qnx.com>
> 	* ltconfig (nto-qnx*): Add support for QNX OS suffix.
> 
> 2004-09-13  Jeff Baker <jbaker@qnx.com>
> 	* config.bfd (mips*eb-*-nto*): New target.
> 	(mips*-*-nto*): New target.
> 
> 2004-09-13  Jeff Baker <jbaker@qnx.com>
> 	* configure (mips*-*-nto*): New target.
> 	* configure.in: Likewise.
> 
> 2004-09-13  Jeff Baker <jbaker@qnx.com>
> 	* Makefile.am: Add targets for QNX MIPS emulation files.
> 	* Makefile.in: Likewise.
> 	* configure.tgt(mips*-*-nto*): New target.
> 	(mips*eb*-*-nto*): New target. 
> 	* emulparams/elf32bmipnto.sh: New file. QNX MIPS
> 	emulation.
> 	* emulparams/elf32lmipnto.sh: New file. QNX MIPS
> 	emulation
> 
> Index: ltconfig
> ===================================================================
> RCS file: /cvs/src/src/ltconfig,v
> retrieving revision 1.21
> diff -w -u -1 -0 -p -r1.21 ltconfig
> --- ltconfig	21 Jul 2004 19:21:41 -0000	1.21
> +++ ltconfig	13 Sep 2004 18:32:11 -0000
> @@ -1389,20 +1389,31 @@ dgux*)
>  
>  sysv4*MP*)
>    if test -d /usr/nec ;then
>      version_type=linux
>      library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
>      soname_spec='$libname.so.$major'
>      shlibpath_var=LD_LIBRARY_PATH
>    fi
>    ;;
>  
> +nto-qnx*)
> +  version_type=linux
> +  need_lib_prefix=no
> +  need_version=no
> +  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
> +  soname_spec='${libname}${release}.so$major'
> +  shlibpath_var=LD_LIBRARY_PATH
> +  shlibpath_overrides_runpath=yes
> +  deplibs_check_method='pass_all'
> +  ;;
> +  
>  *)
>    dynamic_linker=no
>    ;;
>  esac
>  echo "$ac_t$dynamic_linker" 1>&6
>  test "$dynamic_linker" = no && can_build_shared=no
>  
>  # Check for command to grab the raw symbol name followed by C symbol from nm.
>  echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
>  
> Index: bfd/config.bfd
> ===================================================================
> RCS file: /cvs/src/src/bfd/config.bfd,v
> retrieving revision 1.170
> diff -w -u -1 -0 -p -r1.170 config.bfd
> --- bfd/config.bfd	3 Sep 2004 17:15:31 -0000	1.170
> +++ bfd/config.bfd	13 Sep 2004 18:32:22 -0000
> @@ -833,20 +833,30 @@ case "${targ}" in
>      targ_selvecs=ecoff_little_vec
>      ;;
>    mips*el-*-elf* | mips*el-*-rtems* | mips*el-*-vxworks* | mips*-*-chorus*)
>      targ_defvec=bfd_elf32_littlemips_vec
>      targ_selvecs="bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
>      ;;
>    mips*-*-elf* | mips*-*-rtems* | mips*-*-vxworks | mips*-*-windiss)
>      targ_defvec=bfd_elf32_bigmips_vec
>      targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
>      ;;
> +  mips*eb-*-nto*)
> +    targ_defvec=bfd_elf32_bigmips_vec
> +    targ_selvecs="bfd_elf32_littlemips_vec"
> +    targ_cflags=-D__QNXTARGET__
> +    ;;
> +  mips*-*-nto*)
> +    targ_defvec=bfd_elf32_littlemips_vec
> +    targ_selvecs="bfd_elf32_bigmips_vec"
> +    targ_cflags=-D__QNXTARGET__
> +    ;;
>    mips*-*-none)
>      targ_defvec=bfd_elf32_bigmips_vec
>      targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
>      ;;
>    mips*el-*-openbsd*)
>      targ_defvec=bfd_elf32_littlemips_vec
>      targ_selvecs="bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec ecoff_little_vec ecoff_big_vec"
>      ;;
>    mips*-*-openbsd*)
>      targ_defvec=bfd_elf32_bigmips_vec
> Index: gas/configure
> ===================================================================
> RCS file: /cvs/src/src/gas/configure,v
> retrieving revision 1.177
> diff -w -u -1 -0 -p -r1.177 configure
> --- gas/configure	3 Sep 2004 17:15:37 -0000	1.177
> +++ gas/configure	13 Sep 2004 18:32:31 -0000
> @@ -4437,20 +4437,21 @@ echo "$as_me: error: Unknown vendor for 
>        mips-*-ecoff*)			fmt=ecoff ;;
>        mips-*-pe*)			fmt=coff endian=little em=pe ;;
>        mips-*-irix6*)			fmt=elf em=irix ;;
>        mips-*-irix5*)			fmt=elf em=irix ;;
>        mips-*-irix*)			fmt=ecoff em=irix ;;
>        mips-*-lnews*)			fmt=ecoff em=lnews ;;
>        mips-*-riscos*)			fmt=ecoff ;;
>        mips*-*-linux*)			fmt=elf em=tmips ;;
>        mips-*-sysv4*MP* | mips-*-gnu*)	fmt=elf em=tmips ;;
>        mips-*-sysv*)			fmt=ecoff ;;
> +      mips*-*-nto*)			fmt=elf ;;
>        mips-*-elf* | mips-*-rtems*)	fmt=elf ;;
>        mips-*-netbsd*)			fmt=elf ;;
>        mips-*-openbsd*)			fmt=elf ;;
>  
>        mmix-*-*)				fmt=elf ;;
>        mn10200-*-*)			fmt=elf ;;
>        # cpu_type for am33_2.0 is set to mn10300
>        mn10300-*-linux*)			fmt=elf bfd_gas=yes em=linux ;;
>        mn10300-*-*)			fmt=elf ;;
>  
> Index: gas/configure.in
> ===================================================================
> RCS file: /cvs/src/src/gas/configure.in,v
> retrieving revision 1.161
> diff -w -u -1 -0 -p -r1.161 configure.in
> --- gas/configure.in	3 Sep 2004 17:15:40 -0000	1.161
> +++ gas/configure.in	13 Sep 2004 18:32:35 -0000
> @@ -389,20 +389,21 @@ changequote([,])dnl
>        mips-*-ecoff*)			fmt=ecoff ;;
>        mips-*-pe*)			fmt=coff endian=little em=pe ;;
>        mips-*-irix6*)			fmt=elf em=irix ;;
>        mips-*-irix5*)			fmt=elf em=irix ;;
>        mips-*-irix*)			fmt=ecoff em=irix ;;
>        mips-*-lnews*)			fmt=ecoff em=lnews ;;
>        mips-*-riscos*)			fmt=ecoff ;;
>        mips*-*-linux*)			fmt=elf em=tmips ;;
>        mips-*-sysv4*MP* | mips-*-gnu*)	fmt=elf em=tmips ;;
>        mips-*-sysv*)			fmt=ecoff ;;
> +      mips*-*-nto*)			fmt=elf ;;
>        mips-*-elf* | mips-*-rtems*)	fmt=elf ;;
>        mips-*-netbsd*)			fmt=elf ;;
>        mips-*-openbsd*)			fmt=elf ;;
>  
>        mmix-*-*)				fmt=elf ;;
>        mn10200-*-*)			fmt=elf ;;
>        # cpu_type for am33_2.0 is set to mn10300
>        mn10300-*-linux*)			fmt=elf bfd_gas=yes em=linux ;;
>        mn10300-*-*)			fmt=elf ;;
>  
> Index: ld/Makefile.am
> ===================================================================
> RCS file: /cvs/src/src/ld/Makefile.am,v
> retrieving revision 1.158
> diff -w -u -1 -0 -p -r1.158 Makefile.am
> --- ld/Makefile.am	3 Sep 2004 17:15:43 -0000	1.158
> +++ ld/Makefile.am	13 Sep 2004 18:32:47 -0000
> @@ -146,35 +146,37 @@ ALL_EMULATIONS = \
>  	edelta68.o \
>  	eelf32_dlx.o \
>  	eebmon29k.o \
>  	eelf32_i960.o \
>  	eelf32_i860.o \
>  	eelf32_sparc.o \
>  	eelf32b4300.o \
>  	eelf32cr16c.o \
>  	eelf32bmip.o \
>  	eelf32bmipn32.o \
> +	eelf32bmipsnto.o \
>  	eelf32btsmip.o \
>  	eelf32crx.o \
>  	eelf32btsmipn32.o \
>  	eelf32ltsmip.o \
>  	eelf32ltsmipn32.o \
>  	eelf32ebmip.o \
>  	eelf32elmip.o \
>  	eelf32fr30.o \
>  	eelf32frv.o \
>  	eelf32i370.o \
>  	eelf32ip2k.o \
>  	eelf32iq2000.o \
>  	eelf32iq10.o \
>  	eelf32l4300.o \
>  	eelf32lmip.o \
> +	eelf32lmipnto.o \
>  	eelf32lppc.o \
>  	eelf32lppcnto.o \
>  	eelf32lppcsim.o \
>  	eelf32mcore.o \
>  	eelf32mipswindiss.o \
>  	eelf32openrisc.o \
>  	eelf32ppc.o \
>  	eelf32ppc_fbsd.o \
>  	eelf32ppclinux.o \
>  	eelf32ppcnto.o \
> @@ -647,20 +649,26 @@ eelf32b4300.c: $(srcdir)/emulparams/elf3
>    $(srcdir)/emulparams/elf32bmip.sh \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32b4300 "$(tdir_elf32b4300)"
>  eelf32cr16c.c: $(srcdir)/emulparams/elf32cr16c.sh \
>    $(srcdir)/emultempl/elf32.em \
>    $(srcdir)/scripttempl/elf32cr16c.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32cr16c "$(tdir_elf32cr16c)"
>  eelf32bmip.c: $(srcdir)/emulparams/elf32bmip.sh \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32bmip "$(tdir_elf32bmip)"
> +eelf32bmipnto.c: $(srcdir)/emulparams/elf32bmipnto.sh \
> +  $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
> +	${GENSCRIPTS} elf32bmipnto "$(tdir_elf32bmipnto)"
> +eelf32lmipnto.c: $(srcdir)/emulparams/elf32lmipnto.sh \
> +  $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
> +	${GENSCRIPTS} elf32lmipnto "$(tdir_elf32lmipnto)"
>  eelf32bsmip.c: $(srcdir)/emulparams/elf32bsmip.sh \
>    $(srcdir)/emulparams/elf32bmip.sh $(srcdir)/emultempl/irix.em \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32bsmip "$(tdir_elf32bsmip)"
>  eelf32btsmip.c: $(srcdir)/emulparams/elf32btsmip.sh \
>    $(srcdir)/emulparams/elf32bmip.sh \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32btsmip "$(tdir_elf32btsmip)"
>  eelf32crx.c: $(srcdir)/emulparams/elf32crx.sh \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/crxelf.em \
> Index: ld/Makefile.in
> ===================================================================
> RCS file: /cvs/src/src/ld/Makefile.in,v
> retrieving revision 1.170
> diff -w -u -1 -0 -p -r1.170 Makefile.in
> --- ld/Makefile.in	3 Sep 2004 17:15:43 -0000	1.170
> +++ ld/Makefile.in	13 Sep 2004 18:32:53 -0000
> @@ -260,35 +260,37 @@ ALL_EMULATIONS = \
>  	edelta68.o \
>  	eelf32_dlx.o \
>  	eebmon29k.o \
>  	eelf32_i960.o \
>  	eelf32_i860.o \
>  	eelf32_sparc.o \
>  	eelf32b4300.o \
>  	eelf32cr16c.o \
>  	eelf32bmip.o \
>  	eelf32bmipn32.o \
> +	eelf32bmipnto.o \
>  	eelf32btsmip.o \
>  	eelf32crx.o \
>  	eelf32btsmipn32.o \
>  	eelf32ltsmip.o \
>  	eelf32ltsmipn32.o \
>  	eelf32ebmip.o \
>  	eelf32elmip.o \
>  	eelf32fr30.o \
>  	eelf32frv.o \
>  	eelf32i370.o \
>  	eelf32ip2k.o \
>  	eelf32iq2000.o \
>  	eelf32iq10.o \
>  	eelf32l4300.o \
>  	eelf32lmip.o \
> +	eelf32lmipnto.o \
>  	eelf32lppc.o \
>  	eelf32lppcnto.o \
>  	eelf32lppcsim.o \
>  	eelf32mcore.o \
>  	eelf32mipswindiss.o \
>  	eelf32openrisc.o \
>  	eelf32ppc.o \
>  	eelf32ppc_fbsd.o \
>  	eelf32ppclinux.o \
>  	eelf32ppcnto.o \
> @@ -1373,20 +1375,26 @@ eelf32b4300.c: $(srcdir)/emulparams/elf3
>    $(srcdir)/emulparams/elf32bmip.sh \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32b4300 "$(tdir_elf32b4300)"
>  eelf32cr16c.c: $(srcdir)/emulparams/elf32cr16c.sh \
>    $(srcdir)/emultempl/elf32.em \
>    $(srcdir)/scripttempl/elf32cr16c.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32cr16c "$(tdir_elf32cr16c)"
>  eelf32bmip.c: $(srcdir)/emulparams/elf32bmip.sh \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32bmip "$(tdir_elf32bmip)"
> +eelf32bmipnto.c: $(srcdir)/emulparams/elf32bmipnto.sh \
> +  $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
> +	${GENSCRIPTS} elf32bmipnto "$(tdir_elf32bmipnto)"
> +eelf32lmipnto.c: $(srcdir)/emulparams/elf32lmipnto.sh \
> +  $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
> +	${GENSCRIPTS} elf32lmipnto "$(tdir_elf32lmipnto)"
>  eelf32bsmip.c: $(srcdir)/emulparams/elf32bsmip.sh \
>    $(srcdir)/emulparams/elf32bmip.sh $(srcdir)/emultempl/irix.em \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32bsmip "$(tdir_elf32bsmip)"
>  eelf32btsmip.c: $(srcdir)/emulparams/elf32btsmip.sh \
>    $(srcdir)/emulparams/elf32bmip.sh \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
>  	${GENSCRIPTS} elf32btsmip "$(tdir_elf32btsmip)"
>  eelf32crx.c: $(srcdir)/emulparams/elf32crx.sh \
>    $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/crxelf.em \
> Index: ld/configure.tgt
> ===================================================================
> RCS file: /cvs/src/src/ld/configure.tgt,v
> retrieving revision 1.155
> diff -w -u -1 -0 -p -r1.155 configure.tgt
> --- ld/configure.tgt	3 Sep 2004 17:15:44 -0000	1.155
> +++ ld/configure.tgt	13 Sep 2004 18:33:03 -0000
> @@ -422,20 +422,26 @@ mips*-*-netbsd*)	targ_emul=elf32bmip
>  			;;
>  mips*-*-bsd*)		targ_emul=mipsbig ;;
>  mips*vr4300el-*-elf*)	targ_emul=elf32l4300 ;;
>  mips*vr4300-*-elf*)	targ_emul=elf32b4300 ;;
>  mips*vr4100el-*-elf*)	targ_emul=elf32l4300 ;;
>  mips*vr4100-*-elf*)	targ_emul=elf32b4300 ;;
>  mips*vr5000el-*-elf*)	targ_emul=elf32l4300 ;;
>  mips*vr5000-*-elf*)	targ_emul=elf32b4300 ;;
>  mips*el-*-elf*)		targ_emul=elf32elmip ;;
>  mips*-*-elf*)		targ_emul=elf32ebmip ;;
> +mips*-*-nto*)		targ_emul=elf32lmipnto
> +			targ_extra_emuls="elf32bmipnto"
> +			;;
> +mips*eb*-*-nto*)	targ_emul=elf32bmipnto
> +			targ_extra_emuls="elf32lmipnto"
> +			;;
>  mips*el-*-rtems*)	targ_emul=elf32elmip ;;
>  mips*-*-rtems*)		targ_emul=elf32ebmip ;;
>  mips*el-*-vxworks*)	targ_emul=elf32elmip ;;
>  mips*-*-vxworks*)	targ_emul=elf32ebmip
>  		        targ_extra_emuls="elf32elmip" ;;
>  mips*-*-windiss)	targ_emul=elf32mipswindiss ;;
>  mips64*el-*-linux-gnu*)	targ_emul=elf32ltsmipn32
>  			targ_extra_emuls="elf32btsmipn32 elf32ltsmip elf32btsmip elf64ltsmip elf64btsmip"
>  			;;
>  mips64*-*-linux-gnu*)	targ_emul=elf32btsmipn32
> 
> 
> ------------------------------------------------------------------------
> 
> 2004-09-13  Jeff Baker  <jbaker@qnx.com>
> 	* elflink.c (_bfd_elf_add_dynamic_entry): Add code to
> 	warn if adding a DT_TEXTREL to a shared object and
> 	--warn-shared-textrel was specified.
> 
> 2004-09-13  Jeff Baker  <jbaker@qnx.com>
> 	* bfdlink.h (bfd_link_info): Add boolean
> 	warn_shared_textrel.
> 
> 2004-09-13  Jeff Baker  <jbaker@qnx.com>
> 	* lexsup.c: Handle --warn-shared-textrel option.
> 
> Index: bfd/elflink.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/elflink.c,v
> retrieving revision 1.101
> diff -w -u -1 -0 -p -r1.101 elflink.c
> --- bfd/elflink.c	7 Sep 2004 13:40:37 -0000	1.101
> +++ bfd/elflink.c	13 Sep 2004 18:24:51 -0000
> @@ -2644,20 +2644,25 @@ _bfd_elf_add_dynamic_entry (struct bfd_l
>    const struct elf_backend_data *bed;
>    asection *s;
>    bfd_size_type newsize;
>    bfd_byte *newcontents;
>    Elf_Internal_Dyn dyn;
>  
>    hash_table = elf_hash_table (info);
>    if (! is_elf_hash_table (hash_table))
>      return FALSE;
>  
> +  if (info->warn_shared_textrel && info->shared && tag == DT_TEXTREL) {
> +    (*_bfd_error_handler)
> +      (_("warning: creating a DT_TEXTREL in a shared object."));
> +  }
> +  
>    bed = get_elf_backend_data (hash_table->dynobj);
>    s = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
>    BFD_ASSERT (s != NULL);
>  
>    newsize = s->size + bed->s->sizeof_dyn;
>    newcontents = bfd_realloc (s->contents, newsize);
>    if (newcontents == NULL)
>      return FALSE;
>  
>    dyn.d_tag = tag;
> Index: include/bfdlink.h
> ===================================================================
> RCS file: /cvs/src/src/include/bfdlink.h,v
> retrieving revision 1.45
> diff -w -u -1 -0 -p -r1.45 bfdlink.h
> --- include/bfdlink.h	13 Aug 2004 03:16:01 -0000	1.45
> +++ include/bfdlink.h	13 Sep 2004 18:25:04 -0000
> @@ -390,20 +390,23 @@ struct bfd_link_info
>    unsigned int spare_dynamic_tags;
>  
>    /* May be used to set DT_FLAGS for ELF. */
>    bfd_vma flags;
>  
>    /* May be used to set DT_FLAGS_1 for ELF. */
>    bfd_vma flags_1;
>  
>    /* Start and end of RELRO region.  */
>    bfd_vma relro_start, relro_end;
> +
> +  /* Warn if adding a DT_TEXTREL to a shared object.  */
> +  bfd_boolean warn_shared_textrel;
>  };
>  
>  /* This structures holds a set of callback functions.  These are
>     called by the BFD linker routines.  The first argument to each
>     callback function is the bfd_link_info structure being used.  Each
>     function returns a boolean value.  If the function returns FALSE,
>     then the BFD function which called it will return with a failure
>     indication.  */
>  
>  struct bfd_link_callbacks
> Index: ld/lexsup.c
> ===================================================================
> RCS file: /cvs/src/src/ld/lexsup.c,v
> retrieving revision 1.76
> diff -w -u -1 -0 -p -r1.76 lexsup.c
> --- ld/lexsup.c	19 Jul 2004 16:40:52 -0000	1.76
> +++ ld/lexsup.c	13 Sep 2004 18:25:13 -0000
> @@ -139,21 +139,22 @@ enum option_values
>    OPTION_NOSTDLIB,
>    OPTION_NO_OMAGIC,
>    OPTION_STRIP_DISCARDED,
>    OPTION_NO_STRIP_DISCARDED,
>    OPTION_ACCEPT_UNKNOWN_INPUT_ARCH,
>    OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH,
>    OPTION_PIE,
>    OPTION_UNRESOLVED_SYMBOLS,
>    OPTION_WARN_UNRESOLVED_SYMBOLS,
>    OPTION_ERROR_UNRESOLVED_SYMBOLS,
> -  OPTION_REDUCE_MEMORY_OVERHEADS
> +  OPTION_REDUCE_MEMORY_OVERHEADS,
> +  OPTION_WARN_SHARED_TEXTREL
>  };
>  
>  /* The long options.  This structure is used for both the option
>     parsing and the help text.  */
>  
>  struct ld_option
>  {
>    /* The long option information.  */
>    struct option opt;
>    /* The short option with the same meaning ('\0' if none).  */
> @@ -489,20 +490,23 @@ static const struct ld_option ld_options
>  		   "\t\t\t\tfollowing dynamic libs"), TWO_DASHES },
>    { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_NEEDED},
>      '\0', NULL, N_("Do not set DT_NEEDED tags for DT_NEEDED entries\n"
>  		   "\t\t\t\tin following dynamic libs"), TWO_DASHES },
>    { {"as-needed", no_argument, NULL, OPTION_AS_NEEDED},
>      '\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"),
>      TWO_DASHES },
>    { {"no-as-needed", no_argument, NULL, OPTION_NO_AS_NEEDED},
>      '\0', NULL, N_("Always set DT_NEEDED for following dynamic libs"),
>      TWO_DASHES },
> +  { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_SHARED_TEXTREL},
> +      '\0', NULL, N_("Warn if shared object has DT_TEXTREL"),
> +      TWO_DASHES },
>    { {"wrap", required_argument, NULL, OPTION_WRAP},
>      '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
>  };
>  
>  #define OPTION_COUNT ARRAY_SIZE (ld_options)
>  
>  void
>  parse_args (unsigned argc, char **argv)
>  {
>    unsigned i;
> @@ -1209,20 +1213,23 @@ parse_args (unsigned argc, char **argv)
>  	  break;
>  	case OPTION_NO_ADD_NEEDED:
>  	  add_needed = FALSE;
>  	  break;
>  	case OPTION_AS_NEEDED:
>  	  as_needed = TRUE;
>  	  break;
>  	case OPTION_NO_AS_NEEDED:
>  	  as_needed = FALSE;
>  	  break;
> +	case OPTION_WARN_SHARED_TEXTREL:
> +	  link_info.warn_shared_textrel = TRUE;
> +	  break;
>  	case OPTION_WRAP:
>  	  add_wrap (optarg);
>  	  break;
>  	case OPTION_DISCARD_NONE:
>  	  link_info.discard = discard_none;
>  	  break;
>  	case 'X':
>  	  link_info.discard = discard_l;
>  	  break;
>  	case 'x':



More information about the Binutils mailing list