0

I have a variable definition in an Android JNI C function that does nothing but define itself as a string. I want this string to appear in the binary, but when I build the project, the .so file does not contain the string.

Here's what I've tried in the C code.

#pragma GCC push_options
#pragma GCC optimize ("O0")
const char volatile myString[32] = "Some string that must be there";
#pragma GCC pop_options

How can I get disable the compiler from optimizing away this unused variable definition?

user1118764
  • 9,255
  • 18
  • 61
  • 113
  • 1
    const volatile is an oxymoron – Alex Cohn Dec 10 '18 at 05:55
  • Do you set visibility=hidden for your library? – Alex Cohn Dec 10 '18 at 05:57
  • @AlexCohn it looks that way, but actually it const means that the program should not change the value of the variable, while volatile means that the program should not be optimised. They are actually 2 separate things. How do I see if visibility is set to hidden for my library? – user1118764 Dec 10 '18 at 06:12
  • 1
    No, `volatile` means that any thread in the program can change the string without synchronization. – user207421 Dec 10 '18 at 06:23
  • Yup, any thread, just not the current program, from my understanding. Refer to https://stackoverflow.com/questions/4592762/difference-between-const-const-volatile. Anyway, what about the visibility part? – user1118764 Dec 10 '18 at 06:26
  • As for visibility, this is typically set as `LOCAL_CFLAGS += -fvisibility=hidden`, and it's a good practice. To have **myString** exposed by your library, add the *attribute*: `const char volatile myString[32] __attribute__ ((visibility ("default"))) = "Some string that must be there";`. And you don't need `optimize ("O0")`. – Alex Cohn Dec 10 '18 at 07:18
  • Actually, as the [best answer](https://stackoverflow.com/a/4597164/192373) in the linked discussion explains, `const volatile` *«is typically used to access hardware registers that can be read and are updated by the hardware, but make no sense to write to (or might be an error to write to)»*. This is definitely not your case with a string in Android library. You are trying to prohibit a very different kind of *optimization*. You can safely drop `volatile` from the declaration. – Alex Cohn Dec 10 '18 at 07:25
  • How do you know the string isn't in your shared object? You didn't say how you verified that. – Andrew Henle Dec 10 '18 at 10:36
  • @AndrewHenle easy, I did a strings of the .so file and verified that the string couldn't be found – user1118764 Dec 11 '18 at 02:24
  • `strings` can be unreliable. Per [the `strings` man page](http://man7.org/linux/man-pages/man1/strings.1.html): "Depending upon how the strings program was configured it will default to either displaying all the printable sequences that it can find in each file, **or only those sequences that are in loadable, initialized data sections**. ..." Use `strings -a` and maybe even a tool designed to find symbols in executable files such as `nm`, and look for your variable, too. Also check your intermediate object file. – Andrew Henle Dec 11 '18 at 04:39
  • OK, so actually I didn't use the command strings, but rather, the strings window in IDA Pro. When I declare strings that are used, it appears there. When I don't, it doesn't. In any case, I just did a assignment of the string, and assignment back, and it's there in the .so file now. – user1118764 Dec 11 '18 at 05:39

1 Answers1

1

I suspect that your problem is not with the compilation, but with the linking. Linkers often leave out data that is not used, to reduce the size of the binary. To check this, use the strings command or equivalent on the .o file generated from your C file: if the string is in that, but not in your .so your problem is the linking.

Unfortunately, I don't know how to work around this problem with the linker command(s), because all of my Android C programming has been done with a standalone tool-chain and a custom build system.

Your easiest solution is simply to make a copy of the string at run-time. You need to do this in your C code, so that the linker knows the string gets used.

John Dallman
  • 590
  • 4
  • 18