ウォンツテック

そでやまのーと

OS作成 - シェル編

ユーザライブラリ用のmalloc実装中。Antosのmallocなどを参考。AntosではLinuxと同様にmalloc中にheap領域が足りなくなったらsbrk(brk)を呼んでいるけど、その初期値が固定値となっていた。別に固定値でも何の問題も無いけど、Linuxではtextセクション、dataセクション、bssセクションと続く次の領域をheap領域としpagingで実メモリアドレスと関連付けていて実際mallocして取得したアドレスを見てみると大体0x8000000から0x9000000辺りのアドレスをランダムに取得しているようです。
ちょっと気になったのでglibcmallocのソースをちょっとだけ見てみる事にしました。

glibc-2.6.1

malloc/malloc.c

#define public_mALLOc   __libc_malloc  (471行目)
(snip)
strong_alias(__libc_malloc, malloc) (5933行目)

strong_aliasはただのtypedefなのでmallocmalloc.c内ではpublic_mALLOcとして定義されているようです。

3554行目

Void_t*
public_mALLOc(size_t bytes)
{
 (snip)
  victim = _int_malloc(ar_ptr, bytes);
 (snip)
}

実態は_int_mallocのようです。

4061行目

Void_t*
_int_malloc(mstate av, size_t bytes)
{
(snip)
 void *p = chunk2mem(victim);
 alloc_perturb(p, bytes);
 return p;
(snip)

要求しているメモリサイズが小さい場合や大きい場合によって様々な処理をしていますが、結局の所struct malloc_chunk構造体をヘッダーとして持つメモリ領域victimを返しています(ヘッダーを除いた領域)。
victimはstruct malloc_stateの構造体であるavの値によって様々な算出をされてますが、例えば要求サイズ(ヘッダー追加、アライン等をしたサイズ)がget_max_fast() (デフォルトだと64byte)以下の場合、struct malloc_stateのfastbins配列からメモリ候補が返されます。
次に小さい要求サイズ(64*8byte以下ほど)だとstruct malloc_state構造体のbins配列からメモリ候補が返されます。
正確にはメモリサイズにより4つのアルゴリズムが選択されているようです。

1.128KB以上の場合
 system memory mapping使用
2. 512byte 〜 128KB
 pure best-fit allocator
3. 64byte 〜 512byte
 bins配列使用
 状況に応じて対応?(2or4)
4. 64byte未満
 fastbin配列使用

mallocテストをした時のランダムに返ってきたように見えたアドレス値は4のfastbin配列のindexが毎回変化しているため取り出されるアドレス値が変わっていたようです。

※sodexではとりあえず、kernelと同様にK&Rのようなmallocを実装予定です。