EmbeddedRelated.com
Forums

More ld script questions..

Started by James Dabbs January 22, 2004
In the file <lpc2106-rom.ld>, from the file <lpc2106_gcc.zip> on the
yahoo site..

in the prog output section, there are these entries:

*(.rodata)
*(.rodata*)

I understand that the first means "add the entire contents of the
.rodata input segment into the prog output segment," but what is the
function of that second entry with the asterisk after it?

For reference, I've appended the linker script in its entirety.

Thanks for any guidance.

-----BEGIN LINKER SCRIPT-----

/*
SEARCH_DIR( /home/radsett/install/arm-elf/lib)
SEARCH_DIR( /home/radsett/install/lib/gcc-lib/arm-elf/3.3.2)
*/

MEMORY {
flash : ORIGIN = 0, LENGTH = 120K
ram : ORIGIN = 0x40000000, LENGTH = 64K
}

__stack_end__ = 0x40000000 + 64K - 4;
SECTIONS {
. = 0;
startup : { *(.startup)} >flash
prog : {
*(.text)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
} >flash
__end_of_text__ = .;
.data : {
__data_beg__ = .;
__data_beg_src__ = __end_of_text__;
*(.data)
__data_end__ = .;
} >ram AT>flash
.bss : {
__bss_beg__ = .;
*(.bss)
} >ram
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
}
. = ALIGN(32 / 8);
_end = .;
_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
PROVIDE (end = .);

/*
INPUT( -lc -lgcc)
*/

PROVIDE( undefined_instruction_exception = endless_loop);
PROVIDE( software_interrupt_exception = endless_loop);
PROVIDE( prefetch_abort_exception = endless_loop);
PROVIDE( data_abort_exception = endless_loop);
PROVIDE( reserved_exception = endless_loop);
PROVIDE( interrupt_exception = endless_loop);
PROVIDE( fast_interrupt_exception = endless_loop);

PROVIDE( PINSEL0 = 0xE002C000);
PROVIDE( IODIR = 0xE0028008);
PROVIDE( IOCLR = 0xE002800C);
PROVIDE( IOSET = 0xE0028004);

/* UART 0 */

PROVIDE( U0RBR = 0xE000C000);
PROVIDE( U0THR = 0xE000C000);
PROVIDE( U0IER = 0xE000C004);
PROVIDE( U0IIR = 0xE000C008);
PROVIDE( U0FCR = 0xE000C008);
PROVIDE( U0LCR = 0xE000C00C);
PROVIDE( U0LSR = 0xE000C014);
PROVIDE( U0SCR = 0xE000C01C);
PROVIDE( U0DLL = 0xE000C000);
PROVIDE( U0DLM = 0xE000C004);

/* PLL */

PROVIDE( PLLCON = 0xE01FC080);
PROVIDE( PLLCFG = 0xE01FC084);
PROVIDE( PLLSTAT = 0xE01FC088);
PROVIDE( PLLFEED = 0xE01FC08C);

/* MAM */

PROVIDE( MAMCR = 0xE01FC000);
PROVIDE( MAMTIM = 0xE01FC004);

/* VPB */

PROVIDE( VPBDIV = 0xE01FC100);

/* TIMER 0 */

PROVIDE( T0IR = 0xE0004000);
PROVIDE( T0TCR = 0xE0004004);
PROVIDE( T0TC = 0xE0004008);
PROVIDE( T0PR = 0xE000400C);
PROVIDE( T0PC = 0xE0004010);
PROVIDE( T0MCR = 0xE0004014);
PROVIDE( T0MR0 = 0xE0004018);
PROVIDE( T0MR1 = 0xE000401C);
PROVIDE( T0MR2 = 0xE0004020);
PROVIDE( T0MR3 = 0xE0004024);
PROVIDE( T0CCR = 0xE0004028);
PROVIDE( T0CR0 = 0xE000402C);
PROVIDE( T0CR1 = 0xE0004030);
PROVIDE( T0CR2 = 0xE0004034);
PROVIDE( T0EMR = 0xE000403C); -----END LINKER SCRIPT-----



An Engineer's Guide to the LPC2100 Series

At 07:51 AM 1/22/04 -0500, you wrote:
>In the file <lpc2106-rom.ld>, from the file <lpc2106_gcc.zip> on the
>yahoo site..
>
>in the prog output section, there are these entries:
>
> *(.rodata)
> *(.rodata*)

Not all the readonly data ends up in .rodata. Some of it ends up in other
sections (the * is just a wildcard match). This is an area of the compiler
that is vary sparsely documented, at least I couldn't find much
information. Lewin? anyone else?

