.bss section in elf file

If I understand corretly, by creating a section of .bss type (as below code
example) the write/read area of the .bss section is from section's offset
in the file to N and in this case phdr.p_memsz gets incremented by N bytes
and it's up to operating system/kernel zero this memory area. Is my
intepretation right?

<i> Elf32_Phdr phdr;
    // ...
    phdr.p_memsiz = somevalue;
    Elf32_Shdr sec;
    // ...
    sec.sh_name = bss_name;
    sec.sh_type = SHT_nobits;
    sec.sh_flags = SHF_alloc + SHF_write;
    sec.sh_size = N;
    phdr.p_memsiz += N;

</i>

I can't parse your question. The .bss section has no content. At link
time, it gets merged with the .data section into a single PT_LOAD
segment. The reserved VA space for that segment is the sum of .bss and
.data size. The space in the ELF file is the size of the .data section.
The kernel or dynamic linker will map the part from the file that
represents the .data section with mmap as copy-on-write, followed by a
anonymous mapping for the .bss part. The kernel is responsible for
zeroing the latter part. Does that answer your question?

Joerg

Yes, it does. But I still have a couple of questions, do you care to answer?
I do know it doesn't have room in file itself only count bytes it must have
at memory. What I'm trying to understand is where start and end the area of
this. 1) How does it differ if I'm working with a static executable and
using /SHT_NOBITS /i.e, a section not a segment? in this case, I'm
understanding the difference between a section and a segment what I
understood so far a section is required at link-time to make the executable
with the segments whose information come from the sections, it it right? 2)
by the "room" of a section (in memory): Is it the end of .data + .bss
section/segment address to count of bytes I've set in sh_size ?3) Also, can
I play with static executables, say, use .rodata/.data/.bss/.text sections
before I make it dynamic? ie. is there something I couldn't do by using
static but dynamic can do(except use a dynamic library, of couse) ? and I'd
love if you have a good resource about ELF file format. I want to understand
these stuff before try to put my hands on llvm source code.

1) How does it differ if I'm working with a static executable and
using /SHT_NOBITS /i.e, a section not a segment?

Segments are used by the ELF loader (kernel or dynamic linker). Sections
are normally used by tools operating on object files. A segment is
typically a collection of multiple sections. Different granularity.

2) by the "room" of a section (in memory): Is it the end of .data + .bss
section/segment address to count of bytes I've set in sh_size

.bss will be placed at the end of the data segment. Exact start address
is "size of data rounded up by bss alignment". You can compare address
and address + size of .data, .bss and the second (writeable) LOAD
segment in the output of readelf -lS /bin/cat.

3) Also, can I play with static executables, say, use .rodata/.data/
.bss/.text sections before I make it dynamic? ie. is there something
I couldn't do by using static but dynamic can do(except use a dynamic
library, of couse) ?

Static executables are simpler in nature. The most basic difference is
that they don't contain runtime relocations. There are some others, but
that goes into quite a bit more into details.

and I'd love if you have a good resource about ELF file format. I want
to understand these stuff before try to put my hands on llvm source code.

Linkers and Loaders is still a decent starting point, I think. You can
find it either in a good library, Amazon or online via
http://www.iecc.com/linker/ The wikipedia page for ELF has some further
references, e.g. to the original SYSV specification for ELF.

Joerg

Segments are used by the ELF loader (kernel or dynamic linker).
Sectionsare normally used by tools operating on object files. A segment
istypically a collection of multiple sections. Different granularity.

So, the kernel doesn't know about my section of /SHT_NOBITS/ type? the
/size/ tool print corretly the size of /.bss/ I've created but I'm not sure
if it's right.

.bss will be placed at the end of the data segment. Exact start addressis
"size of data rounded up by bss alignment". You can compare addressand
address + size of .data, .bss and the second (writeable) LOADsegment in
the output of readelf -lS /bin/cat.

