Problems with sprintf and libgcc.a

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hi everyone,

im using "toolchain
-bu-2.15_gcc-3.4.3-c-c++-java_nl-1.12.0_gi-6.1.tar.bz2" to compile a
simple program for an ARM920T based microcontroller (AT91RM9200). The
development system is running Fedora Core 3.

i have not been able to use the "sprintf" function..the program does
not compile if i do so. here are the details of my problem:


************************************************************

code snippet of my main.c program (where im calling sprintf):

==============================
#include<stdio.h>
.
sprintf( buf, "This is a test %d one and %d two", 420, 840 );
.==============================

This is the error i get:

==============================
.
arm-elf-gcc -c -Os -DAT91RM9200 -mlittle-endian -mapcs-32 -mcpu=arm920t
-fno-inline -o "init.o"  "init.c"
arm-elf-gcc -c -Os -DAT91RM9200 -mlittle-endian -mapcs-32 -mcpu=arm920t
-fno-inline -o "main.o"  "main.c"
arm-elf-ld  -L --cref -Map BasicBoot.map -EL -T./ld_mk.script -o
"./Mayank/Output/BasicBootDebug.elf" cstartup.o init.o main.o
init.o(.text+0x100): In function `AT91F_US_Baudrate':
: undefined reference to `__udivsi3'
init.o(.text+0x10c): In function `AT91F_US_Baudrate':
: undefined reference to `__umodsi3'
init.o(.text+0x120): In function `AT91F_US_Baudrate':
: undefined reference to `__udivsi3'
init.o(.text+0x134): In function `AT91F_US_Baudrate':
: undefined reference to `__udivsi3'
init.o(.text+0x26c): In function `AT91F_CheckPLL_FrequencyRange':
: undefined reference to `__divsi3'
main.o(.text+0x60): In function `main':
: undefined reference to `sprintf'
make: *** [Mayank/Output/BasicBootDebug.elf] Error 1
==============================

