X

News, tips, partners, and perspectives for the Oracle Solaris operating system

'_init'/'_fini' not found - use the compiler drivers

A recently added error check within ld(1) has uncovered the following condition.

ld: warning: symbol `_init' not found, but .init section exists - \\
       possible link-edit without using the compiler driver
ld: warning: symbol `_fini' not found, but .fini section exists - \\
    possible link-edit without using the compiler driver

The encapsulation, and execution of .init and .fini sections is a combination of user definitions and compiler driver files.

Users typically create these sections using a pragma. For example, the following code produces a .init and .fini section.

% cat foobar.c
    static int foobar = 0;
    #pragma init (foo)
    void foo()
    {
            foobar = 1;
    }
    #pragma fini (bar)
    void bar()
    {
            foobar = 0;
    }

The functions themselves are placed in a .text section, and a call to foo() is placed in a .init section, and a call to bar() is placed in a .fini section. So, how do these functions get called in the runtime environment?

This is where the compiler drivers come in. As part of creating a dynamic object, the compiler drivers provide input files that encapsulate the .init and .fini calls. This encapsulation effectively creates two functions that are labeled _init and _fini respectively.

  _init {          # provided by .init in crti.o
      call foo()   # provided by .init in foobar.c
  }                # provided by .init in crtn.o

  _fini {          # provided by .fini in crti.o
      call bar()   # provided by .fini in foobar.c
  }                # provided by .fini in crtn.o

It is the symbols _init and _fini that are recognized by ld() and are registered within the object so that the two addresses are called at runtime.

Some folks are using ld() directly to build their shared objects, and thus the encapsulating crt files aren't being included within the link-edit. The result is that even though .init and .fini sections may exist, no _init and _fini encapsulation occurs, and no symbols are registered with the object for runtime execution.

This leaves the developer wondering why their .init and .fini code is never executed, and is the rational behind us adding the warning message.

It's best not to use ld() directly to build any executables or shared objects, let the compiler drivers do it for you.

Join the discussion

Comments ( 2 )
  • UX-admin Wednesday, December 20, 2006
    What about assembler (.S) files? I'm writing about cranking out straight assembler code directly in a text editor, no C or any high level language involved. How am I supposed to produce an executable out of those?
  • Rod Evans Wednesday, December 20, 2006

    I'm not sure I understand your question.

    The point of this posting was to show how the code
    produced by the compilation system for such things
    as .init sections, it tied to an
    encapsulation model provided with files that the
    compiler drivers deliver.

    Regardless of these special sections, you still
    need a special crt file to provide the standard
    calling sequence to main(argc, argv).

    It is safest to use a compiler driver to generate
    a final dynamic object.

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
Oracle

Integrated Cloud Applications & Platform Services