>For reference, I've appended the linker script in its entirety.

I've got an updated version of that script at
http://www.aeolusdevelopment.com/Articles/download.html.

Robert

" 'Freedom' has no meaning of itself. There are always restrictions,
be they legal, genetic, or physical. If you don't believe me, try to
chew a radio signal. "

Kelvin Throop, III



>> *(.rodata)
>> *(.rodata*) > Not all the readonly data ends up in .rodata. Some of it ends up in other
> sections (the * is just a wildcard match). This is an area of the compiler

Don't quote me on this, but I _believe_ C++ code may generate stuff in
segments named .rodata-something. I vigorously avoid C++ in embedded
projects, so I don't see it a lot.

Note, the syntax above is _not_ redundant. It places ".rodata" without
suffix first in the image, followed by any ".rodatasomething" data.

--
-- Lewin A.R.W. Edwards (http://www.zws.com/)
Learn how to develop high-end embedded systems on a tight budget!
http://www.amazon.com/exec/obidos/ASIN/0750676094/zws-20



I can see a rodata.str1.4 section in one of the
programs compiled with gcc for my Atmel AT91M40800
(ARM7TDMI core) board. It's NOT a c++ project and it
doesn't explictly declare any constans; rodata.str1.4
contains all the strings in the source. I have no idea
why it's called like that, but the conclusion is
clear: .rodata is not the only section that can hold
readonly data, so that syntax is not redundant; on the
contrary, it's a very good thing to use it (unless you
don't want to start wondering where your strings are,
which is what I did the first time I compiled my
program and used only *(.rodata) in my linker command
file).

Bogdan

--- "Lewin A.R.W. Edwards" <> wrote:
> >> *(.rodata)
> >> *(.rodata*)
> >
> >
> > Not all the readonly data ends up in .rodata.
> Some of it ends up in other
> > sections (the * is just a wildcard match). This
> is an area of the compiler
>
> Don't quote me on this, but I _believe_ C++ code may
> generate stuff in
> segments named .rodata-something. I vigorously avoid
> C++ in embedded
> projects, so I don't see it a lot.
>
> Note, the syntax above is _not_ redundant. It places
> ".rodata" without
> suffix first in the image, followed by any
> ".rodatasomething" data.
>
> --
> -- Lewin A.R.W. Edwards (http://www.zws.com/)
> Learn how to develop high-end embedded systems on a
> tight budget!
>
http://www.amazon.com/exec/obidos/ASIN/0750676094/zws-20
>
>


__________________________________




> I can see a rodata.str1.4 section in one of the
> programs compiled with gcc for my Atmel AT91M40800
> (ARM7TDMI core) board. It's NOT a c++ project and it

I wonder what the difference is, then. If I build a C project (at least,
the projects I have around here - several of which are _very_
complicated), I only get .rodata.

> which is what I did the first time I compiled my
> program and used only *(.rodata) in my linker command
> file).

Hmm. When I encountered this, the linker warned me that it was omitting
sections. It did not silently discard them.

--
-- Lewin A.R.W. Edwards (http://www.zws.com/)
Learn how to develop high-end embedded systems on a tight budget!
http://www.amazon.com/exec/obidos/ASIN/0750676094/zws-20




--- "Lewin A.R.W. Edwards" <> wrote:
> I wonder what the difference is, then. If I build a
> C project (at least,
> the projects I have around here - several of which
> are _very_
> complicated), I only get .rodata.
I searched the net a bit and the only thing I found
is that it could be a matter of gcc versions.
Apparently, gcc versions prior to 3.1.x didn't
generate .rodata.strx.y sections.
>
> > which is what I did the first time I compiled my
> > program and used only *(.rodata) in my linker
> command
> > file).
>
> Hmm. When I encountered this, the linker warned me
> that it was omitting
> sections. It did not silently discard them.
I just commented out my *(.rodata*) line from the
linker script of the project that has the file with a
.rodata.str1.4 section and the linker didn't give any
warnings. I'm using ld 2.12.

