2  * Copyright (c) 1999-2007 Apple Inc.  All Rights Reserved.
 
   4  * @APPLE_LICENSE_HEADER_START@
 
   6  * This file contains Original Code and/or Modifications of Original Code
 
   7  * as defined in and that are subject to the Apple Public Source License
 
   8  * Version 2.0 (the 'License'). You may not use this file except in
 
   9  * compliance with the License. Please obtain a copy of the License at
 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this
 
  13  * The Original Code and all software distributed under the License are
 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 
  18  * Please see the License for the specific language governing rights and
 
  19  * limitations under the License.
 
  21  * @APPLE_LICENSE_HEADER_END@
 
  26 #include "objc-private.h"
 
  27 #include "objc-file.h"
 
  30 // Look for a __DATA or __DATA_CONST or __DATA_DIRTY section 
 
  31 // with the given name that stores an array of T.
 
  33 T* getDataSection(const headerType *mhdr, const char *sectname, 
 
  34                   size_t *outBytes, size_t *outCount)
 
  36     unsigned long byteCount = 0;
 
  37     T* data = (T*)getsectiondata(mhdr, "__DATA", sectname, &byteCount);
 
  39         data = (T*)getsectiondata(mhdr, "__DATA_CONST", sectname, &byteCount);
 
  42         data = (T*)getsectiondata(mhdr, "__DATA_DIRTY", sectname, &byteCount);
 
  44     if (outBytes) *outBytes = byteCount;
 
  45     if (outCount) *outCount = byteCount / sizeof(T);
 
  49 #define GETSECT(name, type, sectname)                                   \
 
  50     type *name(const headerType *mhdr, size_t *outCount) {              \
 
  51         return getDataSection<type>(mhdr, sectname, nil, outCount);     \
 
  53     type *name(const header_info *hi, size_t *outCount) {               \
 
  54         return getDataSection<type>(hi->mhdr(), sectname, nil, outCount); \
 
  57 //      function name                 content type     section name
 
  58 GETSECT(_getObjc2SelectorRefs,        SEL,             "__objc_selrefs"); 
 
  59 GETSECT(_getObjc2MessageRefs,         message_ref_t,   "__objc_msgrefs"); 
 
  60 GETSECT(_getObjc2ClassRefs,           Class,           "__objc_classrefs");
 
  61 GETSECT(_getObjc2SuperRefs,           Class,           "__objc_superrefs");
 
  62 GETSECT(_getObjc2ClassList,           classref_t,      "__objc_classlist");
 
  63 GETSECT(_getObjc2NonlazyClassList,    classref_t,      "__objc_nlclslist");
 
  64 GETSECT(_getObjc2CategoryList,        category_t *,    "__objc_catlist");
 
  65 GETSECT(_getObjc2NonlazyCategoryList, category_t *,    "__objc_nlcatlist");
 
  66 GETSECT(_getObjc2ProtocolList,        protocol_t *,    "__objc_protolist");
 
  67 GETSECT(_getObjc2ProtocolRefs,        protocol_t *,    "__objc_protorefs");
 
  68 GETSECT(getLibobjcInitializers,       UnsignedInitializer, "__objc_init_func");
 
  72 _getObjcImageInfo(const headerType *mhdr, size_t *outBytes)
 
  74     return getDataSection<objc_image_info>(mhdr, "__objc_imageinfo", 
 
  78 // Look for an __objc* section other than __objc_imageinfo
 
  79 static bool segmentHasObjcContents(const segmentType *seg)
 
  81     for (uint32_t i = 0; i < seg->nsects; i++) {
 
  82         const sectionType *sect = ((const sectionType *)(seg+1))+i;
 
  83         if (sectnameStartsWith(sect->sectname, "__objc_")  &&
 
  84             !sectnameEquals(sect->sectname, "__objc_imageinfo"))
 
  93 // Look for an __objc* section other than __objc_imageinfo
 
  95 _hasObjcContents(const header_info *hi)
 
  97     bool foundObjC = false;
 
  99     foreach_data_segment(hi->mhdr(), [&](const segmentType *seg, intptr_t slide)
 
 101         if (segmentHasObjcContents(seg)) foundObjC = true;