Index: llvm/include/llvm/Object/MutableObject.h =================================================================== --- /dev/null +++ llvm/include/llvm/Object/MutableObject.h @@ -0,0 +1,87 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// +// +// Class for doing mutations on object files. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_MUTABLEOBJECT_H +#define LLVM_OBJECT_MUTABLEOBJECT_H + +#include "ObjectFile.h" +#include "llvm/ADT/MutableRange.h" + +namespace llvm { +namespace object { + +class MutableSectionBase { +public: + virtual ~MutableSectionBase() {} + virtual std::unique_ptr clone(); +}; + +class MutableSegmentBase { +public: + virtual ~MutableSegmentBase() {} + virtual std::unique_ptr clone(); +}; + +class MutableSymbolBase { +public: + virtual ~MutableSymbolBase() {} + virtual std::unique_ptr clone(); +}; + +// Custom cloner for MutableRange because MutableXXXBase classes +// are non trivially copyable. +template struct MutableEntryCloner { + T operator()(const T *Other) { return (*Other)->clone(); } +}; + +// MutableRange doesn't take ownership of the underlying container +// this is a small wrapper that does. +template +struct OwningMutableRange : public MutableRange, MutableEntryCloner> { + using VecType = std::vector; + using Base = MutableRange>; + + const VecType OwnedVec; + + OwningMutableRange(VecType Vec) : Base(Vec), OwnedVec(std::move(Vec)) {} +}; + +class MutableObject { + const ObjectFile &ObjFile; + + using SectionList = OwningMutableRange>; + using SegmentList = OwningMutableRange>; + using SymbolList = OwningMutableRange>; + SectionList Sections; + SegmentList Segments; + SymbolList Symbols; + + MutableObject(const ObjectFile &ObjFile, + SectionList::VecType OriginalSections, + SegmentList::VecType OriginalSegments, + SymbolList::VecType OriginalSymbols); + +public: + static Expected> + createMutableObject(const ObjectFile &ObjFile); + + const ObjectFile *getObjectFile() const { return &ObjFile; } + + SectionList §ions() { return Sections; } + SegmentList &segments() { return Segments; } + SymbolList &symbols() { return Symbols; } +}; + +} // namespace object +} // namespace llvm + +#endif // LLVM_OBJECT_MUTABLEOBJECT_H Index: llvm/lib/Object/CMakeLists.txt =================================================================== --- llvm/lib/Object/CMakeLists.txt +++ llvm/lib/Object/CMakeLists.txt @@ -15,6 +15,7 @@ MachOUniversal.cpp Minidump.cpp ModuleSymbolTable.cpp + MutableObject.cpp Object.cpp ObjectFile.cpp RecordStreamer.cpp Index: llvm/lib/Object/MutableObject.cpp =================================================================== --- /dev/null +++ llvm/lib/Object/MutableObject.cpp @@ -0,0 +1,40 @@ +//===- MutableObject.cpp - An object file which can be mutated ------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This class represents an object file which can be mutated, then recreated +// to reflect the changes. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/MutableObject.h" + +using namespace llvm; +using namespace object; + +MutableObject::MutableObject(const ObjectFile &ObjFile, + SectionList::VecType OriginalSections, + SegmentList::VecType OriginalSegments, + SymbolList::VecType OriginalSymbols) + : ObjFile(ObjFile), Sections(std::move(OriginalSections)), + Segments(std::move(OriginalSegments)), + Symbols(std::move(OriginalSymbols)) {} + +Expected> +MutableObject::createMutableObject(const ObjectFile &ObjFile) { + // Hacky way to expose the constructor publicly for make_unique. + struct PublicCtor : public MutableObject { + PublicCtor(const ObjectFile &ObjFile, SectionList::VecType Secs, + SegmentList::VecType Segs, SymbolList::VecType Syms) + : MutableObject(ObjFile, std::move(Secs), std::move(Segs), + std::move(Syms)) {} + }; + + return llvm::make_unique(ObjFile, SectionList::VecType(), + SegmentList::VecType(), + SymbolList::VecType()); +}