Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,34 @@ void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf,
p->setSymbolAndType(ctx.in.symTab->getSymbolIndex(sym), type,
ctx.arg.isMips64EL);

// Discard the invalid pieces among those named
// "DW.ref.__gxx_personality_v0".
StringRef symName = sym.getName();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this limited to DW.ref.__gxx_personality_v0? Even if it is, if the underlying problem is that the pieces of the .eh_frame are optimised, but the relocations are not then why do you need to check for the particular symbol. Surely if the relocation offset doesn't exist then it would apply to all symbols.

Assuming this is specific to DW.ref.__gxx_personality_v0 then this is doing a string comparison on every relocation then checking that the section is an EhInputSection. I suggest that you reverse the order.

if (symName == "DW.ref.__gxx_personality_v0") {
if (auto *es = dyn_cast<EhInputSection>(sec)) {
auto it = partition_point(es->fdes, [=](EhSectionPiece p) {
return p.inputOff <= rel.offset;
});

if (it == es->fdes.begin() ||
it[-1].inputOff + it[-1].size <= rel.offset) {
it = partition_point(es->cies, [=](EhSectionPiece p) {
return p.inputOff <= rel.offset;
});
if (it == es->cies.begin()) {
// invalid piece
p->setSymbolAndType(0, 0, false);
continue;
}
}

if (it[-1].outputOff == -1) {
p->setSymbolAndType(0, 0, false);
continue;
}
}
}

if (sym.type == STT_SECTION) {
// We combine multiple section symbols into only one per
// section. This means we have to update the addend. That is
Expand Down