From b1767533af0252f704910dee73907e5849ab5c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Sun, 11 Aug 2019 00:00:02 +0000 Subject: [PATCH] mmap anonymous --- README.adoc | 44 ++++++++++++++++++++++++++++----- userland/c/malloc.c | 17 ++++++++++--- userland/glibc/README.adoc | 1 - userland/glibc/build | 1 - userland/glibc/test | 1 - userland/{glibc => linux}/brk.c | 0 userland/linux/mmap_anonymous.c | 40 ++++++++++++++++++++++++++++++ userland/posix/mmap_file.c | 11 +-------- 8 files changed, 92 insertions(+), 23 deletions(-) delete mode 100644 userland/glibc/README.adoc delete mode 120000 userland/glibc/build delete mode 120000 userland/glibc/test rename userland/{glibc => linux}/brk.c (100%) create mode 100644 userland/linux/mmap_anonymous.c diff --git a/README.adoc b/README.adoc index 40cad2a..7e131f3 100644 --- a/README.adoc +++ b/README.adoc @@ -12535,11 +12535,26 @@ Programs under link:userland/c/[] are examples of https://en.wikipedia.org/wiki/ Allocate memory! Vs using the stack: https://stackoverflow.com/questions/4584089/what-is-the-function-of-the-push-pop-instructions-used-on-registers-in-x86-ass/33583134#33583134 -* link:userland/c/malloc.c[]: `malloc` hello world: allocate two ints and use them. -* link:userland/c/out_of_memory.c[]: test how much memory Linux lets us allocate +link:userland/c/malloc.c[]: `malloc` hello world: allocate two ints and use them. LInux 5.1 / glibc 2.29 implements it with the <>. +===== malloc out o fmemory + +Test how much memory Linux lets us allocate: + +.... +./run --userland userland/c/out_of_memory.c +.... + +Source: link:userland/c/out_of_memory.c[] + +Outcome at c03d5d18ea971ae85d008101528d84c2ff25eb27 on Ubuntu 19.04 <> host: prints up to `0x1000000000` (64GiB). + +TODO dive into source code. + +Bibliography: https://stackoverflow.com/questions/2798330/maximum-memory-which-malloc-can-allocate + ==== GCC C extensions ===== C empty struct @@ -12638,19 +12653,36 @@ getconf -a ==== mmap -The mmap system call allows advanced memory operations: - -* link:userland/posix/mmap_file.c[]: memory mapped file example +The mmap system call allows advanced memory operations. mmap is notably used to implement the <> function, replacing the previously used break system call. Linux adds has several POSIX extension flags to it. +[[mmap-map-anonymous]] +===== mmap MAP_ANONYMOUS + +Basic `mmap` example, do the same as link:userland/c/malloc.c[], but with `mmap`. + +Example: userland/linux/mmap_anonymous.c[] + +In POSIX 7 mmap always maps to a file. + +If we add the MAP_ANONYMOUS Linux extension however, this is not required, and mmap can be used to allocate memory like malloc. + +===== mmap file + +Memory mapped file example: link:userland/posix/mmap_file.c[] + +The example creates a file, mmaps to it, writes to maped memory, and then closes the file. + +We then read the file and confirm it was written to. + ===== brk Previously <>, but was deprecated in favor of <> -Example: link:userland/glibc/brk.c[] +Example: link:userland/linux/brk.c[] The example allocates two ints and uses them, and then deallocates back. diff --git a/userland/c/malloc.c b/userland/c/malloc.c index ad996eb..7759c66 100644 --- a/userland/c/malloc.c +++ b/userland/c/malloc.c @@ -5,18 +5,27 @@ #include int main(void) { - size_t bytes = sizeof(int) * 2; - /* Allocate 2 ints. */ - int *is = malloc(bytes); + int *is; + size_t nbytes = 2 * sizeof(*is); + + /* Allocate 2 ints. Note that unlike traditional stack arrays (non-VLA) + * this value does not have to be determined at compile time! */ + is = malloc(nbytes); + /* This can happen for example if we ask for too much memory. */ if (is == NULL) { perror("malloc"); exit(EXIT_FAILURE); } + + /* Write to and read from the allocated memory. */ is[0] = 1; + is[1] = 2; assert(is[0] == 1); + assert(is[1] == 2); + /* Free the allocated memory. */ free(is); + return EXIT_SUCCESS; } - diff --git a/userland/glibc/README.adoc b/userland/glibc/README.adoc deleted file mode 100644 index 0bfc9d7..0000000 --- a/userland/glibc/README.adoc +++ /dev/null @@ -1 +0,0 @@ -This directory contains glibc extensions to POSIX / ANSI C. diff --git a/userland/glibc/build b/userland/glibc/build deleted file mode 120000 index ab18017..0000000 --- a/userland/glibc/build +++ /dev/null @@ -1 +0,0 @@ -../build \ No newline at end of file diff --git a/userland/glibc/test b/userland/glibc/test deleted file mode 120000 index 419df4f..0000000 --- a/userland/glibc/test +++ /dev/null @@ -1 +0,0 @@ -../test \ No newline at end of file diff --git a/userland/glibc/brk.c b/userland/linux/brk.c similarity index 100% rename from userland/glibc/brk.c rename to userland/linux/brk.c diff --git a/userland/linux/mmap_anonymous.c b/userland/linux/mmap_anonymous.c new file mode 100644 index 0000000..5ca8a29 --- /dev/null +++ b/userland/linux/mmap_anonymous.c @@ -0,0 +1,40 @@ +/* https://cirosantilli.com/linux-kernel-module-cheat#mmap-map-anonymous */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +int main(void) { + int *is; + size_t nbytes = 2 * sizeof(*is); + + /* Allocate 2 ints. */ + is = mmap( + NULL, + nbytes, + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, + -1, + 0 + ); + + /* This can happen for example if we ask for too much memory. */ + if (is == NULL) { + perror("mmap"); + exit(EXIT_FAILURE); + } + + /* Write to and read from the allocated memory. */ + is[0] = 1; + is[1] = 2; + assert(is[0] == 1); + assert(is[1] == 2); + + /* Free the allocated memory. */ + munmap(is, nbytes); + + return EXIT_SUCCESS; +} diff --git a/userland/posix/mmap_file.c b/userland/posix/mmap_file.c index 831d660..a11ad51 100644 --- a/userland/posix/mmap_file.c +++ b/userland/posix/mmap_file.c @@ -1,13 +1,4 @@ -/* https://cirosantilli.com/linux-kernel-module-cheat#mmap - * - * Example of mmap on files. - * - * Create a file, mmap to it, write to maped memory, close. - * - * Then read the file and confirm it was written to. - * - * Implemented in Linux by the mmap syscall. - */ +/* https://cirosantilli.com/linux-kernel-module-cheat#mmap-file */ #define _XOPEN_SOURCE 700 #include