Discussion:
Elf file and segments
(too old to reply)
f2hanif
2007-11-22 23:29:27 UTC
Permalink
Hi,

Elf file for kitchen program is at the end and few questions:

There will always be 3 segments ? Like right now it has:
'00 .reginfo',
'01 .reginfo .text .rodata' and
'02 .data .sbss .bss'

1. Can it possibly have more than 3 segments, it may be less, but can it
be more ?
2. Do we need to keep track of .reginfo, that is segment 00.

Thanks
Farah




testbin/kitchen readelf:

ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x4000b0
Start of program headers: 52 (bytes into file)
Start of section headers: 10688 (bytes into file)
Flags: 0x1001, noreorder, o32, mips1
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 13
Section header string table index: 10

Section Headers:
[Nr] Name Type Addr Off Size ES Flg
[ 0] NULL 00000000 000000 000000 00
[ 1] .reginfo MIPS_REGINFO 00400094 000094 000018 18 A
[ 2] .text PROGBITS 004000b0 0000b0 000f00 00 AX
[ 3] .rodata PROGBITS 00400fb0 000fb0 000410 00 A
[ 4] .data PROGBITS 10000000 002000 000010 00 WA
[ 5] .sbss NOBITS 10000010 002010 000008 00 WAp
[ 6] .bss NOBITS 10000020 002018 000020 00 WA
[ 7] .comment PROGBITS 00000000 002018 0000c6 00
[ 8] .pdr PROGBITS 00000000 0020e0 000880 00
[ 9] .mdebug.abi32 PROGBITS 00000000 002960 000000 00
[10] .shstrtab STRTAB 00000000 002960 00005f 00
[11] .symtab SYMTAB 00000000 002bc8 0007a0 10
[12] .strtab STRTAB 00000000 003368 000380 00

Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
REGINFO 0x000094 0x00400094 0x00400094 0x00018 0x00018 R 0x4
LOAD 0x000000 0x00400000 0x00400000 0x013c0 0x013c0 R E 0x1000
LOAD 0x002000 0x10000000 0x10000000 0x00010 0x00040 RW 0x1000

Section to Segment mapping:
Segment Sections...
00 .reginfo
01 .reginfo .text .rodata
02 .data .sbss .bss
f2hanif
2007-11-22 23:44:02 UTC
Permalink
A follow up to the last post:

Not an expert in C, but does the following code ignore the segment 00,
that contains .reginfo, that is of type REGINFO.

switch (ph.p_type) {
case PT_NULL: /* skip */ continue;
case PT_PHDR: /* skip */ continue;
case PT_MIPS_REGINFO: /* skip */ continue;
PT_LOAD: break;
default:
kprintf("loadelf: unknown segment type %d\n", ph.p_type);
return ENOEXEC;
}

Above was part of load_elf in loadelf.c.

Regards,
Farah
Tim Brecht
2007-11-23 11:30:04 UTC
Permalink
The code you posted is missing a "case" keyword
and I've included a bit more context.
A continue statement says to do the next loop
in the enclosing loop (in this case the for loop I've
included).

The line "case PT_LOAD: break;" says that if the type for
the segment is PT_LOAD (i.e.,)
#define PT_LOAD 1 /* Loadable program segment */
then break out of the switch statement. The code then calls
as_define_region for that region/segment to store the
useful/necessary information for that segment so that it
can later be loaded into memory.


