From: Jean-Pierre Radley <jpr@jpr.com> Subject: Re: gcc on 5.0.7 Date: 15 Jul 2003 10:28:00 -0400 Jean-Pierre Radley wrote: > Kean, this is from the newsgroup. Sum it up for Roger, would you please? > > Roger Cornelius typed (on Mon, Jul 14, 2003 at 02:38:15PM -0700): > | Ever since installing Openserver 5.0.7, I am unable to use gcc 3.2.1. > | It returns an Undefined symbol _fini error for any compilation > | attempt. > | > | I tried installing the Gnu Development Tools from the OS installation > | CD and that gcc works so far as I've tested, but it's unable to > | build/bootstrap gcc 3.3 and fails at some point with the _fini error. > | > | Using the SCO provided cc to build gcc, make fails with an "undefined > | symbol: DEFAULT_PCC_STRUCT_RETURN" error in i386.c for 3.2.2, and > | configure fails with an "cannot determine size for long long" error > | for gcc 3.3. > | > | I've watched the c.u.s.* and gcc newsgroups and checked the gcc web > | site but have not found any answers or significant discussion. Am I > | missing something? Jean-Pierre,
Can you mirror this reply to the newgroup so that others that watch it can learn about this too? Roger, heres the scoop. When you create an executable with a compiler, you not only link in your objects and libraries, but behind the scenes, the compiler driver (gcc, cc, whatevercc) will prepend special system object files, and append other special ones. For C programs, these are known as the CRT (C run-time) files. These typically do things like set up the float point environment, set up any profiling counters and calls, call any global initialization code and then finally call main(). When the program terminates via any mechanism that uses exit(), then some special code that is appended by the CRT files does global destruction and other cleanups, calculates profiling totals, and then actually exits. In ELF objects, code and data are put into special named "sections". These are controlled by the ".section" assembler directive, and its abbreviations like ".text" which is basically ".section .text" and ".data" which is essentially ".section .data". Code goes into the section called .text, and data goes into the sections .data, .rodata or .bss, depending on how the data is declared. There are several sections which are very special to ELF. For your actual problem as experienced, these are the .init section and the .fini section. These are designed to have initialization and finalization code, respectively. When you link edit an ELF program, the ELF ABI states that all code in a .init section is executed before main() and that call code in a .fini section is executed before exiting. This is how C++ global constructors and destructors are implemented. Although you are not experiencing problems with this yet, I want to document this for the sake of completion, since this message will hopefully make its way to the newsgroup and other people may or may not be experiencing other problems. Modern ELF extended the notion of the .init and .fini sections with three special sections: .preinit_array, .init_array and .fini_array. These arrays store pointers to functions, not arbitrary code as .init and .fini do. The gABI specifies that each entry in the .preinit_array section is executed before the program entry point. This means it gets executed before the CRT stuff gets invoked, which means it gets executed before any code in the .init section. Likewise, the functions in .init_array are also called before the entry point. Shared libraries have .init_array called every time they are loaded. The system also sets things up such that functions in .fini_array are called when a shared library is unloaded and before functions in the .fini section when the program exits normally. So thats what the code needs to do. Here is why you were having a problem. Typically, the CRT is divided into three files. crt1.o, crti.o and crtn.o. crt1.o contains the actual C startup stuff, and work some magic to interact with teh run-time link editor (RTLD). crti.o contails a single function, called _init, that is inserted at the very beginning of the .init section. The same applies to a function called _fini and starts the .fini section. These function do nothing, they are empty. crtn.o, which is one of the last objects link edited into the program or shared library, terminates the .init and .fini sections with a simple return instruction. Thus, when you link edit a program, you get the deifintion of the _init function, then the code from all of your program objects, in order, with their .init and .fini sections, then the termination from crtn.o. This results in a single contiguous function such that when _init is called, all code from all .init sections is executed linearly in object order, and all code from all .fini sections is executed in object order.
When you link edit a program, you use all three startup files: crt1.o, crti.o yourobjects.o libraries.so crtn.o. When you link edit a shared library, you typically omit crt1.o, as the code in it has no meaning to a shared library. There is no need to set up calls to main or reset the floating point environment or set up profiling counters. In fact, doing so can completely screw your program up. Consider, for example, if you had carefully set up your floating point environment to be in IEEE mode, and the code in crt1.o sets it to some other mode. Or consider the fact that profiling counters may get reset erroneously. All the shared libraries need is the stuff in crti.o and crtn.o, to start and finish the .init and .fini sections (and correspondingly the _init and _fini functions for that shared libary). In releases prior to 5.0.7, OpenServer did not have a crti.o. It had the _init stub in crt1.o. This caused untold grief, especially when we started using G++ to create shared libraries. So, starting in release 5.0.7, I split out the stub stuff from crt1.o and put it in crti.o where it always should have been. The native compiler driver (cc) was changed to link with crti.o and so was the officially supported version of GCC (2.95.3). At the time that I made this change, there was no mor work being done on the 2.95 branch of GCC, they were in the middle of doing GCC 3.2. We didnt fully trust the GCC 3 branch yet which is why we never did any work on it to update it to use crti. However, things are now to the point where we will be adopting GCC 3 as the officially supported version of GCC. This will happen for release 5.0.8 of SCO OpenServer. To that end, I did all the required work to get this stuff working in GCC 3. At the time that I did the work, they were at the tail end of getting ready to release 3.3, and the GCC Steering Committee decided that these changes were not appropriate for that release. Thus, these changes were put in at the head of the tree, and are in (or will be in, when it is releaed) GCC 3.4. If you really want a GCC 3.x release, you need to check out the head of the tree to get this stuff. I was intending to backport the changes to 3.3.1 but I have not had the time. If there is ever a 3.3.2, it may go into that but I suspect that the steering committee will veto that notion. For for GCC 3.x, the first version that will be known to work propperly on OSR5 is 3.4. If you are feeling brave, when 3.3.1 is released in a few days/weeks, you can get the stuff from the head from CVS, look at the changelogs for what I had to do for OSR5 and back-port it. I may do that myself if I have the time, and then get Boyd Lynn-Gerber to post the required patch on his website where he collects such things. In two short weeks we will be releasing a significan update to the GNU Development Tools package, which provides the current officially supported GCC and a plethora of other GNU tools that software developers frequently use. This will rely on Support Level Supplement OSS646B, which is the execution environment update. This update fixes the RTLD, libc and crt*.o files such that they meet the gABI requirements, as outlined above. As far as I am concerned every OpenServer system from 5.0.4 on upwards should install OSS646B, but some administrators are loathsome to install such big changes and thats a whole other issue. Hope this helps. Kean
Have you tried Searching this site?
Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more. We appreciate comments and article submissions.
Many of the products and books I review are things I purchased for my own use. Some were given to me specifically for the purpose of reviewing them. I resell or can earn commissions from the sale of some of these items. Links within these pages may be affiliate links that pay me for referring you to them. That's mostly insignificant amounts of money; whenever it is not I have made my relationship plain. I also may own stock in companies mentioned here. If you have any question, please do feel free to contact me.
Specific links that take you to pages that allow you to purchase the item I reviewed are very likely to pay me a commission. Many of the books I review were given to me by the publishers specifically for the purpose of writing a review. These gifts and referral fees do not affect my opinions; I often give bad reviews anyway.
We use Google third-party advertising companies to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, click here.
Click here to add your comments
Thu Oct 6 17:04:56 2005: anonymous
-lcurses does the job
Don't miss responses! Subscribe to Comments by RSS or by Email
Click here to add your comments
If you want a picture to show with your comment, go get a Gravatar