@@ -32,16 +32,18 @@ SYSCALL_NODISCARD inline int close(int fd) {
3232 }
3333}
3434
35- // TODO: doesnt quite work yet, probably needs page alignment
36- SYSCALL_NODISCARD inline int brk (CPU& cpu, Word new_brk) {
37-
38- // TODO: should brk() return the current program break when new_brk == 0?
39- // it only seems to do this when running with strace
35+ // TODO: doesnt quite work yet
36+ SYSCALL_NODISCARD inline Word brk (CPU& cpu, Word new_brk) {
4037
4138 std::println (" new brk: {:#x}" , new_brk);
4239
43- auto new_addr = reinterpret_cast <void *>(new_brk);
44- auto old_addr = cpu.get_program_break ();
40+ auto new_addr = reinterpret_cast <void *>(align_to_page_size (new_brk)+getpagesize ());
41+ auto old_addr = reinterpret_cast <void *>(align_to_page_size (reinterpret_cast <size_t >(cpu.get_program_break ()))+getpagesize ());
42+
43+ // brk() syscall differs from the libc wrapper, in that it returns
44+ // the current program break when calling it with NULL
45+ if (new_brk == 0 )
46+ return reinterpret_cast <Word>(old_addr);
4547
4648 if (new_addr > old_addr) {
4749 // grow the heap
@@ -58,12 +60,10 @@ SYSCALL_NODISCARD inline int brk(CPU& cpu, Word new_brk) {
5860 );
5961
6062 if (ret == MAP_FAILED) {
61- errno = ENOMEM;
6263 return -1 ;
6364 }
6465
6566 cpu.set_program_break (new_addr);
66- return 0 ;
6767
6868 } else if (new_addr < old_addr) {
6969 // shrink the heap
@@ -76,16 +76,12 @@ SYSCALL_NODISCARD inline int brk(CPU& cpu, Word new_brk) {
7676 // return -1;
7777 // }
7878
79- return 0 ;
80-
8179 } else if (new_addr == old_addr) {
8280 // do nothing
83- return 0 ;
8481
85- } else {
86- throw std::runtime_error (" unreachable" );
8782 }
8883
84+ return 0 ;
8985}
9086
9187} // namespace syscalls
0 commit comments