Messages in this thread Patch in this message | | | Date | Mon, 02 Aug 2010 14:27:10 -0700 | From | "H. Peter Anvin" <> | Subject | Re: [PATCH -v3 2/2] x86: more early console output from compressed/misc.c |
| |
On 08/02/2010 02:08 PM, H. Peter Anvin wrote: > On 08/02/2010 01:59 PM, H. Peter Anvin wrote: >> On 08/02/2010 12:35 PM, Yinghai Lu wrote: >>> >>> it seems I can not global variables in arch/x86/boot/compressed/misc.c >>> >> >> I just looked at it, it's the fact that we don't relocate the GOT that >> is causing problems. It's relatively easy to fix: here is a patch, but >> in grand Linus tradition it is completely untested. >> > > Untested indeed... here is one which doesn't clobber live registers. >
And of course I got the test backwards... in AT&T syntax, number compares you!
-hpa
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index f543b70..67a655a 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -124,6 +124,19 @@ relocated: rep stosl /* + * Adjust our own GOT + */ + leal _got(%ebx), %edx + leal _egot(%ebx), %ecx +1: + cmpl %ecx, %edx + jae 2f + addl %ebx, (%edx) + addl $4, %edx + jmp 1b +2: + +/* * Do the decompression, and jump to the new kernel.. */ leal z_extract_offset_negative(%ebx), %ebp diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index faff0dc..52f85a1 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -280,6 +280,19 @@ relocated: rep stosq /* + * Adjust our own GOT + */ + leaq _got(%rip), %rdx + leaq _egot(%rip), %rcx +1: + cmpq %rcx, %rdx + jae 2f + addq %rbx, (%rdx) + addq $8, %rdx + jmp 1b +2: + +/* * Do the decompression, and jump to the new kernel.. */ pushq %rsi /* Save the real mode argument */ diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index 5ddabce..34d047c 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S @@ -41,6 +41,12 @@ SECTIONS *(.rodata.*) _erodata = . ; } + .got : { + _got = .; + KEEP(*(.got.plt)) + KEEP(*(.got)) + _egot = .; + } .data : { _data = . ; *(.data) | |