2009-03-09 23:59:57

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: Absolute symbols in vmlinux_64.lds.S

Why does vmlinux_64.lds.S use absolute symbols for things like
__bss_start/stop:

__bss_start = .; /* BSS */
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
*(.bss.page_aligned)
*(.bss)
}
__bss_stop = .;


vmlinux_32.lds.S puts __bss_start/stop into the .bss section itself. Is
there some particular reason they need to be absolute symbols (relocation?).

Thanks,
J


2009-03-10 01:25:22

by Yinghai Lu

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

Jeremy Fitzhardinge wrote:
> Why does vmlinux_64.lds.S use absolute symbols for things like
> __bss_start/stop:
>
> __bss_start = .; /* BSS */
> .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
> *(.bss.page_aligned)
> *(.bss)
> }
> __bss_stop = .;
>
>
> vmlinux_32.lds.S puts __bss_start/stop into the .bss section itself. Is
> there some particular reason they need to be absolute symbols
> (relocation?).
>

they are the same.

YH

2009-03-10 01:37:33

by Eric W. Biederman

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

Jeremy Fitzhardinge <[email protected]> writes:

> Why does vmlinux_64.lds.S use absolute symbols for things like __bss_start/stop:
>
> __bss_start = .; /* BSS */
> .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
> *(.bss.page_aligned)
> *(.bss)
> }
> __bss_stop = .;
>
>
> vmlinux_32.lds.S puts __bss_start/stop into the .bss section itself. Is there
> some particular reason they need to be absolute symbols (relocation?).

It is more that in vmlinux_32.lds.S they needed to be section relative, to
deal with relocation.

For the 64bit kernel the relocation happens at the level under the page table
so does not show up in vmlinux_64.lds.S. Which means it was probably
laziness that didn't get it changed simply because it hasn't matter.

Eric

2009-03-10 04:38:19

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S



Yinghai Lu <[email protected]> wrote:

>Jeremy Fitzhardinge wrote:
>> Why does vmlinux_64.lds.S use absolute symbols for things like
>> __bss_start/stop:
>>
>> __bss_start = .; /* BSS */
>> .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
>> *(.bss.page_aligned)
>> *(.bss)
>> }
>> __bss_stop = .;
>>
>>
>> vmlinux_32.lds.S puts __bss_start/stop into the .bss section itself. Is
>> there some particular reason they need to be absolute symbols
>> (relocation?).
>>
>
>they are the same.

Do you mean it makes no difference?

J
--
Sent from my Android phone with K-9. Please excuse my brevity.

2009-03-10 05:33:42

by Yinghai Lu

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

Jeremy Fitzhardinge wrote:
>
> Yinghai Lu <[email protected]> wrote:
>
>> Jeremy Fitzhardinge wrote:
>>> Why does vmlinux_64.lds.S use absolute symbols for things like
>>> __bss_start/stop:
>>>
>>> __bss_start = .; /* BSS */
>>> .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
>>> *(.bss.page_aligned)
>>> *(.bss)
>>> }
>>> __bss_stop = .;
>>>
>>>
>>> vmlinux_32.lds.S puts __bss_start/stop into the .bss section itself. Is
>>> there some particular reason they need to be absolute symbols
>>> (relocation?).
>>>
>> they are the same.
>
> Do you mean it makes no difference?

Sure. System.map should tell the value after the building.

YH

2009-03-10 05:35:35

by Sam Ravnborg

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

On Mon, Mar 09, 2009 at 06:23:55PM -0700, Yinghai Lu wrote:
> Jeremy Fitzhardinge wrote:
> > Why does vmlinux_64.lds.S use absolute symbols for things like
> > __bss_start/stop:
> >
> > __bss_start = .; /* BSS */
> > .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
> > *(.bss.page_aligned)
> > *(.bss)
> > }
> > __bss_stop = .;
> >
> >
> > vmlinux_32.lds.S puts __bss_start/stop into the .bss section itself. Is
> > there some particular reason they need to be absolute symbols
> > (relocation?).
> >
>
> they are the same.

