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
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 | ||
|---|---|---|
| 309 | 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. | |
| 316 | Use isa instead of dyn_cast. | |
| 316–319 | Let's reduce the indentation level by using early continues. if (isa<InputSectionDescription>(...)) {
Start = false;
continue;
}
auto *AssignCmd = dyn_cast...;
if (!AssignCmd)
continue; | |
Fixed bug in addStartEndSymbols() which caused the following script to fail
.eh_frame_hdr : {
*(.eh_frame_hdr)
*(.eh_frame_hdr)
}| ELF/LinkerScript.cpp | ||
|---|---|---|
| 316 | 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 | ||
|---|---|---|
| 316 | That's fine, but what about error diagnostics, you suggested to add last time? | |
| ELF/LinkerScript.cpp | ||
|---|---|---|
| 316 | 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 | ||
|---|---|---|
| 316 | 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.
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.