I had searched the net and found that undefined references to
`__divsi3` and `__umodsi3' are caused because of problems or version
mismatches related to libgcc.a . Heres my linker script:

==============================
GROUP("/home/guest/mayank_arm/gnuarm-3.4.3/arm-elf/lib/libc.a"
"/home/guest/mayank_arm/gnuarm-3.4.3/lib/gcc/arm-elf/3.4.3/libgcc.a")

MEMORY
{
    ram : ORIGIN = 0x200000, LENGTH = 0x3000 /*12kb*/
}

SECTIONS
{

    .text : {
            __stext_start = . ;    /*Start of the text section*/
            *(.text)
            *(.rodata.*)
            . = ALIGN(4);
            __stext_end = . ;    /*End of the text section*/
        } > ram


    .data : {

            __sdata_start = . ;    /*Start of the data section*/
            *(.data)
            *(.glue_7*)
            *(.stack)
            *(.*)
            . = ALIGN(4);
            __sdata_end = . ;    /*End of the data section*/
        } > ram

    .bss  : {
            __sbss_start = . ;    /*Start of the bss section*/
            *(.bss)
            . = ALIGN(4);
            __sbss_end = . ;    /*End of the bss section*/
        } > ram
}
==============================

This is how the liker is being called in my Makefile:

==============================
LINK=arm-elf-ld  -L --cref -Map BasicBoot.map -EL -T./ld_mk.script -o
"$(OUTDIR)/$(OUTFILE)" $(OBJ)
==============================

*******************************************************
(I have checked these archives im using, by issuing the command "nm -sC
libc.a|grep sprintf" and libgcc.a for __umodsi3, they were shown to be
present inside their respective files.)

I tried another approach: i commented out the GROUP() in the linker
script, changed the linker invocation in the Makefile to this:

==============================
CFG_LIB2='/home/guest/mayank_arm/gnuarm-3.4.3/arm-elf/lib/libc.a'
CFG_LIB1='/home/guest/mayank_arm/gnuarm-3.4.3/lib/gcc/arm-elf/3.4.3/libgcc.a'

LINK=arm-elf-ld  --cref -Map BasicBoot.map -EL -T./ld_mk.script -o
"$(OUTDIR)/$(OUTFILE)" $(OBJ) --start-group $(CFG_LIB2) $(CFG_LIB1)
--end-group
==============================


These are the errors i get:
==============================
arm-elf-gcc -c -Os -DAT91RM9200 -mlittle-endian -mapcs-32 -mcpu=arm920t
-fno-inline -o "init.o"  "init.c"
arm-elf-gcc -c -Os -DAT91RM9200 -mlittle-endian -mapcs-32 -mcpu=arm920t
-fno-inline -o "main.o"  "main.c"
arm-elf-ld  --cref -Map BasicBoot.map -EL -T./ld_mk.script -o
"./Mayank/Output/BasicBootDebug.elf" cstartup.o init.o main.o
--start-group '/home/guest/mayank_arm/gnuarm-3.4.3/arm-elf/lib/libc.a'
'/home/guest/mayank_arm/gnuarm-3.4.3/lib/gcc/arm-elf/3.4.3/libgcc.a'
--end-group
arm-elf-ld: region ram is full (./Mayank/Output/BasicBootDebug.elf
section .text)
arm-elf-ld: region ram is full (./Mayank/Output/BasicBootDebug.elf
section .data)
arm-elf-ld: section .data [00200000 -> 00221fd7] overlaps section .text
[00200000 -> 002084a3]
arm-elf-ld: section .bss [00200000 -> 00200003] overlaps section .text
[00200000 -> 002084a3]
/home/guest/mayank_arm/gnuarm-3.4.3/arm-elf/lib/libc.a(syscalls.o)(.text+0x69c):
In function `_sbrk':
../../../../../../newlib-1.12.0/newlib/libc/sys/arm/syscalls.c:508:
undefined reference to `end'
make: *** [Mayank/Output/BasicBootDebug.elf] Error 1
==============================

Please note that this particular program had originally been built for
Arm Developer Suite 1.2, and the size of the compiled code was 5k only.
I have made the requisite changes for it to work with GNU tools.

Where am i going wrong ?!

Thanx in anticipation,
Mayank


Re: Problems with sprintf and libgcc.a

Quoted text here. Click to load it

Generaly speaking, it's rarely a good idea to invoke 'ld' yourself
when linking C or C++ programs.  Have 'gcc' invoke it for you instead.
Unless the GCC port is buggy, it'll know how to invoke ld correctly.
In particular, it'll put in all necessary references -lgcc, -lc and
the startup file(s) for you.

Your description shows that the GROUP() thing you put into the linker
script didn't have any effect at all.

The problems with memory space overlaps and such suggest that your
linker script is probably not correct, or at least not compatible with
the GCC output you use it on.

--
Hans-Bernhard Broeker ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Re: Problems with sprintf and libgcc.a
Quoted text here. Click to load it

I've rarely found that to be true when working in an embedded
environment.  I've always had to use a custom linker script and
disable most of the default startup file linkage.

Quoted text here. Click to load it

How does gcc know what startup files to use for my hardware
platform?  Likewise, I don't want gcc linking in a "libc" file
behind my back.  I don't really even like it pulling a libgcc
file out of it's hat either.

Quoted text here. Click to load it

--
Grant Edwards                   grante             Yow!  My CODE of ETHICS
                                  at               is vacationing at famed
We've slightly trimmed the long signature. Click to see the full one.
Re: Problems with sprintf and libgcc.a

Quoted text here. Click to load it


I did write "generally speaking" for a reason.  This may indeed not as
strictly true in embedded work as it is for hosted-environment GCCs,
but it's still worth to be kept in mind.

The rationale behind letting GCC invoke ld is that this is how GCC is
supposed to work --- it makes certain assumptions about the target
platform, and some of those are reflected in pieces of the ld
invocation composed by the "compiler driver program", gcc, including
things like specs file, linker script, startup files, libgcc.a and
libc.  Not letting GCC do this effectively means you're fighting your
tools, instead of configuring them correctly.

Quoted text here. Click to load it

That's nothing a little hack of the 'specs' file couldn't fix.

Quoted text here. Click to load it

It was supposed to be informed about these as part of the job of
porting GCC to that hardware platform.  If that job was never properly
completed, you'll have to do keep telling it on each invocation.

--
Hans-Bernhard Broeker ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Re: Problems with sprintf and libgcc.a
aachen.de says...
Quoted text here. Click to load it

Maybe you work a lot differently than I do, but I don't want to build a
different version of GCC for every variant of a core that I program.

Just let me provide those and let the compiler produce the object code
from the source.  That seems a fair and equitable division of
responsibilities to me :)

Robert

Re: Problems with sprintf and libgcc.a

Quoted text here. Click to load it

I have found it handy command line options to ask gcc
what library files it thinks it should use for libgcc, libc,
libm, etc.  That allows one to manually link in files that are
automatically selected by gcc based on architecture options.

Quoted text here. Click to load it

I've never been brave enough to hack on a specs file.  That's
proably the right way to do it, but it assumes that a given
port of the compiler will only be used for a single project on
a single hardware platform.  I'm often using the same compiler
for multiple projects that have different linkage requirements.

Quoted text here. Click to load it

If I had to port GCC to each hardware platform I'd never get
anything done.  I use a single arm-elf-gcc port for a
half-dozen different target platofrms.

Quoted text here. Click to load it

Yup, that's what makefiles are for.

--
Grant Edwards                   grante             Yow!  This is PLEASANT!
                                  at              
We've slightly trimmed the long signature. Click to see the full one.
Re: Problems with sprintf and libgcc.a

Quoted text here. Click to load it


It won't give you all the machinery behind what it'll output in a
given case, though (most of which is encoded in the specs file).
E.g. looking at what "gcc -v -O2 -g3 -Wall foo.c" does won't tell you
much of anything about what it might do for "gcc -v -O0 bar.cpp".

Quoted text here. Click to load it


If you're brave enough to hack linker scripts, you can brave spec
files, too.  It's no more difficult to read and fiddle with a specs
file than it'd be to second-guess what gcc would do for a given
command line you've never used before.  Nowadays, the syntax of spec
files format is even documented properly.

The specs file is (among other things) GCC's way of encoding the
dependencies between compile-time flags and linker invocations.

Quoted text here. Click to load it

No.  It only assumes that you're prepared to pass gcc a suitable specs
file for each of them.  You don't even have to write a complete specs
file of your own --- you can override only those parts that need
changing, and you can start with the existing specs file of the GCC
you're using (or a --dumpspecs, if it's using the integrated one).

Quoted text here. Click to load it


I don't think it's significantly harder to do the port than to
experiment with your general-purpose GCC until it fits the new
platform.  It involves nothing more than to formalize the knowledge
you have about that platform a little more strictly.  It's an exercise
in putting information in one place (the GCC target specification)
rather than repeating it in the Makefile of every piece of software
you'll ever write to run on that particular target.

--
Hans-Bernhard Broeker ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Re: Problems with sprintf and libgcc.a
aachen.de says...
Quoted text here. Click to load it

It is?  That's good news, where?  Documentation is GNUs greatest
weakness.

I didn't find GCCs linker scripts particularly difficult other than a
marked absence of information on what sections the compiler will produce.  
They are certainly nor more difficult than any other linker script I've
worked with.  And at some point they are needed in order to deal with
application specific memory maps, such as forcing particular information
to a particular location.

Quoted text here. Click to load it

Experiment???

All I do is call GCC to compile and then call ld to link in the
appropriate startup and libraries with the compiled source and memory
map. Why would that involve any experimentation?

Quoted text here. Click to load it

Since the repeat at most involves an include of the appropriate
definitions (not even a cut and paste), I don't see that as particularly
burdensome.  And the information is only in one place, the included file.

Robert

Re: Problems with sprintf and libgcc.a
Quoted text here. Click to load it

[...]
Quoted text here. Click to load it


    info gcc "Invoking GCC" "Spec Files"

(of GCC-3.4.1), or in the equivalent space of whatever format of the
docs you're looking at.

--
Hans-Bernhard Broeker ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Re: Problems with sprintf and libgcc.a
aachen.de says...
Quoted text here. Click to load it

Hmm, all that gets me are some errors and in particular

Unable to find node referenced by `Spec Files' in `(gcc.info.gz)Invoking GCC'.

