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