Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Feb 2, 2022
Merged

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

merged 1 commit into from
Feb 2, 2022

Conversation

simba909
Copy link
Contributor

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
Copy link

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

@@ -77,8 +77,10 @@ enum Transmogrifier {

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@simba909 perhaps an early return will be more future-proof?

@bogo
Copy link
Owner

bogo commented Feb 2, 2022

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

@AppAppWorks
Copy link
Contributor

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

@ValeriusGC
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants