This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Refine warning condition for memory region assignment for non-allocatable section
ClosedPublic

Authored by andcarminati on May 31 2023, 6:30 AM.

Details

Summary

The warning "ignoring memory region assignment for non-allocatable section" should be generated under the following conditions:

  • sections without SHF_ALLOC attribute and,
  • presence of input sections or data commands (ByteCommand)

The goal of the change is to reduce spurious warnings that are generated for some output sections that have no input section.

Diff Detail

Event Timeline

andcarminati created this revision.May 31 2023, 6:30 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 31 2023, 6:30 AM
andcarminati requested review of this revision.May 31 2023, 6:30 AM

Just so I understand I think the main use case for this is where there is a linker script with OutputSections assigned to memory regions that may or may not contain input sections, it will depend on the input sections. As they won't get input sections they won't get the SHF_ALLOC flag and will get a spurious warning?

I agree that we shoudn't warn in that case, although I think the proposed change might suppress too many warnings at the moment.

I note that GNU ld permits the assignment of non SHF_ALLOC sections to MEM regions, assigning them an address if SHF_ALLOC, (although it ignores the empty ones). Although that is a separate issue.

lld/ELF/LinkerScript.cpp
914–919

I think this will also suppress the warning for something like:

.dat : { LONG(0); } > MEM1

Which I note that GNU ld makes SHF_ALLOC but LLD does not, which is a separate issue, but I think we should keep the warning for this case until that can be changed. Perhaps worth warning when the size is non zero or whether the sec contains data generating commands.

lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test
62

Was this meant to be MEM1?

Just done a bit more experiments on the output section just containing LONG. It appears that LLD will give it flags based on the preceding OutputSection. I.e. if it follows .text it will get SHF_ALLOC and SHF_EXECINSTR however if it follows .nonalloc it won't get either. In GNU ld it gets SHF_ALLOC and SHF_WRITE.

Just so I understand I think the main use case for this is where there is a linker script with OutputSections assigned to memory regions that may or may not contain input sections, it will depend on the input sections. As they won't get input sections they won't get the SHF_ALLOC flag and will get a spurious warning?

I agree that we shoudn't warn in that case, although I think the proposed change might suppress too many warnings at the moment.

I note that GNU ld permits the assignment of non SHF_ALLOC sections to MEM regions, assigning them an address if SHF_ALLOC, (although it ignores the empty ones). Although that is a separate issue.

Hi Peter, thank you for the comments. That is the exact point, we are getting spurious warnings for some cases.

lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test
62

Indeed, thank you!

This comment was removed by andcarminati.
lld/ELF/LinkerScript.cpp
914–919

The warning for this case (without the patch) depends on the ordering of the commands. For example:

.nonalloc : { *(.nonalloc) } > MEM1
.dat : { LONG(0); } > MEM1
.intvec0_out (VEC_START + 0x0000) : {KEEP (*(.intvec1)) } > MEM2
.intvec1_out (VEC_START + 0x0020) : {KEEP (*(.intvec1)) } > MEM2
.intvec2_out (VEC_START + 0x0040) : {KEEP (*(.intvec2)) } > MEM2
.intvec3_out (VEC_START + 0x0060) : {KEEP (*(.intvec3)) } > MEM2

Gives:

ld.lld: warning: ignoring memory region assignment for non-allocatable section '.nonalloc'
ld.lld: warning: ignoring memory region assignment for non-allocatable section '.dat'
ld.lld: warning: ignoring memory region assignment for non-allocatable section '.intvec0_out'
ld.lld: warning: ignoring memory region assignment for non-allocatable section '.intvec1_out'
ld.lld: warning: ignoring memory region assignment for non-allocatable section '.intvec2_out'

But, if we change the order:

.nonalloc : { *(.nonalloc) } > MEM1
.intvec0_out (VEC_START + 0x0000) : {KEEP (*(.intvec1)) } > MEM2
.intvec1_out (VEC_START + 0x0020) : {KEEP (*(.intvec1)) } > MEM2
.intvec2_out (VEC_START + 0x0040) : {KEEP (*(.intvec2)) } > MEM2
.intvec3_out (VEC_START + 0x0060) : {KEEP (*(.intvec3)) } > MEM2
.dat : { LONG(0); } > MEM1

