malloc源码分析(2)--常用的常量&&变量&&方法


在glibc源码学习里面有时候会遇见一些#define ,当我们先大概知道一些会在调试的时候更轻松
[未完待续]

SIZE_SZ

这个其实就是用来判断你当前运行环境是32位还是64位的,变化的长度
32位是4
64位是8

#define INTERNAL_SIZE_T size_t
#define SIZE_SZ                (sizeof(INTERNAL_SIZE_T))

SIZE_SZ 相当于就是size_t的大小,在64位上就是8
所以我们相当于

#define SIZE_SZ 8

DEFAULT_MXFAST

这个是默认的fastbin的最大大小

#define DEFAULT_MXFAST     (64 * SIZE_SZ / 4)

有了前面的定义,这里就是

#define DEFAULT_MXFAST    128  

所以一般fastbin默认最大小就是0x80

get_max_fast

static INTERNAL_SIZE_T global_max_fast;
#define get_max_fast() global_max_fast

最开始没有初始化的时候其实global_max_fast为0
当我们跟malloc的时候有一步骤是初始化global_max_fast
他调用了
set_max_fast(DEFAULT_MXFAST)

#define set_max_fast(s) \
  global_max_fast = (((s) == 0)						      \
                     ? SMALLBIN_WIDTH : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))

这个时候相当于是

global_max_fast=( (s + SIZE_SZ) & ~15))

也就是(s+8)&(~0B1111)
相当于低4位全部清0
这里其实最后结果还是128
所以当初始化后

#define get_max_fast() 0x80

MALLOC_ALIGN_MASK 15

我们这里涉及到了太多的操作
我们就直接在64位机器上实验
alignof (long double)=16

#  define MALLOC_ALIGNMENT       (2 *SIZE_SZ < __alignof__ (long double)      \
                                  ? __alignof__ (long double) : 2 *SIZE_SZ)
# else
#  define MALLOC_ALIGNMENT       (2 *SIZE_SZ)
# endif
#endif

#define MALLOC_ALIGN_MASK      (MALLOC_ALIGNMENT - 1)

相当于是

#  define MALLOC_ALIGNMENT       (2 *SIZE_SZ < 16      \
                                  ? __alignof__ (long double) : 2 *SIZE_SZ)
# else
#  define MALLOC_ALIGNMENT       (2 *SIZE_SZ)
# endif
#endif

所以可以看见结果就是

#  define MALLOC_ALIGNMENT      16
#define MALLOC_ALIGN_MASK      15

NBINS 128

这个是bins的所有大小,包括small bin和largen bin

#define NBINS             128

NSMALLBINS 64

smallbins的数量

#define NSMALLBINS         64

MIN_LARGE_SIZE 0x400

#define SMALLBIN_WIDTH    MALLOC_ALIGNMENT
#define SMALLBIN_CORRECTION (MALLOC_ALIGNMENT > 2 * SIZE_SZ)
#define MIN_LARGE_SIZE    ((NSMALLBINS - SMALLBIN_CORRECTION) * SMALLBIN_WIDTH)

也就是

#define SMALLBIN_WIDTH 16
#define SMALLBIN_CORRECTION 0
#define MIN_LARGE_SIZE  0x400

也就是说最小的large bin是0x400,最大的small bin不超过0x400

in_smallbin_range

#define in_smallbin_range(sz)  \
  ((unsigned long) (sz) < (unsigned long) MIN_LARGE_SIZE)
#define in_smallbin_range(sz)  \
  ((unsigned long) (sz) < 0x400)

smallbin_index

这里的其实比较简单,应该就是简单区分32位和64位机器

#define smallbin_index(sz) \
  ((SMALLBIN_WIDTH == 16 ? (((unsigned) (sz)) >> 4) : (((unsigned) (sz)) >> 3))\
   + SMALLBIN_CORRECTION)

所以我们相当于

#define smallbin_index(sz) \
(unsigned(sz)>>4)

为什么这样算呢,其实这个跟small bin的结构有关系
在64位上,一共有64-2=62个链表,为什么减去两个呢,因为其实bins的前64个应该都是small bin,但是glibc在实现的时候把这个bin也当作一个特别的chunk,所以可以理解为0刚好对应于prev_size,1对应于size,所以从2,3开始才真正是bins链表的地址,同时如果bins里面没有空闲链表,他便会指向0下标的地址
所以我们只需要通过>>4位也就是/16就可以很快找到下标了
在这里插入图片描述
所以我们最后的大小也并不是0x400,而是63*16=0x3f0

