[PATCH] D49557: [ELF] Fix handling of FDE negative relative PC addr

Andrew Ng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 19 10:25:25 PDT 2018


andrewng created this revision.
andrewng added reviewers: ruiu, grimar.
Herald added subscribers: arichardson, emaste.
Herald added a reviewer: espindola.

Signed values for the FDE PC addr were not correctly handled in
readFdeAddr(). If the value is negative and the type of the value is
smaller than 64 bits, the FDE PC addr overflow error would be
incorrectly triggered.

Fixed readFdeAddr() to properly handle signed values by sign extending
where appropriate.


https://reviews.llvm.org/D49557

Files:
  ELF/SyntheticSections.cpp
  test/ELF/eh-frame-negative-relative-pcaddr.s


Index: test/ELF/eh-frame-negative-relative-pcaddr.s
===================================================================
--- /dev/null
+++ test/ELF/eh-frame-negative-relative-pcaddr.s
@@ -0,0 +1,39 @@
+# REQUIRES: x86
+
+# Tests that FDE pc negative relative addressing does not trigger overflow error.
+# This situation can arise when .eh_frame is placed after .text.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "SECTIONS { \
+# RUN:   .text : { *(.text) } \
+# RUN:   .eh_frame : { *(.eh_frame) } \
+# RUN: }" > %t.script
+# RUN: ld.lld --eh-frame-hdr --script %t.script %t.o -o /dev/null
+
+.text
+.global _start
+_start:
+ nop
+
+.section .eh_frame, "a"
+  .long 12   # Size
+  .long 0x00 # ID
+  .byte 0x01 # Version.
+
+  .byte 0x52 # Augmentation string: 'R','\0'
+  .byte 0x00
+
+  .byte 0x01
+
+  .byte 0x01 # LEB128
+  .byte 0x01 # LEB128
+
+  .byte 0x1B # DW_EH_PE_pcrel | DW_EH_PE_sdata4
+
+  .byte 0xFF
+
+  .long 12   # Size
+  .long 20   # ID
+fde:
+  .long _start - fde
+  .long 0
Index: ELF/SyntheticSections.cpp
===================================================================
--- ELF/SyntheticSections.cpp
+++ ELF/SyntheticSections.cpp
@@ -521,7 +521,12 @@
     return read16(Buf);
   case DW_EH_PE_udata4:
     return read32(Buf);
+  case DW_EH_PE_sdata2:
+    return (int16_t)read16(Buf);
+  case DW_EH_PE_sdata4:
+    return (int32_t)read32(Buf);
   case DW_EH_PE_udata8:
+  case DW_EH_PE_sdata8:
     return read64(Buf);
   case DW_EH_PE_absptr:
     return readUint(Buf);
@@ -536,7 +541,7 @@
   // The starting address to which this FDE applies is
   // stored at FDE + 8 byte.
   size_t Off = FdeOff + 8;
-  uint64_t Addr = readFdeAddr(Buf + Off, Enc & 0x7);
+  uint64_t Addr = readFdeAddr(Buf + Off, Enc & 0xf);
   if ((Enc & 0x70) == DW_EH_PE_absptr)
     return Addr;
   if ((Enc & 0x70) == DW_EH_PE_pcrel)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D49557.156307.patch
Type: text/x-patch
Size: 1873 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180719/1e0a5b95/attachment-0001.bin>


More information about the llvm-commits mailing list