newlib代码:
caddr_t
_sbrk (int incr)
{
extern char end asm ("end"); /* Defined by the linker. */
static char * heap_end;
char * prev_heap_end;
if (heap_end == NULL)
heap_end = & end;
prev_heap_end = heap_end;
if (heap_end + incr > stack_ptr)
{
/* Some of the libstdc++-v3 tests rely upon detecting
out of memory errors, so do not abort here. */
#if 0
extern void abort (void);
_write (1, "_sbrk: Heap and stack collision\n", 32);
abort ();
#else
errno = ENOMEM;
return (caddr_t) -1;
#endif
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
第一次调用使用end符号获取堆的起始地址,因此只需要在链接文件中在heap起始地址定义end标号即可。
.heap 0x00200000 (NOLOAD):
{
. = ALIGN(64);
__heap_start = .;
PROVIDE(end = .);
. = . + 0xA0000;
__end__ = .;
}
如上,使用PROVIDE声明了end标号。

本文介绍了_cbrk函数在内存管理中的作用,它用于动态分配堆空间。当首次调用时,利用链接器定义的end标号获取堆的初始地址。如果尝试分配的空间超过栈指针,会设置errno为ENOMEM并返回错误。链接文件中通过PROVIDE声明end标号,定义堆的起始和结束位置。这个过程对于理解和调试内存溢出问题至关重要。
1081

被折叠的 条评论
为什么被折叠?



