OpaqueSection.hpp   [plain text]


/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
 *
 * Copyright (c) 2005-2006 Apple Computer, 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 __OPAQUE_SECTION__
#define __OPAQUE_SECTION__


#include <vector>

#include "ObjectFile.h"

namespace opaque_section {


class Segment : public ObjectFile::Segment
{
public:
								Segment(const char* name)		{ fName = name; }
	virtual const char*			getName() const					{ return fName; }
	virtual bool				isContentReadable() const		{ return true; }
	virtual bool				isContentWritable() const		{ return false; }
	virtual bool				isContentExecutable() const		{ return (strcmp(fName, "__TEXT") == 0); }
private:
	const char*					fName;
};


class Reader : public ObjectFile::Reader 
{
public:
												Reader(const char* segmentName, const char* sectionName, const char* path, 
													const uint8_t fileContent[], uint64_t fileLength, uint32_t ordinal, const char* symbolName=NULL);
	virtual										~Reader();
	
	void											addSectionReference(uint8_t kind, uint64_t offsetInSection, const ObjectFile::Atom* targetAtom, 
																		uint64_t offsetInTarget, const ObjectFile::Atom* fromTargetAtom=NULL, uint64_t offsetInFromTarget=0);
	
	virtual const char*								getPath()								{ return fPath; }
	virtual time_t									getModificationTime()					{ return 0; }
	virtual DebugInfoKind							getDebugInfoKind()						{ return ObjectFile::Reader::kDebugInfoNone; }
	virtual std::vector<class ObjectFile::Atom*>&	getAtoms()								{ return fAtoms; }
	virtual std::vector<class ObjectFile::Atom*>*	getJustInTimeAtomsFor(const char* name) { return NULL; }
	virtual std::vector<Stab>*						getStabs()								{ return NULL; }

private:
	const char*										fPath;
	std::vector<class ObjectFile::Atom*>			fAtoms;
};

class Reference : public ObjectFile::Reference
{
public:
							Reference(uint8_t kind, uint64_t fixupOffset, const ObjectFile::Atom* target, uint64_t targetOffset,
										const ObjectFile::Atom* fromTarget=NULL, uint64_t fromTargetOffset=0)
								: fFixUpOffset(fixupOffset), fTarget(target), fTargetOffset(targetOffset), fKind(kind), 
									fFromTarget(fromTarget), fFromTargetOffset(fromTargetOffset)  {}
	virtual					~Reference() {}