I did find

http://www.cse.ohio-state.edu/cgi-bin/info/info/gcc,Spec%20Files

which I will take a look at.

Robert

Re: Problems with sprintf and libgcc.a
Quoted text here. Click to load it
... snip ...
Quoted text here. Click to load it

Sounds as if you haven't got the info system properly installed.
"Info" by itself should bring up a master menu and an optional
tutorial.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on
We've slightly trimmed the long signature. Click to see the full one.
Re: Problems with sprintf and libgcc.a
Quoted text here. Click to load it

Seems likely, although it's a straightforward cygwin install.

I just did a little more exploration and it seems that some of the nodes
are missing and that's one of them.  Odd, I'll have to fix that.  In any
case the web link seems to be the same source.

Robert

Re: Problems with sprintf and libgcc.a
Quoted text here. Click to load it



Come, now, you sure know that "some errors" is no way to report a
problem...

Quoted text here. Click to load it

That means you have info installed, and a gcc info file installed in a
place where info finds it --- but it's not the one for a recent GCC.
There's a reasion I mentioned the version number being referred to,
see?

--
Hans-Bernhard Broeker ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Re: Problems with sprintf and libgcc.a
aachen.de says...
Quoted text here. Click to load it

You're right, I was brushing quickly past it since they weren't visible
long enough to decipher.  Which just left the following which yo kindly
deciphered.

