C功能参数神秘漂移?

And*_*ang 5 c assembly function mips parameter-passing

我正在使用Samba 3.6.25工作.当我按照"smbclient"的源代码试图构建我自己的SMB服务器列表实用程序时,我遇到了一个奇怪的事情:

当我调用一个函数时,它会跳过我的第一个参数,然后用第二个参数填充它,然后第二个填充第三个参数,如下所示.

我调用该函数是:cli_rpc_pipe_open_noauth_transport()cli_pipe.c.我在其中添加了一些调试代码:

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;
    }
……
Run Code Online (Sandbox Code Playgroud)

这就是我调用这个函数的方式:

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);
}
Run Code Online (Sandbox Code Playgroud)

这是我在控制台中得到的:

--- 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
Run Code Online (Sandbox Code Playgroud)

它没有意义!注意到我传递的四个参数是:0xdb2b20,0x1,0xda31c0,0x7fe9fdc8但是cli_rpc_pipe_open_noauth_transport()得到的是:0x1,0xda31c0,0x7fe9fdc8,0xdaf3d0

很明显,第一个参数"0xdb2b20"丢失了,第二个参数取代了它.

有谁知道发生了什么,我怎么能解决它?

非常感谢你提前!

- - 附加信息:

我使用的工具链是mipsel-linux-uclibc-cc/ld/ar.我试图objdump几个目标文件,看看发生了什么.

我转储了自己的程序,这里是调用函​​数的汇编.注意到四个参数按顺序传递: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
Run Code Online (Sandbox Code Playgroud)

然后我转储了smbclient,它也调用了cli_rpc_pipe_open_noauth_transport().这里出现了问题:似乎a0不用于传递参数!!!

<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
Run Code Online (Sandbox Code Playgroud)

最后我转储cli_rpc_pipe_open_noauth_transport()本身,看起来它在smbclient的方式下工作:

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
Run Code Online (Sandbox Code Playgroud)

附加信息No.2 - 我如何编译我的程序

  1. 我从官方FTP服务器上下载了Samba.
  2. 配置并制作(交叉编译)
  3. 找到"source3"目录中的所有.o文件,然后将它们一起存档在一个.a文件中.
  4. 创建我自己的应用程序,调用Samba函数大多就像它自己的程序"smbclient"一样,有很多-I选项可以确保编译工作
  5. 链接Samba正式提供的libsmbclient.a,以及我自己在步骤3中存档的.a.

附加信息第3号

此存储库的完整源代码:https: //github.com/Andrew-MC/SMB-CIFS_discovery

And*_*ang 1

提问者的回答在这里:

我解决了。其实我并没有解决问题本身,而是尝试了另一种方式来达到我的目的。

我构建项目的旧方法是:首先构建 Samba,然后链接 Samba 存储库外部的 Samba 对象和静态库文件。这是我遇到问题的时候。

我改变了构建的方式:首先用我自己的代码覆盖原来的Samba“smbclient”代码,然后构建Samba。Samba Makefile 将我的源文件识别为 smbclient 源文件并顺利编译和链接它们。最后,它成功了。

请参考我在问题中提到的 GitHub 存储库。