Index: llvm/include/llvm/Object/MutableELFObject.h
===================================================================
--- /dev/null
+++ llvm/include/llvm/Object/MutableELFObject.h
@@ -0,0 +1,81 @@
+//===-- MutableELFObject.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MUTABLEELFOBJECT_H
+#define LLVM_OBJECT_MUTABLEELFOBJECT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/MutableObject.h"
+
+namespace llvm {
+namespace object {
+
+template <typename ELFT> class MutableELFObject;
+
+static DataRefImpl toDataRef(uintptr_t Ptr) {
+  DataRefImpl Ref;
+  Ref.p = Ptr;
+  return Ref;
+}
+
+template <typename ELFT> class MutableELFSection {
+public:
+  Elf_Shdr_Impl<ELFT> Header;
+  std::string Name;
+  OwningArrayRef<uint8_t> Data;
+
+  MutableELFSection(uintptr_t ToCopy, const MutableELFObject<ELFT> *ObjFile)
+      : MutableELFSection(toDataRef(ToCopy), ObjFile) {}
+  MutableELFSection(DataRefImpl ToCopy, const MutableELFObject<ELFT> *ObjFile)
+      : Header(*ObjFile->getSection(ToCopy)),
+        Data(OwningArrayRef<uint8_t>(Header.sh_size)) {
+    ::memcpy(Data.data(), ObjFile->base() + Header.sh_offset, Header.sh_size);
+  }
+};
+
+template <typename ELFT> class MutableELFObject : public ELFObjectFile<ELFT> {
+  friend class MutableELFSection<ELFT>;
+
+  MutableRange<MutableELFSection<ELFT>> Sections;
+
+  void moveSectionNext(DataRefImpl &Sec) const override { ++Sec.p; }
+
+  Expected<StringRef> getSectionName(DataRefImpl Sec) const override {
+    MutableRange::MappingType Mapping = Sections[Sec.p];
+    if (Mapping.New) {
+      auto *NewSec = Sections.getNew(Mapping.Ptr);
+      return NewSec->Name;
+    }
+    return ELFObjectFile<ELFT>::getSectionName(toDataRef(Mapping.Ptr));
+  }
+
+public:
+  MutableELFObject(ELFObjectFile<ELFT> &B)
+      : ELFObjectFile<ELFT>(std::move(B)),
+        Sections(B.section_begin(), B.section_end(),
+                 [&](SectionRef Ref) { return Ref.getRawDataRefImpl().p; }) {}
+
+  section_iterator section_begin() const override {
+    return section_iterator(SectionRef(toDataRef(0), this));
+  }
+
+  section_iterator section_end() const override {
+    return section_iterator(SectionRef(toDataRef(Sections.size()), this));
+  }
+
+  MutableELFSection<ELFT> *getMutableSection(section_iterator Sec) {
+    auto Index = Sec->getRawDataRefImpl().p;
+    return Sections.makeMutable(Index, this);
+  }
+};
+
+} // namespace object
+} // namespace llvm
+
+#endif // LLVM_OBJECT_MUTABLEELFOBJECT_H
Index: llvm/include/llvm/Object/MutableObject.h
===================================================================
--- /dev/null
+++ llvm/include/llvm/Object/MutableObject.h
@@ -0,0 +1,77 @@
+//===-- MutableObject.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MUTABLEOBJECT_H
+#define LVM_OBJECT_MUTABLEOBJECT_H
+
+#include "llvm/Object/ELFObjectFile.h"
+
+namespace llvm {
+namespace object {
+
+// T is a wrapper type around Iterable::value_type and must have a constructor
+// taking an Iterable::value_type.
+template <typename T> class MutableRange {
+public:
+  struct MappingType {
+    bool New : 1;
+    uintptr_t Ptr : sizeof(void *) * 8 - 1;
+
+    MappingType(bool New, uintptr_t Ptr) : New(New), Ptr(Ptr) {}
+
+    uintptr_t getPtr() const { return Ptr; }
+  };
+
+  using iterator = typename std::vector<MappingType>::iterator;
+  using value_type = MappingType;
+
+private:
+  std::vector<MappingType> Mappings;
+  std::vector<T> NewValues;
+
+public:
+  template <typename Iterable, typename Extractor>
+  MutableRange(Iterable Range, Extractor Extract)
+      : MutableRange(Range.begin(), Range.end(), Extract) {}
+
+  template <typename Iter, typename Extractor>
+  MutableRange(Iter Begin, Iter End, Extractor Extract) {
+    std::transform(
+        Begin, End, std::back_inserter(Mappings),
+        [&Extract](typename Iter::value_type Value) -> MappingType {
+          auto Extracted = Extract(Value);
+          assert(Extracted <= (UINT64_MAX >> 1) && "returned type too large");
+          return MappingType(false, reinterpret_cast<uintptr_t>(Extracted));
+        });
+  }
+
+  MappingType operator[](uint64_t Index) const { return Mappings[Index]; }
+
+  size_t size() const { return Mappings.size(); }
+
+  iterator begin() { return Mappings.begin(); }
+  iterator end() { return Mappings.end(); }
+
+  const T *getNew(uint64_t Index) const { return &NewValues[Index]; }
+  T *getNew(uint64_t Index) { return &NewValues[Index]; }
+
+  template <typename... Args>
+  T *makeMutable(uint64_t Index, Args &&... Arguments) {
+    MappingType Mapping = Mappings[Index];
+    if (Mapping.New)
+      return &NewValues[reinterpret_cast<uintptr_t>(Mapping.Ptr)];
+    NewValues.emplace_back(Mapping.getPtr(), Arguments...);
+    Mappings[Index] = MappingType(true, NewValues.size() - 1);
+    return &NewValues.back();
+  }
+};
+
+} // namespace object
+} // namespace llvm
+
+#endif // LVM_OBJECT_MUTABLEOBJECT_H