This is an archive of the discontinued LLVM Phabricator instance.

[ELF] LinkerScript: Implement custom output section factory
AbandonedPublic

Authored by evgeny777 on Jul 29 2016, 5:41 AM.

Details

Reviewers
ruiu
Summary

This patch implements extra output section factory for use in LinkerScript class. It attempts to merge input sections with the same name and different flags. When merge is impossible, error is raised.

See discussion here:
https://reviews.llvm.org/D22683

Diff Detail

Event Timeline

evgeny777 updated this revision to Diff 66112.Jul 29 2016, 5:41 AM
evgeny777 retitled this revision from to [ELF] LinkerScript: Implement custom output section factory.
evgeny777 updated this object.
evgeny777 added a reviewer: ruiu.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.
evgeny777 added subscribers: emaste, davide, grimar and 2 others.
grimar added inline comments.Jul 29 2016, 6:08 AM
ELF/LinkerScript.cpp
61

You moved this and some other code. Was there a reason for that ? It creates some noise in the patch.

135

Is it intended ` ?

139

Ditto.

ELF/OutputSections.h
681

Doesn't seem you destroy factory using base class pointer. Virtual descructor is excessive.

683

Why not = 0 ?

705

Missing override keyword.

ELF/Writer.cpp
663

May be would be better just initialize Writer::Factory differently depending on whether script is used or not ?

evgeny777 updated this revision to Diff 66117.Jul 29 2016, 6:37 AM
evgeny777 removed rL LLVM as the repository for this revision.

Updated diff, so now it's little less noisy.
The main problem is that lot of code was moved from LinkerScript to OutputSectionFactory, so it's hard to make it look pretty

ruiu edited edge metadata.Jul 29 2016, 8:57 AM

Honestly this does not seem to simplify things. It may, but it also introduces new complexities. We now have BaseFactory and two Factory classes, and we are doing some object-oriented juggling there. Not sure if we can get rid of it (maybe we can just remove the base class and have two classes?) But at least for https://reviews.llvm.org/D22683, I'd say we want to just use the existing factory if this patch can't be simplified.

Honestly, I don't know how to radically simplify this. Using two separate classes involves code duplication:

  • Output section creation (see OutputSectionFactoryBase::create)
  • Handling .opd, .init_array and .fini_array (See Writer::finalizeSections)
  • OwningSections vector (minor issue, but still ...)

So, I also think it makes sense to proceed with https://reviews.llvm.org/D22683 without this change.

ELF/Writer.cpp
663

Not sure. You'll have to maintain two different indexes with the same class.

grimar added a comment.Aug 8 2016, 8:26 AM

Btw currenly when linking FreeBSD kernel LLD produces 7(!) different .rodata sections:

[ 6] .rodata           PROGBITS         ffffffff80c87c8c  00c86c8c
     00000000000e6e4d  0000000000000001 AMS       0     0     1
[ 7] .rodata           PROGBITS         ffffffff80d6eae0  00d6dae0
     0000000000246f00  0000000000000000   A       0     0     32
[ 8] .rodata           PROGBITS         ffffffff80fb59e0  00fb49e0
     00000000000001f0  0000000000000010  AM       0     0     16
[ 9] .rodata           PROGBITS         ffffffff80fb5bd0  00fb4bd0
     00000000000002a0  0000000000000004 AMS       0     0     16
[10] .rodata           PROGBITS         ffffffff80fb5e70  00fb4e70
     0000000000000108  0000000000000008  AM       0     0     8
[11] .rodata           PROGBITS         ffffffff80fb5f78  00fb4f78
     000000000000000c  0000000000000004 AMS       0     0     4
[12] .rodata           PROGBITS         ffffffff80fb5f88  00fb4f88
     0000000000001158  0000000000000001 AMS       0     0     8

While ld produces only one:
[ 6] .rodata PROGBITS ffffffff80e85100 00c85100

0000000000325aaa  0000000000000000   A       0     0     32

Btw currenly when linking FreeBSD kernel LLD produces 7(!) different .rodata sections:

[ 6] .rodata           PROGBITS         ffffffff80c87c8c  00c86c8c
     00000000000e6e4d  0000000000000001 AMS       0     0     1
[ 7] .rodata           PROGBITS         ffffffff80d6eae0  00d6dae0
     0000000000246f00  0000000000000000   A       0     0     32
[ 8] .rodata           PROGBITS         ffffffff80fb59e0  00fb49e0
     00000000000001f0  0000000000000010  AM       0     0     16
[ 9] .rodata           PROGBITS         ffffffff80fb5bd0  00fb4bd0
     00000000000002a0  0000000000000004 AMS       0     0     16
[10] .rodata           PROGBITS         ffffffff80fb5e70  00fb4e70
     0000000000000108  0000000000000008  AM       0     0     8
[11] .rodata           PROGBITS         ffffffff80fb5f78  00fb4f78
     000000000000000c  0000000000000004 AMS       0     0     4
[12] .rodata           PROGBITS         ffffffff80fb5f88  00fb4f88
     0000000000001158  0000000000000001 AMS       0     0     8

While ld produces only one:
[ 6] .rodata PROGBITS ffffffff80e85100 00c85100

0000000000325aaa  0000000000000000   A       0     0     32

I noticed the same. This is likely to be a bug. Many loadable sections are also not put in a PT_LOAD. And this makes the loader very angry.

ruiu added a comment.Aug 8 2016, 1:38 PM

It means that we need to have a separate logic than the regular one to create output sections for the linker script, right?

davide added a comment.Aug 8 2016, 1:40 PM
In D22960#509021, @ruiu wrote:

It means that we need to have a separate logic than the regular one to create output sections for the linker script, right?

Yes. I think so. Large part of the headache derives from the fact that ld.bfd is actually linker-script driven in any case.

ruiu added a comment.Aug 8 2016, 2:52 PM

Yup. My gut is in many cases we want to separate code paths for linker scripts and non-linker scripts even if they can share code. It's because the complexity to fix the impedance mismatch between the two code paths tend to surpass the benefit of sharing a small amount of code.

evgeny777 abandoned this revision.Aug 15 2016, 4:51 AM

Output sections are now merged in LinkerScript<ELFT>::createInputSectionList