1

Application written in C, and runs on Ubuntu 18.04.
This application links with couple of shared libraries, lets say shared_lib1_external.so, and shared_lib1_internal.so.

I have this unique scenario where the shared_lib1_external is used initially(during application startup), and so some of the globals get initialized in this shared_lib1_external.
But then after startup is completed, need to use shared_lib1_internal for subsequent usage. Now this leaves us with shared_lib1_internal, which does not have the globals initialized correctly.

Just to clarify, when I say global symbols, I am only interested in getting global variables, not global functions from the library. For example:
int global_counter = 0;
int global_array[10];

Now after startup is done, I do have the option to use dlopen(to open shared_lib_external.so), and then use dlsym(shared_lib_external's handle, "global_symbol_name"), to fetch the global symbols.
But this can be tedious, since there are several globals, but more importantly, there are also static variables which are local to the library, but gets initialized during startup, and used during runtime. Now we cannot get static symbols through dlsym, which is another issue.
For example, static variables like below:
static int local_counter;

When I do an object dump:
objdump -t shared_lib1_internal.so,
both static and global symbols show up either in .bss (OR) in .data section, depending on whether variable is initialized or not.

So question is, is there a programmatic way to do the steps below in my C application:
After application startup is completed, the following steps to be executed by the C application:
Step1-> Retrieve the entire .bss and .data sections of shared_lib1_external.so, into application's memory.
Step2-> Copy-over the entire .bss and .data sections retrieved in Step1, to the corresponding
sections in shared_lib1_internal.so

user3622275
  • 21
  • 1
  • 6
  • I think you're asking if one Linux process can sneakily peek at another Linux process's memory. No :) If you're asking: can I programmatically get the same information about an object module that objdump shows me: Yes. – paulsm4 Jun 12 '21 at 01:17
  • You may have misunderstood something; when you first `dlopen` a library, its global variables get "initialized correctly". Perhaps you wish to use `dlmopen(LM_ID_NEWLM,...)` which allows multiple independent instances of one shared object. – Lorinczy Zsigmond Jun 12 '21 at 05:06
  • @paulsm4, Trying to programmatically get the same info, that objdump shows. As far as APIs, besides dlsym, there is dladdr and dlinfo, but not sure how to get the entire .bss and .data sections. Assuming that .bss and .data sections are contiguous and not distributed. Alternatively, is there some other way, where I dont need to manually pass the symbol-names to dlsym, but query and get a linked-list of symbols. In my use-case, the process that calls these APIs to get .bss and .data info, will also be linked to those same shared objects. Are there any APIs that can help get this info – user3622275 Jun 12 '21 at 22:36
  • @user3622275 - got it. STRONG SUGGESTION: "Use the Source". Download the "binutils" source code, and adapt objdump.c: https://ftp.gnu.org/gnu/binutils/. Here's objdump.c: https://github.com/CyberGrandChallenge/binutils/blob/master/binutils/objdump.c. You'll notice that it relies on a lot of other stuff, like [DWARF](https://stackoverflow.com/a/2511910/421195). But you can absolutely accomplish your goal. Good luck! – paulsm4 Jun 12 '21 at 22:53
  • @paulsm4, thanks for your inputs. Took a quick look at the code, seems like a fair amount of code that needs to be understood. Will need some time and effort, to figure out how it can be used to accomplish my goal. Interestingly, in objdump.c, they are NOT using apis like-> dlopen, dlsym, dladdr, dlinfo and so on. – user3622275 Jun 13 '21 at 18:18

1 Answers1

1

As I said above:

STRONG SUGGESTION: "Use the Source".

Download the "binutils" source code, and adapt objdump.c: ftp.gnu.org/gnu/binutils.

Here's objdump.c: https://github.com/CyberGrandChallenge/binutils/blob/master/binutils/objdump.c.

You'll notice that it relies on a lot of other stuff, like DWARF. But you can absolutely accomplish your goal.

I'm not asking you to necessarily UNDERSTAND all of binutils. The idea is that your app can use the same APIs that objdump.c uses.

Which happen to be mostly binutils APIs (vs. APIs like dlopen et al). In other words:

  1. download binutils source, verify that you can successfully build it. At a minimum, you'll need some binutils header files.
  2. Ensure you have binutils installed on your Linux distro (so you can use the binutils libraries in your own app as needed).
  3. Create a little C-language "hello world" that reads the object file's .bss and .data sections, like you want your app to do.
  4. Successfully build and run your "hello world".
  5. Finally, apply what you've learned to do the same in your app.

Good luck! Please post back what you find!

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • thanks for listing the steps, that helps. It is easy to find reference code, for dl* apis, like dlopen, dlsym..etc, and I have used dl* apis, so have some familiarity. In this case, need to figure out objdump.c, and figure out apis to retreive each symbol. Also for my project, we cannot use GPL code, and objdump.c has GPL license. We prefer APACHE or BSD license. Anyways, I am also considering a different approach. If I try the option that you have described, will post my findings. – user3622275 Jun 14 '21 at 19:17