簡體   English   中英

在 linux 中不使用 libc 如何在堆上分配 memory

[英]How do you allocate memory on the heap without using libc in linux

我試圖在堆上分配 memory 而不使用 libc 和使用 linux 系統調用。 我試過使用 mmap 和 brk 但 brk 不會像我讀過的那樣返回堆的結尾,因為它不作為系統調用存在,並且 mmap 只會導致段錯誤.

_start.c

#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define MAP_PRIVATE 0x2
#define MAP_ANONYMOUS 0x20

extern void *mmap(void *addr, unsigned long sz, int prot, int mode, int fd, unsigned long offset);
extern void  exit(int exit_code);

int _start()
{
    void *mem = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    *(int*)mem = 4;

    exit(*(int*)mem);
}

我嘗試這樣做的原因是因為我正在開發一個替代 libc(如果我不知道如何做到這一點,顯然不是一個稱職的 libc,它主要是一個學習練習/有趣的項目),我需要弄清楚如何在堆上實際分配。 我已經尋找了一段時間,但我仍然不知道它是如何工作的。

系統調用.s

    .text
    .global mmap
mmap:
    mov $9, %rax
    syscall
    ret

    .global exit
exit:
    mov $60, %rax
    syscall
    ret

我使用的編譯命令是gcc -nostdlib _start.c syscalls.s

就像我說的,我正在運行 Linux。 具體來說:Ubuntu 20.04 LTS 和 kernel 5.11.0-43-generic。

好吧,這是一個使用strace和使用調試器的好機會。 man 2 syscall

   Arch/ABI      arg1  arg2  arg3  arg4  arg5  arg6  arg7  Notes
   ──────────────────────────────────────────────────────────────
   x86-64        rdi   rsi   rdx   r10   r8    r9    -

gdb a.out

(gdb) b syscalls.s:5
Breakpoint 1 at 0x1050: file syscalls.s, line 5.
(gdb) r
Starting program: /dev/shm/.1000.home.tmp.dir/a.out 

Breakpoint 1, mmap () at syscalls.s:5
5           syscall
(gdb) info registers
rax            0x9                 9
rbx            0x0                 0
rcx            0x22                34                # here it is
rdx            0x3                 3
rsi            0x1000              4096
rdi            0x0                 0
rbp            0x7fffffffd968      0x7fffffffd968
rsp            0x7fffffffd950      0x7fffffffd950
r8             0xffffffffffffffff  -1
r9             0x0                 0
r10            0x555555554000      93824992231424     # WRONG!
r11            0x206               518
r12            0x555555555000      93824992235520
r13            0x7fffffffd970      140737488345456
r14            0x0                 0
r15            0x0                 0
rip            0x555555555050      0x555555555050 <mmap+7>
eflags         0x202               [ IF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0

我們看到 r10 中的值是一些垃圾,而0x22rcx中。 請咨詢https://uclibc.org/docs/psABI-x86_64.pdf

你必須做https://github.com/numactl/numactl/blob/master/syscall.c#L160一些旋轉。 只需mov %rcx, %r10就足夠了。

總的來說,使用https://github.com/lattera/glibc/blob/master/sysdeps/unix/sysv/linux/x86_64/syscall.S#L29

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM