快乐虾
http://blog.csdn.net/lights_joy/
本文适用于
Cygwin checkout-2008-09-28
vs2008
欢迎转载,但请保留作者信息
在fork出来的子进程里,首先复制的就是cygheap的内容,接着又连续从父进程中复制了下面两块内容:
child_copy (parent, false,
"dll data", dll_data_start, dll_data_end,
"dll bss", dll_bss_start, dll_bss_end,
"user heap", cygheap->user_heap.base, cygheap->user_heap.ptr,
NULL);
/* step 2 now that the dll has its heap filled in, we can fill in the
user's data and bss since user_data is now filled out. */
child_copy (parent, false,
"data", user_data->data_start, user_data->data_end,
"bss", user_data->bss_start, user_data->bss_end,
NULL);
第一块复制的是cygwin.dll的数据段,第二块复制的是user_data的内容。
在这里定义了几个全局变量dll_data_start, dll_data_end, dll_bss_start, dll_bss_end。这是几个宏定义:
#define dll_data_start &_data_start__
#define dll_data_end &_data_end__
#define dll_bss_start &_bss_start__
#define dll_bss_end &_bss_end__
这几个全局变量并不在c/cpp文件里面定义,而是由链接器计算而得:
.data ALIGN(__section_alignment__) :
{
__data_start__ = .;
*(.data)
*(.data2)
*(SORT(.data$*))
__data_end__ = .;
*(.data_cygwin_nocopy)
}
.bss ALIGN(__section_alignment__) :
{
__bss_start__ = .;
*(.bss)
*(COMMON)
__bss_end__ = .;
}
它们指明了cygwin.dll里的数据段的起始地址和结束地址。
在vs2008下编译的时候,由于vs将这些数据都放在.data段中,因此我们直接复制.data这个段的内容:
GetModuleInformation( hProcess, hCygwinDll, &modinfo, sizeof(MODULEINFO) );
// 根据lpBaseOfDll得到其它的数据
lpbuf = (BYTE*)modinfo.lpBaseOfDll;
//取得节数目
pfh = (PIMAGE_FILE_HEADER) ((LPVOID)((BYTE *)(lpbuf)+((PIMAGE_DOS_HEADER)(lpbuf))-> e_lfanew+sizeof(DWORD)));
int nSectionCount = pfh-> NumberOfSections;
poh = (PIMAGE_OPTIONAL_HEADER)(pfh + 1);
psh = (PIMAGE_SECTION_HEADER) ((LPVOID)((BYTE *)pfh + sizeof(IMAGE_FILE_HEADER) + pfh->SizeOfOptionalHeader));
dwBase = 0;
for(int i = 0; i < nSectionCount; i++)
{
if(strcmp( ".data", (char *)psh->Name) == 0)
{
dwBase = (DWORD)modinfo.lpBaseOfDll + psh->VirtualAddress;
}
else if(dwBase > 0)
{
child_copy (parent, false,
"dll data", dwBase, (BYTE*)modinfo.lpBaseOfDll + psh->VirtualAddress,
NULL);
break;
}
psh++;
}
感谢Tr0j4n提供的代码。
在cygwin里user_data里的data_start等几个成员可以用于指示malloc / free等的heap范围,但由于我们并没有将malloc / free的heap放在user_data里,因此这个复制相当于空操作。
cygwin下的共享内存区(2009-9-8)
cygwin下的user heap(2009-9-8)
cygwin下的cygheap:从父进程到子进程的复制(2009-9-7)
cygwin下的/etc/fstab(2009-9-7)
cygwin关键技术:fork(2009-9-4)
cygwin关键技术:设备模拟(2009-9-4)
cygwin关键技术:cygheap(2009-9-2)
cygwin关键技术:tls(2009-8-24)
在vs2008下使用cygwin(23):stdin,stdout和stderr(2008-10-21)