This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Change the way we compute file offsets
ClosedPublic

Authored by evgeny777 on Sep 28 2016, 4:00 AM.

Details

Summary

Imagine we have too sections .foo and .bar with virtual addresses 0x10000 and 0x20000, which share the same segment:

PHDRS { all PT_LOAD; }
SECTIONS {
   .foo (0x10000) : { *(.foo*) } : all
   .bar (0x20000) : { *(.bar*) } : all
}

Now also imagine that section .foo is the first section in PT_LOAD and segment virtual address is the same as section .foo, i.e 0x10000
As we have only one PT_LOAD, OS kernel should allocate the both sections correctly using only one memory mapping operation. The only
way this can be done is setting difference between file offsets of .bar and .foo to the same value as difference between their virtual addresses, i.e:

File_offset(.bar) - File_offset(.foo) = VA(.bar) - VA(.foo) = 0x10000

In such case both sections be correctly loaded using a single mmap() call.

Also It looks like both gold and ld use the same approach.

Diff Detail

Repository
rL LLVM

Event Timeline

evgeny777 updated this revision to Diff 72792.Sep 28 2016, 4:00 AM
evgeny777 retitled this revision from to [ELF] Change the way we compute file offsets.
evgeny777 updated this object.
evgeny777 added reviewers: rafael, ruiu.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.
evgeny777 added subscribers: grimar, ikudrin, llvm-commits.
grimar added inline comments.Sep 28 2016, 4:27 AM
ELF/Writer.cpp
1055 ↗(On Diff #72792)

Why do you need this ?

1206 ↗(On Diff #72792)

I think this looks nicer in 2 lines:

if (!First || Sec == First)
  return alignTo(Off, Target->MaxPageSize, Sec->getVA());
return std::max(Off, First->getFileOffset() + Sec->getVA() - First->getVA());
1225 ↗(On Diff #72792)

Excessive line.

evgeny777 added inline comments.Sep 28 2016, 4:56 AM
ELF/Writer.cpp
1055 ↗(On Diff #72792)

This patch was done in times we could have non-allocatable sections in the middle of the section list. This is no longer needed as well as taking maximum of old and new offset. I'll update the diff.

evgeny777 updated this revision to Diff 72801.Sep 28 2016, 4:57 AM
evgeny777 removed rL LLVM as the repository for this revision.

Addressed review comments

ruiu added inline comments.Sep 28 2016, 1:00 PM
ELF/OutputSections.h
112 ↗(On Diff #72801)

Needs a comment about what this is and why we need it.

evgeny777 updated this revision to Diff 72896.Sep 28 2016, 2:07 PM

Added comment for 'FirstInPtLoad'

ruiu accepted this revision.Sep 28 2016, 2:14 PM
ruiu edited edge metadata.

LGTM

This revision is now accepted and ready to land.Sep 28 2016, 2:14 PM
This revision was automatically updated to reflect the committed changes.