Quoted text here. Click to load it

Ahh, I'll have to update, although as a documentation medium info doesn't
shine.  In any case the web link I found does seem to be what you were
referring to.  It'll do for my initial explorations.

Robert

Re: Problems with sprintf and libgcc.a
Im the OP, i would like to reiterate the following comment:

Quoted text here. Click to load it

produce.

Im a senior undergrad who has just started working with the GNU-ARM
toolchain. Ive found it difficult to understand what sections the
compiler would produce, and how to map them in the appropriate output
section (.text or .data, since these are the only two i would extract
from the *.elf file to make a final *.bin file that would be loaded
onto the chip). Would someone please help me with that.

Regards,
Mayank


Re: Problems with sprintf and libgcc.a
Quoted text here. Click to load it

Mayank,

mail me with a good return address.

Correct the address in my sig in the obvious way.

--

Tauno Voipio
tauno voipio (at) iki fi


Re: Problems with sprintf and libgcc.a

Quoted text here. Click to load it

But since I've got to write a linker script anyway, why bother
with a specs file?  I don't really see much of an advantage. It
seems simpler to have the target-specific stuff in one file.

Quoted text here. Click to load it

It's an interesting idea.  I'll have to try it on my next
project.

Quoted text here. Click to load it

Not sure what you mean.  I don't have to experiment with gcc at
all.  I just write a linker script.

Quoted text here. Click to load it

That's a good point.

--
Grant Edwards                   grante             Yow!  I just had my entire
                                  at               INTESTINAL TRACT coated
We've slightly trimmed the long signature. Click to see the full one.
Re: Problems with sprintf and libgcc.a
Quoted text here. Click to load it

My vote to this, too. No need to re-build GCC & co for
each target system.

The trick is to use -Wl for gcc command line (in Makefile):

LDFLAGS  = -g -nostartfiles -Wl,-Map=$(TRG).map,--cref,-T,aif.ld

--

Tauno Voipio
tauno voipio (at) iki fi


Re: Problems with sprintf and libgcc.a
aachen.de says...
Quoted text here. Click to load it

In general, I'd have to disagree on this point.  I'd rather know what my
tools are doing rather than have them do it behind my back.  I've found
that the more specific your needs and the more you deviate from the
hosted model of the particular model the more likely know-it-all compile
drivers are to get it wrong.

Robert

Re: Problems with sprintf and libgcc.a

Quoted text here. Click to load it

Knowing what they're doing is one thing --- that's what gcc and ld
each have a '-v' switch for.  It's a totally different thing to jump
in and do-it-yourself every single time, just because you don't
believe the compiler driver can get it right.  Our OP clearly
demonstrates that individual programmers can get that completely wrong
at least as easily as the GCC porters.

--
Hans-Bernhard Broeker ( snipped-for-privacy@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.

Site Timeline