5

I am working on an iOS app which links several static libraries. The challenge is, those linked libraries define same method names with different implementations. Oddly, I don't get any duplicate symbol definition errors; but, to no surprise, I end up with access to only one implementation of the method.

To be more clear, say I have libA and libB and they both define a global C method called func1()

When I link both libA and libB, and make a call to func1(), it resolves to either libA's or libB's implementation without any compilation warning. I, however, need to be able to access both libA's func1() and libB's func1() separately.

There's a similar SO post that explains how it can be done in C (via symbol renaming) but unfortunately, as I found out, objcopy tool doesn't work for ARM architecture (hence iPhone).

(I will submit it to the App Store, hence, dynamic linking is not an option)

Community
  • 1
  • 1
Ege Akpinar
  • 3,266
  • 1
  • 23
  • 29
  • If you have the source code for either of the libraries, then the solution is obvious. Alternatively, you could probably use `lipo` to package the two libraries into one, which *should* if my memory holds, keep only one of the symbols. – Richard J. Ross III Mar 11 '13 at 18:09
  • Thanks @RichardJ.RossIII but I don't have the source code and not sure your suggestion would help because I want to keep those symbols separately, I need them both, I don't want to reduce them to one symbol – Ege Akpinar Mar 11 '13 at 19:19
  • I would say to use `dlopen` and `dlsym` to load the symbols in dynamically, and separately, but unfortunately that won't work now that apple bans those from use. I'm no expert at the structure of a `.a` file, but I have a feeling that it is possible to do this via a hex editor, manually. Let me try something, and I'll see if I can help you out. – Richard J. Ross III Mar 11 '13 at 19:24

1 Answers1

4

It appears that you are in luck - you can still rename symbols with the ARM binary format, it's just a bit more hacky than the objcopy method...

NOTE: This has only been tested minimally, and I would strongly advise you to make a backup of all libraries in question before trying this!

Also note that this only works for files not compiled with the C++ compiler! This will fail if the C++ compiler was used on these files.

  1. First, you will need a decent hex editor, for this example, I will be using Hex Fiend.
  2. Next, you will open up a copy of your of of your libraries, let's call it lib1-renamed.a, and do the following with it:

    • Find the name of the symbol you wish to re-name. It can be found using the nm tool, or, if you know the header name, you should be set.

    • Next, you will use hex fiend, and to a textual replace of the old name (in this case foo), and give it a new name (in this case, bar). These names must have the same length, or it will corrupt the binary's offsets!

      Note: if there is more than one function that contain's foo's name in it, you may have problems.

  3. Now, you must edit the headers of the library you changed, to use the new function name (bar) instead of the old one.

If you have done the three simple steps above properly, you should now be able to compile & link the two files successfully, and call both implementations.

If you are trying to do this with a universal binary (e.g. one the works on the simulator as well), you'd be best off using lipo to separate the two binaries, using objcopy on the i386/x64 binary, and then using my method on the ARM binary, and lipo it back together.

†: Simplicity is not guaranteed, nor is it covered by the Richard J. Ross III super warranty. For more information about the super warranty, call 1-800-FREE-WARRANTY now. That's 1-800-FREE-WARRANTY now!

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
  • Testing this first thing tomorrow, greatly appreciate your effort (and your footnote even more!) :) – Ege Akpinar Mar 11 '13 at 20:48
  • 1
    @EgeAkpinar Don't forget your free super warrantee! – Richard J. Ross III Mar 11 '13 at 20:51
  • Well turns out I don't need warranty, because it worked like a charm. I'd tried renaming before but missed that I should rename to same length. Thank you so much! – Ege Akpinar Mar 12 '13 at 10:18
  • 7
    @AndiDog I appreciate your edit, but my humor is here to stay. Sometimes people take this site far too seriously, and a good laugh keeps you in a good mood. – Richard J. Ross III Apr 18 '13 at 17:11
  • This will be great if it works... I will not be making a copy of the static library, however, as I am using source control. Here goes nothing! P.S. Is there no way to do this with `lipo` or some other command line tool? I don't know enough about post-assembly development / penetration testing etc. – dave Oct 15 '15 at 22:11