[llvm] r204398 - Add an option to MCJIT to have it forward all sections to the

Philip Reames listmail at philipreames.com
Thu Mar 20 16:57:42 PDT 2014


In this case, I might vote for changing the default.  Given the old 
behaviour is unlikely to be correct, I don't see the benefit in keeping 
it as the default.

Philip

On 03/20/2014 02:06 PM, Lang Hames wrote:
> Author: lhames
> Date: Thu Mar 20 16:06:46 2014
> New Revision: 204398
>
> URL: http://llvm.org/viewvc/llvm-project?rev=204398&view=rev
> Log:
> Add an option to MCJIT to have it forward all sections to the
> RTDyldMemoryManager, regardless of whether it thinks they're "required for
> execution".
>
> Currently, RuntimeDyld only passes sections that are "required for execution"
> to the RTDyldMemoryManager, and takes "required for execution" to mean exactly
> "contains symbols or relocations". There are two problems with this:
> (1) It can drop sections with anonymous data that is referenced by code.
> (2) It leaves the JIT client no way to inspect interesting sections that aren't
>      actually required to run the program (e.g dwarf sections).
>
> A test case is still in the works.
>
> Future work: We may want to replace this with a generic section filtering
> mechanism, but that will require more consideration. For now, this flag at least
> allows clients to volunteer to do the filtering themselves.
>
> Fixes <rdar://problem/15177691>.
>
>
> Modified:
>      llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
>      llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
>      llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
>      llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
>      llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=204398&r1=204397&r2=204398&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original)
> +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Thu Mar 20 16:06:46 2014
> @@ -462,6 +462,21 @@ public:
>       llvm_unreachable("No support for an object cache");
>     }
>   
> +  /// setProcessAllSections (MCJIT Only): By default, only sections that are
> +  /// "required for execution" are passed to the RTDyldMemoryManager, and other
> +  /// sections are discarded. Passing 'true' to this method will cause
> +  /// RuntimeDyld to pass all sections to its RTDyldMemoryManager regardless
> +  /// of whether they are "required to execute" in the usual sense.
> +  ///
> +  /// Rationale: Some MCJIT clients want to be able to inspect metadata
> +  /// sections (e.g. Dwarf, Stack-maps) to enable functionality or analyze
> +  /// performance. Passing these sections to the memory manager allows the
> +  /// client to make policy about the relevant sections, rather than having
> +  /// MCJIT do it.
> +  virtual void setProcessAllSections(bool ProcessAllSections) {
> +    llvm_unreachable("No support for ProcessAllSections option");
> +  }
> +
>     /// Return the target machine (if available).
>     virtual TargetMachine *getTargetMachine() { return NULL; }
>   
>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=204398&r1=204397&r2=204398&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h (original)
> +++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h Thu Mar 20 16:06:46 2014
> @@ -36,6 +36,7 @@ class RuntimeDyld {
>     // interface.
>     RuntimeDyldImpl *Dyld;
>     RTDyldMemoryManager *MM;
> +  bool ProcessAllSections;
>   protected:
>     // Change the address associated with a section when resolving relocations.
>     // Any relocations already associated with the symbol will be re-resolved.
> @@ -84,6 +85,19 @@ public:
>     void deregisterEHFrames();
>   
>     StringRef getErrorString();
> +
> +  /// By default, only sections that are "required for execution" are passed to
> +  /// the RTDyldMemoryManager, and other sections are discarded. Passing 'true'
> +  /// to this method will cause RuntimeDyld to pass all sections to its
> +  /// memory manager regardless of whether they are "required to execute" in the
> +  /// usual sense. This is useful for inspecting metadata sections that may not
> +  /// contain relocations, E.g. Debug info, stackmaps.
> +  ///
> +  /// Must be called before the first object file is loaded.
> +  void setProcessAllSections(bool ProcessAllSections) {
> +    assert(!Dyld && "setProcessAllSections must be called before loadObject.");
> +    this->ProcessAllSections = ProcessAllSections;
> +  }
>   };
>   
>   } // end namespace llvm
>
> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h?rev=204398&r1=204397&r2=204398&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h (original)
> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h Thu Mar 20 16:06:46 2014
> @@ -251,6 +251,10 @@ public:
>     /// Sets the object manager that MCJIT should use to avoid compilation.
>     void setObjectCache(ObjectCache *manager) override;
>   
> +  void setProcessAllSections(bool ProcessAllSections) override {
> +    Dyld.setProcessAllSections(ProcessAllSections);
> +  }
> +
>     void generateCodeForModule(Module *M) override;
>   
>     /// finalizeObject - ensure the module is fully processed and is usable.
>
> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=204398&r1=204397&r2=204398&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Thu Mar 20 16:06:46 2014
> @@ -161,25 +161,22 @@ ObjectImage* RuntimeDyldImpl::loadObject
>     DEBUG(dbgs() << "Parse relocations:\n");
>     for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections();
>          SI != SE; ++SI) {
> -    bool IsFirstRelocation = true;
>       unsigned SectionID = 0;
>       StubMap Stubs;
>       section_iterator RelocatedSection = SI->getRelocatedSection();
>   
> -    for (const RelocationRef &Reloc : SI->relocations()) {
> -      // If it's the first relocation in this section, find its SectionID
> -      if (IsFirstRelocation) {
> -        bool IsCode = false;
> -        Check(RelocatedSection->isText(IsCode));
> -        SectionID =
> -            findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
> -        DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
> -        IsFirstRelocation = false;
> -      }
> +    if ((SI->relocation_begin() != SI->relocation_end()) ||
> +        ProcessAllSections) {
> +      bool IsCode = false;
> +      Check(RelocatedSection->isText(IsCode));
> +      SectionID =
> +        findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
> +      DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
> +    }
>   
> +    for (const RelocationRef &Reloc : SI->relocations())
>         processRelocationRef(SectionID, Reloc, *Obj, LocalSections, LocalSymbols,
>                              Stubs);
> -    }
>     }
>   
>     // Give the subclasses a chance to tie-up any loose ends.
> @@ -665,23 +662,40 @@ RuntimeDyld::RuntimeDyld(RTDyldMemoryMan
>     // permissions are applied.
>     Dyld = 0;
>     MM = mm;
> +  ProcessAllSections = false;
>   }
>   
>   RuntimeDyld::~RuntimeDyld() {
>     delete Dyld;
>   }
>   
> +static std::unique_ptr<RuntimeDyldELF> createRuntimeDyldELF(
> +                                                   RTDyldMemoryManager *MM,
> +                                                   bool ProcessAllSections) {
> +  std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM));
> +  Dyld->setProcessAllSections(ProcessAllSections);
> +  return Dyld;
> +}
> +
> +static std::unique_ptr<RuntimeDyldMachO> createRuntimeDyldMachO(
> +                                                   RTDyldMemoryManager *MM,
> +                                                   bool ProcessAllSections) {
> +  std::unique_ptr<RuntimeDyldMachO> Dyld(new RuntimeDyldMachO(MM));
> +  Dyld->setProcessAllSections(ProcessAllSections);
> +  return Dyld;
> +}
> +
>   ObjectImage *RuntimeDyld::loadObject(ObjectFile *InputObject) {
>     std::unique_ptr<ObjectImage> InputImage;
>   
>     if (InputObject->isELF()) {
>       InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(InputObject));
>       if (!Dyld)
> -      Dyld = new RuntimeDyldELF(MM);
> +      Dyld = createRuntimeDyldELF(MM, ProcessAllSections).release();
>     } else if (InputObject->isMachO()) {
>       InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(InputObject));
>       if (!Dyld)
> -      Dyld = new RuntimeDyldMachO(MM);
> +      Dyld = createRuntimeDyldMachO(MM, ProcessAllSections).release();
>     } else
>       report_fatal_error("Incompatible object format!");
>   
> @@ -704,7 +718,7 @@ ObjectImage *RuntimeDyld::loadObject(Obj
>     case sys::fs::file_magic::elf_core:
>       InputImage.reset(RuntimeDyldELF::createObjectImage(InputBuffer));
>       if (!Dyld)
> -      Dyld = new RuntimeDyldELF(MM);
> +      Dyld = createRuntimeDyldELF(MM, ProcessAllSections).release();
>       break;
>     case sys::fs::file_magic::macho_object:
>     case sys::fs::file_magic::macho_executable:
> @@ -718,7 +732,7 @@ ObjectImage *RuntimeDyld::loadObject(Obj
>     case sys::fs::file_magic::macho_dsym_companion:
>       InputImage.reset(RuntimeDyldMachO::createObjectImage(InputBuffer));
>       if (!Dyld)
> -      Dyld = new RuntimeDyldMachO(MM);
> +      Dyld = createRuntimeDyldMachO(MM, ProcessAllSections).release();
>       break;
>     case sys::fs::file_magic::unknown:
>     case sys::fs::file_magic::bitcode:
>
> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h?rev=204398&r1=204397&r2=204398&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h (original)
> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h Thu Mar 20 16:06:46 2014
> @@ -187,6 +187,10 @@ protected:
>     Triple::ArchType Arch;
>     bool IsTargetLittleEndian;
>   
> +  // True if all sections should be passed to the memory manager, false if only
> +  // sections containing relocations should be. Defaults to 'false'.
> +  bool ProcessAllSections;
> +
>     // This mutex prevents simultaneously loading objects from two different
>     // threads.  This keeps us from having to protect individual data structures
>     // and guarantees that section allocation requests to the memory manager
> @@ -320,10 +324,15 @@ protected:
>     unsigned computeSectionStubBufSize(ObjectImage &Obj, const SectionRef &Section);
>   
>   public:
> -  RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
> +  RuntimeDyldImpl(RTDyldMemoryManager *mm)
> +    : MemMgr(mm), ProcessAllSections(false), HasError(false) {}
>   
>     virtual ~RuntimeDyldImpl();
>   
> +  void setProcessAllSections(bool ProcessAllSections) {
> +    this->ProcessAllSections = ProcessAllSections;
> +  }
> +
>     ObjectImage* loadObject(ObjectImage* InputObject);
>   
>     void *getSymbolAddress(StringRef Name) {
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list