]> git.saurik.com Git - apple/ld64.git/blobdiff - src/LLVMReader.hpp
ld64-84.1.2.tar.gz
[apple/ld64.git] / src / LLVMReader.hpp
diff --git a/src/LLVMReader.hpp b/src/LLVMReader.hpp
deleted file mode 100644 (file)
index e49c5ae..0000000
+++ /dev/null
@@ -1,561 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
- *
- * Copyright (c) 2006-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __LLVM_READER_H__
-#define __LLVM_READER_H__
-
-#include <stdlib.h>
-#include <vector>
-#include "MachOFileAbstraction.hpp"
-#include "Architectures.hpp"
-#include "ObjectFile.h"
-#include "llvm/LinkTimeOptimizer.h"
-
-#define LLVMLinkTimeOptimizer "LLVMlto.dylib"
-
-class LLVMReader;
-
-//
-// LLVMReference handles LLVMAtom references. These references facilitate 
-// symbol resolution.
-//
-
-class LLVMReference : public ObjectFile::Reference
-{
-public:
-                                                                               LLVMReference (const char *n) : fName(n), fAtom(0), fFromAtom(0) { }
-
-       bool                                                            isTargetUnbound() const                         { return fAtom == 0; }
-       bool                                                            isFromTargetUnbound() const             { return true; }
-       uint8_t                                                         getKind() const                                         { return 0; }
-       uint64_t                                                        getFixUpOffset() const                          { return 0; }
-       const char *                                            getTargetName() const                           { return fName; }
-       ObjectFile::Atom&                                       getTarget() const                                       { return *fAtom; }
-       uint64_t                                                        getTargetOffset() const                         { return 0; }
-       bool                                                            hasFromTarget() const                           { return false; }
-       ObjectFile::Atom&                                       getFromTarget() const                           { return *fFromAtom; }
-       const char *                                            getFromTargetName() const                       { return NULL; }
-       uint64_t                                                        getFromTargetOffset() const             { return 0; }
-       TargetBinding                                           getTargetBinding() const;
-       TargetBinding                                           getFromTargetBinding() const  { return kDontBind; }
-       void                                                            setTarget (ObjectFile::Atom &a, uint64_t offset) 
-                                                                               { fAtom = &a; }
-       void                                                            setFromTarget(ObjectFile::Atom &a)      { }
-       const char *                                            getDescription() const                          { return NULL; }
-
-private:
-       const char *                                            fName;
-       ObjectFile::Atom *                                      fAtom;
-       ObjectFile::Atom *                                      fFromAtom;
-};
-
-ObjectFile::Reference::TargetBinding LLVMReference::getTargetBinding() const 
-{ 
-       if (strncmp (fName, "__ld64.llvm", 11) == 0)
-               return kDontBind;
-       else return kUnboundByName;
-}
-
-//
-// LLVMAtom acts as a proxy Atom for the symbols that are exported by LLVM bytecode file. Initially,
-// LLVMReader creates LLVMAtoms to allow linker proceed with usual symbol resolution phase. After
-// optimization is performed, real Atoms are created for these symobls. However these real Atoms
-// are not inserted into global symbol table. LLVMAtom holds real Atom and forwards appropriate
-// methods to real atom.
-//
-
-class LLVMAtom : public ObjectFile::Atom
-{
-public:
-       ObjectFile::Reader *                                            getFile() const                         { return fOwner; }
-       bool                                                                            getTranslationUnitSource (const char **dir, const char **name) const 
-                                                                                                                                                       { return fRealAtom->getTranslationUnitSource (dir, name); }
-       const char *                                                            getName () const                        { return fAtomName;     }
-       const char *                                                            getDisplayName() const          { return this->getName(); }
-       Scope                                                                           getScope() const                        { return fScope; }
-       DefinitionKind                                                          getDefinitionKind() const;
-       SymbolTableInclusion                                            getSymbolTableInclusion() const 
-                                                                                                                                                       { return fRealAtom->getSymbolTableInclusion(); }
-       bool                                                                            dontDeadStrip() const           { return false; }
-       bool                                                                            isZeroFill() const                      { return fRealAtom->isZeroFill(); }
-       uint64_t                                                                        getSize() const                         { return fRealAtom->getSize(); }
-       std::vector<ObjectFile::Reference*>&            getReferences() const 
-                                                                                                                                                       { return (fRealAtom ? fRealAtom->getReferences() : (std::vector<ObjectFile::Reference*>&)fReferences); }
-       bool                                                                            mustRemainInSection() const { return fRealAtom->mustRemainInSection(); }
-       const char *                                                            getSectionName() const          { return (fRealAtom ? fRealAtom->getSectionName() : NULL); }
-       // Linker::optimize() sets section for this atom, not fRealAtom. Use this Atom's fSection.
-       class ObjectFile::Section *                                     getSection() const                      { return fSection; }
-       ObjectFile::Segment&                                            getSegment() const                      { return fRealAtom->getSegment(); }
-       uint32_t                                                                        getOrdinal() const { return (fRealAtom ? fRealAtom->getOrdinal() : 0); }
-       ObjectFile::Atom&                                                       getFollowOnAtom() const         { return fRealAtom->getFollowOnAtom(); }
-       std::vector<ObjectFile::LineInfo>*                      getLineInfo() const             { return fRealAtom->getLineInfo(); }
-       ObjectFile::Alignment                                           getAlignment() const;
-       void                                                                            copyRawContent(uint8_t buffer[]) const 
-                                                                                                                                                       { fRealAtom->copyRawContent(buffer); }
-       void                                                                            setScope(Scope s)                       { if (fRealAtom) fRealAtom->setScope(s); }
-
-       LLVMAtom(ObjectFile::Reader *owner, const char *n, llvm::LLVMSymbol *ls);
-       
-       void                                                                            setRealAtom (ObjectFile::Atom *atom) 
-                                                                                                                                                       { fRealAtom = atom; }
-       void                                                                            addReference(ObjectFile::Reference *ref) 
-                                                                                                                                                       { fReferences.push_back(ref); }
-
-       void                                                                            setSectionOffset(uint64_t offset) { fSectionOffset = offset; if (fRealAtom) fRealAtom->setSectionOffset(offset); }
-       void                                                                            setSection(class ObjectFile::Section* sect) { fSection = sect; if (fRealAtom) fRealAtom->setSection(sect); }
-                                                                                                                                                       
-private:
-       ObjectFile::Reader *                                            fOwner;
-       const char *                                                            fAtomName;
-       llvm::LLVMSymbol *                                                      fLLVMSymbol;
-       ObjectFile::Atom *                                                      fRealAtom;
-       std::vector<ObjectFile::Reference*>             fReferences;
-       ObjectFile::Atom::Scope                                         fScope;
-       ObjectFile::Atom::DefinitionKind                        fDefKind;
-};
-
-ObjectFile::Atom::DefinitionKind LLVMAtom::getDefinitionKind() const 
-{ 
-       if (fRealAtom) 
-               return fRealAtom->getDefinitionKind();
-       else
-               return fDefKind;
-}
-
-LLVMAtom::LLVMAtom(ObjectFile::Reader *owner, const char *n, llvm::LLVMSymbol *ls) : fOwner(owner), fAtomName(n), fLLVMSymbol(ls), fRealAtom(0) 
-{
-
-       if (!ls) return;
-
-       switch (ls->getLinkage()) {
-       case llvm::LTOExternalLinkage:
-               fScope = scopeGlobal;
-               fDefKind = kRegularDefinition;
-               break;
-       case llvm::LTOLinkOnceLinkage:
-       case llvm::LTOWeakLinkage:
-               // ??? How to differentiate between this two linkage types ?
-               fScope = scopeGlobal;
-               fDefKind = kWeakDefinition;
-               break;
-       default:
-               throw "Unexpected LLVM Symbol Linkage info\n";
-               break;
-       }
-}
-
-ObjectFile::Alignment LLVMAtom::getAlignment() const
-{
-       if (fRealAtom)
-               return fRealAtom->getAlignment(); 
-       else {
-               ObjectFile::Alignment alignment(fLLVMSymbol->getAlignment());
-               return alignment;
-       }
-}
-
-//
-// LLVMReader does not expose internal symbols defined and used inside bytecode file. However, 
-// these symbols may refere other external symbols. IntercessorAtom facilitate by acting as a 
-// orignator of such references during pre-optimization symbol resoultion phase. These atoms
-// are immediately removed after optimization.
-//
-
-class IntercessorAtom : public ObjectFile::Atom
-{
-public:
-       ObjectFile::Reader *                                            getFile() const                         { return fOwner; }
-       bool                                                                            getTranslationUnitSource (const char **dir, const char **name) const 
-                                                                                                                                                       { return false; }
-       const char *                                                            getName () const                        { return fAtomName;     }
-       const char *                                                            getDisplayName() const          { return this->getName(); }
-       Scope                                                                           getScope() const                        { return scopeGlobal; }
-       DefinitionKind                                                          getDefinitionKind() const   { return kRegularDefinition; }
-       SymbolTableInclusion                                            getSymbolTableInclusion() const 
-       { return kSymbolTableNotIn; }
-       bool                                                                            dontDeadStrip() const           { return false; }
-       bool                                                                            isZeroFill() const                      { return false; }
-       uint64_t                                                                        getSize() const                         { return 0; }
-       std::vector<ObjectFile::Reference*>&            getReferences() const           { return  (std::vector<ObjectFile::Reference*>&)fReferences; }
-       bool                                                                            mustRemainInSection() const { return false; }
-       const char *                                                            getSectionName() const          { return NULL; }
-       class ObjectFile::Section *                                     getSection() const                      { return NULL; }
-       ObjectFile::Segment&                                            getSegment() const                      { return this->getSegment(); }
-       uint32_t                                                                        getOrdinal() const          { return 0; }
-       ObjectFile::Atom&                                                       getFollowOnAtom() const         { return this->getFollowOnAtom(); }
-       std::vector<ObjectFile::LineInfo>*                      getLineInfo() const             { return NULL; }
-       ObjectFile::Alignment                                           getAlignment() const            { ObjectFile::Alignment a(0); return a; }
-       void                                                                            copyRawContent(uint8_t buffer[]) const 
-                                                                                                                                                       { }
-       void                                                                            setScope(Scope s)                       { }
-
-
-       IntercessorAtom(ObjectFile::Reader *owner, std::set<std::string> &references);
-       
-       void                                                                            addReference(ObjectFile::Reference *ref) 
-                                                                                                                                                       { fReferences.push_back(ref); }
-       void                                                                            addReferences(std::set<std::string> &references);
-private:
-       ObjectFile::Reader *                                            fOwner;
-       char *                                                          fAtomName;
-       std::vector<ObjectFile::Reference*>             fReferences;
-       ObjectFile::Atom::Scope                                         fScope;
-       ObjectFile::Atom::DefinitionKind                        fDefKind;
-};
-
-IntercessorAtom::IntercessorAtom(ObjectFile::Reader *owner, std::set<std::string> &references)
-{
-       static int sCount = 0;
-       fOwner = owner;
-       fAtomName = (char *) malloc (sizeof(char)*20);
-       sprintf (fAtomName,"__ld64.llvm%d__",sCount++);
-
-       for (std::set<std::string>::iterator it = references.begin(); it != references.end(); it++) {
-       std::string r = *it;
-       this->addReference(new LLVMReference(r.c_str()));
-       }
-}
-
-void IntercessorAtom::addReferences(std::set<std::string> &references)
-{
-       for (std::set<std::string>::iterator it = references.begin(); it != references.end(); it++) {
-       std::string r = *it;
-       this->addReference(new LLVMReference(r.c_str()));
-       }
-}
-
-class InIntercessorSet
-{
-public:
-       InIntercessorSet(std::set<ObjectFile::Atom*>& iAtoms) : fIntercessorAtoms(iAtoms) {}
-
-       bool operator()(ObjectFile::Atom*& atom) const {
-               return ( fIntercessorAtoms.count(atom) != 0 );
-       }
-
-private:
-       std::set<ObjectFile::Atom*>& fIntercessorAtoms;
-};
-
-//
-// LLVMOptimizer class is responsible for communicating with LLVM LTO library.
-// One LLVMOptimizer object is created per Linker invocation. All LLVMReaders share this
-// one single optimizer object.
-//
-
-class LLVMOptimizer
-{
-public:
-                                                                                               LLVMOptimizer(Options &opt);
-                                                                                               ~LLVMOptimizer()                                { if (fLLVMHandle) dlclose(fLLVMHandle);        }
-
-
-       void                                                                            optimize(std::vector<ObjectFile::Atom *>&, std::vector<ObjectFile::Atom*>&, uint32_t);
-       void                                                                            read(ObjectFile::Reader *, const char *, std::set<std::string>&, std::vector<ObjectFile::Atom*>&, const char *);
-       void                                                                            reconcileOptimizedAtoms(std::vector<class ObjectFile::Atom*>&, std::vector<class ObjectFile::Atom*>&);
-       void                                                                            addIntercessor(IntercessorAtom * atom) { fIntercessorAtoms.insert(atom); }
-       void                                                                            addReader(ObjectFile::Reader *reader) { fLLVMReaders[reader->getPath()] = reader; }
-       cpu_type_t                                                                      getCpuType(std::string &targetTriple);
-       bool                                                                            validArchitecture(const char *path, cpu_type_t architecture);
-       class LCStringEquals
-       {
-       public:
-               bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
-       };
-       typedef hash_map<const char*, LLVMAtom*, hash<const char*>, LCStringEquals> LLVMAtomToNameMapper;
-       typedef hash_map<const char*, ObjectFile::Reader*, hash<const char*>, LCStringEquals> ReaderToPathMapper;
-       
-    typedef llvm::LinkTimeOptimizer * (*createLLVMOptimizer_func_t) ();
-private:
-       bool                                                                            fOptimized;
-       llvm::LinkTimeOptimizer                                         *fOptimizer;
-       void                                                                            *fLLVMHandle;
-       LLVMAtomToNameMapper                                            fLLVMSymbols;
-       Options&                                                                        fOptions;
-       std::set<ObjectFile::Atom*>                                     fIntercessorAtoms;
-       ReaderToPathMapper                                                      fLLVMReaders;
-};
-
-LLVMOptimizer::LLVMOptimizer(Options &opts) : fOptions(opts)
-{
-       fLLVMHandle = (llvm::LinkTimeOptimizer *) dlopen (LLVMLinkTimeOptimizer, RTLD_LAZY);
-       if (!fLLVMHandle)
-               throwf("Unable to load LLVM library: \n", dlerror());
-
-       createLLVMOptimizer_func_t createLLVMOptimizer_fp = (createLLVMOptimizer_func_t)dlsym(fLLVMHandle, "createLLVMOptimizer");
-       if (createLLVMOptimizer_fp == NULL)
-               throwf("couldn't find \"createLLVMOptimizer\" ", dlerror());
-       fOptimizer = createLLVMOptimizer_fp();
-       fOptimized = false;
-}
-
-cpu_type_t LLVMOptimizer::getCpuType(std::string &targetTriple)
-{
-       if ( strncmp (targetTriple.c_str(), "powerpc-", 8) == 0)
-               return CPU_TYPE_POWERPC;
-       else if ( strncmp (targetTriple.c_str(), "powerpc64-", 10))
-               return CPU_TYPE_POWERPC64;
-       // match "i[3-9]86-*".
-       else if ( targetTriple.size() >= 5 && targetTriple[0] == 'i' && targetTriple[2] == '8' && targetTriple[3] == '6' && targetTriple[4] == '-' && targetTriple[1] - '3' < 6  )
-               return CPU_TYPE_I386;
-       else
-               return CPU_TYPE_ANY;
-}
-
-bool LLVMOptimizer::validArchitecture(const char *path, cpu_type_t architecture)
-{
-       std::string targetTriple;
-       fOptimizer->getTargetTriple(path, targetTriple);
-       if (architecture != getCpuType(targetTriple)) {
-               fOptimizer->removeModule(path);
-               return false;
-       }
-
-       return true;
-}
-
-void LLVMOptimizer::optimize(std::vector<ObjectFile::Atom*> &allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, uint32_t nextInputOrdinal)
-{
-       if (fOptimized)
-               return;
-
-       char * tmp = "/tmp/ld64XXXXXXXX";
-       char * bigOfile = (char *) malloc (strlen (tmp) + 3);
-       if (!bigOfile)
-               throw "Unable to create temp file name";
-       strcpy (bigOfile, tmp);
-       mktemp (bigOfile);
-       strcat (bigOfile, ".o");
-
-       std::vector <const char *> exportList;
-       for (std::vector<ObjectFile::Atom*>::iterator it = allAtoms.begin(); it != allAtoms.end(); ++it) {
-               ObjectFile::Atom *atom = *it;
-               if (atom->getName()) {
-                       ReaderToPathMapper::iterator pos = fLLVMReaders.find(atom->getFile()->getPath());
-                       if (pos != fLLVMReaders.end())
-                               exportList.push_back(atom->getName());
-               }
-                       
-       }
-
-       std::string targetTriple;
-       llvm::LTOStatus status = fOptimizer->optimizeModules(bigOfile, exportList, targetTriple, fOptions.saveTempFiles(), fOptions.getOutputFilePath());
-       if (status != llvm::LTO_OPT_SUCCESS) {
-               if (status == llvm::LTO_WRITE_FAILURE)
-                       throw "Unable to write optimized output file";
-               if (status == llvm::LTO_ASM_FAILURE)
-                       throw "Unable to assemble optimized output file";
-               if (status == llvm::LTO_MODULE_MERGE_FAILURE)
-                       throw "Unable to merge bytecode files";
-               if (status == llvm::LTO_NO_TARGET)
-                       throw "Unable to load target optimizer";
-       }
-       fOptimized = true;
-
-       Options::FileInfo info = fOptions.findFile (bigOfile);
-       ObjectFile::Reader* nr = NULL;
-       int fd = ::open(info.path, O_RDONLY, 0);
-       if ( fd == -1 )
-               throwf("can't open file, errno=%d", errno);
-       if ( info.fileLen < 20 )
-               throw "file too small";
-
-       uint8_t* p = (uint8_t*)::mmap(NULL, info.fileLen, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
-       if ( p == (uint8_t*)(-1) )
-               throwf("can't map file, errno=%d", errno);
-       
-       cpu_type_t cpt = getCpuType(targetTriple);
-       switch (cpt) {
-       case CPU_TYPE_POWERPC:
-               if ( mach_o::relocatable::Reader<ppc>::validFile(p) )
-                       nr = new mach_o::relocatable::Reader<ppc>(p, info.path, info.modTime, fOptions.readerOptions(), nextInputOrdinal);
-               break;
-       case CPU_TYPE_POWERPC64:
-               if ( mach_o::relocatable::Reader<ppc64>::validFile(p) )
-                       nr = new mach_o::relocatable::Reader<ppc64>(p, info.path, info.modTime, fOptions.readerOptions(), nextInputOrdinal);
-               break;
-       case CPU_TYPE_I386:
-               if ( mach_o::relocatable::Reader<x86>::validFile(p) )
-                       nr = new mach_o::relocatable::Reader<x86>(p, info.path, info.modTime, fOptions.readerOptions(), nextInputOrdinal);
-               break;
-       default:
-               throw "file is not of required architecture";
-               break;
-       }
-
-       std::vector<class ObjectFile::Atom*> optimizedAtoms;
-       optimizedAtoms = nr->getAtoms();
-       reconcileOptimizedAtoms(optimizedAtoms, newAtoms);
-
-       allAtoms.erase(std::remove_if(allAtoms.begin(), allAtoms.end(), InIntercessorSet(fIntercessorAtoms)), allAtoms.end());
-       unlink(bigOfile);
-       free(bigOfile); 
-}
-
-void LLVMOptimizer::read(ObjectFile::Reader *reader, const char *path, std::set<std::string> &references, std::vector<ObjectFile::Atom*> &atoms, const char *intercessorName)
-{
-       llvm::LinkTimeOptimizer::NameToSymbolMap symbols;
-       llvm::LTOStatus status = fOptimizer->readLLVMObjectFile (path, symbols, references);
-       if (status != llvm::LTO_READ_SUCCESS)
-               throw "Unable to read LLVM bytecode file";
-
-       for (llvm::LinkTimeOptimizer::NameToSymbolMap::iterator itr = symbols.begin();
-                itr != symbols.end(); itr++) {
-               const char *name = itr->first;
-               llvm::LLVMSymbol *ls = itr->second;
-               LLVMAtom *a = new LLVMAtom(reader, name, ls);
-
-               LLVMAtomToNameMapper::iterator pos = fLLVMSymbols.find(name);
-               bool insertNewAtom = true;
-               if (pos != fLLVMSymbols.end()) {
-                       LLVMAtom *existingAtom = pos->second;
-                       ObjectFile::Atom::DefinitionKind newDefKind = a->getDefinitionKind();
-                       ObjectFile::Atom::DefinitionKind existingDefKind = existingAtom->getDefinitionKind();
-                       if (newDefKind == ObjectFile::Atom::kRegularDefinition 
-                               && existingDefKind == ObjectFile::Atom::kRegularDefinition)
-                               throwf ("duplicate symbol %s in %s and %s\n", name, a->getFile()->getPath(), existingAtom->getFile()->getPath());
-                       else if (newDefKind == ObjectFile::Atom::kWeakDefinition 
-                                        && existingDefKind == ObjectFile::Atom::kRegularDefinition)
-                               insertNewAtom = false;
-                       else if (newDefKind == ObjectFile::Atom::kWeakDefinition 
-                                        && existingDefKind == ObjectFile::Atom::kWeakDefinition)
-                               // pick one
-                               insertNewAtom = false;
-                       else if (newDefKind == ObjectFile::Atom::kRegularDefinition 
-                                        && existingDefKind == ObjectFile::Atom::kWeakDefinition)
-                               insertNewAtom = true;
-               }
-               if (insertNewAtom) {
-                       atoms.push_back(a);
-                       fLLVMSymbols[name] = a;
-                       a->addReference(new LLVMReference (intercessorName));
-               }
-       }
-}
-
-void LLVMOptimizer::reconcileOptimizedAtoms(std::vector<class ObjectFile::Atom*>& optimizedAtoms,
-                                                                                       std::vector<class ObjectFile::Atom*>& newAtoms)
-{
-       for (std::vector<ObjectFile::Atom *>::iterator itr = optimizedAtoms.begin(); 
-                itr != optimizedAtoms.end(); ++itr) {
-
-               ObjectFile::Atom* atom = *itr;
-               if (!atom->getName()) {
-                       newAtoms.push_back(atom);
-                       continue;
-               }
-
-               LLVMAtomToNameMapper::iterator pos = fLLVMSymbols.find(atom->getName());
-               if ( pos != fLLVMSymbols.end() ) {
-
-                       LLVMAtom *la = fLLVMSymbols[atom->getName()];
-                       la->setRealAtom(atom);
-
-               } 
-               else
-                       newAtoms.push_back(atom);
-       }
-}
-
-//
-// LLVM bytecode file reader
-//
-
-class LLVMReader : public ObjectFile::Reader
-{
-public:
-       static bool                                                                             validFile(const uint8_t* fileContent, const char *path, cpu_type_t architecture, Options &opts);
-       static LLVMReader*                                                              make(const uint8_t* fileContent, const char* path, time_t modTime, Options& options) 
-                                                                                                                                                       { return new LLVMReader(fileContent, path, modTime, options); }
-       virtual                                                                                 ~LLVMReader();
-       virtual std::vector<class ObjectFile::Atom*>&   getAtoms()                              { return (std::vector<class ObjectFile::Atom*>&)(fAtoms); }
-       virtual std::vector<class ObjectFile::Atom*>*   getJustInTimeAtomsFor(const char* name) { return NULL; }
-       virtual const char*                                                             getPath()                               { return fPath; }
-       virtual time_t                                                                  getModificationTime()   { return fModTime; }
-       virtual ObjectFile::Reader::DebugInfoKind               getDebugInfoKind()              { return kDebugInfoNone; }
-       virtual std::vector<Stab>*                                              getStabs()                              { return NULL; }
-
-       ObjectFile::Atom *                                                              retriveIntercessorAtom()        { fAtoms.pop_back();return fIntercessorAtom; }
-       ObjectFile::Atom *                                                              getIntercessorAtom()    { return fIntercessorAtom; }
-
-private:
-
-                                                                                                       LLVMReader(const uint8_t* fileContent, const char* path, time_t modTime, Options& options);
-       void                                                                                    optimize(std::vector<ObjectFile::Atom*>& allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, uint32_t);
-       
-       const char*                                                                             fPath;
-       time_t                                                                                  fModTime;
-       std::vector<ObjectFile::Atom*>                                  fAtoms;
-       IntercessorAtom *                                                               fIntercessorAtom;
-       static LLVMOptimizer                                                    *fOptimizer;
-       std::set<std::string>                                                   fLLVMReferences;
-};
-
-LLVMOptimizer  *LLVMReader::fOptimizer = NULL;
-
-LLVMReader::~LLVMReader()
-{
-       if (fOptimizer)
-               delete fOptimizer;
-}
-
-LLVMReader::LLVMReader (const uint8_t* fileContent, const char *path, time_t modTime, Options& options)
-{
-
-       fPath = path;
-       fModTime = modTime;
-       fIntercessorAtom = new IntercessorAtom(this, fLLVMReferences);
-       fOptimizer->read(this, path, fLLVMReferences, fAtoms, fIntercessorAtom->getName());
-       fIntercessorAtom->addReferences(fLLVMReferences);
-       fAtoms.push_back(fIntercessorAtom);
-       fOptimizer->addIntercessor(fIntercessorAtom);
-       fOptimizer->addReader(this);
-}
-
-bool LLVMReader::validFile(const uint8_t* fileContent, const char *path, cpu_type_t architecture, Options &opts)
-{
-       if (fileContent[0] == 'l'
-               && fileContent[1] == 'l'
-               && fileContent[2] == 'v'
-               && (fileContent[3] == 'c' || fileContent[3] == 'm')) {
-
-               // create optimizer
-               if (!fOptimizer)
-                       fOptimizer = new LLVMOptimizer(opts);
-
-               if (fOptimizer->validArchitecture(path, architecture))
-                       return true;
-       }
-               
-       return false;
-}
-
-void LLVMReader::optimize(std::vector<ObjectFile::Atom *> &allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, uint32_t nextInputOrdinal)
-{ 
-       if (fOptimizer)  
-               fOptimizer->optimize(allAtoms, newAtoms, nextInputOrdinal);
-}
-
-#endif
-