Thats depends on the value of '.' where you assign __bss_start.
We have had several bugs where the symbol assinged outside the
section was less than expected because the linker aling the
start of the section equal to the lrgest alignment requirement
of a member in the section.

So in this case if '.' equals to 0xabcd and the lagest
alignment requirement inside the block is 0x1000 and we have
__bss_start1 = .;
.bss : {
__bss_start2 = .;
*(.bss.page_aligned)
}

Then you would see that:
__bss_start1 equals 0xabcd
__bss_start2 equals 0xb000

Which may result in unexpected behaviour.

The case I have in mind prevented the kernel from booting!
So unless there are specific reasons (which should be documented)
then always move the assignmnets inside the {} block.

Sam

2009-03-10 05:49:39

by Eric W. Biederman

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

Sam Ravnborg <[email protected]> writes:

> On Mon, Mar 09, 2009 at 06:23:55PM -0700, Yinghai Lu wrote:
>> Jeremy Fitzhardinge wrote:
>> > Why does vmlinux_64.lds.S use absolute symbols for things like
>> > __bss_start/stop:
>> >
>> > __bss_start = .; /* BSS */
>> > .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
>> > *(.bss.page_aligned)
>> > *(.bss)
>> > }
>> > __bss_stop = .;
>> >
>> >
>> > vmlinux_32.lds.S puts __bss_start/stop into the .bss section itself. Is
>> > there some particular reason they need to be absolute symbols
>> > (relocation?).
>> >
>>
>> they are the same.
>
> Thats depends on the value of '.' where you assign __bss_start.
> We have had several bugs where the symbol assinged outside the
> section was less than expected because the linker aling the
> start of the section equal to the lrgest alignment requirement
> of a member in the section.
>
> So in this case if '.' equals to 0xabcd and the lagest
> alignment requirement inside the block is 0x1000 and we have
> __bss_start1 = .;
> .bss : {
> __bss_start2 = .;
> *(.bss.page_aligned)
> }
>
> Then you would see that:
> __bss_start1 equals 0xabcd
> __bss_start2 equals 0xb000
>
> Which may result in unexpected behaviour.
>
> The case I have in mind prevented the kernel from booting!
> So unless there are specific reasons (which should be documented)
> then always move the assignmnets inside the {} block.

I have no complaint with that. I believe the symbols are absolute
simply because they were originally coded that way and the relocatable
kernel work on x86_64 didn't need them to change.

Eric

2009-03-10 05:57:33

by Yinghai Lu

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

On Mon, Mar 9, 2009 at 10:37 PM, Sam Ravnborg <[email protected]> wrote:
> On Mon, Mar 09, 2009 at 06:23:55PM -0700, Yinghai Lu wrote:
>> Jeremy Fitzhardinge wrote:
>> > Why does vmlinux_64.lds.S use absolute symbols for things like
>> > __bss_start/stop:
>> >
>> > ?__bss_start = .; ? ? ? ?/* BSS */
>> > ?.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
>> > ? ? *(.bss.page_aligned)
>> > ? ? *(.bss)
>> > ? ? }
>> > ?__bss_stop = .;
>> >
>> >
>> > vmlinux_32.lds.S puts __bss_start/stop into the .bss section itself. ?Is
>> > there some particular reason they need to be absolute symbols
>> > (relocation?).
>> >
>>
>> they are the same.
>
> Thats depends on the value of '.' where you assign __bss_start.
> We have had several bugs where the symbol assinged outside the
> section was less than expected because the linker aling the
> start of the section equal to the lrgest alignment requirement
> of a member in the section.
>
> So in this case if '.' equals to 0xabcd and the lagest
> alignment requirement inside the block is 0x1000 and we have
> __bss_start1 = .;
> .bss : {
> ? ? ? ?__bss_start2 = .;
> ? ? ? ?*(.bss.page_aligned)
> }
>
> Then you would see that:
> __bss_start1 equals 0xabcd
> __bss_start2 equals 0xb000

good to know...

anyway, more lines

. = ALIGN(PAGE_SIZE);
__nosave_begin = .;
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
*(.data.nosave)
} :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */
. = ALIGN(PAGE_SIZE);
__nosave_end = .;

