Skip to contentSkip to conversation

common RODATA in vmlinux.lds.h (2.5.59)

DISCUSSION Greg Ungerer 4 participants 14 messages Jan 22, 2003 – Jan 23, 2003

lore
Share & tools
lore
#0 lore raw

Hi All,

The new common definition of RODATA for linker scripts (in include/asm-generic/vmlinux.lds.h) is causing me some amount of pain, at least on the m68knommu architecture.

The problem is that on the m68knommu arch linker script it fundamentaly groups everything into 2 memory regions, one for flash and one for ram. Each section is then directed to the appropriate memory region, eg:

        .text : {
            *(.text)
        } > flash

With the way the RODATA define is setup I cannot do this. It contains definitions for a number of complete sections.

Anyone got any ideas on the best way to fix this?

Regards
Greg

------------------------------------------------------------------------
Greg Ungerer -- Chief Software Wizard EMAIL: [email protected]
Snapgear Pty Ltd PHONE: +61 7 3279 1822
825 Stanley St, FAX: +61 7 3279 1820
Woolloongabba, QLD, 4102, Australia WEB: www.SnapGear.com

#1 lore raw
Quoted 9 lines · Greg Ungerer

The new common definition of RODATA for linker scripts (in include/asm-generic/vmlinux.lds.h) is causing me some amount of pain, at least on the m68knommu architecture.

The problem is that on the m68knommu arch linker script it fundamentaly groups everything into 2 memory regions, one for flash and one for ram. Each section is then directed to the appropriate memory region, eg:

Quoted 8 lines
         .text : {
             *(.text)
         } > flash

With the way the RODATA define is setup I cannot do this. It contains definitions for a number of complete sections.

Anyone got any ideas on the best way to fix this?

First of all, asm-generic/vmlinux.lds.h is there to share common code where possible, so if it's not possible, you still have the option of having your own special code in arch/$(ARCH)/vmlinux.lds.S

Having said that, you could add

	#define TEXT_MEM > flash

at the beginning of arch/m68knommu/vmlinux.lds.S

and

	#ifndef TEXT_MEM
	#define TEXT_MEM
	#endif

at the beginning of include/asm-generic/vmlinux.lds.h and then change

	.text : {
		*(.text)

- }
+ } TEXT_MEM

Would that work for you?

--Kai

#2 lore raw

Hi Kai,

Quoted 1 line · Kai Germaschewski

First of all, asm-generic/vmlinux.lds.h is there to share common code where possible, so if it's not possible, you still have the option of having your own special code in arch/$(ARCH)/vmlinux.lds.S

And that is exactly what I have done as an immediate fix.

It would be nice if all architectures could use this common code. Saves me having to specifically fix m68knommu linker script when ever things inside RODATA change.

Quoted 19 lines

Having said that, you could add

	#define TEXT_MEM > flash

at the beginning of arch/m68knommu/vmlinux.lds.S

and

	#ifndef TEXT_MEM
	#define TEXT_MEM
	#endif

at the beginning of include/asm-generic/vmlinux.lds.h and then change

	.text : {
		*(.text)
(quoted diff) +1 -1
-	}
+	} TEXT_MEM
Quoted 1 line

Would that work for you?

Yep, I would be happy with that.

Regards
Greg

------------------------------------------------------------------------
Greg Ungerer -- Chief Software Wizard EMAIL: [email protected]
SnapGear Pty Ltd PHONE: +61 7 3435 2888
825 Stanley St, FAX: +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia WEB: www.SnapGear.com

#3 lore raw

Yeah, the new generic RODATA stuff is way broken on the v850 too.

Besides the over-eager use of sections, it also assumes that C symbol names map one-to-one with `linker symbol' names, which isn't true with the default v850 compiler.

Here's my local rewrite of include/asm-generic/vmlinux.lds.h, which works on the v850, and seems like it should be usable by other systems as well.

It does two things:

(1) Separates the RODATA stuff into two macros, an input-sections-and- symbols macro, RODATA_CONTENTS, which can be put into any appropriate section, and a RODATA_SECTION macro, which simply defines an appropriate section using that. I guess most archs could just use RODATA_SECTION in the same way they use `RODATA' now, but the v850 uses RODATA_CONTENTS instead.

This assumes that the original division into lots of little output sections was gratuitous, and that putting everything into a single section is OK.

