qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: qemu-ppc64-linux-user: signal handler endianness in elfv2


From: David Gibson
Subject: Re: qemu-ppc64-linux-user: signal handler endianness in elfv2
Date: Mon, 16 Mar 2020 19:43:26 +1100

On Sun, Mar 15, 2020 at 10:40:00PM -0500, Vincent Fazio wrote:
> David,
> 
> On Sun, Mar 15, 2020 at 10:12 PM David Gibson
> <address@hidden> wrote:
> >
> > On Thu, Feb 27, 2020 at 01:40:53PM -0600, Vincent Fazio wrote:
> >
> > Sorry, I should have replied to this earlier.
> >
> > > In the ELFv2 ABI, function pointers are relative to the TOC stored in 
> > > GPR2.
> > > There's no hop into .opd to pull an address that needs to be endian 
> > > swapped
> > > relative to the host as in ELFv1.
> >
> > Right.
> >
> > > As best as I can tell, GPR2 is in QEMU's host endianness as it's 
> > > calculated
> >
> > Sort of.  In hardware the register has no endianness, since it's not
> > byte-addressable.  In qemu's modelling, env->gpr[2], like all the
> > registers, is stored in host endianness.  That's because the fact
> > those registers have an in memory representation is a qemu/host side
> > detail.
> >
> > > from GPR12 or the ELF load address + entry point so there should be no 
> > > need
> > > to swap the value of the signal handler function pointer in ELFv2.
> >
> > Erm... if the address was coming from a register, yes.  But AFAICT
> > it's not coming from a register, it's coming from the guest's struct
> > sigaction, which I'd expect to be in target/guest endianness.
> >
> 
> I can dig into this a bit more when i'm back at work with hardware.
> but the gist is that the value copied into the struct is calculated
> from GPR2/GPR12 as they're set after the jump into the ELF binary.

Where is this copying into the structure happening in the code?  If
that's qemu code putting something in there, I suspect we should have
a swap at that point (which would cancel the other one).

I had looked through the code before, and I thought that structure was
just copied as a whole from the guest memory at sigaction() time.

> In ELFv2, function pointers are _relative_ to the values stored in
> those registers, so they will maintain their endianness. It's probably
> not exactly clear in the example below, but i was trying show:
> 
> 1) the offsets within the ELF for the TOC, entry point, and the
> sigaction handler
> 2) GPR12 is the basis for GPR2. In ELFv2, GPR12 is set when hitting
> the PLT stub and is the entry point for the ELF binary
> 3) that the handler value is calculated relative to GPR2
> 4) that dereferencing the pointer shows the same byte pattern (when
> endianness is accounted for)
> 5) all of this assumes the registers are in host (not target)
> endianness. the registers should all be valid virtual addresses in the
> host that map to the ELF on disk.
> 
> I'm sure i'm missing some technical jargon with how QEMU does it's
> magic, and most of my assembly experience comes from x86 Windows PEs,
> not x86/PPC Linux ELFs, so forgive me if some of my terms are
> incorrect.
> 
> >
> > >
> > > >>>
> > > vfazio@vfazio1 ~/development/buildroot $
> > > output/host/powerpc64-buildroot-linux-musl/bin/objdump -x
> > > output/build/libopenssl-1.1.1d/libcrypto.so | egrep -e
> > > ".TOC|\<_init|ill_handler"
> > > 0000000000186014 l     F .text    0000000000000034 0x60 ill_handler
> > > 00000000002b7f00 l     O .got    0000000000000000 .TOC.
> > > 000000000007de00 l     F .init    0000000000000010 0x60 _init
> > >
> > > 000000000007de00 <_init>:
> > >    7de00:       3c 4c 00 24     addis   r2,r12,36
> > >    7de04:       38 42 a1 00     addi    r2,r2,-24320
> > >
> > > (gdb) p/x 0x7de00 + (36 << 16) - 24320
> > > $69 = 0x2b7f00
> > >
> > >    7f180:       3f a2 ff ed     addis   r29,r2,-19
> > >    7f184:       3b bd e1 14     addi    r29,r29,-7916
> > >
> > > (gdb) p/x 0x2b7f00 - (19 << 16) - 7916
> > > $75 = 0x186014
> > >
> > > (gdb) where
> > > #0  setup_rt_frame (sig=4, ka=0x628c5f80 <sigact_table+96>, 
> > > info=0x629314d8,
> > > set=0x7fffffffd368, env=0x629240c0) at
> > > /home/vfazio/development/qemu/linux-user/ppc/signal.c:579
> > > #1  0x000000006008d6b3 in handle_pending_signal (cpu_env=0x629240c0, 
> > > sig=4,
> > > k=0x629314d0) at /home/vfazio/development/qemu/linux-user/signal.c:922
> > > #2  0x000000006008d84b in process_pending_signals (cpu_env=0x629240c0) at
> > > /home/vfazio/development/qemu/linux-user/signal.c:960
> > > #3  0x0000000060097ec7 in cpu_loop (env=0x629240c0) at
> > > /home/vfazio/development/qemu/linux-user/ppc/cpu_loop.c:469
> > > #4  0x000000006006444e in main (argc=9, argv=0x7fffffffde48,
> > > envp=0x7fffffffde98) at 
> > > /home/vfazio/development/qemu/linux-user/main.c:865
> > >
> > > (gdb) p/x env->gpr[2]
> > > $83 = 0x4000c21f00
> > > (gdb) p/x env->gpr[2] - (19 << 16) - 7916
> > > $84 = 0x4000af0014
> > > (gdb) p/x ka->_sa_handler
> > > $85 = 0x4000af0014
> > > (gdb) p/x *ka->_sa_handler
> > > $86 = 0x13004c3c
> > >
> > > 0000000000186014 <ill_handler>:
> > >   186014:       3c 4c 00 13     addis   r2,r12,19
> > >   186018:       38 42 1e ec     addi    r2,r2,7916
> > >   18601c:       7c 08 02 a6     mflr    r0
> > >
> > > <<<
> > >
> > > If this seems reasonable, I can submit a patch.
> > >
> >
> 
> Thanks,
> -Vincent
> 

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]