+//
+// An SectionBoundaryAtom represent the start or end of a section
+//
+template <typename A>
+class SectionBoundaryAtom : 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 fSymbolName; }
+ virtual const char* getDisplayName() const { return fDisplayName; }
+ virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
+ virtual ObjectFile::Atom::DefinitionKind getDefinitionKind() const { return ObjectFile::Atom::kWeakDefinition; }
+ virtual ObjectFile::Atom::ContentType getContentType() const { return fStart ? ObjectFile::Atom::kSectionStart : ObjectFile::Atom::kSectionEnd; }
+ virtual bool isZeroFill() const { return false; }
+ virtual bool isThumb() const { return false; }
+ virtual SymbolTableInclusion getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableNotIn; }
+ 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 fSectionName; }
+ virtual ObjectFile::Segment& getSegment() const { return *fSegment; }
+ 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) { }
+ 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 const ObjectFile::ReaderOptions& getOptions() const { return fOwner.fOptions; }
+ virtual uint64_t getObjectAddress() const { return 0; }
+ virtual const void* getSectionRecord() const { return NULL; }
+ virtual unsigned int getSectionIndex() const { return 0; }
+
+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>;
+
+
+ class Segment : public ObjectFile::Segment
+ {
+ public:
+ Segment(const char* name, bool r, bool w, bool x):
+ fName(name), fReadable(r), fWritable(w), fExecutable(x) {}
+
+ virtual const char* getName() const { return fName; }
+ virtual bool isContentReadable() const { return fReadable; }
+ virtual bool isContentWritable() const { return fWritable; }
+ virtual bool isContentExecutable() const { return fExecutable; }
+ private:
+ const char* fName;
+ bool fReadable;
+ bool fWritable;
+ bool fExecutable;
+ };
+
+ SectionBoundaryAtom(Reader<A>&, bool start, const char* symbolName, const char* segSectName);
+ virtual ~SectionBoundaryAtom() {}
+
+ Reader<A>& fOwner;
+ class Segment* fSegment;
+ const char* fSymbolName;
+ const char* fSectionName;
+ const char* fDisplayName;
+ bool fStart;
+ static std::vector<ObjectFile::Reference*> fgNoReferences;
+};
+
+template <typename A>
+std::vector<ObjectFile::Reference*> SectionBoundaryAtom<A>::fgNoReferences;
+
+// examples:
+// section$start$__DATA$__my
+// section$end$__DATA$__my
+template <typename A>
+SectionBoundaryAtom<A>::SectionBoundaryAtom(Reader<A>& owner, bool start, const char* symbolName, const char* segSectName)
+ : fOwner(owner), fSymbolName(symbolName), fSectionName(NULL), fStart(start)
+{
+ const char* segSectDividor = strrchr(segSectName, '$');
+ if ( segSectDividor == NULL )
+ throwf("malformed section reference name: %s", symbolName);
+ fSectionName = segSectDividor + 1;
+ int segNameLen = segSectDividor - segSectName;
+ if ( segNameLen > 16 )
+ throwf("malformed section reference name: %s", symbolName);
+ char segName[18];
+ strlcpy(segName, segSectName, segNameLen+1);
+ if ( strcmp(segName, "__TEXT") == 0 )
+ fSegment = new Segment("__TEXT", true, false, true);
+ else if ( strcmp(segName, "__DATA") == 0 )
+ fSegment = new Segment("__DATA", true, true, false);
+ else
+ fSegment = new Segment(strdup(segName), true, true, false);
+
+ asprintf((char**)&fDisplayName, "%s of section '%s' in segment '%s'", (start ? "start" : "end"), fSectionName, segName);
+}
+