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.