Skip to content

Commit 7b93d03

Browse files
committed
improved brk
1 parent ed0777c commit 7b93d03

File tree

4 files changed

+18
-18
lines changed

4 files changed

+18
-18
lines changed

src/cpu.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,6 @@ class Executor {
389389
};
390390

391391
void CPU::execute(const Instruction& instruction) {
392-
log("{}", instruction);
392+
// log("{}", instruction);
393393
std::visit(Executor(*this), instruction);
394394
}

src/machine.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
int Machine::run() {
1010
while (true) {
1111
Word pc = m_cpu.get_pc();
12-
log("{:#x}", pc);
12+
// log("{:#x}", pc);
1313

1414
m_cpu.execute(Decoder::decode(fetch()));
1515

src/memory.hh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,14 @@ public:
5151
*reinterpret_cast<T*>(address) = value;
5252
}
5353

54-
// TODO: what about page alignment?
5554
[[nodiscard]] void* get_initial_program_break() const {
5655
auto& [addr, len] = m_mapped_segments.back();
57-
return static_cast<char*>(addr) + len;
56+
size_t program_break = reinterpret_cast<size_t>(addr) + len;
57+
// set the program break to the next full page, to avoid address collisions with the
58+
// previous page from the data segment
59+
// TODO: dont jump to the next page if program_break is perfectly page aligned
60+
size_t aligned = align_to_page_size(program_break) + getpagesize();
61+
return reinterpret_cast<void*>(aligned);
5862
}
5963

6064
private:

src/syscalls.hh

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)