for (i=0; i<eh.e_phnum; i++) {

...

switch (ph.p_type) {
case PT_NULL: /* skip */ continue;
case PT_PHDR: /* skip */ continue;
case PT_MIPS_REGINFO: /* skip */ continue;
case PT_LOAD: break;
default:
kprintf("loadelf: unknown segment type %d\n",
ph.p_type);
return ENOEXEC;
}

result = as_define_region(curthread->t_vmspace,
ph.p_vaddr, ph.p_memsz,
ph.p_flags & PF_R,
ph.p_flags & PF_W,
ph.p_flags & PF_X);

The cs350-readelf program dumps this info -- see the TYPE column below.
So the code above will skip the REGINFO segment. But

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
REGINFO 0x000094 0x00400094 0x00400094 0x00018 0x00018 R 0x4
LOAD 0x000000 0x00400000 0x00400000 0x002c0 0x002c0 R E 0x1000
LOAD 0x001000 0x10000000 0x10000000 0x00000 0x00010 RW 0x1000

You'll see in the next loop in load_elf that a similar case statement
is used to figure out which segments to load into memory.
Not an expert in C, but does the following code ignore the segment 00, that
contains .reginfo, that is of type REGINFO.
switch (ph.p_type) {
case PT_NULL: /* skip */ continue;
case PT_PHDR: /* skip */ continue;
case PT_MIPS_REGINFO: /* skip */ continue;
PT_LOAD: break;
kprintf("loadelf: unknown segment type %d\n", ph.p_type);
return ENOEXEC;
}
Above was part of load_elf in loadelf.c.
Regards,
Farah
f2hanif
2007-11-23 17:27:09 UTC
Permalink
Thank you for the clarification.
Post by Tim Brecht
The code you posted is missing a "case" keyword
and I've included a bit more context.
A continue statement says to do the next loop
in the enclosing loop (in this case the for loop I've included).
The line "case PT_LOAD: break;" says that if the type for
the segment is PT_LOAD (i.e.,)
#define PT_LOAD 1 /* Loadable program segment */
then break out of the switch statement. The code then calls
as_define_region for that region/segment to store the
useful/necessary information for that segment so that it
can later be loaded into memory.
for (i=0; i<eh.e_phnum; i++) {
...
switch (ph.p_type) {
case PT_NULL: /* skip */ continue;
case PT_PHDR: /* skip */ continue;
case PT_MIPS_REGINFO: /* skip */ continue;
case PT_LOAD: break;
kprintf("loadelf: unknown segment type %d\n",
ph.p_type);
return ENOEXEC;
}
result = as_define_region(curthread->t_vmspace,
ph.p_vaddr, ph.p_memsz,
ph.p_flags & PF_R,
ph.p_flags & PF_W,
ph.p_flags & PF_X);
The cs350-readelf program dumps this info -- see the TYPE column below.
So the code above will skip the REGINFO segment. But
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
REGINFO 0x000094 0x00400094 0x00400094 0x00018 0x00018 R 0x4
LOAD 0x000000 0x00400000 0x00400000 0x002c0 0x002c0 R E 0x1000
LOAD 0x001000 0x10000000 0x10000000 0x00000 0x00010 RW 0x1000
You'll see in the next loop in load_elf that a similar case statement
is used to figure out which segments to load into memory.
Post by f2hanif
Not an expert in C, but does the following code ignore the segment 00,
that contains .reginfo, that is of type REGINFO.
switch (ph.p_type) {
case PT_NULL: /* skip */ continue;
case PT_PHDR: /* skip */ continue;
case PT_MIPS_REGINFO: /* skip */ continue;
PT_LOAD: break;
kprintf("loadelf: unknown segment type %d\n", ph.p_type);
return ENOEXEC;
}
Above was part of load_elf in loadelf.c.
Regards,
Farah
Tim Brecht
2007-11-23 00:37:02 UTC
Permalink
Post by f2hanif
Hi,
'00 .reginfo',
'01 .reginfo .text .rodata' and
'02 .data .sbss .bss'
We actually don't care about the 00 segment.
And don't forget about the stack segment so
that makes 3.
Post by f2hanif
1. Can it possibly have more than 3 segments, it may be less, but can it be
more ?
We won't worry about more segments.
Post by f2hanif
2. Do we need to keep track of .reginfo, that is segment 00.
No.
Post by f2hanif
Thanks
Farah
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x4000b0
Start of program headers: 52 (bytes into file)
Start of section headers: 10688 (bytes into file)
Flags: 0x1001, noreorder, o32, mips1
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 13
Section header string table index: 10
[Nr] Name Type Addr Off Size ES Flg
[ 0] NULL 00000000 000000 000000 00
[ 1] .reginfo MIPS_REGINFO 00400094 000094 000018 18 A
[ 2] .text PROGBITS 004000b0 0000b0 000f00 00 AX
[ 3] .rodata PROGBITS 00400fb0 000fb0 000410 00 A
[ 4] .data PROGBITS 10000000 002000 000010 00 WA
[ 5] .sbss NOBITS 10000010 002010 000008 00 WAp
[ 6] .bss NOBITS 10000020 002018 000020 00 WA
[ 7] .comment PROGBITS 00000000 002018 0000c6 00
[ 8] .pdr PROGBITS 00000000 0020e0 000880 00
[ 9] .mdebug.abi32 PROGBITS 00000000 002960 000000 00
[10] .shstrtab STRTAB 00000000 002960 00005f 00
[11] .symtab SYMTAB 00000000 002bc8 0007a0 10
[12] .strtab STRTAB 00000000 003368 000380 00
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
REGINFO 0x000094 0x00400094 0x00400094 0x00018 0x00018 R 0x4
LOAD 0x000000 0x00400000 0x00400000 0x013c0 0x013c0 R E 0x1000
LOAD 0x002000 0x10000000 0x10000000 0x00010 0x00040 RW 0x1000
Segment Sections...
00 .reginfo
01 .reginfo .text .rodata
02 .data .sbss .bss
Continue reading on narkive:
Loading...