If more than a single output section is added to a PT_LOAD header, only the first section should set the LMAOffset of the segment. Otherwise, we get a load-address overlap error
Details
Diff Detail
- Repository
- rLLD LLVM Linker
Event Timeline
ELF/LinkerScript.cpp | ||
---|---|---|
794 | I think the comment above should be updated to reflect this change. But also: your test pass if I reduce this to if (PhdrEntry *L = Ctx->OutSec->PtLoad) if (Sec == L->FirstSec) L->LMAOffset = Ctx->LMAOffset; Can you add a test/update it accordingly to check the rest? Also, I think that (L->FirstSec == Out::ElfHeader) condition is not correct. Because |
ELF/LinkerScript.cpp | ||
---|---|---|
794 | The following tests rely on the additional check and fail if it is removed: lld :: ELF/linkerscript/at-addr.s lld :: ELF/linkerscript/at.s lld :: ELF/linkerscript/loadaddr.s lld :: ELF/linkerscript/merge-header-load.s lld :: ELF/linkerscript/overlay.test lld :: ELF/linkerscript/segment-headers.s lld :: ELF/note-loadaddr.s The ELF header section is added to the first PT_LOAD header unconditionally here: https://github.com/llvm-mirror/lld/blob/master/ELF/Writer.cpp#L1807 I think we need to check for both ElfHeader and ProgramHeaders and will try to come up with an additional test case for that. |
ELF/LinkerScript.cpp | ||
---|---|---|
794 | Ah I see, I did not check the other tests.
Yes. I think we might need some little helper function so that it can be reused in places like
Yeah, that is for the case when PHDRS command is not used in the linker script. But if it is used, it is not added unconditionally then. |
ELF/LinkerScript.cpp | ||
---|---|---|
794 | I don't think the createPhdrs() functions in Writer.cpp and Linkerscript.cpp share a lot of common functionality. What kind of helper function do you have in mind? With the PHDRS linker script command, the user is in charge of reasonably adding output sections to PT_LOAD segments. |
ELF/LinkerScript.cpp | ||
---|---|---|
794 | I was thinking about something very trivial. Like: static bool isHeaderSection(InputSection *IS) { return IS == Out::ElfHeader || IS == Out::ProgramHeaders; } So you could perhaps write: if (PhdrEntry *L = Ctx->OutSec->PtLoad) if ((Sec == L->FirstSec) || (isHeaderSection(L->FirstSec) && (L->LastSec == Sec))) Does it make sense? |
ELF/LinkerScript.cpp | ||
---|---|---|
794 | It would certainly help the readability of the code. I can add that function. However, this case (FirstSec == Out::ProgramHeaders) can only occur if the PHDRS command is used, and for that case this patch does not provide a solution (see my comment above). Do you have an idea for that problem? |
ELF/LinkerScript.cpp | ||
---|---|---|
794 | I only can think of helper function that would iterate over OutputSections to find the first non-header section for the PT_LOAD given. This should solve the problem, right? |
ELF/LinkerScript.cpp | ||
---|---|---|
794 | Yes, that should solve the problem for PHDRS command. Would you agree to have that in a follow-up patch or should it already go into this one? |
ELF/LinkerScript.cpp | ||
---|---|---|
794 | I would perhaps include it into this one because adding the helper discussed looks like a correct way to go forward here. I think you can leave the test case as is though (since we already have a number of the tests failing without the new code). |
LGTM, thanks! I'll commit this for you and land a little refactoring change on top I think.
(btw, I think you can request for commit access now if you want/need it).
ELF/LinkerScript.cpp | ||
---|---|---|
758 | It is taken from LinkerScript.cpp I guess. I think it is ok to have a copy for now since this helper is little. |
ELF/LinkerScript.cpp | ||
---|---|---|
758 | Oops. it is the same file :) Ignore this comment then. |
I committed r338699, it removes isHeaderSection.
I think it was my mistake to suggest adding it to this patch.
It is taken from LinkerScript.cpp I guess. I think it is ok to have a copy for now since this helper is little.