__bss_start = .; /* BSS */
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
*(.bss.page_aligned)
*(.bss)
}
__bss_stop = .;

_end = . ;


there are extra ALIGN(PAGE_SIZE) between them....

YH

2009-03-10 11:22:34

by Sam Ravnborg

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

On Mon, Mar 09, 2009 at 10:57:19PM -0700, Yinghai Lu wrote:
> On Mon, Mar 9, 2009 at 10:37 PM, Sam Ravnborg <[email protected]> wrote:
> > On Mon, Mar 09, 2009 at 06:23:55PM -0700, Yinghai Lu wrote:
> >> Jeremy Fitzhardinge wrote:
> >> > Why does vmlinux_64.lds.S use absolute symbols for things like
> >> > __bss_start/stop:
> >> >
> >> > ?__bss_start = .; ? ? ? ?/* BSS */
> >> > ?.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
> >> > ? ? *(.bss.page_aligned)
> >> > ? ? *(.bss)
> >> > ? ? }
> >> > ?__bss_stop = .;
> >> >
> >> >
> >> > vmlinux_32.lds.S puts __bss_start/stop into the .bss section itself. ?Is
> >> > there some particular reason they need to be absolute symbols
> >> > (relocation?).
> >> >
> >>
> >> they are the same.
> >
> > Thats depends on the value of '.' where you assign __bss_start.
> > We have had several bugs where the symbol assinged outside the
> > section was less than expected because the linker aling the
> > start of the section equal to the lrgest alignment requirement
> > of a member in the section.
> >
> > So in this case if '.' equals to 0xabcd and the lagest
> > alignment requirement inside the block is 0x1000 and we have
> > __bss_start1 = .;
> > .bss : {
> > ? ? ? ?__bss_start2 = .;
> > ? ? ? ?*(.bss.page_aligned)
> > }
> >
> > Then you would see that:
> > __bss_start1 equals 0xabcd
> > __bss_start2 equals 0xb000
>
> good to know...
>
> anyway, more lines
>
> . = ALIGN(PAGE_SIZE);
> __nosave_begin = .;
> .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
> *(.data.nosave)
> } :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */
> . = ALIGN(PAGE_SIZE);
> __nosave_end = .;
>
> __bss_start = .; /* BSS */
> .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
> *(.bss.page_aligned)
> *(.bss)
> }
> __bss_stop = .;
>
> _end = . ;
>
>
> there are extra ALIGN(PAGE_SIZE) between them....

So you say that we do hit this issue here - right.
But the better way to do it is to include the assignment inside the {} block,
thus we are not dependent on an ALIGN() that logically belongs to .data_nosave.

Sam

2009-03-10 20:37:19

by H. Peter Anvin

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

Eric W. Biederman wrote:
>
> I have no complaint with that. I believe the symbols are absolute
> simply because they were originally coded that way and the relocatable
> kernel work on x86_64 didn't need them to change.
>

I have a vague memory of a bug in the x86-64 ld.

-hpa

2009-03-10 21:25:43

by Eric W. Biederman

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

"H. Peter Anvin" <[email protected]> writes:

> Eric W. Biederman wrote:
>>
>> I have no complaint with that. I believe the symbols are absolute
>> simply because they were originally coded that way and the relocatable
>> kernel work on x86_64 didn't need them to change.
>>
>
> I have a vague memory of a bug in the x86-64 ld.

Oh. I'm certain of it. ld has all kinds of bugs off and on,
occasionally we are bound to run into a few of them.

ld bugs isn't the reason for using absolute linker symbols. We use a
bunch of relative linker symbols as well. All of the generic linker
scripts sections use them as well as a few of the x86_64 specific
sections.

For crazy things like 0 relative per cpu sections it might matter.
For the rest of the symbols absolute or relative simply
doesn't matter.

Is anyone interested in writing a patch testing it and changing things?

If not things should be good enough for now.

Eric

2009-03-10 22:27:11

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: Re: Absolute symbols in vmlinux_64.lds.S

Eric W. Biederman wrote:
> Is anyone interested in writing a patch testing it and changing things?
>
> If not things should be good enough for now.
>

Yeah, I'm just testing one now.

J