Before this answer I had created the section using this code (I didn't knew
but was looking for what does mean the second /LOAD/ which I see in a lot of
ELF executables). I dertermined the are of .bss section to write/read using
this:
int bss_area = start +sizeof(Elf32_Ehdr) +sizeof(Elf32_phdr)
+sizeof(code) +sizeof(sec);
According to below code, is this right? it does work fine. Execute and
return expected return code. But I'm not sure which value put in some
sections. if it's wrong, what's the right way to create this sections? I
tried make code short as possible to your read but without loss context. But
if you want to make a full working version tell me I can post it.
#define START 0x08048000Elf32_shdr sec[5]; const char *names[] = { "",
".shstrtab", ".text", ".rodata", ".bss", }; const char
msg[] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F, // msg: db 'Hello, World!', 10
0x2C, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A }; unsigned char
code[] = { 0xBA, 0x00, 0x00, 0x00, 0x00, // mov edx, length 0xB9, 0x00,
0x00, 0x00, 0x00, // mov ecx, msgptr 0xBB, 0x01, 0x00, 0x00, 0x00, // mov
ebx, 1 0xB8, 0x04, 0x00, 0x00, 0x00, // mov eax, 4 0xCD, 0x80
// int 0x80 0xBB, 0x00, 0x00, 0x00, 0x00, // mov ebx, 0 0xB8, 0x01, 0x00,
0x00, 0x00, // mov eax, 1 0xCD, 0x80 // int 0x80
};sec[0].sh_name = 0;sec[0].sh_type = SHT_null;// entry 1 -
.textsec[1].sh_name = sec1_offset;sec[1].sh_type =
SHT_progbits;sec[1].sh_flags = SHF_alloc | SHF_execinstr;sec[1].sh_addr =
START + sizeof(Elf32_Ehdr) + sizeof(Elf32_phdr);sec[1].sh_offset =
sizeof(Elf32_Ehdr) + sizeof(Elf32_phdr);sec[1].sh_size = sizeof(code);//
entry 2 - .rodatasec[2].sh_name = sec2_offset;sec[2].sh_type =
SHT_progbits;sec[2].sh_flags = SHF_alloc;sec[2].sh_align =
0x4;sec[2].sh_addr = START + sizeof(Elf32_Ehdr) + sizeof(Elf32_phdr) +
sizeof(code);sec[2].sh_offset = sizeof(Elf32_Ehdr) + sizeof(Elf32_phdr) +
sizeof(code);sec[2].sh_size = sizeof(msg);// entry 3 -
.shstrtabsec[3].sh_name = sec3_offset;sec[3].sh_type =
SHT_strtab;sec[3].sh_flags = SHF_alloc;sec[3].sh_offset =
sizeof(Elf32_Ehdr) + sizeof(Elf32_phdr) + sizeof(msg) +
sizeof(code);sec[3].sh_size = section_length;// entry 4 -
.bsssec[4].sh_name = sec2_name_offset; // pointer to '.bss' string in
namessec[4].sh_type = SHT_nobits;sec[4].sh_flags = SHF_alloc +
SHF_write;sec[4].sh_addr = // pointer to begging of this section at memory
START + sizeof(Elf32_Ehdr) + sizeof(Elf32_phdr) +
sizeof(code) + sizeof(Elf32_phdr) * 3;sec[4].sh_offset =
sizeof(Elf32_Ehdr) + sizeof(Elf32_phdr) + sizeof(code)
+sizeof(Elf32_Phdr) * 3;sec[4].sh_align = sizeof(int);sec[4].sh_size =
sizeof(int) * 2;
And I fill the file with this:
  const char *outfile = "test"; FILE *fp = fopen(outfile, "w+b"); assert(fp);
// pointer to msg int msgptr = START + sizeof(Elf32_Ehdr) +
sizeof(Elf32_phdr) + sizeof(code); int msglen = sizeof(msg);
memcpy(&code[1], &msglen, sizeof(int)); memcpy(&code[6], &msgptr,
sizeof(int)); fwrite(&ehdr, sizeof(Elf32_Ehdr), 1, fp); fwrite(&phdr,
sizeof(Elf32_phdr), 1, fp); fwrite(&code, sizeof(code), 1, fp);
fwrite(msg, sizeof(msg), 1, fp); for(size_t i = 0; i <
sizeof(names) / sizeof(names[0]); i++) { fwrite(names[i], strlen(names[i])
+ 1, 1, fp); } fwrite(&sec, sizeof(sec), 1, fp); fclose(fp);

Linkers and Loaders is still a decent starting point, I think. You canfind
it either in a good library, Amazon or online
viahttp://www.iecc.com/linker/ The wikipedia page for ELF has some
furtherreferences, e.g. to the original SYSV specification for ELF.

Thanks very much. I will get this book.