[PATCH] D78005: [yaml2obj] - Reimplement how tool calculates memory sizes of segments.
George Rimar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri May 22 05:51:26 PDT 2020
grimar marked an inline comment as done.
grimar added inline comments.
================
Comment at: llvm/test/tools/yaml2obj/ELF/program-header-nobits.yaml:33-34
+## This segment includes sections 1 to 4 + the .filler chunk.
+# NOOFFSET-NEXT: LOAD 0x000000 0x0000000200000000 0x0000000200000000 0x000200 0x000220
+# OFFSET-NEXT: LOAD 0x000158 0x0000000200000158 0x0000000200000158 0x0000a8 0x0000c8
+## This segment includes the first two sections.
----------------
jhenderson wrote:
> grimar wrote:
> > jhenderson wrote:
> > > FileSize here looks like it should be 0x220, matching the memory size (which looks to be correct). It looks like the .nobits2 section is not being allocated file space, even though there's something non-nobits appearing after it. Please correct my understanding if I've misunderstood something. Same problem with the OFFSET case (off by 0x20 in file size).
> > > It looks like the .nobits2 section is not being allocated file space, even though there's something non-nobits appearing after it.
> >
> > Yes, yaml2obj does not allocate a file space in such case. In fact the following piece is the all we do for SHT_NOBITS:
> >
> > ```
> > } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec)) {
> > // SHT_NOBITS sections do not have any content to write.
> > SHeader.sh_entsize = 0;
> > SHeader.sh_size = S->Size;
> > }
> > ```
> >
> > I.e. it never allocates a file space for SHT_NOBITS. Seems to be the root of the problem.
> >
> > So, should we teach yaml2obj to allocate a file space for a SHT_NOBITS section if there is any no-nobits chunk after it?
> > How does this behavior sound for you?
> I think that would make sense. As far as I know, when a SHT_NOBITS section appears in the middle of a segment (i.e. with other non-nobits sections afterwards), there's no other way of representing it correctly without allocating file space - if you include it in the address space, the later progbits sections will have an incorrect address to content mapping at runtime.
>
> What do linkers do with a linker script where a nobits section is followed by a progbits section in the same segment?
I've tested GNU linkers. The behavior is similar. They allocate a space then:
```
.section .foo.nobits, "aw", @nobits
.quad 0
.section .bar1.nobits, "aw", @nobits
.quad 0
.quad 0
.section .bar2.nobits, "aw", @nobits
.quad 0
.section .zed, "aw"
.quad 0
.quad 0
.quad 0
```
```
SECTIONS {
. = 0x1000;
.foo.nobits : { *(.foo.nobits) }
.zed : { *(.zed) }
.bar1.nobits : { *(.bar.nobits) }
.bar2.nobits : { *(.bar.nobits) }
}
```
bfd output:
```
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .foo.nobits NOBITS 0000000000001000 00001000
0000000000000008 0000000000000000 WA 0 0 1
[ 2] .zed PROGBITS 0000000000001008 00001008
0000000000000018 0000000000000000 WA 0 0 1
[ 3] .bar1.nobits NOBITS 0000000000001020 00001020
0000000000000010 0000000000000000 WA 0 0 1
[ 4] .bar2.nobits NOBITS 0000000000001030 00001020
0000000000000008 0000000000000000 WA 0 0 1
[ 5] .symtab SYMTAB 0000000000000000 00001020
0000000000000078 0000000000000018 6 5 8
[ 6] .strtab STRTAB 0000000000000000 00001098
0000000000000001 0000000000000000 0 0 1
[ 7] .shstrtab STRTAB 0000000000000000 00001099
0000000000000046 0000000000000000 0 0 1
Key to Flags:
...
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x0000000000000020 0x0000000000000038 RW 0x1000
Section to Segment mapping:
Segment Sections...
00 .foo.nobits .zed .bar1.nobits .bar2.nobits
```
Note that there is a single PT_LOAD and the file space is allocated for `.foo.nobits`.
But when I provide a script which creates 2 segments:
```
SECTIONS {
. = 0x1000;
.foo.nobits : { *(.foo.nobits) }
. = 0x2000;
.zed : { *(.zed) }
.bar1.nobits : { *(.bar.nobits) }
.bar2.nobits : { *(.bar.nobits) }
}
```
then no allocation happens:
```
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .foo.nobits NOBITS 0000000000001000 00001000
0000000000000008 0000000000000000 WA 0 0 1
[ 2] .zed PROGBITS 0000000000002000 00001000
0000000000000018 0000000000000000 WA 0 0 1
[ 3] .bar1.nobits NOBITS 0000000000002018 00001018
0000000000000010 0000000000000000 WA 0 0 1
[ 4] .bar2.nobits NOBITS 0000000000002028 00001018
0000000000000008 0000000000000000 WA 0 0 1
[ 5] .symtab SYMTAB 0000000000000000 00001018
0000000000000078 0000000000000018 6 5 8
[ 6] .strtab STRTAB 0000000000000000 00001090
0000000000000001 0000000000000000 0 0 1
[ 7] .shstrtab STRTAB 0000000000000000 00001091
0000000000000046 0000000000000000 0 0 1
...
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x0000000000000000 0x0000000000000008 RW 0x1000
LOAD 0x0000000000001000 0x0000000000002000 0x0000000000002000
0x0000000000000018 0x0000000000000030 RW 0x1000
```
I'll try to improve yaml2obj in this area.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D78005/new/
https://reviews.llvm.org/D78005
More information about the llvm-commits
mailing list