forked from OSchip/llvm-project
[ELF] --emit-relocs: adjust offsets of .rel[a].eh_frame relocations
.eh_frame pieces may be dropped due to GC/ICF. When --emit-relocs adds relocations against .eh_frame, the offsets need to be adjusted. Use the same way as MergeInputSection with a special case handling outSecOff==-1 for an invalid piece (see eh-frame-marker.s). This exposes an issue in mips64-eh-abs-reloc.s that we don't reliably handle anyway. Just add --no-check-dynamic-relocations to paper over it. Original patch by Ayrton Muñoz Differential Revision: https://reviews.llvm.org/D122459
This commit is contained in:
parent
f7381a795a
commit
6faba31e0d
|
@ -160,11 +160,15 @@ uint64_t SectionBase::getOffset(uint64_t offset) const {
|
||||||
case Regular:
|
case Regular:
|
||||||
case Synthetic:
|
case Synthetic:
|
||||||
return cast<InputSection>(this)->outSecOff + offset;
|
return cast<InputSection>(this)->outSecOff + offset;
|
||||||
case EHFrame:
|
case EHFrame: {
|
||||||
// The file crtbeginT.o has relocations pointing to the start of an empty
|
// The file crtbeginT.o has relocations pointing to the start of an empty
|
||||||
// .eh_frame that is known to be the first in the link. It does that to
|
// .eh_frame that is known to be the first in the link. It does that to
|
||||||
// identify the start of the output .eh_frame.
|
// identify the start of the output .eh_frame.
|
||||||
return offset;
|
const EhInputSection *es = cast<EhInputSection>(this);
|
||||||
|
if (InputSection *isec = es->getParent())
|
||||||
|
return isec->outSecOff + es->getParentOffset(offset);
|
||||||
|
return es->getParentOffset(offset);
|
||||||
|
}
|
||||||
case Merge:
|
case Merge:
|
||||||
const MergeInputSection *ms = cast<MergeInputSection>(this);
|
const MergeInputSection *ms = cast<MergeInputSection>(this);
|
||||||
if (InputSection *isec = ms->getParent())
|
if (InputSection *isec = ms->getParent())
|
||||||
|
@ -1334,6 +1338,21 @@ void EhInputSection::split(ArrayRef<RelTy> rels) {
|
||||||
getObjMsg(d.data() - rawData.data()));
|
getObjMsg(d.data() - rawData.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const EhSectionPiece &EhInputSection::getSectionPiece(uint64_t offset) const {
|
||||||
|
if (this->data().size() < offset)
|
||||||
|
fatal(toString(this) + ": offset is outside the section");
|
||||||
|
return partition_point(
|
||||||
|
pieces, [=](EhSectionPiece p) { return p.inputOff <= offset; })[-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the offset in an output section for a given input offset.
|
||||||
|
uint64_t EhInputSection::getParentOffset(uint64_t offset) const {
|
||||||
|
const EhSectionPiece &piece = getSectionPiece(offset);
|
||||||
|
if (piece.outputOff == -1) // invalid piece
|
||||||
|
return offset - piece.inputOff;
|
||||||
|
return piece.outputOff + (offset - piece.inputOff);
|
||||||
|
}
|
||||||
|
|
||||||
static size_t findNull(StringRef s, size_t entSize) {
|
static size_t findNull(StringRef s, size_t entSize) {
|
||||||
for (unsigned i = 0, n = s.size(); i != n; i += entSize) {
|
for (unsigned i = 0, n = s.size(); i != n; i += entSize) {
|
||||||
const char *b = s.begin() + i;
|
const char *b = s.begin() + i;
|
||||||
|
|
|
@ -325,6 +325,10 @@ public:
|
||||||
SmallVector<EhSectionPiece, 0> pieces;
|
SmallVector<EhSectionPiece, 0> pieces;
|
||||||
|
|
||||||
SyntheticSection *getParent() const;
|
SyntheticSection *getParent() const;
|
||||||
|
uint64_t getParentOffset(uint64_t offset) const;
|
||||||
|
|
||||||
|
// Return the EHSectionPiece at a given input section offset.
|
||||||
|
const EhSectionPiece &getSectionPiece(uint64_t offset) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a section that is added directly to an output section
|
// This is a section that is added directly to an output section
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
# RELOC: Offset Info Type Symbol's Value Symbol's Name + Addend
|
# RELOC: Offset Info Type Symbol's Value Symbol's Name + Addend
|
||||||
# RELOC-NEXT: {{0*}}[[#%x,OFF:]] [[#%x,]] R_X86_64_PC32 [[#%x,]] foo + 0
|
# RELOC-NEXT: {{0*}}[[#%x,OFF:]] [[#%x,]] R_X86_64_PC32 [[#%x,]] foo + 0
|
||||||
# RELOC-NEXT: {{0*}}[[#%x,OFF+20]] [[#%x,]] R_X86_64_PC32 [[#%x,]] bar + 0
|
# RELOC-NEXT: {{0*}}[[#%x,OFF+24]] [[#%x,]] R_X86_64_PC32 [[#%x,]] bar + 0
|
||||||
# RELOC-NEXT: {{0*}}[[#OFF]] [[#%x,]] R_X86_64_PC32 [[#%x,]] foo + 1
|
# RELOC-NEXT: {{0*}}[[#OFF+48]] [[#%x,]] R_X86_64_PC32 [[#%x,]] foo + 1
|
||||||
# RELOC-NEXT: {{0*}}[[#OFF+20]] [[#%x,]] R_X86_64_NONE 0{{$}}
|
# RELOC-NEXT: {{0*}}[[#%x,OFF-24]] [[#%x,]] R_X86_64_NONE 0{{$}}
|
||||||
|
|
||||||
# EH: Format: DWARF32
|
# EH: Format: DWARF32
|
||||||
# EH: 00000018 00000014 0000001c FDE cie=00000000 pc={{0*}}[[#%x,FOO:]]...
|
# EH: 00000018 00000014 0000001c FDE cie=00000000 pc={{0*}}[[#%x,FOO:]]...
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
# Having an R_MIPS_64 relocation in eh_frame would previously crash LLD
|
# Having an R_MIPS_64 relocation in eh_frame would previously crash LLD
|
||||||
# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o
|
# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o
|
||||||
# RUN: llvm-readobj -r %t.o | FileCheck %s -check-prefix OBJ
|
# RUN: llvm-readobj -r %t.o | FileCheck %s -check-prefix OBJ
|
||||||
# RUN: ld.lld --eh-frame-hdr -shared -z notext -o %t.so %t.o
|
# RUN: ld.lld --eh-frame-hdr -shared -z notext -o %t.so %t.o --no-check-dynamic-relocations
|
||||||
# RUN: llvm-readobj -r %t.so | FileCheck %s -check-prefix PIC-RELOCS
|
# RUN: llvm-readobj -r %t.so | FileCheck %s -check-prefix PIC-RELOCS
|
||||||
|
|
||||||
# Linking this as a PIE executable would also previously crash
|
# Linking this as a PIE executable would also previously crash
|
||||||
# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %S/Inputs/archive2.s -o %t-foo.o
|
# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %S/Inputs/archive2.s -o %t-foo.o
|
||||||
# -pie needs -z notext because of the R_MIPS_64 relocation
|
# -pie needs -z notext because of the R_MIPS_64 relocation
|
||||||
# RUN: ld.lld --eh-frame-hdr -Bdynamic -pie -z notext -o %t-pie-dynamic.exe %t.o %t-foo.o
|
# RUN: ld.lld --eh-frame-hdr -Bdynamic -pie -z notext -o %t-pie-dynamic.exe %t.o %t-foo.o --no-check-dynamic-relocations
|
||||||
# RUN: llvm-readobj -r %t-pie-dynamic.exe | FileCheck %s -check-prefix PIC-RELOCS
|
# RUN: llvm-readobj -r %t-pie-dynamic.exe | FileCheck %s -check-prefix PIC-RELOCS
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue