bogo / arm64-to-sim

Transmogrify native iOS frameworks to run in iOS Simulator on Apple silicon.
https://bogo.wtf/arm64-to-sim.html
MIT License
532 stars 86 forks source link

Avoid setting section offsets if the S_ZEROFILL flag is set #8

Closed simba909 closed 2 years ago

simba909 commented 2 years ago

First off, the work done here is absolutely fantastic! 👏🏻 Never got it to fully work for my use-case in the past but with the recent release of Xcode 13.3 beta 1 I could finally get a hint as to what was wrong with my initial attempt:

../Example.a(Something.o), section __DATA/__bss has type zero-fill but non-zero file offset [...]

After a few minutes of thinking I brought out otool and had a look. Here's the __DATA section:

Section
  sectname __bss
   segname __DATA
      addr 0x0000000000000798
      size 0x0000000000000008
    offset 8
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000001
 reserved1 0
 reserved2 0

It indeed has a non-zero offset and judging by that above error (which I might be reading too much into..) it shouldn't have. Now I just needed to figure out how the tool would be able to know that 🤔

After some sleuthing I realised that the flags 0x00000001 is the key - if it's set to 1 then it matches the S_ZEROFILL constant from MachO.loader. Using this info the offset-manipulating code can be changed to avoid setting the offset if the S_ZEROFILL flag is set:

let offsetSections = sections.map { section -> section_64 in
    var section = section
    if section.flags != S_ZEROFILL {
        section.offset += UInt32(offset)
        section.reloff += section.reloff > 0 ? UInt32(offset) : 0
    }
    return section
}

Much to my surprise the above seems to work and the error in Xcode is gone! This also makes the resulting library work for my use-case 🎉

I do realise that the solution might be a bit naïve; it should probably do some bitmask checking on the flags to see if the S_ZEROFILL flag is set but that didn't seem to be necessary at least for my use-case 🤔

igor-makarov commented 2 years ago

@bogo @simba909 I've just arrived at this exact conclusion independently - this looks like a correct change! 💪🏻

bogo commented 2 years ago

This is a great find, thank you so much for contributing @simba909 and @igor-makarov!

AppAppWorks commented 2 years ago

@bogo I discovered that sections of types S_GB_ZEROFILL and S_THREAD_LOCAL_ZEROFILL should also be excluded from offset patching.

ValeriusGC commented 2 years ago

Только что собрал на CodeMagic для Flutter: cocoapods (1.11.2) Xcode 13.0 yandex_mapkit 2.0.6 --> YandexMapMobile 4.0.0.-full