Re: Help- selective symbol exposure after link

kaz@nt.com
25 Jan 1997 21:52:42 -0500

          From comp.compilers

Related articles
Help- selective symbol exposure after link jason@interval.net (Jason Spielman) (1997-01-22)
Re: Help- selective symbol exposure after link kaz@nt.com (1997-01-25)
Re: Help- selective symbol exposure after link maslen@best.com (Thomas M. Maslen) (1997-01-25)
Re: Help- selective symbol exposure after link mac@coos.dartmouth.edu (1997-01-25)
Re: Help- selective symbol exposure after link dlmoore@ix.netcom.com (David L Moore) (1997-01-26)
Re: Help- selective symbol exposure after link whsieh@cs.washington.edu (1997-01-29)
Re: Help- selective symbol exposure after link maslen@best.com (Thomas M. Maslen) (1997-01-29)
Re: Help- selective symbol exposure after link aeb@saltfarm.bt.co.uk (1997-01-29)
[11 later articles]
| List of all articles for this month |

From: kaz@nt.com
Newsgroups: comp.compilers,comp.lang.c
Date: 25 Jan 1997 21:52:42 -0500
Organization: Prism Systems Inc.
References: 97-01-183
Keywords: linker, comment

Jason Spielman <jason@interval.net> wrote:
>Q: How does one link several object files into a single object file
> or library, where symbols are resolved locally as much as possible,
> and where only selected symbols are exported/exposed/made public?


The standard C language method is to use the storage class ``static''
for file-scope objects. This designation marks them as private to the
translation unit---that is, invisible to the outside.


>Here is an example:
>File b.c contains a function named b1() which does something simple.
>File a.c contains a function named a1() which calls b1();
>File main.c include main() which calls a1().


All these functions must have external linkage, unfortunately.


>I'd like to create an object (or library) ab.o, composed of
>a.o and b.o, which only exposes a1(). With this ab.o, I then


This is not possible in the standard C language. An object is either
visible to the whole project or its private to a single translation
unit. A practical implication of this is that the way you break down
your project into translation units _matters_. In this case, you would
want to combine a.c with b.c.


>should be able to compile main.c and create an executable.
>I tried an incremental link followed by a strip (tried various
>combinations) but nothing seems to work. Below are listed the
>files and the errors I got during my efforts:




>PS. it's on a linux-2.0.18 platform; however I've tried it on various
> other platforms, including sunos-4.1.3, dec-alpha-osf1-v3.2, and
> can't get it to work anywhere


That's a good sign that it's probably not supposed to work, right?


>PPS. I am a strong advocate of declaring functions static or external
> but re-organizing the code to use that mechanism is an unrealistic
> option.


Looks like you need a different programming language, because in C you would
have to design your program as above.


The underlying assembly language and object code tools on the
platforms that you mentioned all work the way C does: a symbol in
object file is either private to that unit or it's global, even if you
program in assembly language. A high level language would have to
pull some dirty tricks with symbol names to do what you are asking
for.


>BFD: sta31925: symbol `b1' required but not present


You can try using function pointers. You can make the function b1
private to a translation unit, but if you have a pointer to the
function b1, you can use it from anywhere in the program. So, inside
b1, you can provide a globally visible method for extracting a pointer
to b1. This could be in the form of a data structure which stores the
pointer, or in the form of another function which returns a pointer to
b1:


file b1.h:


struct b_stuff {
int (* b1)(void);
int (* b2)(void);
int (* b3)(void);
int (* b4)(void);
};


extern struct b_stuff b_func;


file b1.c:


static int b1(void) { /* ... */ }
static int b2(void) { /* ... */ }
static int b3(void) { /* ... */ }
static int b4(void) { /* ... */ }


struct b_stuff b_func = { b1, b2, b3, b4 };




here, the only symbol you have exported from translation unit b.c is
``b_func''. Through this one symbol you can access four private
functions as b_func.b1() and so forth. Hence the potential for name
clashes is vastly reduced.


As a last resort, you could simply duplicate function b1 so that it is both
in a.c and in b.c (marked static in both, of course, to avoid a clash). For
convenience, you could put this static declaration into an include file.
[Uh, we know standard C doesn't permit this, but you may be confusing cause
and effect. The C89 committee carefully avoided putting anything into the
standard that you couldn't do with the lousiest linker in common use. We'd
like to see something better than the lousiest linker. -John]
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.