objc-file.mm 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
  3. *
  4. * @APPLE_LICENSE_HEADER_START@
  5. *
  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
  11. * file.
  12. *
  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.
  20. *
  21. * @APPLE_LICENSE_HEADER_END@
  22. */
  23. #if __OBJC2__
  24. #include "objc-private.h"
  25. #include "objc-file.h"
  26. // Look for a __DATA or __DATA_CONST or __DATA_DIRTY section
  27. // with the given name that stores an array of T.
  28. template <typename T>
  29. T* getDataSection(const headerType *mhdr, const char *sectname,
  30. size_t *outBytes, size_t *outCount)
  31. {
  32. unsigned long byteCount = 0;
  33. T* data = (T*)getsectiondata(mhdr, "__DATA", sectname, &byteCount);
  34. if (!data) {
  35. data = (T*)getsectiondata(mhdr, "__DATA_CONST", sectname, &byteCount);
  36. }
  37. if (!data) {
  38. data = (T*)getsectiondata(mhdr, "__DATA_DIRTY", sectname, &byteCount);
  39. }
  40. if (outBytes) *outBytes = byteCount;
  41. if (outCount) *outCount = byteCount / sizeof(T);
  42. return data;
  43. }
  44. #define GETSECT(name, type, sectname) \
  45. type *name(const headerType *mhdr, size_t *outCount) { \
  46. return getDataSection<type>(mhdr, sectname, nil, outCount); \
  47. } \
  48. type *name(const header_info *hi, size_t *outCount) { \
  49. return getDataSection<type>(hi->mhdr(), sectname, nil, outCount); \
  50. }
  51. // function name content type section name
  52. GETSECT(_getObjc2SelectorRefs, SEL, "__objc_selrefs");
  53. GETSECT(_getObjc2MessageRefs, message_ref_t, "__objc_msgrefs");
  54. GETSECT(_getObjc2ClassRefs, Class, "__objc_classrefs");
  55. GETSECT(_getObjc2SuperRefs, Class, "__objc_superrefs");
  56. GETSECT(_getObjc2ClassList, classref_t const, "__objc_classlist");
  57. GETSECT(_getObjc2NonlazyClassList, classref_t const, "__objc_nlclslist");
  58. GETSECT(_getObjc2CategoryList, category_t * const, "__objc_catlist");
  59. GETSECT(_getObjc2CategoryList2, category_t * const, "__objc_catlist2");
  60. GETSECT(_getObjc2NonlazyCategoryList, category_t * const, "__objc_nlcatlist");
  61. GETSECT(_getObjc2ProtocolList, protocol_t * const, "__objc_protolist");
  62. GETSECT(_getObjc2ProtocolRefs, protocol_t *, "__objc_protorefs");
  63. GETSECT(getLibobjcInitializers, UnsignedInitializer, "__objc_init_func");
  64. objc_image_info *
  65. _getObjcImageInfo(const headerType *mhdr, size_t *outBytes)
  66. {
  67. return getDataSection<objc_image_info>(mhdr, "__objc_imageinfo",
  68. outBytes, nil);
  69. }
  70. // Look for an __objc* section other than __objc_imageinfo
  71. static bool segmentHasObjcContents(const segmentType *seg)
  72. {
  73. for (uint32_t i = 0; i < seg->nsects; i++) {
  74. const sectionType *sect = ((const sectionType *)(seg+1))+i;
  75. if (sectnameStartsWith(sect->sectname, "__objc_") &&
  76. !sectnameEquals(sect->sectname, "__objc_imageinfo"))
  77. {
  78. return true;
  79. }
  80. }
  81. return false;
  82. }
  83. // Look for an __objc* section other than __objc_imageinfo
  84. bool
  85. _hasObjcContents(const header_info *hi)
  86. {
  87. bool foundObjC = false;
  88. foreach_data_segment(hi->mhdr(), [&](const segmentType *seg, intptr_t slide)
  89. {
  90. if (segmentHasObjcContents(seg)) foundObjC = true;
  91. });
  92. return foundObjC;
  93. }
  94. // OBJC2
  95. #endif