[lld] r232414 - [ELF] Use pcrel format for eh_frame_ptr field encoding
Simon Atanasyan
simon at atanasyan.com
Mon Mar 16 14:07:46 PDT 2015
Author: atanasyan
Date: Mon Mar 16 16:07:46 2015
New Revision: 232414
URL: http://llvm.org/viewvc/llvm-project?rev=232414&view=rev
Log:
[ELF] Use pcrel format for eh_frame_ptr field encoding
The `eh_frame_ptr` field in the `.eh_frame_hdr` section contains an address
of the `.eh_frame` section. Using an absolute 32-bit format for encoding
of this field does not work for 64-bit targets. It is better to use a
relative format because it covers both 32-bit and 64-bit cases. Sure
this work if a distance between `.eh_frame_hdr` and `.eh_frame` sections
is less than 4 Gb but it is a rather correct assumption.
http://reviews.llvm.org/D8352
Modified:
lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
lld/trunk/test/elf/eh_frame_hdr.test
Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=232414&r1=232413&r2=232414&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Mon Mar 16 16:07:46 2015
@@ -1450,7 +1450,8 @@ template <class ELFT> class EHFrameHeade
public:
EHFrameHeader(const ELFLinkingContext &context, StringRef name,
TargetLayout<ELFT> &layout, int32_t order)
- : Section<ELFT>(context, name, "EHFrameHeader"), _layout(layout) {
+ : Section<ELFT>(context, name, "EHFrameHeader"), _ehFrameOffset(0),
+ _layout(layout) {
this->setOrder(order);
this->_entSize = 0;
this->_type = SHT_PROGBITS;
@@ -1467,24 +1468,27 @@ public:
void finalize() override {
OutputSection<ELFT> *s = _layout.findOutputSection(".eh_frame");
- _ehFrameAddr = s ? s->virtualAddr() : 0;
+ OutputSection<ELFT> *h = _layout.findOutputSection(".eh_frame_hdr");
+ if (s && h)
+ _ehFrameOffset = s->virtualAddr() - (h->virtualAddr() + 4);
}
- virtual void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override {
+ void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) override {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
int pos = 0;
dest[pos++] = 1; // version
- dest[pos++] = llvm::dwarf::DW_EH_PE_udata4; // eh_frame_ptr_enc
+ dest[pos++] = llvm::dwarf::DW_EH_PE_pcrel |
+ llvm::dwarf::DW_EH_PE_sdata4; // eh_frame_ptr_enc
dest[pos++] = llvm::dwarf::DW_EH_PE_omit; // fde_count_enc
dest[pos++] = llvm::dwarf::DW_EH_PE_omit; // table_enc
- *reinterpret_cast<typename llvm::object::ELFFile<ELFT>::Elf_Word *>(
- dest + pos) = (uint32_t)_ehFrameAddr;
+ *reinterpret_cast<typename llvm::object::ELFFile<ELFT>::Elf_Sword *>(
+ dest + pos) = _ehFrameOffset;
}
private:
- uint64_t _ehFrameAddr;
+ int32_t _ehFrameOffset;
TargetLayout<ELFT> &_layout;
};
} // end namespace elf
Modified: lld/trunk/test/elf/eh_frame_hdr.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/eh_frame_hdr.test?rev=232414&r1=232413&r2=232414&view=diff
==============================================================================
--- lld/trunk/test/elf/eh_frame_hdr.test (original)
+++ lld/trunk/test/elf/eh_frame_hdr.test Mon Mar 16 16:07:46 2015
@@ -1,7 +1,7 @@
#RUN: yaml2obj -format=elf %s > %t
#RUN: lld -flavor gnu -target x86_64-linux %t --noinhibit-exec \
#RUN: -o %t1
-#RUN: llvm-readobj -s %t1 | FileCheck %s
+#RUN: llvm-objdump -s %t1 | FileCheck %s
!ELF
FileHeader:
@@ -23,4 +23,8 @@ Symbols:
Type: STT_SECTION
Section: .eh_frame
-#CHECK: .eh_frame_hdr
+# CHECK: Contents of section .eh_frame:
+# CHECK-NEXT: 4001e0 00
+# CHECK-NEXT: Contents of section .eh_frame_hdr:
+# CHECK-NEXT: 4001e8 011bffff f4ffffff
+# ^ 0x4001e0 - 0x4001e8 - 4 = 0xfffffff4
More information about the llvm-commits
mailing list