>
> --
> -- Lewin A.R.W. Edwards (http://www.zws.com/)
> Learn how to develop high-end embedded systems on a
> tight budget!
>
http://www.amazon.com/exec/obidos/ASIN/0750676094/zws-20
>
>


__________________________________



OK.. * is a wildcard.. I guess I should have figure that one out..

Another question, more conceptual. This ld uses named sections, using >
to say where it will be loaded, and AT> to say where it is at the moment
of reset. (I think, anyway). Let's say I also want to use
__attribute__ to define some functions in RAM, naming this ".ramtext" in
my C code. My guess is that this looks something like this:

prog : {
*(.text)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
__end_of_prog__ = . ;
} >flash

.ramtext : {
__ramtext_beg__ = . ;
__ramtext_beg_src__ = __end_of_prog__ ;
*(.ramtext)
__ramtext_end__ = .;
} >ram AT>flash

And then my boot.s would just copy (__ramtext_end__ - __ramtext_beg__)
bytes from __ramtext_beg_src__ to __ramtext_beg__.

Is this right?

Thanks.

-----Original Message-----
From: James Dabbs [mailto:]
Sent: Thursday, January 22, 2004 7:52 AM
To:
Subject: [lpc2100] More ld script questions.. In the file <lpc2106-rom.ld>, from the file <lpc2106_gcc.zip> on the
yahoo site..

in the prog output section, there are these entries:

*(.rodata)
*(.rodata*)

I understand that the first means "add the entire contents of the
.rodata input segment into the prog output segment," but what is the
function of that second entry with the asterisk after it?

For reference, I've appended the linker script in its entirety.

Thanks for any guidance.

-----BEGIN LINKER SCRIPT-----

/*
SEARCH_DIR( /home/radsett/install/arm-elf/lib)
SEARCH_DIR( /home/radsett/install/lib/gcc-lib/arm-elf/3.3.2)
*/

MEMORY {
flash : ORIGIN = 0, LENGTH = 120K
ram : ORIGIN = 0x40000000, LENGTH = 64K
}

__stack_end__ = 0x40000000 + 64K - 4;
SECTIONS {
. = 0;
startup : { *(.startup)} >flash
prog : {
*(.text)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
} >flash
__end_of_text__ = .;
.data : {
__data_beg__ = .;
__data_beg_src__ = __end_of_text__;
*(.data)
__data_end__ = .;
} >ram AT>flash
.bss : {
__bss_beg__ = .;
*(.bss)
} >ram
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
}
. = ALIGN(32 / 8);
_end = .;
_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
PROVIDE (end = .);

/*
INPUT( -lc -lgcc)
*/

PROVIDE( undefined_instruction_exception = endless_loop); PROVIDE(
software_interrupt_exception = endless_loop); PROVIDE(
prefetch_abort_exception = endless_loop); PROVIDE( data_abort_exception
= endless_loop); PROVIDE( reserved_exception = endless_loop); PROVIDE(
interrupt_exception = endless_loop); PROVIDE( fast_interrupt_exception =
endless_loop);

PROVIDE( PINSEL0 = 0xE002C000);
PROVIDE( IODIR = 0xE0028008);
PROVIDE( IOCLR = 0xE002800C);
PROVIDE( IOSET = 0xE0028004);

/* UART 0 */

PROVIDE( U0RBR = 0xE000C000);
PROVIDE( U0THR = 0xE000C000);
PROVIDE( U0IER = 0xE000C004);
PROVIDE( U0IIR = 0xE000C008);
PROVIDE( U0FCR = 0xE000C008);
PROVIDE( U0LCR = 0xE000C00C);
PROVIDE( U0LSR = 0xE000C014);
PROVIDE( U0SCR = 0xE000C01C);
PROVIDE( U0DLL = 0xE000C000);
PROVIDE( U0DLM = 0xE000C004);

/* PLL */

PROVIDE( PLLCON = 0xE01FC080);
PROVIDE( PLLCFG = 0xE01FC084);
PROVIDE( PLLSTAT = 0xE01FC088);
PROVIDE( PLLFEED = 0xE01FC08C);

/* MAM */

PROVIDE( MAMCR = 0xE01FC000);
PROVIDE( MAMTIM = 0xE01FC004);

/* VPB */

PROVIDE( VPBDIV = 0xE01FC100);

/* TIMER 0 */

PROVIDE( T0IR = 0xE0004000);
PROVIDE( T0TCR = 0xE0004004);
PROVIDE( T0TC = 0xE0004008);
PROVIDE( T0PR = 0xE000400C);
PROVIDE( T0PC = 0xE0004010);
PROVIDE( T0MCR = 0xE0004014);
PROVIDE( T0MR0 = 0xE0004018);
PROVIDE( T0MR1 = 0xE000401C);
PROVIDE( T0MR2 = 0xE0004020);
PROVIDE( T0MR3 = 0xE0004024);
PROVIDE( T0CCR = 0xE0004028);
PROVIDE( T0CR0 = 0xE000402C);
PROVIDE( T0CR1 = 0xE0004030);
PROVIDE( T0CR2 = 0xE0004034);
PROVIDE( T0EMR = 0xE000403C); -----END LINKER SCRIPT-----



At 11:52 AM 1/22/04 -0500, you wrote:

snip

>And then my boot.s would just copy (__ramtext_end__ - __ramtext_beg__)
>bytes from __ramtext_beg_src__ to __ramtext_beg__.
>
>Is this right?

That sounds right.

Robert

" 'Freedom' has no meaning of itself. There are always restrictions,
be they legal, genetic, or physical. If you don't believe me, try to
chew a radio signal. "

Kelvin Throop, III


--- James Dabbs <> wrote:
> Another question, more conceptual. This ld uses
> named sections, using >
> to say where it will be loaded, and AT> to say where
> it is at the moment
> of reset. (I think, anyway). Let's say I also want
> to use
> __attribute__ to define some functions in RAM,
> naming this ".ramtext" in
> my C code. My guess is that this looks something
> like this:
>
> prog : {
> *(.text)
> *(.rodata)
> *(.rodata*)
> *(.glue_7)
> *(.glue_7t)
> __end_of_prog__ = . ;
> } >flash
>
> .ramtext : {
> __ramtext_beg__ = . ;
> __ramtext_beg_src__ = __end_of_prog__ ;
> *(.ramtext)
> __ramtext_end__ = .;
> } >ram AT>flash
>
I didn't see anybody using "AT" in this way. My
linker script would probably look like this instead:

.ramtext : AT( ADDR( flash ) + SIZEOF( prog ) )
{
/* the rest goes here */
} > ram

I'm not saying that your syntax is wrong, I just
never seen it in practice, nor heard of it, so if it
doesn't work you can try the above variant instead.
Another advice (this comes directly from experience):
try to always set the location counter (.) to a
multiple of 4 at the end of the section declaration,
or at least do this for data sections, or you might
have some nasty surprises.
> And then my boot.s would just copy (__ramtext_end__
> - __ramtext_beg__)
> bytes from __ramtext_beg_src__ to __ramtext_beg__.
>
> Is this right?
Almost. This will work for simple examples.
However, things will get much more interesting if you
have pointers to functions in your program. They must
be changed to reflect the new address of your code in
RAM. I'm not exactly sure how GCC handles this, but
you'll need to specify -fPIC for compilation and hope
that the rest of the story is already implemented in
the runtime. __________________________________




At 12:51 PM 1/22/04 -0800, you wrote:
>--- James Dabbs <> wrote:
> > Another question, more conceptual. This ld uses
> > named sections, using >
> > to say where it will be loaded, and AT> to say where
> > it is at the moment
> > of reset. (I think, anyway). Let's say I also want
> > to use
> > __attribute__ to define some functions in RAM,
> > naming this ".ramtext" in
> > my C code. My guess is that this looks something
> > like this:
> >
> > prog : {
> > *(.text)
> > *(.rodata)
> > *(.rodata*)
> > *(.glue_7)
> > *(.glue_7t)
> > __end_of_prog__ = . ;
> > } >flash
> >
> > .ramtext : {
> > __ramtext_beg__ = . ;
> > __ramtext_beg_src__ = __end_of_prog__ ;
> > *(.ramtext)
> > __ramtext_end__ = .;
> > } >ram AT>flash
> >
> I didn't see anybody using "AT" in this way. My
>linker script would probably look like this instead:
>
> .ramtext : AT( ADDR( flash ) + SIZEOF( prog ) )
> {
> /* the rest goes here */
> } > ram

His original syntax is more or less straight out of the ld manual. > I'm not saying that your syntax is wrong, I just
>never seen it in practice, nor heard of it, so if it
>doesn't work you can try the above variant instead.
>Another advice (this comes directly from experience):
>try to always set the location counter (.) to a
>multiple of 4 at the end of the section declaration,
>or at least do this for data sections, or you might
>have some nasty surprises.
> > And then my boot.s would just copy (__ramtext_end__
> > - __ramtext_beg__)
> > bytes from __ramtext_beg_src__ to __ramtext_beg__.
> >
> > Is this right?
> Almost. This will work for simple examples.
>However, things will get much more interesting if you
>have pointers to functions in your program. They must
>be changed to reflect the new address of your code in
>RAM. I'm not exactly sure how GCC handles this, but
>you'll need to specify -fPIC for compilation and hope
>that the rest of the story is already implemented in
>the runtime.

ld should handle that transparently. All the records that are in FLASH
will already be located to run from ram. Now if you try to use them
directly from flash w/o copying them I would expect problems.

I don't see why position independent code would be needed (it is always
ending up in the same place and that place is defined at link time).

Robert

>__________________________________
" 'Freedom' has no meaning of itself. There are always restrictions,
be they legal, genetic, or physical. If you don't believe me, try to
chew a radio signal. "

Kelvin Throop, III