栈保护机者(stack protector)机制,用来检测缓冲区越界。
思想:在栈帧中任何局部缓冲区与栈状态之间存储一个特殊的金丝雀(canary)值(只读),也称之为哨兵值(guard value),是在程序每次运行时随机产生的。在恢复寄存器状态和从函数返回之前,程序检查这个金丝雀值是否被该函数的某个操作或者该函数调用的某个函数的某个操作改变了。
GCC只有函数中有局部char类型缓冲区的时候才插入这样的代码。
movl %gs:20, %eax Retrieve canary
...
xorl %gs:20, %eax Compare to stored value
数组是同样大小的块的序列来分配,这些块中保存着这些数组元素;结构则作为变长的块来分配,块中保存着结构元素;联合是作为一个单独的块来分配,这个块足够大,能够装下联合中最大的元素。
x86-64 遵循一组更严格的对齐要求。对于任何需要K字节的标量数据类型来说,它的起始地址必须是K的倍数。
x86-64硬件和编程规则的形成改变了处理器,过去它严重依赖栈来保存程序状态,现在则是将最常使用的状态部分保存在更快并扩展了的寄存器组中。