What is the drift of parameters when a function is called? (The first parameter is lost and the second parameter becomes the value of the first parameter)

  c++, question

I have the same question above StackOverflow. “C function parameter mysteriously drifted?

The following are Chinese questions:


I am currently making a small tool based on Samba 3.6.25. Please refer tosmbclientThe function calling method of the program is to design an SMB/CIFS discovery/directory listing tool.

There is a called library function in a static library. a. When I called, I found that the parameters magically drifted, the first parameter somehow lost, and the later parameters were added to the front …

The function I want to call iscli_pipe.cFrom insidecli_rpc_pipe_open_noauth_transport()The method is called like this:

NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
 enum dcerpc_transport_t transport,
 const struct ndr_syntax_id *interface,
 struct rpc_pipe_client **presult)
 {
 
 struct rpc_pipe_client *result;
 struct pipe_auth_data *auth;
 NTSTATUS status;
 
 status = cli_rpc_pipe_open(cli, transport, interface, &result);
 _DEBUG("cli = %p", cli);
 _DEBUG("transport = %p", transport);
 _DEBUG("interface = %p", interface);
 _DEBUG("presult = %p", presult);
 _DEBUG("cli->desthost = %p", cli->desthost);
 _DEBUG("cli->desthost = \"%s\"", cli->desthost);
 if (!  NT_STATUS_IS_OK(status)) {
 return status;
 }
 ......

I call it this way:

NTSTATUS _pipe_open_noauth(struct cli_state *cli, const struct ndr_syntax_id *intf, struct rpc_pipe_client **presult)
 {
 SMBD_DEBUG("cli = %p", cli);
 SMBD_DEBUG("intf = %p", intf);
 SMBD_DEBUG("presult = %p", presult);
 SMBD_DEBUG("cli->desthost = %p", cli->desthost);
 SMBD_DEBUG("cli->desthost = \"%s\"", cli->desthost);
 return cli_rpc_pipe_open_noauth_transport(cli, 1, intf, presult);
 }

But the output I got was this:

--- SMBD (util_smbclient.c, 117): cli = 0xdb2b20
 --- SMBD (util_smbclient.c, 118): intf = 0xda31c0
 --- SMBD (util_smbclient.c, 119): presult = 0x7fe9fdc8
 --- SMBD (util_smbclient.c, 120): cli->desthost = 0xdd3a50
 --- SMBD (util_smbclient.c, 121): cli->desthost = "192.168.1.125"
 === Samba (rpc_client/cli_pipe.c, 2873): cli = 0x1
 === Samba (rpc_client/cli_pipe.c, 2874): transport = 0xda31c0
 === Samba (rpc_client/cli_pipe.c, 2875): interface = 0x7fe9fdc8
 === Samba (rpc_client/cli_pipe.c, 2876): presult = 0xdaf3d0

Obviously, my first parameteraDisappeared, and the second parameterbReplaced in the called functionaThe location of the; The following parameters are replaced in sequence …

Excuse me, everyone, what is going on here? Is there something wrong with the linker?


Additional Information 1:

The tool chain I used was mipsel-linux-uclibc-cc/ld/ar, and I tried to do objdump on the generation target:

Your own program:

It can be found that the parameters are passed in the order a0, a1, a2, a3:

409bf0:   8fdc0010    lw  gp,16(s8)
 409bf4:   8fc40020    lw  a0,32(s8)
 409bf8:   24050001    li  a1,1            # store “1” in a1
 409bfc:   8fc60024    lw  a2,36(s8)
 409c00:   8fc70028    lw  a3,40(s8)
 409c04:   8f99ab74    lw  t9,-21644(gp)
 409c08:   00000000    nop
 409c0c:   0320f809    jalr    t9
 409c10:   00000000    nop
 409c14:   8fdc0010    lw  gp,16(s8)
 409c18:   03c0e821    move    sp,s8
 409c1c:   8fbf001c    lw  ra,28(sp)
 409c20:   8fbe0018    lw  s8,24(sp)
 409c24:   03e00008    jr  ra
 409c28:   27bd0020    addiu   sp,sp,32

smbclient:

This is Samba’s own realization. It seems strange thatA0 is not used to pass parameters

<cli_rpc_pipe_open_noauth>:
 …
 487840:   8fdc0018    lw  gp,24(s8)
 487844:   8fc2003c    lw  v0,60(s8)
 487848:   00000000    nop
 48784c:   afa20010    sw  v0,16(sp)
 487850:   02002021    move    a0,s0
 487854:   8fc50034    lw  a1,52(s8)
 487858:   24060001    li  a2,1    # Here, the number “1” was stored in a2 instead of a1!  !  !
 48785c:   8fc70038    lw  a3,56(s8)
 487860:   8f99aed0    lw  t9,-20784(gp)
 487864:   00000000    nop
 487868:   0320f809    jalr    t9  # cli_rpc_pipe_open_noauth_transport()
 48786c:   00000000    nop
 487870:   8fdc0018    lw  gp,24(s8)
 487874:   02001021    move    v0,s0
 487878:   03c0e821    move    sp,s8
 48787c:   8fbf0028    lw  ra,40(sp)
 487880:   8fbe0024    lw  s8,36(sp)
 487884:   8fb00020    lw  s0,32(sp)
 487888:   03e00008    jr  ra
 48788c:   27bd0030    addiu   sp,sp,48

The called function itself:

It seems that a0 does not store parameters in the same way as smbclient did earlier:

0053bdac <cli_rpc_pipe_open_noauth_transport>:
 53bdac:   3c1c0087    lui gp,0x87
 53bdb0:   279c3624    addiu   gp,gp,13860
 53bdb4:   0399e021    addu    gp,gp,t9
 53bdb8:   27bdffc0    addiu   sp,sp,-64
 53bdbc:   afbf0038    sw  ra,56(sp)
 53bdc0:   afbe0034    sw  s8,52(sp)
 53bdc4:   afb00030    sw  s0,48(sp)
 53bdc8:   03a0f021    move    s8,sp
 53bdcc:   afbc0018    sw  gp,24(sp)
 53bdd0:   afc40040    sw  a0,64(s8)
 53bdd4:   afc50044    sw  a1,68(s8)
 53bdd8:   afc60048    sw  a2,72(s8)
 53bddc:   afc7004c    sw  a3,76(s8)
 53bde0:   8f848080    lw  a0,-32640(gp)
 53bde4:   00000000    nop
 53bde8:   24844da0    addiu   a0,a0,19872
 53bdec:   24050b39    li  a1,2873
 53bdf0:   8fc60044    lw  a2,68(s8)
 53bdf4:   8f99cab0    lw  t9,-13648(gp)
 53bdf8:   00000000    nop
 53bdfc:   0320f809    jalr    t9              <—— invoke cli_rpc_pipe_open()
 53be00:   00000000    nop

Note: I am hereStackOverflowOn the same question:C function parameter mysteriously drifted?

Resolved by myself-to be exact, the reason for the original problem is still unknown. I didn’t solve it in a targeted way, but I completed my goal in a different way.

The previous problem was that Samba was compiled first and then an application was compiled to link Samba’s. o file.
Now I change to: copy my application code into Samba’s project, and let Samba’s Makefile compile my application directly, so that the compiled program can be executed normally.