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

Kaylor, Andrew andrew.kaylor at intel.com
Thu Mar 20 17:13:36 PDT 2014


One reason the non-executable sections weren't being loaded is that when dynamic code is registered with GDB for debugging GDB expects the debug sections not to have been loaded.

As I recall, there is some flag you can set in the ELF header to tell GDB that the debug sections have been loaded, but I don't believe I was ever able to get everything working that way.

-Andy

-----Original Message-----
From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Philip Reames
Sent: Thursday, March 20, 2014 4:58 PM
To: Lang Hames; llvm-commits at cs.uiuc.edu
Subject: Re: [llvm] r204398 - Add an option to MCJIT to have it forward all sections to the

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/ExecutionE
> ngine/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/ExecutionE
> ngine/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/MCJ
> IT/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/Run
> timeDyld/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/Run
> timeDyld/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

_______________________________________________
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