[You might notice that this follows the macro scheme already used by the v850's vmlinux.lds.S file]

(2) Adds a CSYM' macro which is used for every symbol name that is exported to C. By default this just expands to its argument, but an arch may define C_SYMBOL_PREFIX' in order to add a prefix to all C symbols.

What do you think of this?

[To be honest, I think the stuff with `LOAD_OFFSET' is a bit of a waste; it seems cleaner to just have archs define their own sections as appropriate, and use RODATA_CONTENTS directly -- it's the input sections and related symbols that are always changing (and so better centralized), after all, not the output sections.]

Thanks,

-Miles

Here's my rewrite of include/asm-generic/vmlinux.lds.h:

#ifndef LOAD_OFFSET
#define LOAD_OFFSET 0
#endif

#ifndef C_SYMBOL_PREFIX
#define C_SYMBOL_PREFIX
#endif

#define __paste(x,y) x##y
#define _paste(x,y) __paste(x,y)
#define CSYM(name) _paste(C_SYMBOL_PREFIX,name)

/* Section contents for read-only data. */

#define RODATA_CONTENTS							      \
		*(.rodata) *(.rodata.*)					      \
		*(__vermagic)		/* Kernel version magic */	      \
		*(.rodata1)						      \
	/* Kernel symbol table: Normal symbols */			      \
	CSYM(__start___ksymtab) = .;					      \
		*(__ksymtab)						      \
	CSYM(__stop___ksymtab) = .;					      \
	/* Kernel symbol table: GPL-only symbols */			      \
	CSYM(__start___gpl_ksymtab) = .;				      \
		*(__gpl_ksymtab)					      \
	CSYM(__stop___gpl_ksymtab) = .;					      \
	/* Kernel symbol table: strings */				      \
		*(__ksymtab_strings)

/* A standalone section containing RODATA_CONTENTS. */

#define RODATA_SECTION							      \
	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		      \
		RODATA_CONTENTS						      \
	}
Signature · 2 lines
-- 
Suburbia: where they tear out the trees and then name streets after them.
#4 lore raw

Hiya Miles,

Quoted 11 lines · Miles Bader

Yeah, the new generic RODATA stuff is way broken on the v850 too.

Besides the over-eager use of sections, it also assumes that C symbol names map one-to-one with `linker symbol' names, which isn't true with the default v850 compiler.

Here's my local rewrite of include/asm-generic/vmlinux.lds.h, which works on the v850, and seems like it should be usable by other systems as well.

It does two things:

[snip]

Quoted 2 lines

What do you think of this?

I like it. Looks like an ideal solution, keeps a bunch of stuff common, but is a lot more flexible in terms of output sections (and their regions) .

Quoted 5 lines

[To be honest, I think the stuff with `LOAD_OFFSET' is a bit of a waste; it seems cleaner to just have archs define their own sections as appropriate, and use RODATA_CONTENTS directly -- it's the input sections and related symbols that are always changing (and so better centralized), after all, not the output sections.]

Agree 100%.

Regards
Greg

------------------------------------------------------------------------
Greg Ungerer -- Chief Software Wizard EMAIL: [email protected]
SnapGear Pty Ltd PHONE: +61 7 3435 2888
825 Stanley St, FAX: +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia WEB: www.SnapGear.com

#5 lore raw
In reply to Miles Bader
Quoted 6 lines · Miles Bader

[To be honest, I think the stuff with `LOAD_OFFSET' is a bit of a waste; it seems cleaner to just have archs define their own sections as appropriate, and use RODATA_CONTENTS directly -- it's the input sections and related symbols that are always changing (and so better centralized), after all, not the output sections.]

There were some reports of failed boots that boiled down to mis-alignment of a single section.
With your suggestion we will end up in the same problem. __start_ksymbtab will in some cases have a value less than the actual start of the first symbol.

Sam

#7 lore raw
In reply to Miles Bader
Quoted 1 line · Miles Bader

Yeah, the new generic RODATA stuff is way broken on the v850 too.

Yup, I actually noticed when looking things over, sorry about that.

Quoted 7 lines

(1) Separates the RODATA stuff into two macros, an input-sections-and- symbols macro, RODATA_CONTENTS, which can be put into any appropriate section, and a RODATA_SECTION macro, which simply defines an appropriate section using that. I guess most archs could just use RODATA_SECTION in the same way they use `RODATA' now, but the v850 uses RODATA_CONTENTS instead.

Quoted 6 lines

This assumes that the original division into lots of little output sections was gratuitous, and that putting everything into a single section is OK.

[You might notice that this follows the macro scheme already used by the v850's vmlinux.lds.S file]

Yes, I saw it, but on the other hand I'd like to avoid introducing complexity which isn't really needed. So the important question is: Is there a reason that v850 does things differently, or could it just as well live with separate .text and .rodata sections (Note that sections like .rodata1 will be discarded when empty).

The idea behind the cleanup is two-fold:
o Make it easier to add e.g. special sections like __ksymtab and friends.
o Make the building of vmlinux more consistent, i.e. share a common way where possible and explicitly document places where archs need to do things differently. Today, there's a lot of differences between archs, most of them I think just for historical grown-with-time reasons.

A reason to use sections of their own for e.g. __ex_table, __ksymtab etc. is also to get alignment right without magic numbers in vmlinux.lds.S.

One example of the inconsistency is e.g. the _etext symbol. For v850 it includes .rodata, exception table etc. So if calculating _etext - _stext, one gets a wrong impression of the code size, and generic code which assumes that there's code between _stext and _etext (kernel/extable.c) obviously uses a wrong assumption.

Quoted 6 lines

(2) Adds a CSYM' macro which is used for every symbol name that is exported to C. By default this just expands to its argument, but an arch may define C_SYMBOL_PREFIX' in order to add a prefix to all C symbols.

What do you think of this?

I definitely agree with (2), with (1) only if there's a good reason.

--Kai

#6 lore raw
In reply to Sam Ravnborg
Quoted 11 lines · Sam Ravnborg
Quoted 5 lines

[To be honest, I think the stuff with `LOAD_OFFSET' is a bit of a waste; it seems cleaner to just have archs define their own sections as appropriate, and use RODATA_CONTENTS directly -- it's the input sections and related symbols that are always changing (and so better centralized), after all, not the output sections.]

There were some reports of failed boots that boiled down to mis-alignment of a single section.
With your suggestion we will end up in the same problem. __start_ksymbtab will in some cases have a value less than the actual start of the first symbol.

Then it would seem an alignment directive should probably be included before __start_ksymbtab (and possibly other places). [but I can't see what it has to do with having separate sections or not.]

-Miles

Signature · 2 lines
"Most attacks seem to take place at night, during a rainstorm, uphill,
 where four map sheets join."   -- Anon. British Officer in WW I
#8 lore raw
In reply to Kai Germaschewski
Quoted 2 lines · Kai Germaschewski

Yes, I saw it, but on the other hand I'd like to avoid introducing complexity which isn't really needed.

Actually as far as I can see, my suggested alternative is _less_ complex than the current RODATA.

It seems to me that the absolutely most straight-forward solution is to have a single macro that groups input sections and symbol defs, and is simply embeddable into any old output section, i.e. RODATA_CONTENTS (note that it's actually shorter than RODATA). Is there some reason why multiple output sections are actually necessary?

Also, I've found that defining symbols outside the sections, like RODATA does, to be somewhat dangerous, and have had much better luck defining them inside the sections whenever possible (sometimes it isn't, of course, but none of the RODATA symbols appear to have any problems).

Quoted 3 lines

So the important question is: Is there a reason that v850 does things differently, or could it just as well live with separate .text and .rodata sections.

It's not that it _needs_ to group things inside a single output section (though often doing so is just simpler), but it _does_ need more control over the output sections than is provided by the current RODATA macro:
at least, it needs to be able to specify which memory regions the various sections go, sometimes at separate link- and run-time addresses (i.e., a "> MEM AT> OTHER_MEM" directive following each output section).

-Miles

Signature · 2 lines
A zen-buddhist walked into a pizza shop and
said, "Make me one with everything."
#12 lore raw
In reply to Kai Germaschewski

Hi Kai,

Quoted 1 line · Kai Germaschewski

Yes, I saw it, but on the other hand I'd like to avoid introducing complexity which isn't really needed. So the important question is: Is there a reason that v850 does things differently, or could it just as well live with separate .text and .rodata sections (Note that sections like .rodata1 will be discarded when empty).

The reason we tend to group all these things together is that logically that is the way they are layed out between flash and ram (and running the kernel code in flash is really the case that is interresting here). Where you have the text and rodata parts resident in flash (and this is where they stay), and the data and bss in ram (but they start in flash and are copied on start up to ram). So 2 very different memory regions involved, not just one contiguous blob like on most VM architectures.

So to build a flash image most people just objcopy out the text and the data (and init really too) sections and cat them together and that is the binary image that you program into your flash. If you have lots of sections this makes this extraction and concatentation process just plain ugly. And when you add new sections your flash building needs to know about them and handle them.

Regards
Greg

------------------------------------------------------------------------
Greg Ungerer -- Chief Software Wizard EMAIL: [email protected]
SnapGear Pty Ltd PHONE: +61 7 3435 2888
825 Stanley St, FAX: +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia WEB: www.SnapGear.com

#9 lore raw
In reply to Miles Bader
Quoted 6 lines · Miles Bader
Quoted 2 lines · Kai Germaschewski

Yes, I saw it, but on the other hand I'd like to avoid introducing complexity which isn't really needed.

Actually as far as I can see, my suggested alternative is _less_ complex than the current RODATA.

I don't see that. Your suggestion has two macros, RODATA_CONTENTS and RODATA_SECTION, and arch/*/vmlinux.lds.S would use one or the other. Surely you agree that all arch/*/vmlinux.lds.S using the same one would be simpler?

Quoted 5 lines

It seems to me that the absolutely most straight-forward solution is to have a single macro that groups input sections and symbol defs, and is simply embeddable into any old output section, i.e. RODATA_CONTENTS (note that it's actually shorter than RODATA). Is there some reason why multiple output sections are actually necessary?

I suppose the major reasons for multiple output sections is consistency with the default ld script, and alignment in particular. Note that

	. = __start___ksymtab
	*(__ksymtab)

is broken when . isn't aligned to the requirements of *(__ksymtab) already
- the only way to ensure that in your solution is . = ALIGN(x) beforehand, where it's however necessary to know the requirements of __ksymtab. This means magic numbers which are not even constant for different archs and of course it's also fragile, if someone changes the struct which is put into __ksymtab, they most likely don't remember to change all the magic numbers in arch/*/vmlinux.lds.S.

Using sections allows to do instead:

	__ksymtab : {
		__start___ksymtab = . ;
		*(__ksymtab)
	}

which will align things correctly without further tricks.

You want to use sections as an abstraction for different parts of the image, like text/rodata vs data. However, let me claim the sections are not the right tool for the job, instead that's why ELF segments exist. Just declaring two MEMORY regions, e.g. rom/ram and putting text/rodata sections into rom, the rest into ram will give you a vmlinux with two segments, exactly what you need. (There's two ways to do that, using MEMORY or PHDRS - whatever works better for you)

Quoted 4 lines

Also, I've found that defining symbols outside the sections, like RODATA does, to be somewhat dangerous, and have had much better luck defining them inside the sections whenever possible (sometimes it isn't, of course, but none of the RODATA symbols appear to have any problems).

Yes, you're right on that one, it's already fixed in -mm, the mainline fix has to wait for Linus' return ;)

Quoted 10 lines
Quoted 3 lines

So the important question is: Is there a reason that v850 does things differently, or could it just as well live with separate .text and .rodata sections.

It's not that it _needs_ to group things inside a single output section (though often doing so is just simpler), but it _does_ need more control over the output sections than is provided by the current RODATA macro:
at least, it needs to be able to specify which memory regions the various sections go, sometimes at separate link- and run-time addresses (i.e., a "> MEM AT> OTHER_MEM" directive following each output section).

All of this can, AFAICS, be nicely handled by additional "{TEXT,RODATA,DATA}_MEM" macros which allow the arch to specify regions as necessary.

--Kai

#13 lore raw
In reply to Greg Ungerer
Quoted 15 lines · Greg Ungerer
Quoted 5 lines · Kai Germaschewski

Yes, I saw it, but on the other hand I'd like to avoid introducing complexity which isn't really needed. So the important question is: Is there a reason that v850 does things differently, or could it just as well live with separate .text and .rodata sections (Note that sections like .rodata1 will be discarded when empty).

The reason we tend to group all these things together is that logically that is the way they are layed out between flash and ram (and running the kernel code in flash is really the case that is interresting here). Where you have the text and rodata parts resident in flash (and this is where they stay), and the data and bss in ram (but they start in flash and are copied on start up to ram). So 2 very different memory regions involved, not just one contiguous blob like on most VM architectures.

Quoted 7 lines

So to build a flash image most people just objcopy out the text and the data (and init really too) sections and cat them together and that is the binary image that you program into your flash. If you have lots of sections this makes this extraction and concatentation process just plain ugly. And when you add new sections your flash building needs to know about them and handle them.

Let me just point to the other reply I just wrote. I think you're using the wrong tool and should use ELF segments instead, that's what they're there for in the first place. If you base your flash building on segments, there should be no need for it to know about sections at all.

--Kai

#10 lore raw
In reply to Kai Germaschewski
Quoted 5 lines · Kai Germaschewski
Quoted 2 lines

Actually as far as I can see, my suggested alternative is _less_ complex than the current RODATA.

I don't see that. Your suggestion has two macros, RODATA_CONTENTS and RODATA_SECTION, and arch/*/vmlinux.lds.S would use one or the other.

Well, actually I was also suggesting that there really shouldn't be RODATA_SECTION at all, and every linker script should just use RODATA_CONTENTS embedded in an existing section of their choice or in a trivial .rodata section, e.g:

.rodata { RODATA_CONTENTS }

Quoted 2 lines

Surely you agree that all arch/*/vmlinux.lds.S using the same one would be simpler?

No, in fact I don't think it would -- your suggestion is that there should be a single macro affected by all sorts of `magic defines' that somehow change its behavior (e.g. LOAD_OFFSET, and the output-memory-area defines you mentioned to solve my output memory region problem). This sort of structure seems very confusing to me, even if it's superficially simpler (by having only a `single macro').

Not having the macro(s) create output sections makes the result a _lot_ easier to understand, since there's not all this behind-the-scenes tweaking going on by the macro, it's all pretty straight-forward.

Quoted 2 lines

I suppose the major reasons for multiple output sections is consistency with the default ld script

Why is this important?

Quoted 1 line

and alignment in particular.

This is more important problem with my scheme:

Quoted 6 lines

the only way to ensure that in your solution is . = ALIGN(x) beforehand, where it's however necessary to know the requirements of __ksymtab. This means magic numbers which are not even constant for different archs and of course it's also fragile, if someone changes the struct which is put into __ksymtab, they most likely don't remember to change all the magic numbers in arch/*/vmlinux.lds.S.

I see your point, but is this really a problem in practice? I suspect that about 99% of the time you can get away with simply being a bit conservative, e.g., aligning to an 8- or 16-byte boundary (I would be very surprised if there's an arch that aligns structs more than that, for obvious reasons).

Quoted 2 lines

You want to use sections as an abstraction for different parts of the image, like text/rodata vs data.

Um, no I don't. I just want to control where the output sections go, e.g., into RAM or ROM, and how the load-time and run-time addresses are related. Most of the time I don't care what the output sections are, as long as I can control their disposition.

Quoted 6 lines

However, let me claim the sections are not the right tool for the job, instead that's why ELF segments exist. Just declaring two MEMORY regions, e.g. rom/ram and putting text/rodata sections into rom, the rest into ram will give you a vmlinux with two segments, exactly what you need. (There's two ways to do that, using MEMORY or PHDRS - whatever works better for you)

I'm not sure what you mean by `segments' (the GNU ld linker script documentation is dreadful), but I'll try to look them up and see if they can help me solve my problem.

Quoted 3 lines

All of this can, AFAICS, be nicely handled by additional "{TEXT,RODATA,DATA}_MEM" macros which allow the arch to specify regions as necessary.

That sounds clumsy to me, because it adds lots of `parameters' to the common macros -- I'd prefer a solution where the macros can be as much of a black-box as possible -- but it will probably work.

Thanks,

-Miles

Signature · 1 line
Fast, small, soon; pick any 2.
#11 lore raw
In reply to Kai Germaschewski

Hi Kai,

Kai Germaschewski wrote:
[snip]

Quoted 3 lines

You want to use sections as an abstraction for different parts of the image, like text/rodata vs data. However, let me claim the sections are not the right tool for the job, instead that's why ELF segments exist. Just declaring two MEMORY regions, e.g. rom/ram and putting text/rodata
sections into rom, the rest into ram will give you a vmlinux with two segments, exactly what you need. (There's two ways to do that, using MEMORY or PHDRS - whatever works better for you)

I can see your point here. So as long as we can get the sections within RODATA placed into the right segment then we can still do what we need. That will be good enough for me in the m68knommu case.

[snip]

Quoted 9 lines
Quoted 6 lines

It's not that it _needs_ to group things inside a single output section (though often doing so is just simpler), but it _does_ need more control over the output sections than is provided by the current RODATA macro:
at least, it needs to be able to specify which memory regions the various sections go, sometimes at separate link- and run-time addresses (i.e., a "> MEM AT> OTHER_MEM" directive following each output section).

All of this can, AFAICS, be nicely handled by additional "{TEXT,RODATA,DATA}_MEM" macros which allow the arch to specify regions as necessary.

Oddly enough (or perhaps not :-) this is virtually the method I currently use in the m68knommu vmlinux.lds.S to allow it to link for both flash+ram or ram-only operation - depending on a CONFIG_ option.

Regards
Greg

------------------------------------------------------------------------
Greg Ungerer -- Chief Software Wizard EMAIL: [email protected]
SnapGear Pty Ltd PHONE: +61 7 3435 2888
825 Stanley St, FAX: +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia WEB: www.SnapGear.com