vm_offset_t、(void *) 和 mach_vm_size_t 之间的区别

Difference between vm_offset_t, (void *), and mach_vm_size_t

我正在尝试理解 this code for reading virtual memory mappings,但我无法理解不同的数据类型,因为我找不到任何好的文档。

vm_offset_tvoid *mach_vm_size_t有什么区别?在我的机器上,它们似乎都是 8 字节(64 位),用于导航虚拟内存。他们的目的有什么区别?拥有这些不同类型的意义何在?

编辑:

例如,在链接代码中:

unsigned char *
readProcessMemory (int pid, mach_vm_address_t addr, mach_msg_type_number_t *size)
{
    // Helper function to read process memory (a la Win32 API of same name)
    // To make it easier for inclusion elsewhere, it takes a pid, and
    // does the task_for_pid by itself. Given that iOS invalidates task ports
    // after use, it's actually a good idea, since we'd need to reget anyway

    task_t  t;
    task_for_pid(mach_task_self(),pid, &t);
        mach_msg_type_number_t  dataCnt = size;
        vm_offset_t readMem;
    
    // Use vm_read, rather than mach_vm_read, since the latter is different
    // in iOS.

        kern_return_t kr = vm_read(t,        // vm_map_t target_task,
                     addr,     // mach_vm_address_t address,
                     *size,     // mach_vm_size_t size
                     &readMem,     //vm_offset_t *data,
                     size);     // mach_msg_type_number_t *dataCnt

        if (kr) {
                // DANG..
                fprintf (stderr, "Unable to read target task's memory @%p - kr 0x%x\n" , addr, kr);
                 return NULL;
                }

    return ( (unsigned char *) readMem);

}

根据 this documentation of the vm_read functiondata_out 参数是“读取返回的动态字节数组的外指针”。

但是在上面的代码中,他们为 data_out 传入了 &readMem(类型 vm_offset_t *)。我对这里如何使用 readMem 感到困惑 - 它是指向读取返回的动态字节数组的指针吗?还是它实际上包含动态字节数组? vm_offset_t 是指针还是地址?它的目的是什么?

同样

vm_offset_tvoid*mach_vm_size_t在内部都是unsigned long的同义词,但它们用于使代码更具可读性和表现力。

vm_read returns readMem 中的 address,这意味着 readMem 需要转换为指针,并且取消引用以访问其值。

此外,readMem 指向的内存区域由内核分配,因此需要用 vm_deallocate. To avoid this, consider using vm_read_overwrite 释放它,这将填充它提供的缓冲区。