Message board for the users of flat assembler.
> Unix > brk vs sbrk vs mmap on FreeBSD
Chewy509 16 Nov 2006, 00:56
I'm in the process of porting some apps to FreeBSD, and have found that my malloc() code wasn't working.
After some testing, came across that sbrk (brk is aliased to sbrk on fbsd) is no longer supported for 64bit apps on AMD64. (Returns error 45 - EOPNOTSUPP // Operation Not Supported). However couldn't find any documentation anywhere on the internet to support this? The kernel source seems to run around in circles... (if someone could tell the exact source code file that does the actual sbrk implementation, it would be great).
So did some research and found that FreeBSD coders recommend mmap() over sbrk() anyway... However when using mmap(), I'm getting an invalid file handle message? Code is below:
memInit: mov r4, 0 ; don't care where the memory is allocated mov r5, 1048576 ; alloc 1MB mov r3, 3 ; RW access to memory mov r2, 4096 ; MAP_ANON - not a file mov r8, -1 ; -1 for file handle if using MAP_ANON mov r9, 0 ; ignored for MAP_ANON mov r0, 197 ; mmap(); syscall mov qword [_mmap], r0 ; save address so we can release it on exit; ret
Note: r0 = rax, r1 = rbx, r2 = rcx, r3 = rdx, r4 = rdi, r5 = rsi, r6 = rbp, r7 = rsp.
Carry flag is set, and r0 = EBADF (9) ; Bad File Descriptor?
So does anyone have an example of a working call to mmap() or tell me what's wrong with the above code, and possibly confirm the implementation status of sbrk()?
|16 Nov 2006, 00:56||
jb 01 Apr 2007, 00:12
According to the NetBSD 3.1 man page for mmap, MAP_SHARED or MAP_PRIVATE should be present.
Another thing is, you leave out argument #7. Your r9 is not the `offset' but the `pad' parameter. You should push a zero offset for amd64 I think.
Anyhow, in NetBSD 3.1/i386 this test program seems to work:
$ cat test.asm
format elf executable
push 0 0 ;64 bit offset
push 0xdeadbeef ;pad
push -1 ;fd
push 0x1002 ;MAP_ANON|MAP_PRIVATE
push 7 ;rwx
push 2*4096 ;give me two pages
push 0 ;I don't care where
xor eax,eax ;exit 0
Just after the system call, running under a debugger, the memory map looks like this:
08048000 4K read/write/exec [ heap ]
BDBFD000 8K read/write/exec [ anon ]
BDBFF000 4K read/exec [ uvm_aobj ]
BDC00000 30720K [ stack ]
BFA00000 1984K read/write [ stack ]
BFBF0000 64K read/write [ stack ]
The second line shows the 8K allocated.
|01 Apr 2007, 00:12||
Chewy509 04 Apr 2007, 01:39
Thanks for the late reply, but did eventually sort this issue out...
On FreeBSD 6.1, the direct interface to mmap() syscall will always return invalid file descriptor, but if you use the generic syscall interface, it works fine. (The syscall that lets you call other syscalls through it, I'm at work and don't have the syscall number handy).
Reading through the FreeBSD libc, and it's mmap() call, it eventually maps through it the kernel mmap() syscall, with an 8th parameter as well (the mmap() man page only has 7 parameters, which is correct for the libc mmap() call, but not for the kernel mmap() call).
But in the end I did get it working (somewhat).
|04 Apr 2007, 01:39||
jb 04 Apr 2007, 18:57
Running ktruss (or strace or whatever it is called on FreeBSD) is often a convenient alternative to reading politically correct man pages.
|04 Apr 2007, 18:57||
< Last Thread | Next Thread >
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.