Module: CocoapodsMangle::Defines

Defined in:
lib/cocoapods_mangle/defines.rb

Overview

Generates mangling defines from a provided list of binaries

Class Method Summary collapse

Class Method Details

.category_selectors(binaries, classes) ⇒ Array<String>

Note:

Selectors on classes which are being mangled will not be mangled

Get the category selectors defined in a list of binaries

Parameters:

  • binaries (Array<String>)

    The binaries containing symbols to be mangled

  • classes (Array<String>)

    The classes which are being mangled

Returns:

  • (Array<String>)

    The category selectors defined in the binaries



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/cocoapods_mangle/defines.rb', line 65

def self.category_selectors(binaries, classes)
  symbols = run_nm(binaries, '-U')
  selectors = symbols.select { |selector| selector[/ t [-|+]\[[^ ]*\([^ ]*\) [^ ]*\]/] }
  selectors = selectors.reject do |selector|
    class_name = selector[/[-|+]\[(.*?)\(/m, 1]
    classes.include? class_name
  end
  selectors = selectors.map { |selector| selector[/[^ ]*\]\z/][0...-1] }
  selectors = selectors.map { |selector| selector.split(':').first }
  selectors.uniq
end

.classes(binaries) ⇒ Array<String>

Get the classes defined in a list of binaries

Parameters:

  • binaries (Array<String>)

    The binaries containing symbols to be mangled

Returns:

  • (Array<String>)

    The classes defined in the binaries



24
25
26
27
28
29
30
31
32
33
# File 'lib/cocoapods_mangle/defines.rb', line 24

def self.classes(binaries)
  all_symbols = run_nm(binaries, '-gU')
  all_symbols = all_symbols.reject { |symbol| swift_symbol?(symbol) }

  class_symbols = all_symbols.select do |symbol|
    symbol[/OBJC_CLASS_\$_/]
  end
  class_symbols = class_symbols.map { |klass| klass.gsub(/^.*\$_/, '') }
  class_symbols.uniq
end

.constants(binaries) ⇒ Array<String>

Get the constants defined in a list of binaries

Parameters:

  • binaries (Array<String>)

    The binaries containing symbols to be mangled

Returns:

  • (Array<String>)

    The constants defined in the binaries



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/cocoapods_mangle/defines.rb', line 39

def self.constants(binaries)
  all_symbols = run_nm(binaries, '-gU')
  all_symbols = all_symbols.reject { |symbol| swift_symbol?(symbol) }

  consts = all_symbols.select { |const| const[/ S /] }
  consts = consts.reject { |const| const[/_OBJC_/] }
  consts = consts.reject { |const| const[/__block_descriptor.*/] }
  consts = consts.map! { |const| const.gsub(/^.* _/, '') }
  consts = consts.uniq

  other_consts = all_symbols.select { |const| const[/ T /] }
  other_consts = other_consts.reject { |const| const[/__copy_helper_block.*/] }
  other_consts = other_consts.reject { |const| const[/__destroy_helper_block.*/] }
  other_consts = other_consts.map! { |const| const.gsub(/^.* _/, '') }
  other_consts = other_consts.uniq

  consts + other_consts
end

.mangling_defines(prefix, binaries_to_mangle) ⇒ Array<String>

Returns The mangling defines.

Parameters:

  • prefix (String)

    The prefix to prefix to mangled symbols

  • binaries_to_mangle (Array<String>)

    The binaries containing symbols to be mangled

Returns:

  • (Array<String>)

    The mangling defines



9
10
11
12
13
14
15
16
17
18
# File 'lib/cocoapods_mangle/defines.rb', line 9

def self.mangling_defines(prefix, binaries_to_mangle)
  classes = classes(binaries_to_mangle)
  constants = constants(binaries_to_mangle)
  category_selectors = category_selectors(binaries_to_mangle, classes)

  defines = prefix_symbols(prefix, classes)
  defines += prefix_symbols(prefix, constants)
  defines += prefix_selectors(prefix, category_selectors)
  defines
end

.prefix_selectors(prefix, selectors) ⇒ Object

Prefix a given list of selectors

Parameters:

  • prefix (String)

    The prefix to use

  • selectors (Array<String>)

    The selectors to prefix



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/cocoapods_mangle/defines.rb', line 93

def self.prefix_selectors(prefix, selectors)
  selectors_to_prefix = selectors
  defines = []

  property_setters = selectors.select { |selector| selector[/\Aset[A-Z]/] }
  property_setters.each do |property_setter|
    property_getter = selectors.find do |selector|
      upper_getter = property_setter[3..-1]
      lower_getter = upper_getter[0, 1].downcase + upper_getter[1..-1]
      selector == upper_getter || selector == lower_getter
    end
    next if property_getter.nil?

    selectors_to_prefix.reject! { |selector| selector == property_setter }
    selectors_to_prefix.reject! { |selector| selector == property_getter }

    defines << "#{property_setter}=set#{prefix}#{property_getter}"
    defines << "#{property_getter}=#{prefix}#{property_getter}"
  end

  defines += prefix_symbols(prefix, selectors_to_prefix)
  defines
end

.prefix_symbols(prefix, symbols) ⇒ Object

Prefix a given list of symbols

Parameters:

  • prefix (String)

    The prefix to prepend

  • symbols (Array<String>)

    The symbols to prefix



82
83
84
85
86
# File 'lib/cocoapods_mangle/defines.rb', line 82

def self.prefix_symbols(prefix, symbols)
  symbols.map do |symbol|
    "#{symbol}=#{prefix}#{symbol}"
  end
end

.run_nm(binaries, flags) ⇒ Object



169
170
171
# File 'lib/cocoapods_mangle/defines.rb', line 169

def self.run_nm(binaries, flags)
  `nm #{flags} #{binaries.join(' ')}`.split("\n")
end

.swift_symbol?(symbol) ⇒ Boolean

Is symbol a Swift symbol? This is used to avoid mangling Swift.

Parameters:

  • symbol (String)

    The symbol to check

Returns:

  • (Boolean)

    true if it is a Swift symbol, false otherwise



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/cocoapods_mangle/defines.rb', line 121

def self.swift_symbol?(symbol)
  # Swift binaries have many symbols starting with $s_ that should be excluded
  # e.g. '0000000000000258 S _$s9ManglePod9SomeClassCMF'
  symbol[/\$s/] ||
    # Internal Swift symbols starting with __swift or ___swift such as should not be mangled
    # e.g. '00000000000050ac S ___swift_reflection_version' 
    symbol[/ __(_)?swift/] ||
    # Internal Swift symbols starting with digit+Swift+optional_digit should not be mangled
    # e.g. '34SwiftOverride', '34Swift570Override' 
    symbol[/\d+Swift(\d+)?/] ||
    # Internal Swift symbols starting with Swift+digit should not be mangled
    # e.g. 'Swift570Override' 
    symbol[/Swift\d+/] ||        
    # Internal SwiftUI symbols starting with digit+SwiftUI+optional_digit such as should not be mangled
    # e.g. '55SwiftUI', '55SwiftUI45'
    symbol[/\d+SwiftUI(\d+)?/] ||
    # Swift symbols starting with symbolic should be ignored
    # e.g. '0000000000000248 S symbolic _____ 9ManglePod9SomeClassC'
    symbol[/symbolic /] ||
    # Swift symbol references to Objective-C symbols should not be mangled
    # e.g. '00000000000108ca S _associated conformance So26SCNetworkReachabilityFlagsVs10SetAlgebraSCSQ'
    symbol[/associated conformance/] ||
    # " globalinit" symbols should be skipped
    # e.g. 0000000000000000 T " globalinit_33_A313450CFC1FC3D0CBEF4411412DB9E8_func0"
    symbol[/ globalinit/] ||
    # "globalinit" symbols should be skipped
    # e.g. 0000000000000000 T "globalinit_33_A313450CFC1FC3D0CBEF4411412DB9E8_func0"
    symbol[/globalinit/] ||
    # Swift classes inheriting from Objective-C classes should not be mangled
    # e.g. '0000000000000290 S _OBJC_CLASS_$__TtC9ManglePod19SomeFoundationClass'
    symbol[/_OBJC_CLASS_\$__/] ||
    # Swift symbols starting with ____ should be ignored
    # e.g. ' ____ 6Lottie15AnimatedControlCC'
    symbol[/____ /] ||
    # _PROTOCOL symbols should be skipped
    # e.g. 0000000000000000 _PROTOCOL_METHOD_TYPES_CAAction
    symbol[/_PROTOCOL/] ||
    # _swiftoverride_ symbols should be skipped
    # e.g. _swiftoverride_
    symbol[/_\w+_swiftoverride_/] ||
    # _Zxxxswift symbols should be skipped
    # e.g. _ZN5swift34swift50override_conformsToProtocolEPKNS
    symbol[/_Z\w+swift/] ||
    # get_witness_table symbols should be skipped
    # e.g. get_witness_table Say6.2
    symbol[/get_witness_table /]
end