Who is responsible for clearing section .bss ?

William Tambe tambewilliam@gmail.com
Mon Apr 6 16:06:20 GMT 2020


On Mon, Apr 6, 2020 at 11:47 AM Carlos O'Donell <carlos@redhat.com> wrote:
>
> 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?

It does. Many thanks!

>
> --
> Cheers,
> Carlos.
>


More information about the Libc-help mailing list