まず読者が知らねばならぬのはプロセスアドレス空間の全体像です。
図の上から説明していきますね。
32 ビットのカーネル空間は 0xFFFFFFFF から 0xc0000000 が 1GB になります。
0xc0000000 から 0xF7FFFFFFF は物理アドレスのカーネルイメージにマップされ、その他の領域は自由に使われるって理解でよろしいかと思います。
次にスタックセグメントは上位アドレスから下がっていきますが、32 ビットだと 4 から 8MB ぐらいでしょうかね。
スタックセグメントはランダムに生成される stack オフセットから開始します。
そして RLIMIT_STACK はプロセススタックの最大サイズのことです。
setrlimit と getrlimit 関数の resource の種類としてアクセスできます。
#include <sys/time.h> #include <sys/resource.h> int getrlimit(int resource, struct rlimit *rlim); int setrlimit(int resource, const struct rlimit *rlim);
struct rlimit はソフトリミットとハードリミットとして指定できます。
struct rlimit { rlim_t rlim_cur; /* Soft limit */ rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */ };
スタックの次は、メモリーマッピング(Memory Mapping)セグメントになりますが、これはスタックセグメントの末尾アドレスからランダムに生成されるオフセットを足した位置から開始します。
メモリーマッピングは mmap 関数などでも使われますが、動的ライブラリなどもマップされるので、かなり自由度の高い領域ですかね。
最後にヒープセグメントですが、これは下位アドレスから上位アドレスにあげていきます。
また開始位置は未初期化データセグメント(BSS)の終了アドレスの後に brk オフセットを足したアドレスとなります。
sbrk は start break の略で、ヒープセグメントの開始位置を意味します。
それと brk は program break の略で、ヒープの終了位置を意味します。
ちなみに後述しますが brk オフセットを指定できる sbrk() 関数という直接コールする機会がほぼゼロの低レイヤーな関数が存在します。
Copyright 2018-2019, by Masaki Komatsu