QNX MIPS Support Patch

Jeff Baker jbaker@qnx.com
Mon Sep 13 19:03:00 GMT 2004


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
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qnx_changelog.patch
URL: <https://sourceware.org/pipermail/binutils/attachments/20040913/8c6d147b/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qnx_copy_rel.patch
URL: <https://sourceware.org/pipermail/binutils/attachments/20040913/8c6d147b/attachment-0001.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qnx_gas_pic.patch
URL: <https://sourceware.org/pipermail/binutils/attachments/20040913/8c6d147b/attachment-0002.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qnx_mips_target.patch
URL: <https://sourceware.org/pipermail/binutils/attachments/20040913/8c6d147b/attachment-0003.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qnx_shared_textrel.patch
URL: <https://sourceware.org/pipermail/binutils/attachments/20040913/8c6d147b/attachment-0004.ksh>


More information about the Binutils mailing list