[comp.os.os9] C Linker Library problems -- help!

knudsen@cbnewsd.att.com (michael.j.knudsen) (04/26/91)

Could someone help explain the exact rules by which the OSK C Linker
handles references to functions and global values that occur both
in your program's .r files and also in a library file that you name
with the -L flag?

In theory, if function F exists in your own code and also a library,
it is ignored in the library and your own F is linked.
But it doesn't work that well for me -- I get "multiply defined
symbol" errors.  So I THINK the rules are more like:

(1) If F is defined in both places (yours and library) and F is
entirely self-contained in the library source (it makes no
references to other functions or variables nor does anything else
reference F), then the linker works well.

(2) If F in the library source also is called by another function E
in the library source, then you get an error.
Your own F can't be linked because E is already pre-linked to the
library's version of F.  (This is my theory).

(3) If F in the library calls G in the library, then by (2) you
can't replace G with your own, but you *should* be able to replace F.
Seems that you can't even replace F.

If only (1) and (2) are true, then I should be able to replace an
"incestuous" set of inter-twined fcns and vars if I redefine them
all at once.  If (3) also applies, then we're in big trouble.

Anyone got the facts?  The manual isn't very specific.

PS: The .r file I'm using as a "lib" was not originally intended
as such -- its several functions and global arrays were not MERGEd
together, but just compiled from one source file.
Does that confuse the Linker L68?  THIS may be the real problem!
Note that RDUMP doesn't list its individual functions; maybe
that's why L68 can't pull them apart either.

I lost that one .c source in a crash and am trying to replace its
functions a few at a time, as I decide existing ones in the .r file
are buggy.  So I can't change the .r lib file now.
Any way to split it into a merged lib format?
-- 
"What America needs is A Thousand Points When Lit..."

	knudsen@iceland.att.com

blarson@blars (04/26/91)

In article <1991Apr25.175935.8665@cbnewsd.att.com> knudsen@cbnewsd.att.com (michael.j.knudsen) writes:

>In theory, if function F exists in your own code and also a library,
>it is ignored in the library and your own F is linked.

Nice theory.  Too bad it's wrong.  (Most unix linkers work that way.)
L68 does not allow multiple routines with the same name.  Circularly
refering routines, which other operating systems allow by putting the
same routine in the library multiple times, must be done as a single
source file on OSK.  This is one of the uglier hacks still needed in C
news for OSK.

I'll clarify why that is irrelivent in this case:

>PS: The .r file I'm using as a "lib" was not originally intended
>as such -- its several functions and global arrays were not MERGEd
>together, but just compiled from one source file.

All routines in any one source file are always pulled in as a unit.
Microware even took advantage of this on their 6809 version by having
some routines printf needed only pulled in if there was a reference to
another function in your code.  (The other function did nothing, and
did not have to be called!)

>Does that confuse the Linker L68?  THIS may be the real problem!

Confuse, no, but it won't pull the routines apart.

>(3) If F in the library calls G in the library, then by (2) you
>can't replace G with your own, but you *should* be able to replace F.

It would be nice.  Sugest it as an enhancement to microware.

>Any way to split it into a merged lib format?

Dissassemble or rewrite.


-- 
blarson@usc.edu
		C news and rn for os9/68k!
-- 
Bob Larson (blars)	blarson@usc.edu			usc!blarson
	Hiding differences does not make them go away.
	Accepting differences makes them unimportant.

knudsen@cbnewsd.att.com (michael.j.knudsen) (04/30/91)

In article <196@blars>, blarson@blars writes:

> >In theory, if function F exists in your own code and also a library,
> >it is ignored in the library and your own F is linked.
> Nice theory.  Too bad it's wrong.  (Most unix linkers work that way.)

Not entirely wrong.  I successfully replaced gets() with my own
version on both 6809 and 68K, putting my gets() in a mainline file.

> L68 does not allow multiple routines with the same name.  Circularly
> refering routines, which other operating systems allow by putting the
> same routine in the library multiple times, must be done as a single
> source file on OSK.  This is one of the uglier hacks still needed in C
> news for OSK.

