Extra callq at beginning of function call


#1

I’ve been working on a rust UEFI operating system, and I’m getting confused about this one callq that seems to be calling to code that doesn’t exist.

0x0000000006693fa0 <+0>:	push   %rbp
0x0000000006693fa1 <+1>:	mov    %rsp,%rbp
0x0000000006693fa4 <+4>:	sub    $0x180,%rsp
0x0000000006693fab <+11>:	mov    %rdi,%rax
0x0000000006693fae <+14>:	mov    $0x1d,%ecx
0x0000000006693fb3 <+19>:	mov    $0x8,%edx
0x0000000006693fb8 <+24>:	lea    -0x130(%rbp),%r8
0x0000000006693fbf <+31>:	mov    %rdi,-0x158(%rbp)
0x0000000006693fc6 <+38>:	mov    %r8,%rdi
0x0000000006693fc9 <+41>:	mov    %rsi,-0x160(%rbp)
0x0000000006693fd0 <+48>:	mov    %ecx,%esi
0x0000000006693fd2 <+50>:	mov    %rax,-0x168(%rbp)
0x0000000006693fd9 <+57>:	callq  0x66c3700
0x0000000006693fde <+62>:	mov    -0x160(%rbp),%rax
0x0000000006693fe5 <+69>:	mov    %rax,-0x8(%rbp)
0x0000000006693fe9 <+73>:	callq  0x66941d0 <gnu_efi::mem::size_of<gnu_efi::def::MemoryDescriptors>> 
0x0000000006693fee <+78>:	lea    -0x88(%rbp),%rdi
0x0000000006693ff5 <+85>:	mov    %rax,-0x10(%rbp)
0x0000000006693ff9 <+89>:	callq  0x66941e0 <gnu_efi::mem::uninitialized<gnu_efi::def::MemoryDescriptors>>
0x0000000006693ffe <+94>:	callq  0x66941f0 <gnu_efi::mem::uninitialized<usize>>
0x0000000006694003 <+99>:	mov    %rax,-0x90(%rbp)
0x000000000669400a <+106>:	callq  0x66941f0 <gnu_efi::mem::uninitialized<usize>>
0x000000000669400f <+111>:	mov    %rax,-0x98(%rbp)
0x0000000006694016 <+118>:	callq  0x6694200 <gnu_efi::mem::uninitialized<u32>>
0x000000000669401b <+123>:	lea    -0x88(%rbp),%rdx
0x0000000006694022 <+130>:	mov    %eax,-0x9c(%rbp)
0x0000000006694028 <+136>:	mov    -0x8(%rbp),%rdi
0x000000000669402c <+140>:	mov    0x38(%rdi),%rdi
0x0000000006694030 <+144>:	mov    %rdx,-0xc0(%rbp)
0x0000000006694037 <+151>:	movq   $0x3,-0xb8(%rbp)
0x0000000006694042 <+162>:	mov    -0xc0(%rbp),%rdx
0x0000000006694049 <+169>:	mov    -0xb8(%rbp),%rsi
0x0000000006694050 <+176>:	mov    %rdi,-0x170(%rbp)
0x0000000006694057 <+183>:	mov    %rdx,%rdi
0x000000000669405a <+186>:	callq  0x6694210 <gnu_efi::slice::[T].SliceExt::as_mut_ptr>
0x000000000669405f <+191>:	lea    -0x10(%rbp),%rdi
0x0000000006694063 <+195>:	lea    -0x90(%rbp),%rdx
0x000000000669406a <+202>:	lea    -0x98(%rbp),%rcx
0x0000000006694071 <+209>:	lea    -0x9c(%rbp),%r8
0x0000000006694078 <+216>:	mov    %rax,-0xb0(%rbp)
0x000000000669407f <+223>:	mov    -0xb0(%rbp),%rsi
0x0000000006694086 <+230>:	mov    -0x170(%rbp),%rax
0x000000000669408d <+237>:	callq  *%rax
0x000000000669408f <+239>:	lea    -0xa8(%rbp),%rdi
0x0000000006694096 <+246>:	lea    0x31293(%rip),%rsi        # 0x66c5330 <_ZN4core3num7flt2dec8strategy5grisu12CACHED_POW1017h66041a01fc2c0e94E+248>
0x000000000669409d <+253>:	mov    %rax,-0xa8(%rbp)
0x00000000066940a4 <+260>:	callq  0x6694230 <gnu_efi::cmp::PartialEq::ne<gnu_efi::err::Status>>
0x00000000066940a9 <+265>:	and    $0x1,%al
0x00000000066940ab <+267>:	mov    %al,-0xc1(%rbp)
0x00000000066940b1 <+273>:	testb  $0x1,-0xc1(%rbp)
0x00000000066940b8 <+280>:	je     0x669418d <gnu_efi::api::BootServices::get_memory_map+493>
0x00000000066940be <+286>:	lea    -0x130(%rbp),%rax
0x00000000066940c5 <+293>:	movups 0x3679c(%rip),%xmm0        # 0x66ca868 <panic_bounds_check_loc55659+16>
0x00000000066940cc <+300>:	movaps %xmm0,-0x110(%rbp)
0x00000000066940d3 <+307>:	mov    -0x110(%rbp),%rsi
0x00000000066940da <+314>:	mov    -0x108(%rbp),%rdx
0x00000000066940e1 <+321>:	lea    -0xa8(%rbp),%rcx
0x00000000066940e8 <+328>:	mov    %rcx,-0x128(%rbp)
0x00000000066940ef <+335>:	mov    %rcx,-0x130(%rbp)
0x00000000066940f6 <+342>:	mov    %rax,-0x138(%rbp)
0x00000000066940fd <+349>:	mov    %rdx,-0x178(%rbp)
0x0000000006694104 <+356>:	mov    %rsi,-0x180(%rbp)
0x000000000669410b <+363>:	lea    -0x3562(%rip),%rdx        # 0x6690bb0 <gnu_efi::err::Status.::core::fmt::Debug::fmt>
0x0000000006694112 <+370>:	lea    -0x120(%rbp),%rdi
0x0000000006694119 <+377>:	mov    -0x138(%rbp),%rax
0x0000000006694120 <+384>:	mov    (%rax),%rax
0x0000000006694123 <+387>:	mov    %rax,-0x140(%rbp)
0x000000000669412a <+394>:	mov    -0x140(%rbp),%rsi
0x0000000006694131 <+401>:	callq  0x66942c0 <gnu_efi::fmt::ArgumentV1<'a>::new<gnu_efi::err::Status>>
0x0000000006694136 <+406>:	lea    -0xf8(%rbp),%rdi
0x000000000669413d <+413>:	lea    -0x120(%rbp),%rax
0x0000000006694144 <+420>:	mov    %rax,-0x150(%rbp)
0x000000000669414b <+427>:	movq   $0x1,-0x148(%rbp)
0x0000000006694156 <+438>:	mov    -0x150(%rbp),%rcx
0x000000000669415d <+445>:	mov    -0x148(%rbp),%r8
0x0000000006694164 <+452>:	mov    -0x180(%rbp),%rsi
0x000000000669416b <+459>:	mov    -0x178(%rbp),%rdx
0x0000000006694172 <+466>:	callq  0x6694270 <gnu_efi::fmt::Arguments<'a>::new_v1>
0x0000000006694177 <+471>:	lea    -0xf8(%rbp),%rdi
0x000000000669417e <+478>:	lea    0x3670b(%rip),%rax        # 0x66ca890 <panic_bounds_check_loc55661+8>
0x0000000006694185 <+485>:	mov    %rax,%rsi
0x0000000006694188 <+488>:	callq  0x6694cc0 <_ZN4core9panicking9panic_fmt17ha6b3c19493c123b3E>
0x000000000669418d <+493>:	mov    $0x78,%eax
0x0000000006694192 <+498>:	mov    %eax,%edx
0x0000000006694194 <+500>:	lea    -0x88(%rbp),%rcx
0x000000000669419b <+507>:	mov    -0x158(%rbp),%rsi
0x00000000066941a2 <+514>:	mov    %rsi,%rdi
0x00000000066941a5 <+517>:	mov    %rcx,%rsi
0x00000000066941a8 <+520>:	callq  0x66c3730
0x00000000066941ad <+525>:	mov    -0x90(%rbp),%rcx
0x00000000066941b4 <+532>:	mov    -0x158(%rbp),%rdx
0x00000000066941bb <+539>:	mov    %rcx,0x78(%rdx)
0x00000000066941bf <+543>:	mov    -0x168(%rbp),%rax
0x00000000066941c6 <+550>:	add    $0x180,%rsp
0x00000000066941cd <+557>:	pop    %rbp
0x00000000066941ce <+558>:	retq 

Although the code makes sense in general, there is one line that says callq 0x66c3700, and gdb can’t find that symbol in my object file. I looked at the MIR generated for this code and couldn’t figure out what this function call might be.

Here’s the code that this function corresponds to:

pub fn get_memory_map(&self) -> (def::MemoryDescriptors, usize) {
    let mut memory_map_size = mem::size_of::<def::MemoryDescriptors>();
    unsafe {
        let mut memory_map: def::MemoryDescriptors = mem::uninitialized();
        let mut map_key = mem::uninitialized();
        let mut descriptor_size = mem::uninitialized();
        let mut descriptor_version = mem::uninitialized();

        let status = (self.GetMemoryMap)(
                &mut memory_map_size,
                memory_map.descriptors.as_mut_ptr(),
                &mut map_key,
                &mut descriptor_size,
                &mut descriptor_version);

        if status != def::Status::Success {
            panic!("Unable to get memory map: {:?}", status);
        }

        (memory_map, map_key)
    }
}

Does anyone have any ideas what that callq might be?


#2

Given mov $0x1d,%ecx, I’m guessing it’s a call to memset.

If you want a more readable version of the assembly, rustc --emit asm might help.


#3

Yep! It was a call to memset. Adding rlibc to my Cargo.toml fixed the problem.