简体   繁体   中英

Can I replace a symbol in a static library with my own version?

Using gcc/ld, I want to use libfoo.a , which contains a symbol symbol_foo (which is a function - an ISR if that matters). Other functions in libfoo uses this function obviously. What I want to do is compile my own binary, using libfoo.a , but linking in my own version of symbol_foo instead.

Is this possible? Currently I get an ld error due to multiple definitions of the symbol. Ie it's not declared "soft-linked" or anything like that in the original static library.

Ideally I'd like there to exist something like __attribute__((ld_override)) or whatever, but I'm guessing there does not. Any ideas?

It depends on the design of the library. In your case, the answer is "No", because the function isn't isolated in the library. For a good exposition on library construction, see PJ Plauger The Standard C Library 1992. Yes, it is fairly old, so the version of Standard C is C90, but the ideas it espouses are still valid.

When the linker is building a program, it is processing a series of object files and libraries, looking for unsatisfied references (symbol names) and tracking definitions. In most circumstances, it is started with the symbol main as undefined.

  • As it processes an object file, it notes which symbols are defined that satisfy an undefined symbol and remembers all the names that are defined by that file (and it complains if one of the symbols it finds clashes with one it already knows about).
  • As it processes a static library, it looks for symbols that are defined that it does not already have a definition for. When it finds such a symbol, it links the object file from the library, noting which symbols are defined and which are still undefined.

Now, if the object file containing symbol_foo only defines symbol_foo , then if you've linked your symbol_foo before it reads the library, the linker will ignore the symbol_foo from the library; it already has a definition and doesn't need another. However, it is probable that the object file containing symbol_foo in the libfoo.a library also defines some other symbols, and those other symbols are needed by the linker, so it has to link the object file containing symbol_foo , and complains because that symbol is doubly-defined, even though others in the same file are not.

Plauger advocates that each object file in a (static) library should define a single external symbol. This allows the maximum substitutability for the functions in the library. I believe it is fair to assume that the designer of libfoo.a didn't make that decision, at least wrt symbol_foo .

You can extract the object files from libfoo.a (use a temporary directory) and examine their contents with nm ; you may be able to do that directly on the library itself. Used with the proper options, that will show you which files define and reference which other symbols.

Note that the rules for linking with shared libraries are somewhat different. There are also 'weak' symbols which can alter the behaviour. You can also often create 'relocatable' or 'relinkable' object files from multiple object files ( ld -r usually); that gives you a single bigger object file and alters the equation. Finally, for now, linker scripts can control which symbols are visible outside the library. So, this is no more than a gloss over the subject.

As a general rule, if you want to override (replace) a non-weak, global symbol in a static library and still use the rest of the library, you're also going to need to replace all the other non-weak, global symbols in the same compilation unit in the static libary.

You can find all the symbols in the library with nm -- running
nm libfoo.a | grep ' [BDGRST] \\|:' nm libfoo.a | grep ' [BDGRST] \\|:' will list each object (compilation unit) in the library, followed by all the non-weak global symbols in that object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM