This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Linkerscript: Implement LOADADDR
ClosedPublic

Authored by evgeny777 on Sep 7 2016, 9:31 AM.

Details

Summary

This patch implements LOADADDR() linkerscript function and ability to fetch LMA for section.

Diff Detail

Repository
rL LLVM

Event Timeline

evgeny777 updated this revision to Diff 70546.Sep 7 2016, 9:31 AM
evgeny777 retitled this revision from to [ELF] Linkerscript: Implement LOADADDR.
evgeny777 updated this object.
evgeny777 added reviewers: ruiu, rafael.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.
evgeny777 added subscribers: grimar, ikudrin, llvm-commits.
ruiu added inline comments.Sep 7 2016, 5:45 PM
ELF/LinkerScript.cpp
435 ↗(On Diff #70546)

Do you need to set an LMA to sections without AT command?

ELF/LinkerScript.h
161 ↗(On Diff #70546)

LMA is fine with me as we write VA instead of Va, so please rename this function.

ELF/Writer.cpp
949 ↗(On Diff #70546)

What is b in bHasLma?

993–994 ↗(On Diff #70546)

Why do we have to create a new segment if there's a section with a LMA?

grimar added inline comments.Sep 8 2016, 1:10 AM
ELF/Writer.cpp
993 ↗(On Diff #70546)

You can write this as:

bHasLma |= Script<ELFT>::X->hasLma(Sec->getName())
evgeny777 added inline comments.Sep 8 2016, 3:19 AM
ELF/LinkerScript.cpp
435 ↗(On Diff #70546)

Yes, because LMA and VMA might not be the same, even if there is no AT command for a section. See summary for this patch

ELF/Writer.cpp
993–994 ↗(On Diff #70546)

There is no straight way to get LMA for section from section header. The header field sh_addr is VMA, not LMA. However tools like objdump and objcopy still can fetch LMA. They are doing this by examining segment table and fetching segment physical address in case segment virtual address matches section VMA. This means that if section LMA doesn't match VMA, it should have separate load segment in order to properly calculate LMA for them.

evgeny777 updated this revision to Diff 70674.Sep 8 2016, 3:32 AM
evgeny777 removed rL LLVM as the repository for this revision.

Rebased + addressed review comments

ruiu added inline comments.Sep 12 2016, 2:32 PM
ELF/LinkerScript.cpp
429 ↗(On Diff #70801)

Please add a comment about that with a reference to the GNU manual.

1269 ↗(On Diff #70801)

It may not be a name, so I'd name Tok.

ELF/Writer.cpp
949 ↗(On Diff #70801)

HasLMA for the sake of consistency.

993–995 ↗(On Diff #70801)

Please add a comment about that so that people who read this code can understand why it checks HasLma.

evgeny777 updated this revision to Diff 71125.Sep 13 2016, 2:28 AM

Addressed review comments

evgeny777 added inline comments.Sep 13 2016, 2:29 AM
ELF/LinkerScript.cpp
431 ↗(On Diff #71125)

This wasn't needed, because setLMAOffset is called in SetAddrs(). See lines 399 - 403

ELF/Writer.cpp
1003–1004 ↗(On Diff #71125)

See lines 987-995

evgeny777 updated this revision to Diff 71798.Sep 19 2016, 3:48 AM

Added test case

Any comments on this?

evgeny777 updated this revision to Diff 72189.Sep 22 2016, 10:13 AM
evgeny777 updated this object.

Diff updated. It turned out, that binutils can fetch LMA for section even if it doesn't start PT_LOAD segment, so
this patch can be simplified.

test/ELF/linkerscript/loadaddr.s
14 ↗(On Diff #72189)

You probably want to check LOADADDR(xxx), where xxx - section that does not exist.

evgeny777 added inline comments.Sep 26 2016, 6:45 AM
test/ELF/linkerscript/loadaddr.s
14 ↗(On Diff #72189)

Unfortunately this will not work, because empty sections are not fully supported: empty sections which don't contain symbols are simply ignored. I'm making a patch which addresses this problem.

grimar added inline comments.Sep 26 2016, 8:27 AM
test/ELF/linkerscript/loadaddr.s
14 ↗(On Diff #72189)

I was mean something like I did in my version of that: D24910

## Check that we error out if trying to get load address of
## section that does not exist.
# RUN: echo "SECTIONS { .bar LOADADDR(.zed) : { *(.bar*) } }" > %t.script
# RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \
# RUN:  | FileCheck -check-prefix=ERR %s
# ERR: undefined section .zed

So there is no .zed section and it is impossible to call LOADADDR(.zed)

evgeny777 updated this revision to Diff 73059.Sep 30 2016, 8:40 AM

Addressed review comments

ruiu accepted this revision.Oct 5 2016, 1:08 PM
ruiu edited edge metadata.

LGTM

This revision is now accepted and ready to land.Oct 5 2016, 1:08 PM
This revision was automatically updated to reflect the committed changes.