同时注意哦,smallbin的范围和fast bin的范围也是有重复的

bin_at

这里其实就挺有意思了,因为我们的nbins为128,但是我们的bins有254个size_t,因为他是个双向链表,需要记录fd和bk
上面也提到了真正small bins有62个加上large bin有62+64=126个
因为这里我们的254个中的第一个对是不适用的,所以我们从上面转化到下面就需要减一下1然后乘以2就是我们的fd

#define bin_at(m, i) \
  (mbinptr) (((char *) &((m)->bins[((i) - 1) * 2]))			      \
             - offsetof (struct malloc_chunk, fd))

last

#define last(b)      ((b)->bk)

__malloc_initialized

这个与ptmalloc_int有关

 int __malloc_initialized = -1;

arena_get

这里thread_arena会在ptmalloc_int被赋值成&main_arena

#define arena_get(ptr, size) do { \
      ptr = thread_arena;						      \
      arena_lock (ptr, size);						      \
  } while (0)

arena_lock就是上锁,也没什么特别好说的

MIN_CHUNK_SIZE 0x20

#define MIN_CHUNK_SIZE        (offsetof(struct malloc_chunk, fd_nextsize))

额这里大概讲一下malloc_chunk结构
在64位就是

struct malloc_chunk{
size_t prev_size;
size_t size;
size_t fd;
size_t bk;
size_t fd_nextsize
size_t bk_nextsize;
}

所以这里就是

#define MIN_CHUNK_SIZE      0x20

MINSIZE 0x20

#define MINSIZE  \
  (unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))

也就是 0x20

request2size

#define request2size(req)                                         \
  (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE)  ?             \
   MINSIZE :                                                      \
   ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)

也就是

#define request2size(req)                                         \
  (((req) +<9)  ?             \
0x20 :                                                      \
   ((req) +0x17) & ~0xf)
size0x200x300x40
req0~0x180x19~0x280x29~-0x38

checked_request2size

一般都不会挂,除非你真的分配超级大的

#define REQUEST_OUT_OF_RANGE(req)                                 \
  ((unsigned long) (req) >=						      \
   (unsigned long) (INTERNAL_SIZE_T) (-2 * MINSIZE))
   
#define checked_request2size(req, sz)                             \
  if (REQUEST_OUT_OF_RANGE (req)) {					      \
      __set_errno (ENOMEM);						      \
      return 0;								      \
    }									      \
  (sz) = request2size (req);

也就是

#define REQUEST_OUT_OF_RANGE(req)                                 \
  ((unsigned long) (req) >=						      \
   (unsigned long) (INTERNAL_SIZE_T) (-2 * 0x20))

这个大小有点大欸,因为毕竟是unsigned long
也就是大于0xfffffffc0 ,4294967232
这里也就是不能让这个值太大,至于为什么要是-0x40我也不太懂
然后就是如果不大的话就用request2size转化一下
这里可以重点关注,因为攻击unsorted bin的时候会用到
我们想要分配的chunk size不能-40<=x<0,不能在这个范围内

unsorted_chunks

#define unsorted_chunks(M)          (bin_at (M, 1))

BINMAPSHIFT 5

idx2block

#define idx2block(i)     ((i) >> BINMAPSHIFT)
#define BINMAPSHIFT      5

就是

#define idx2block(i)     ((i) >> 5)

idx2bit

#define idx2bit(i) ((1U << ((i) & ((1U << BINMAPSHIFT) - 1))))
也就是
#define idx2bit(i) ((1U << ((i) & 31)))

BITSPERMA 32

#define BITSPERMAP       (1U << BINMAPSHIFT)
#define BITSPERMAP       32

BINMAPSIZE 4

#define BINMAPSIZE       (NBINS / BITSPERMAP)
#define BINMAPSIZE       (4

have_fastchunks

#define have_fastchunks(M)     (((M)->flags & FASTCHUNKS_BIT) == 0)

contiguous

#define contiguous(M)          (((M)->flags & NONCONTIGUOUS_BIT) == 0)
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值