objc-file.mm 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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, "__objc_classlist");
  57. GETSECT(_getObjc2NonlazyClassList, classref_t, "__objc_nlclslist");
  58. GETSECT(_getObjc2CategoryList, category_t *, "__objc_catlist");
  59. GETSECT(_getObjc2NonlazyCategoryList, category_t *, "__objc_nlcatlist");
  60. GETSECT(_getObjc2ProtocolList, protocol_t *, "__objc_protolist");
  61. GETSECT(_getObjc2ProtocolRefs, protocol_t *, "__objc_protorefs");
  62. GETSECT(getLibobjcInitializers, UnsignedInitializer, "__objc_init_func");
  63. objc_image_info *
  64. _getObjcImageInfo(const headerType *mhdr, size_t *outBytes)
  65. {
  66. return getDataSection<objc_image_info>(mhdr, "__objc_imageinfo",
  67. outBytes, nil);
  68. }
  69. // Look for an __objc* section other than __objc_imageinfo
  70. static bool segmentHasObjcContents(const segmentType *seg)
  71. {
  72. for (uint32_t i = 0; i < seg->nsects; i++) {
  73. const sectionType *sect = ((const sectionType *)(seg+1))+i;
  74. if (sectnameStartsWith(sect->sectname, "__objc_") &&
  75. !sectnameEquals(sect->sectname, "__objc_imageinfo"))
  76. {
  77. return true;
  78. }
  79. }
  80. return false;
  81. }
  82. // Look for an __objc* section other than __objc_imageinfo
  83. bool
  84. _hasObjcContents(const header_info *hi)
  85. {
  86. bool foundObjC = false;
  87. foreach_data_segment(hi->mhdr(), [&](const segmentType *seg, intptr_t slide)
  88. {
  89. if (segmentHasObjcContents(seg)) foundObjC = true;
  90. });
  91. return foundObjC;
  92. }
  93. // OBJC2
  94. #endif