	virtual ObjectFile::Reference::TargetBinding	getTargetBinding() const	{ return ObjectFile::Reference::kBoundDirectly; }
	virtual ObjectFile::Reference::TargetBinding	getFromTargetBinding() const{ return ObjectFile::Reference::kDontBind; }
	virtual uint8_t									getKind() const				{ return fKind; }
	virtual uint64_t								getFixUpOffset() const		{ return fFixUpOffset; }
	virtual const char*								getTargetName() const		{ return fTarget->getName(); }
	virtual ObjectFile::Atom&						getTarget() const			{ return *((ObjectFile::Atom*)fTarget); }
	virtual uint64_t								getTargetOffset() const		{ return fTargetOffset; }
	virtual ObjectFile::Atom&						getFromTarget() const		{ return *((ObjectFile::Atom*)fFromTarget); }
	virtual const char*								getFromTargetName() const	{ return fFromTarget->getName();  }
	virtual uint64_t								getFromTargetOffset() const { return fFromTargetOffset; }
	virtual void									setTarget(ObjectFile::Atom&, uint64_t offset) { throw "can't set target"; }
	virtual void									setFromTarget(ObjectFile::Atom&) { throw "can't set from target"; }
	virtual const char*								getDescription() const		{ return "opaque section reference"; }

private:
	uint64_t				fFixUpOffset;
	const ObjectFile::Atom*	fTarget;
	uint64_t				fTargetOffset;
	uint8_t					fKind;
	const ObjectFile::Atom*	fFromTarget;
	uint64_t				fFromTargetOffset;
};


class Atom : public ObjectFile::Atom {
public:
	virtual ObjectFile::Reader*					getFile() const				{ return &fOwner; }
	virtual bool								getTranslationUnitSource(const char** dir, const char** name) const { return false; }
	virtual const char*							getName() const				{ return fName; }
	virtual const char*							getDisplayName() const;
	virtual Scope								getScope() const			{ return ObjectFile::Atom::scopeLinkageUnit; }
	virtual DefinitionKind						getDefinitionKind() const	{ return kRegularDefinition; }
	virtual SymbolTableInclusion				getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableNotIn; }
	virtual	bool								dontDeadStrip() const		{ return true; }
	virtual bool								isZeroFill() const			{ return false; }
	virtual uint64_t							getSize() const				{ return fFileLength; }
	virtual std::vector<ObjectFile::Reference*>&  getReferences() const		{ return (std::vector<ObjectFile::Reference*>&)(fReferences); }
	virtual bool								mustRemainInSection() const { return false; }
	virtual const char*							getSectionName() const		{ return fSectionName; }
	virtual Segment&							getSegment() const			{ return fSegment; }
	virtual ObjectFile::Atom&					getFollowOnAtom() const		{ return *((ObjectFile::Atom*)NULL); }
	virtual uint32_t							getOrdinal() const			{ return fOrdinal; }
	virtual std::vector<ObjectFile::LineInfo>*	getLineInfo() const			{ return NULL; }
	virtual ObjectFile::Alignment				getAlignment() const		{ return ObjectFile::Alignment(4); }
	virtual void								copyRawContent(uint8_t buffer[]) const;

	virtual void								setScope(Scope)				{ }

protected:
	friend class Reader;
	
											Atom(Reader& owner, Segment& segment, const char* sectionName, 
												const uint8_t fileContent[], uint64_t fileLength, uint32_t ordinal, const char* symbolName);
	virtual									~Atom() {}
	
	Reader&									fOwner;
	Segment&								fSegment;
	const char*								fName;
	const char*								fSectionName;
	const uint8_t*							fFileContent;
	uint32_t								fOrdinal;
	uint64_t								fFileLength;
	std::vector<ObjectFile::Reference*>		fReferences;
};


	
Atom::Atom(Reader& owner, Segment& segment, const char* sectionName, const uint8_t fileContent[], uint64_t fileLength, uint32_t ordinal, const char* symbolName) 
	: fOwner(owner), fSegment(segment), fSectionName(sectionName), fFileContent(fileContent), fOrdinal(ordinal), fFileLength(fileLength) 
{ 
	if ( symbolName != NULL )
		fName = strdup(symbolName);
	else
		asprintf((char**)&fName, "__section$%s%s", segment.getName(), sectionName);
}


Reader::Reader(const char* segmentName, const char* sectionName, const char* path, const uint8_t fileContent[], 
			uint64_t fileLength, uint32_t ordinal, const char* symbolName)
 : fPath(path)
{
	fAtoms.push_back(new Atom(*this, *(new Segment(segmentName)), strdup(sectionName), fileContent, fileLength, ordinal, symbolName));
}

Reader::~Reader()
{
}

void Reader::addSectionReference(uint8_t kind, uint64_t offsetInSection, const ObjectFile::Atom* targetAtom, 
								uint64_t offsetInTarget, const ObjectFile::Atom* fromTargetAtom, uint64_t offsetInFromTarget)
{
	fAtoms[0]->getReferences().push_back(new Reference(kind, offsetInSection, targetAtom, offsetInTarget, fromTargetAtom, offsetInFromTarget));
}


const char*	 Atom::getDisplayName() const
{
	static char name[64];
	sprintf(name, "opaque section %s %s", fSegment.getName(), fSectionName);
	return name;
}


void Atom::copyRawContent(uint8_t buffer[]) const
{
	memcpy(buffer, fFileContent, fFileLength);
}



};



#endif // __OPAQUE_SECTION__