Linux: Malformed linker script: vmlinux.lds

Created on 3 Sep 2018  路  26Comments  路  Source: ClangBuiltLinux/linux

Trying to link vmlinux with LLD:

ld.lld: error: ./arch/x86/kernel/vmlinux.lds:342: at least one side of the expression must be absolute
ld.lld: error: ./arch/x86/kernel/vmlinux.lds:343: at least one side of the expression must be absolute

These are the lines 342 and 343 from vmlinux.lds:

init_per_cpu__gdt_page = gdt_page + __per_cpu_load;
init_per_cpu__irq_stack_union = irq_stack_union + __per_cpu_load;

There is a patch resolving this issue: https://marc.info/?l=llvm-commits&m=150594588415147&w=2
Thanks to George Rimar for pointing out.

[ARCH] x86_64 [BUG] linux [FIXED][LINUX] 5.1 [TOOL] lld

All 26 comments

@tpimh did you test the above patch with and without lld?

I only tested with LLD, will test with GNU ld today, but I'm sure there will be no problems.
I was able to link the kernel (using relatively small config) with LLD with two small fixes, maybe I should create separate issues for each problem I faced.

Yes please, finer grained issues make things easier to track. Thanks for the report (and the suggested fix!)

Just tested with ld.bfd, successfully built and boots fine. Version: GNU ld (GNU Binutils) 2.31.1
LLD linked kernel with same config appears to be 18% smaller size.

LLD linked kernel with same config appears to be 18% smaller size.

That's a big deal. I wonder if things are potentially missing; did you boot test in a VM then on metal?

Whoa!

I would be interesting to see per-section diff (readelf -a can show individual section sizes).

No, I only tested it in qemu. Will publish per-section diff later today.

Here you go: diff.txt

So .text and .data are exactly the same size. Frankly I don't see where the difference comes from.

@gwelymernans is helping test the above patch.

The original author of the patch is @espindola.

Which patch? The error message in lld?
The logic is that we can add an address (something based on '.') and plain numbers, but adding two addresses is meaningless.

What I had locally for benchmarking linking the kernel was:

init_per_cpu__gdt_page = ABSOLUTE(gdt_page) + __per_cpu_load;
init_per_cpu__irq_stack_union = ABSOLUTE(irq_stack_union) + __per_cpu_load;

I can't remember at the moment why I decided that gdt_page and irq_stack_union were actually absolute values.

In your original message you mentioned, that you will try upstreaming it once everything works. I tested the patch with both lld and bfd and confirmed that it works. Time to upstream?

I will if @espindola doesn't ;)

If someone could take care of upstreaming it I would be very grateful. I left LLVM before having time to properly test it.

@vo4 volunteered to help

@vo4 sent this upstream (cant find link)

@espindola Could you sign off on the patch I sent upstream?

Sure, how do I do that?

I see my old @gmail.com address mentioned, am I cced?

@espindola Thanks for signing off on the change. Which email address do you prefer nowadays?

My current email is [email protected]

Thanks for cleaning up and upstreaming the change!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tpgxyz picture tpgxyz  路  4Comments

nathanchance picture nathanchance  路  3Comments

tpimh picture tpimh  路  5Comments

nathanchance picture nathanchance  路  4Comments

nathanchance picture nathanchance  路  3Comments