diff --git a/elf.cc b/elf.cc
index 78e99af867fa4b1b31bf20765e2ebca0c346f422..f2abbe78febdd82f02c2111c843af534937cec5b 100644
--- a/elf.cc
+++ b/elf.cc
@@ -348,12 +348,31 @@ namespace elf {
         }
     }
 
+    void elf_object::relocate_pltgot()
+    {
+        auto rel = dynamic_ptr<Elf64_Rela>(DT_JMPREL);
+        auto nrel = dynamic_val(DT_PLTRELSZ) / sizeof(*rel);
+        for (auto p = rel; p < rel + nrel; ++p) {
+            auto info = p->r_info;
+              u32 sym = info >> 32;
+              u32 type = info & 0xffffffff;
+              assert(type = R_X86_64_JUMP_SLOT);
+              void *addr = _base + p->r_offset;
+              // The JUMP_SLOT entry already points back to the PLT, just
+              // make sure it is relocated relative to the object base.
+              *static_cast<u64*>(addr) += reinterpret_cast<u64>(_base);
+        }
+    }
+
     void elf_object::relocate()
     {
         assert(!dynamic_exists(DT_REL));
         if (dynamic_exists(DT_RELA)) {
             relocate_rela();
         }
+        if (dynamic_exists(DT_JMPREL)) {
+            relocate_pltgot();
+        }
     }
 
     unsigned long
diff --git a/elf.hh b/elf.hh
index ece9af995ae08b6f4606873e428247b6d3d876ce..bb6a37f33ea2f8cb5b9ab8ef716459db5a55cf99 100644
--- a/elf.hh
+++ b/elf.hh
@@ -272,6 +272,7 @@ namespace elf {
         symbol_module symbol(unsigned idx);
         Elf64_Xword symbol_tls_module(unsigned idx);
         void relocate_rela();
+        void relocate_pltgot();
     protected:
         program& _prog;
 	Elf64_Ehdr _ehdr;