RFC: Adding non-PIC executable support to MIPS
Daniel Jacobowitz
dan@debian.org
Sun Jul 27 15:32:00 GMT 2008
Thanks for the review. I have just a few questions left for you
(search for "?" :-). As this is 99% about the binutils changes, I've
trimmed the CC list a bit.
On Sun, Jul 27, 2008 at 10:10:23AM +0100, Richard Sandiford wrote:
> Daniel Jacobowitz <dan@debian.org> writes:
> > All comments welcome - Richard, especially from you. How would you
> > like to proceed? I think the first step should be to get your other
> > binutils/gcc patches merged, including MIPS16 PIC; I used those as a
> > base. But see a few of the notes for potential problems with those
> > patches.
>
> Yeah, Nick's approved most of the remaining binutils changes (thanks).
> I haven't applied them yet because of the doubt over whether st_size
> should be even or odd for ISA-encoded MIPS16 symbols. I don't really
> have an opinion, so I'll accept a maintainerly decision...
In that case, I suggest we go with even sizes.
> Anyway, the gcc patch looks good to me, thanks. The only niggle
> I could see was that you didn't update the comment for:
>
> +/* True if the output file is marked as ".abicalls; .option pic0"
> + (-call_mixed). This is a GNU extension. */
> +#define TARGET_ABICALLS_PIC0 \
> + (TARGET_ABSOLUTE_ABICALLS && TARGET_PLT)
>
> (That kind of thing was inevitable given the amount of code you had
> to wade through. I'm impressed if there's really only one instance!)
Yeah, thanks :-) I spent a merry morning adjusting the comments in
binutils, but wasn't as thorough for GCC. Fixed.
> I think the gcc side is good to go, modulo the _mcount thing.
Ok. Want me to find a fix, or will you?
> As far as binutils goes, I saw a couple of potential problems:
>
> (1) The patch adds the following code to
> _bfd_mips_elf_create_dynamic_sections:
>
> + if (htab->use_plts_and_copy_relocs && htab->root.hplt == NULL)
> + {
> + h = _bfd_elf_define_linkage_sym (abfd, info, s,
> + "_PROCEDURE_LINKAGE_TABLE_");
> + htab->root.hplt = h;
> + if (h == NULL)
> + return FALSE;
> + h->type = STT_FUNC;
> + }
>
> But use_plts_and_copy_relocs is only set after all input bfds have
> been read in.
Whoops. I've had recurring problems with this - there were several
other things our previous patch did based on the first time a pic0
input was seen and this was one of them. I had in my notes that
the _P_L_T_ symbol was going to be tricky to get right and I just just
drop it. But obviously I didn't.
I'll define the symbol later. This is straightforward, as nothing (in
non-VxWorks anyway) refers to the symbol.
> But pointer equality is needed for non-call GOT relocations too.
> I couldn't see anything that explicitly handled that case.
I'm not sure about this. While pointer equality, the concept, is
needed, I don't think it mandates a valid address on the PLT entry
(which is what this flag controls). Won't the dynamic linker do the
right thing?
> Some minor nits too:
>
> + 0x03990000, /* l[wd] $25, %lo(&GOTPLT[0])($28) */
> + 0x01d90000, /* l[wd] $25, %lo(&GOTPLT[0])($14) */
> + 0x01d90000, /* l[wd] $25, %lo(&GOTPLT[0])($14) */
>
> These are all fixed as either lw or ld.
Right, it turned out I needed three separate sequences fairly late in
the patch's life cycle. Fixed.
> How about something like the following:
>
> - non-PIC references to H, make sure that H has an la25 stub. */
> + non-PIC branches and jumps to H, make sure that H has an la25 stub.
> + We specifically ignore branches and jumps from EF_PIC objects,
> + where the onus is on the compiler or programmer to perform any
> + necessary initialization of $25. Sometimes such initialization
> + is unnecessary; for example, -mno-shared functions do not use
> + the incoming value of $25, and may therefore be called directly. */
I like your version, thanks. However, I moved most of it to the new
function mips_elf_relocation_needs_la25_stub rather than the use here.
> I think this deserves a comment. (It's because the .got.plt
> address calculation is no longer accurate after the addition
> of the reserved entries, right?) I realise this function isn't
> used for non-VxWorks before the patch, but it's a generic concept
> even so...
Right. I added a comment:
/* This function only works for VxWorks, because a non-VxWorks .got.plt
section starts with reserved entries. */
> I'd prefer to see some part of:
>
> (h != NULL
> && !PIC_OBJECT_P (input_bfd)
> && (r_type == R_MIPS_26 || r_type == R_MIPS_PC16
> || r_type == R_MIPS16_26))
>
> be a separate function that is used both here and in
> _bfd_mips_elf_check_relocs.
Changed. I moved the input_bfd check too; that seemed like the most
sensible logical unit.
> - htab->plt_header_size = 4 * ARRAY_SIZE (mips_exec_plt0_entry);
> + htab->plt_header_size = 4 * ARRAY_SIZE (mips_o32_exec_plt0_entry);
>
> Probably worth a comment saying that all the plt headers are the same size.
> It looked a bit odd using something with "o32" in it for n32 and n64.
Yeah, good idea.
> FWIW, I thought about adding this too, but rejected it because I was
> afraid of trapping valid uses. E.g. it makes it impossible to use
> relocations against SHN_ABS symbols, even though such symbols aren't
> (generally) subject to runtime relocation. I realise you copied this
> from other ports though.
Right. I'd prefer to leave it - it did find a number of useful
problems in the course of our development. If someone bumps into it
with a legitimate use case I'm happy to relax it further.
> Why !info->shared?
No particular reason; as you know it makes no difference in the
current code, and I don't know what shared PLTs might look like yet.
I removed it, since that's safer than not.
> I think it'd be good to tighten the assert, as it would currently trigger
> for valid X >= -0x80000000 addresses (both in 32-bit and 64-bit code).
> I don't know of any system out there that allows dynamic executables
> in kernel space, but I've ceased to be surprised by such things ;)
OK. Could you check that I got this right?
/* The PLT sequence is not safe for N64 if .got.plt's address can
not be loaded in two instructions. */
BFD_ASSERT ((gotplt_value & ~(bfd_vma) 0x7fffffff) == 0
|| ~(gotplt_value | 0x7fffffff) == 0);
> +/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
> +
> +bfd_boolean
> +_bfd_mips_elf_hash_symbol (struct elf_link_hash_entry *h)
> Were you able to test this
No. I figured I'd add this, since it has a slightly non-obvious bit,
in case someone comes up with a clever way to use .gnu.hash on MIPS
(with an entirely non-PIC binary, it should be quite feasible, but
it'd be an ABI change). I'm happy to drop it though, so I've done so.
> "- 17" rather than "- 28"?
Yes, you're right.
> Please keep the "... <...>:" addresses at least. (You did this
> in some of the other tests, thanks.) The non-disassembly dumps
> rely on functions being at certain addresses, and I think it's
> easier to follow the test if those addresses are explicit in
> the disassembly.
>
> (I've used custom scripts for this sort of test to try to
> protect them from fluctuations in the size of the dynamic info.
> The addresses should be pretty stable.)
They're a pain to update when something does change; I spent most of
an entire day fixing hardcoded addresses in the test scripts, and like
Ian, I'm starting to wonder about the value.
I put the addresses back for symbols, which sounds like a fine
compromise.
--
Daniel Jacobowitz
CodeSourcery
More information about the Binutils
mailing list