We get:

ld.lld: warning: ignoring memory region assignment for non-allocatable section '.nonalloc'
ld.lld: warning: ignoring memory region assignment for non-allocatable section '.intvec0_out'
ld.lld: warning: ignoring memory region assignment for non-allocatable section '.intvec1_out'
ld.lld: warning: ignoring memory region assignment for non-allocatable section '.intvec2_out'

With the change, we have a more deterministic output, just for the .nonalloc

What do you think? We can change to keep the warning for the mentioned case, but it will depend on the ordering to be triggered.

andcarminati edited the summary of this revision. (Show Details)

All current suggestions addressed:

  • Warnings kept for data generation commands (ByteCommand)
  • Test update (fix MEM -> MEM1)
peter.smith accepted this revision.Jun 2 2023, 8:33 AM

Thanks for the update this looks good to me. If in a later change we can make the ByteCommands set the SHF_ALLOC flag on the OutputSection we can update the test.

Please leave a few days for MaskRay (Code Owner) to comment to see if he has any suggestions.

This revision is now accepted and ready to land.Jun 2 2023, 8:33 AM

Thanks for the update this looks good to me. If in a later change we can make the ByteCommands set the SHF_ALLOC flag on the OutputSection we can update the test.

Please leave a few days for MaskRay (Code Owner) to comment to see if he has any suggestions.

Thank you very much for the review.

MaskRay requested changes to this revision.Jun 5 2023, 10:37 AM

Thanks for the patch. The code looks good, there are a few needed changes so I clicked "Request Changes".

lld/ELF/LinkerScript.cpp
916

isa<ByteCommand>

Actually, you can rewrite this scope with llvm::any_of

lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test
22

Any reason to test -Map=? To test all sections are present, use llvm-readelf -S

50

Don't indent .section. The .section below is not indented.

72

delete trailing blank lines

This revision now requires changes to proceed.Jun 5 2023, 10:37 AM

[ELF] Fix linker warning condition for empty sections

I don't think there is a bug. The new patch makes the behavior closer to GNU ld which may be more desired. "Refine" may be more appropriate.

[ELF] Refine warning condition for memory region assignment for non-allocatable section

lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test
12

Otherwise, this doesn't really test that there is no other warning.

andcarminati retitled this revision from [ELF] Fix linker warning condition for empty sections to [ELF] Refine warning condition for memory region assignment for non-allocatable section.

All comments from MaskRay were addressed.

andcarminati marked 2 inline comments as done.Jun 6 2023, 8:53 AM
MaskRay accepted this revision.Jun 8 2023, 1:22 PM

Some nits

lld/ELF/LinkerScript.cpp
916

Ping for this unaddressed comment. isa<ByteCommand>

lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test
27

File offsets will make test updates difficult if .symtab/.strtab changes. https://maskray.me/blog/2021-08-08-toolchain-testing#the-test-checks-too-much

Perhaps the "Off" column should all use {{.*}} to ignore values, as well "Size" for .comment/.symtab/.shstrtab

This revision is now accepted and ready to land.Jun 8 2023, 1:22 PM

MaskRay' s comment about the test was addressed.

andcarminati marked 4 inline comments as done.Jun 9 2023, 7:32 AM
andcarminati marked 3 inline comments as done.

If there are no more comments, can you kindly commit this change, when you have time @MaskRay ?

Herald added a project: Restricted Project. · View Herald TranscriptJun 13 2023, 2:57 PM
MaskRay updated this revision to Diff 531083.Jun 13 2023, 3:01 PM
MaskRay edited the summary of this revision. (Show Details)

simplify and better test

MaskRay added a comment.EditedJun 13 2023, 3:04 PM

Since you do not use arc diff 'HEAD^' to update the differential, arc patch D151802 doesn't give author name/email information. You need to provide a git commit --amend --author='...' command for me to give credits to you!

Since you do not use arc diff 'HEAD^' to update the differential, arc patch D151802 doesn't give author name/email information. You need to provide a git commit --amend --author='...' command for me to give credits to you!

Sorry for this missing detail:

git commit --amend --author='Andreu Carminati <andreu.carminati@hightec-rt.com>'

Thank you!