if ( !fOwner.fOptions.fNoEHLabels )
fSymbolTableInclusion = ObjectFile::Atom::kSymbolTableIn;
}
+ else if ( (strncmp(fSection->sectname(), "__objc_classrefs", 16) == 0) && (strcmp(fSection->segname(), "__DATA") == 0) ) {
+ fSynthesizedName = "objc-class-pointer-name-PENDING";
+ fScope = ObjectFile::Atom::scopeLinkageUnit;
+ owner.fAtomsPendingAName.push_back(this);
+ owner.fSectionsWithAtomsPendingAName.insert(fSection);
+ fKind = ObjectFile::Atom::kWeakDefinition;
+ }
else if ( section == owner.fUTF16Section ) {
if ( fOwner.fOptions.fForFinalLinkedImage ) {
fDontDeadStrip = false;
if ( funcAtom != NULL )
asprintf((char**)&fSynthesizedName, "%s.lsda", funcAtom->getDisplayName());
}
+ else if ( (strncmp(fSection->sectname(), "__objc_classrefs", 16) == 0) && (strcmp(fSection->segname(), "__DATA") == 0) ) {
+ std::vector<ObjectFile::Reference*>& references = this->getReferences();
+ if ( references.size() != 1 )
+ throwf("__objc_classrefs element missing reloc (count=%ld) for target class in %s", references.size(), fOwner.getPath());
+ const char* targetName = references[0]->getTargetName();
+ if ( strncmp(targetName, "_OBJC_CLASS_$_", 14) == 0 )
+ asprintf((char**)&fSynthesizedName, "objc-class-ref-to-%s", &targetName[14]);
+ else
+ asprintf((char**)&fSynthesizedName, "objc-class-ref-to-%s", targetName);
+ }
}
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 isZeroFill() const { return fZeroFill; }
virtual bool isThumb() const { return false; }
virtual SymbolTableInclusion getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableNotIn; }
virtual bool dontDeadStrip() const { return false; }
const char* fSectionName;
const char* fDisplayName;
bool fStart;
+ bool fZeroFill;
static std::vector<ObjectFile::Reference*> fgNoReferences;
};
// 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)
+ : fOwner(owner), fSymbolName(symbolName), fSectionName(NULL), fStart(start), fZeroFill(false)
{
const char* segSectDividor = strrchr(segSectName, '$');
if ( segSectDividor == NULL )
strlcpy(segName, segSectName, segNameLen+1);
if ( strcmp(segName, "__TEXT") == 0 )
fSegment = new Segment("__TEXT", true, false, true);
- else if ( strcmp(segName, "__DATA") == 0 )
+ else if ( strcmp(segName, "__DATA") == 0 ) {
fSegment = new Segment("__DATA", true, true, false);
+ if ( (strcmp(fSectionName, "__bss") == 0) || (strcmp(fSectionName, "__common") == 0) )
+ fZeroFill = true;
+ }
else
fSegment = new Segment(strdup(segName), true, true, false);
{
public:
static bool validFile(const uint8_t* fileContent, bool subtypeMustMatch=false, cpu_subtype_t subtype=0);
+ static const char* fileKind(const uint8_t* fileContent);
Reader(const uint8_t* fileContent, const char* path, time_t modTime,
const ObjectFile::ReaderOptions& options, uint32_t ordinalBase);
virtual ~Reader() {}
else if ((strcmp(sect->sectname(), "__cfstring") == 0) && (strcmp(sect->segname(), "__DATA") == 0)) {
atomSize = 4 * sizeof(pint_t);
}
+ // special case class reference sections
+ else if ( (strncmp(sect->sectname(), "__objc_classrefs", 16) == 0) && (strcmp(sect->segname(), "__DATA") == 0) ) {
+ atomSize = sizeof(pint_t);;
+ }
break;
}
if ( atomSize != 0 ) {
// do nothing
break;
case DW_EH_PE_pcrel:
- result += startAddr;
+ // <rdar://problem/7200658> pc-rel sdata4 should return zero if content is zero
+ if ( (result != 0) || ((encoding & DW_EH_PE_indirect) != 0) )
+ result += startAddr;
break;
case DW_EH_PE_textrel:
throw "DW_EH_PE_textrel pointer encoding not supported";
return true;
}
+
+template <>
+const char* Reader<ppc>::fileKind(const uint8_t* fileContent)
+{
+ const macho_header<P>* header = (const macho_header<P>*)fileContent;
+ if ( header->magic() != MH_MAGIC )
+ return NULL;
+ if ( header->cputype() != CPU_TYPE_POWERPC )
+ return NULL;
+ switch ( header->cpusubtype() ) {
+ case CPU_SUBTYPE_POWERPC_750:
+ return "ppc750";
+ case CPU_SUBTYPE_POWERPC_7400:
+ return "ppc7400";
+ case CPU_SUBTYPE_POWERPC_7450:
+ return "ppc7450";
+ case CPU_SUBTYPE_POWERPC_970:
+ return "ppc970";
+ case CPU_SUBTYPE_POWERPC_ALL:
+ return "ppc";
+ }
+ return "ppc???";
+}
+
+template <>
+const char* Reader<ppc64>::fileKind(const uint8_t* fileContent)
+{
+ const macho_header<P>* header = (const macho_header<P>*)fileContent;
+ if ( header->magic() != MH_MAGIC )
+ return NULL;
+ if ( header->cputype() != CPU_TYPE_POWERPC64 )
+ return NULL;
+ return "ppc64";
+}
+
+template <>
+const char* Reader<x86>::fileKind(const uint8_t* fileContent)
+{
+ const macho_header<P>* header = (const macho_header<P>*)fileContent;
+ if ( header->magic() != MH_MAGIC )
+ return NULL;
+ if ( header->cputype() != CPU_TYPE_I386 )
+ return NULL;
+ return "i386";
+}
+
+template <>
+const char* Reader<x86_64>::fileKind(const uint8_t* fileContent)
+{
+ const macho_header<P>* header = (const macho_header<P>*)fileContent;
+ if ( header->magic() != MH_MAGIC )
+ return NULL;
+ if ( header->cputype() != CPU_TYPE_X86_64 )
+ return NULL;
+ return "x86_64";
+}
+
+template <>
+const char* Reader<arm>::fileKind(const uint8_t* fileContent)
+{
+ const macho_header<P>* header = (const macho_header<P>*)fileContent;
+ if ( header->magic() != MH_MAGIC )
+ return NULL;
+ if ( header->cputype() != CPU_TYPE_ARM )
+ return NULL;
+ switch ( header->cpusubtype() ) {
+ case CPU_SUBTYPE_ARM_V4T:
+ return "armv4t";
+ case CPU_SUBTYPE_ARM_V5TEJ:
+ return "armv5";
+ case CPU_SUBTYPE_ARM_V6:
+ return "armv6";
+ case CPU_SUBTYPE_ARM_V7:
+ return "armv7";
+ }
+ return "arm???";
+}
+
+
template <typename A>
bool Reader<A>::isWeakImportSymbol(const macho_nlist<P>* sym)
{