Who is responsible for clearing section .bss ?

Carlos O'Donell carlos@redhat.com
Mon Apr 6 15:46:53 GMT 2020


On 4/6/20 11:25 AM, William Tambe via Libc-help wrote:
> Looking through start.S implementations, not a single architecture
> appears to be clearing section .bss .

There is the initial application BSS, for which the kernel has to ensure
we have zero pages when the p_filesz is less than the p_memsz (and
clear any partial pages from disk).

Then there are the loaded libraries which have BSS also and they are
handled by the loader.

> Which function in GLIBC clears section .bss or is the Linux kernel
> responsible for clearing section .bss before executing entry-point
> _start ?

The BSS is part of a PT_LOAD segment that is RW, but is *larger*
than the filesz.

A combination of the kernel and ld.so clear the pages.

With ld.so clearing the remainder of a page, and the kernel providing
zeroed pages.

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
...
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x021508 0x021508 R   0x1000
  LOAD           0x022000 0x0000000000022000 0x0000000000022000 0x14c2dd 0x14c2dd R E 0x1000
  LOAD           0x16f000 0x000000000016f000 0x000000000016f000 0x04bb7c 0x04bb7c R   0x1000
  LOAD           0x1bb6e8 0x00000000001bc6e8 0x00000000001bc6e8 0x0050d8 0x009018 RW  0x1000

The last entry has: p_memsz > p_filesz;

Then in elf/dl-map-segments.h:

104       if (c->allocend > c->dataend)
105         {
106           /* Extra zero pages should appear at the end of this segment,
107              after the data mapped from the file.   */
...
131               memset ((void *) zero, '\0', zeropage - zero);
...
137           if (zeroend > zeropage)
138             {
139               /* Map the remaining zero pages in from the zero fill FD.  */
140               caddr_t mapat;
141               mapat = __mmap ((caddr_t) zeropage, zeroend - zeropage,
142                               c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED,
143                               -1, 0);
144               if (__glibc_unlikely (mapat == MAP_FAILED))
145                 return DL_MAP_SEGMENTS_ERROR_MAP_ZERO_FILL;
146             }

Does that answer your question?

-- 
Cheers,
Carlos.



More information about the Libc-help mailing list