Current revision does not allow adding symbols to special output sections, like .eh_frame, .eh_frame_hdr and others.
This patch implements this feature (which is required by our dynamic linker)
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
This patch seems a bit tricky because it handles symbols at start or end of sections command specially. For example, it works as expected if a command is
.eh_frame_hdr { _foo = .; *(.eh_frame_hdr); _bar = .; }
but doesn't if
.eh_frame_hdr { _foo = .; *(.eh_frame_hdr); _bar1 = .; bar2 = .; }
I can see why you needed to do this (because special output sections are not a list of output sections), but I'm wondering if there's a better way than the way you implemented in this patch.
I agree, but unfortunately I don't see a lot of other options. What comes to my mind is:
- Implement more sophisticated logic, so it would handle your case.
- Check for symbol names (section name + "_end" or "_start"), and if there are then add start and/or end symbols.
Any other suggestions are appreciated, of course.
ELF/LinkerScript.cpp | ||
---|---|---|
314 ↗ | (On Diff #68838) | I'd also mention that special sections are not a list of regular output sections and therefore the regular mechanism to define symbols doesn't work. It's also good to mention that this approach is not perfect -- it only handles start and end symbols. |
321 ↗ | (On Diff #68838) | Use isa instead of dyn_cast. |
321–324 ↗ | (On Diff #68838) | Let's reduce the indentation level by using early continues. if (isa<InputSectionDescription>(...)) { Start = false; continue; } auto *AssignCmd = dyn_cast...; if (!AssignCmd) continue; |
ELF/LinkerScript.cpp | ||
---|---|---|
316 ↗ | (On Diff #68841) | Format. |
333–335 ↗ | (On Diff #68841) | If an output section is defined as .eh_frame { start = .; foo.o(.eh_frame); bar = .; bar.o(.eh_frame); end = . } then bar is silently set so that it points to the end of .eh_frame section? I think we want to print an error message for that instead. |
Fixed bug in addStartEndSymbols() which caused the following script to fail
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_hdr) }
ELF/LinkerScript.cpp | ||
---|---|---|
321 ↗ | (On Diff #69490) | It seems unnecessarily complicated to me. Why don't you do something like this? // Add start symbols. for (int I = 0, E = Cmd->Commands.size(); I < E; ++I) { if (!isa<SymbolAssignment>(Cmd->Commands[I])) break; .... } // Add end symbols. for (int I = Cmd->Commands.size() - 1; I >= 0; --I) { if (!isa<SymbolAssignment>(Cmd->Commands[I])) break; .... } |
ELF/LinkerScript.cpp | ||
---|---|---|
321 ↗ | (On Diff #69490) | That's fine, but what about error diagnostics, you suggested to add last time? |
ELF/LinkerScript.cpp | ||
---|---|---|
321 ↗ | (On Diff #69490) | Well, maybe something like this? // Add start symbols. int I = 0; for (int E = Cmd->Commands.size(); I < E; ++I) { if (!isa<SymbolAssignment>(Cmd->Commands[I])) break; .... } // Add end symbols. int J = Cmd->Commands.size() - 1; for (; J >= 0; --J) { if (!isa<SymbolAssignment>(Cmd->Commands[J])) break; .... } // Warn on stray assignment expressions. for (; I <= J; ++I) if (auto *Foo = dyn_cast<SymbolAssignment>(Cmd->Commands[I]) .... |
ELF/LinkerScript.cpp | ||
---|---|---|
321 ↗ | (On Diff #69490) | The problem in this implementation is that it add 'end' symbols in reverse order. The following one will not work: .eh_frame_hdr : { foo = .; *(.eh_frame_hdr) bar1 = .; bar2 = bar1 + 1; } |
Diff updated.
I've simplified the 'addStartEndSymbols' function and hope it's easier to understand now.