Yes -- according to Tim Koonce/Kientzle, L68 does two passes and
will complain if the same name shows up twice in a lib.

> All routines in any one source file are always pulled in as a unit.
> Confuse, no, but it won't pull the routines apart.

Yep, others have confirmed that this is the problem.  THe bunch of
functions I'm trying to replace was not intended as a lib and so
was not MERGEd up.

> Microware even took advantage of this on their 6809 version by having
> some routines printf needed only pulled in if there was a reference to
> another function in your code.  (The other function did nothing, and

Yeah, pflinit() and pffinit().
Another smart thing I discovered -- if your mainline declares some
data array as extern but never actually refers to it in executable
code, AND you have that array in another mainline file, the linker
just leaves it out!  I found this out when I added a nonsense array
just to pad the data size out to a certain value.

> It would be nice.  Sugest it as an enhancement to microware.

I guess for 68K this is not necessarily a joke, as it has been for
years with 6809.  Hope M'ware doesn't abandon OSK for OS-9000 for a
few more years...  James?

> >Any way to split it into a merged lib format?
> Dissassemble or rewrite.

Will rewrite ultimately (source was lost in a crash).  Meanwhile
someone suggested going into the .r file with a binary editor and
changing the names of any functions I wanted to replace
incrementally.  What a hack, but maybe worth it.
-- 
"What America needs is A Thousand Points When Lit..."

	knudsen@iceland.att.com

jclark@sdcc6.ucsd.edu (John Clark) (04/30/91)

In article <196@blars> blarson@usc.edu writes:
+
+Nice theory.  Too bad it's wrong.  (Most unix linkers work that way.)
+L68 does not allow multiple routines with the same name.  Circularly
+refering routines, which other operating systems allow by putting the
+same routine in the library multiple times, must be done as a single
+source file on OSK.  This is one of the uglier hacks still needed in C

You can put multiple occurances of the same library names in your link
command. You can repeat this until you 'undef' problems stop, or you give
up.

I once thought of writing an 'lorder' 'tsort' pair which would do
what most un*x library builds do, i.e. include multiple instances of
files which have circular dependencies. The other solutions are an
N-pass linker or a .SYM table tacked on the front of a 'merged'
library. The N-pass has the 'advantage' of lower memory usage,
whereas the table requires some amount of storage for the table, or
some cache management routines to efficiently use the table on disk.

At one time I did find a 'lorder' on CompuServe but it was for
os9-6809. I looked into the rel file format but that was the end of
it. Another alternative is to write a new linker, but isn't that
what you buy operationing systems for? I wrote one once, but why do
it again!

-- 

John Clark
jclark@ucsd.edu

jclark@sdcc6.ucsd.edu (John Clark) (04/30/91)

In article <1991Apr29.223454.5112@cbnewsd.att.com> knudsen@cbnewsd.att.com (michael.j.knudsen) writes:
+
+> All routines in any one source file are always pulled in as a unit.
+> Confuse, no, but it won't pull the routines apart.
+
+Yep, others have confirmed that this is the problem.  THe bunch of
+functions I'm trying to replace was not intended as a lib and so
+was not MERGEd up.

The 'pulling' out of individual functions was possible in assmebly
files which had individual '.psect's for each function. I have never
used the psect feature of r68?(other than the absolute minimum) so
I can't comment on L68's behavior. But in other systems, one could get
the 'as needed function' extraction behavior mentioned above. As for
a C module with the 'same' feature, is there a compiler directive to
allow each function put into a unique psect. But then what about variables
used by that function. There are a number of complexities which the
'as needed extraction' implies. May be it's better for the
'programmer' to simplify the situation by coding one function per
source file. That has been my policy(where ever possible) for some
time. The main problem is the number of modules. But with 'make' and
appropriate makefiles the problem is managable.
-- 

John Clark
jclark@ucsd.edu

blarson@blars (04/30/91)

In article <18814@sdcc6.ucsd.edu> jclark@sdcc6.ucsd.edu (John Clark) writes:
>May be it's better for the
>'programmer' to simplify the situation by coding one function per
>source file. That has been my policy(where ever possible) for some
>time. The main problem is the number of modules. But with 'make' and
>appropriate makefiles the problem is managable.

If only OSK make worked reliably.  It works most of the time on simple
makefiles and fails strangly when the number of routines linked gets
large, the number of rules get large, the number of dependencies of a
rule gets large, the size of a rule gets large, or anything else
exceeds some apperently rediculously small internal buffer size which
has no error checking to see if the buffer overflows.  About the only
thing that does complain about a length exceeded is command line
length, which is also way to small for complicated makefiles....
(The usual symptom is to just start ignoring rules, changing
dependencies, and things like that rather than direct error messages.)

I'm still using damage control procedues from my experences with OSK
2.2, so some of these bugs may be fixed later.  (2.4 isn't yet
available for my machine -- I'm on the waiting list.)

The "usual workaround" is to request each file on the make request
rather than depending on the rules to find out the module is needed.
Instead of "make foobar" use "make foobar.r barfoo.r flowbuz.r blop.r
kerblooie.r gagchoak.r foobar".  I've got a lot of little shell files
named "maker" in various directories with commands like this.

-- 
blarson@usc.edu
		C news and rn for os9/68k!
-- 
Bob Larson (blars)	blarson@usc.edu			usc!blarson
	Hiding differences does not make them go away.
	Accepting differences makes them unimportant.

knudsen@cbnewsd.att.com (michael.j.knudsen) (04/30/91)

In article <198@blars>, blarson@blars writes:
> If only OSK make worked reliably.  It works most of the time on simple

Uh-oh.  Well, now I don't feel so bad about some strange things
that have happened, even on OSK 2.4 on the MM/1 68070 box.

First, to avoid really long L68 command line, I merge groups of .r
files into three files a.m, b.m, and c.m.
My final product "depends" on those three, and each .m fiole
depends on its set of .r files.
Well, make only makes the first .m file in the product dependency
list.  The manual even warns about this (without being at all
apologetic about such a shortcoming).  So I have a shell script
named "makem" which does "make a.m" etc., and finally links them
all.

You can't call these intermediate files "a.r" or else Make
instantly compalins it can't find a.c to make a.r -- even tho I
explicitly give the rule to make a.r right under the dependency
line.  What ever happened to the classic notion that explicit rules
overrode the defaults?

Sometimes I get strange errors from MERGE like "Can't open file blah.r"
which probably means a blank or linefeed got into the file name.

Worst of all, and in line with Bob Larson's comments, I put some
code in one source file (out of two dozen) to fix something.  No
effect, but no harm either so I left that code in.  Two days later,
after working on some totally unrelated stuff in the same product,
the fix suddenly started working!  As if the first few Makes didn't
"take" on that source file!  Must I "touch *.c" before Make just to
be sure, and bring a good SciFi novel (like the manual)?

Tim (Koonce) Kientzle has a really nice PD Make for 6809 that I've
used for some time, and it's been suggested to port it to OSK and
just bypass Microware's job.  But so far my experience with porting
6809 C code is that you get lots of voodoo errors in 68K, so not a
project to be undertaken lightly.

> rule gets large, the size of a rule gets large, or anything else
> exceeds some apparently rediculously small internal buffer size which
> has no error checking to see if the buffer overflows.

Really bugs me that there's so much room in OSK, but the Make is
written with small arrays and tables that overflow silently.
Maybe its writers knew better than to trust their own malloc() and
realloc(), or were just in a hurry?

>  About the only
> thing that does complain about a length exceeded is command line
> length, which is also way too small for complicated makefiles....

That's a relief -- at least I could try L68 on the whole s-load
of .r files and skip the intermediate merges, and hear about it if
it gets too long.

> I'm still using damage control procedues from my experences with OSK
> 2.2, so some of these bugs may be fixed later.  (2.4 isn't yet
> available for my machine -- I'm on the waiting list.)

From my experience you have nothing to wait for (see above).
I suspect all the M'ware programmers are on OS-9000, which after all
runs on a REAL microprocessor (walkie-talkie company's chips don't
count out there in the Real World :-(
I hope someone at Microware can confirm that OSK bugs are still
being fixed, tho.  Pardon my flame but as a Coco 6809 survivor I can
sympathize with the Kurds, and smell "abandonment" a mile away.

> Instead of "make foobar" use "make foobar.r barfoo.r flowbuz.r blop.r
> kerblooie.r gagchoak.r foobar".  I've got a lot of little shell files

Can you trust make to at least do every argument on that command line?
I thought I tried and it only made the first one...mike k
-- 
"What America needs is A Thousand Points When Lit..."

	knudsen@iceland.att.com

bill@mwca.UUCP (Bill Sheppard) (04/30/91)

In article <1991Apr29.223454.5112@cbnewsd.att.com> knudsen@cbnewsd.att.com (michael.j.knudsen) writes:
>...Hope M'ware doesn't abandon OSK for OS-9000 for a few more years...

>	knudsen@iceland.att.com

Don't worry, we have no plans to abandon OS-9 for OS-9000; they are
complementary products.  With the nine largest consumer electronics
companies in the world gearing up to produce OS-9 based CD-I players, we
are about to see an exponential increase in the number of OS-9 based platforms
worldwide.  (Of course, it may take awhile for people to figure out they've
got a powerful multi-user multi-tasking computer sitting on their stereo
shelf!!)
-- 
 ##############################################################################
 # Bill Sheppard  --  bills@microware.com  --  {uunet,sun}!mcrware!mwca!bill  #
 # Microware Systems Corporation  ---  OS-9: Seven generations beyond OS/2!!  #
 ######Opinions expressed are my own, though you'd be wise to adopt them!######

jejones@mcrware.UUCP (James Jones) (05/01/91)

In article <1991Apr30.154454.27728@cbnewsd.att.com> knudsen@cbnewsd.att.com (michael.j.knudsen) writes:
>I suspect all the M'ware programmers are on OS-9000, which after all
>runs on a REAL microprocessor (walkie-talkie company's chips don't
>count out there in the Real World :-(

I'm not sure where you get your suspicions from.  It seems to me that it
would be less than optimal to not keep working on an OS that will be on
all those CD-I players, and considering the OS-9 stuff whose current or
eventual release is mentioned in the latest *Pipelines*, it would be hard
to believe that nobody's working on OS-9.  (Besides, OS-9000 runs on things
other than descendants of the 4004. :-)

	James Jones

(My opinions are mine; that is to say, they belong to me.  This disclaimer,
though, is adapted from the lines of Anne Elk (Miss).)

blarson@blars (05/05/91)

In article <1991Apr30.154454.27728@cbnewsd.att.com> knudsen@cbnewsd.att.com (michael.j.knudsen) writes:
>In article <198@blars>, blarson@blars writes:
>> If only OSK make worked reliably.  It works most of the time on simple
...
>"take" on that source file!  Must I "touch *.c" before Make just to
>be sure, and bring a good SciFi novel (like the manual)?

From my experience, it wouldn't do you the slightest bit of good.
Neither would "del *.r".  The problem is forgotten dependencies --
make didn't think that .r file was needed even though you told it it
was.  (at least with the del *.r attempt l68 complains about a file
not found instead of using an obsolete version.)  The other problem is
forgetting a complete rule and using the default version.  There is an
option to turn off defaut rules, but then you get to specify everything...

The error for "macro not found" is quite rediculous as well, giving no
hint at what the problem is or where it the file...


>> Instead of "make foobar" use "make foobar.r barfoo.r flowbuz.r blop.r
>> kerblooie.r gagchoak.r foobar".  I've got a lot of little shell files
>Can you trust make to at least do every argument on that command line?

It works for me.



-- 
blarson@usc.edu
		C news and rn for os9/68k!
-- 
Bob Larson (blars)	blarson@usc.edu			usc!blarson
	Hiding differences does not make them go away.
	Accepting differences makes them unimportant.