+//
+// An AbsoluteAtom represents an N_ABS symbol which can only be created in
+// assembly language and usable by static executables such as the kernel/
+//
+template <typename A>
+class AbsoluteAtom : public BaseAtom
+{
+public:
+ virtual ObjectFile::Reader* getFile() const { return &fOwner; }
+ virtual bool getTranslationUnitSource(const char** dir, const char** name) const
+ { return fOwner.getTranslationUnitSource(dir, name); }
+ virtual const char* getName() const { return &fOwner.fStrings[fSymbol->n_strx()]; }
+ virtual const char* getDisplayName() const { return getName(); }
+ virtual ObjectFile::Atom::Scope getScope() const { return fScope; }
+ virtual ObjectFile::Atom::DefinitionKind getDefinitionKind() const { return ObjectFile::Atom::kAbsoluteSymbol; }
+ virtual bool isZeroFill() const { return false; }
+ virtual SymbolTableInclusion getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableInAsAbsolute; }
+ virtual bool dontDeadStrip() const { return false; }
+ virtual uint64_t getSize() const { return 0; }
+ virtual std::vector<ObjectFile::Reference*>& getReferences() const { return fgNoReferences; }
+ virtual bool mustRemainInSection() const { return true; }
+ virtual const char* getSectionName() const { return "._absolute"; }
+ virtual ObjectFile::Segment& getSegment() const { return LinkEditSegment::fgSingleton; }
+ virtual ObjectFile::Atom& getFollowOnAtom() const { return *(ObjectFile::Atom*)NULL; }
+ virtual std::vector<ObjectFile::LineInfo>* getLineInfo() const { return NULL; }
+ virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(0); }
+ virtual void copyRawContent(uint8_t buffer[]) const { }
+ virtual void setScope(ObjectFile::Atom::Scope newScope) { fScope = newScope; }
+ virtual void setSize(uint64_t size) { }
+ virtual void addReference(ObjectFile::Reference* ref) { throw "ld: can't add references"; }
+ virtual void sortReferences() { }
+ virtual void addLineInfo(const ObjectFile::LineInfo& info) { throw "ld: can't add line info to tentative definition"; }
+ virtual uint64_t getObjectAddress() const { return fSymbol->n_value(); }
+ virtual void setSectionOffset(uint64_t offset) { /* don't let fSectionOffset be altered*/ }
+ virtual const void* getSectionRecord() const { return NULL; }
+
+protected:
+ typedef typename A::P P;
+ typedef typename A::P::E E;
+ typedef typename A::P::uint_t pint_t;
+ typedef typename A::ReferenceKinds Kinds;
+ friend class Reader<A>;
+
+ AbsoluteAtom(Reader<A>&, const macho_nlist<P>*);
+ virtual ~AbsoluteAtom() {}
+
+ Reader<A>& fOwner;
+ const macho_nlist<P>* fSymbol;
+ ObjectFile::Atom::Scope fScope;
+ static std::vector<ObjectFile::Reference*> fgNoReferences;
+};
+
+template <typename A>
+std::vector<ObjectFile::Reference*> AbsoluteAtom<A>::fgNoReferences;
+
+template <typename A>
+AbsoluteAtom<A>::AbsoluteAtom(Reader<A>& owner, const macho_nlist<P>* symbol)
+ : fOwner(owner), fSymbol(symbol)
+{
+ // store absolute adress in fSectionOffset
+ fSectionOffset = symbol->n_value();
+ // compute scope
+ uint8_t type = symbol->n_type();
+ if ( (type & N_EXT) == 0 )
+ fScope = ObjectFile::Atom::scopeTranslationUnit;
+ else if ( (type & N_PEXT) != 0 )
+ fScope = ObjectFile::Atom::scopeLinkageUnit;
+ else
+ fScope = ObjectFile::Atom::scopeGlobal;
+ //fprintf(stderr, "AbsoluteAtom(%p) %s\n", this, this->getDisplayName());
+}
+