Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ld: final link failed: File truncated #926

Closed
aliceinwire opened this issue Nov 6, 2018 · 19 comments
Closed

ld: final link failed: File truncated #926

aliceinwire opened this issue Nov 6, 2018 · 19 comments

Comments

@aliceinwire
Copy link
Contributor

aliceinwire commented Nov 6, 2018

kernel: 4.19.1
kernel_config: https://gist.github.com/aliceinwire/72d090b6ff4ec8cc019882e553fbeacb
patch: https://gist.github.com/aliceinwire/9cc9d852f5a99450f035052474d85044

localhost ~ # gcc --version
gcc (Gentoo 7.3.0-r3 p1.4) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

kpatch-build log: https://gist.github.com/aliceinwire/2a3910a958b8809b04c7baae516544c7

@joe-lawrence
Copy link
Contributor

The "sibling call from callable instruction with modified stack frame" are only warning messages. See the note in the kernel documentation on those.

This looks to be the real failure:

ld: warning: dot moved backwards before `.text.__startup_secondary_64'
ld: warning: dot moved backwards before `.text.__startup_secondary_64'
ld: final link failed: File truncated
make: *** [Makefile:1032: vmlinux] Error 1

__startup_secondary_64() is defined in arch/x86/kernel/head64.c, can you attach head64.o or is it empty?

@aliceinwire
Copy link
Contributor Author

aliceinwire commented Nov 19, 2018

This is the output (warning big file):
elivepatch-b0c6620d-20ae-4bd8-8c18-c16b81a6e90f.tar.gz

I looked a bit into the head64.o file:

2e743432eaf6 /tmp/elivepatch-b0c6620d-20ae-4bd8-8c18-c16b81a6e90f/usr/src/linux/
arch/x86/kernel # objdump -x head64.o  |grep __startup_secondary_64
  9 .text.__startup_secondary_64 00000003  0000000000000000  0000000000000000  00000b38  2**0
0000000000000000 l    d  .text.__startup_secondary_64   0000000000000000 .text.__startup_secondary_64
0000000000000000 g     F .text.__startup_secondary_64   0000000000000003 __startup_secondary_64
000000000000e99b R_X86_64_64       .text.__startup_secondary_64
0000000000000070 R_X86_64_64       .text.__startup_secondary_64
0000000000000160 R_X86_64_64       .text.__startup_secondary_64
0000000000000168 R_X86_64_64       .text.__startup_secondary_64+0x0000000000000003
0000000000000d9f R_X86_64_64       .text.__startup_secondary_64
00000000000000f0 R_X86_64_64       .text.__startup_secondary_64
0000000000000040 R_X86_64_PC32     .text.__startup_secondary_64
0000000000000044 R_X86_64_PC32     .text.__startup_secondary_64+0x0000000000000003
2e743432eaf6 /tmp/elivepatch-b0c6620d-20ae-4bd8-8c18-c16b81a6e90f/usr/src/linux/
arch/x86/kernel # readelf -h head64.o
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          151984 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         41
  Section header string table index: 37

CFLAGS:
https://paste.pound-python.org/show/jmkJctutf4RRj8wsmdQK/

@sm00th
Copy link
Contributor

sm00th commented Nov 19, 2018

I can reproduce it with gcc version 8.2.1 20181105 (Red Hat 8.2.1-5) (GCC) on 4.19/4.20-rc this only happens when optimizing for size and building with function-sections enabled, i.e. KCFLAGS="-ffunction-sections -Os".

@joe-lawrence
Copy link
Contributor

Does this occur when simply building a newish kernel and CONFIG_CC_OPTIMIZE_FOR_SIZE set? Or does it only occur when kpatch-build is building its before/after kernels?

@sm00th
Copy link
Contributor

sm00th commented Nov 20, 2018

Does this occur when simply building a newish kernel and CONFIG_CC_OPTIMIZE_FOR_SIZE set? Or does it only occur when kpatch-build is building its before/after kernels?

Because it is only reproducible with -ffunction-sections it does not happen during "normal" kernel builds.

@joe-lawrence
Copy link
Contributor

Because it is only reproducible with -ffunction-sections it does not happen during "normal" kernel builds.

Ah, got it. FWIW, I get a slightly different build error when setting CONFIG_CC_OPTIMIZE_FOR_SIZE and exporting KCFLAGS="-ffunction-sections" with both gcc v7.2.1 and v4.8.5:

% make -j$(nproc)
...
String table index out of bounds
make[2]: *** [arch/x86/boot/compressed/Makefile:127: arch/x86/boot/compressed/vmlinux.relocs] Error 1
make[2]: *** Deleting file 'arch/x86/boot/compressed/vmlinux.relocs'
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [arch/x86/boot/Makefile:112: arch/x86/boot/compressed/vmlinux] Error 2
make: *** [arch/x86/Makefile:283: bzImage] Error 2

So I guess the question is whether -Os and -ffunction-sections are expected to be compatible.

@sm00th
Copy link
Contributor

sm00th commented Nov 21, 2018

String table index out of bounds

Uh, I started getting this as well yesterday (no idea what have changed in my environment) and it has nothing to do with -Os, this one is reproducible for me with just KCFLAGS="-ffunction-sections" and CONFIG_X86_NEED_RELOCS=y

@sm00th
Copy link
Contributor

sm00th commented Nov 22, 2018

I've been looking at it a bit more and I have a picture of what is going on, but still have no idea who is at fault here.

The difference between perf/size optimized objectfiles that breaks linking is the section alignment (sh_addralign).

$ eu-readelf -S head64-perf-optimized.o | grep __startup_secondary
[16] .text.__startup_secondary_64 PROGBITS     0000000000000000 00000c60 00000003  0 AX     0   0 16
$ eu-readelf -S head64-size-optimized.o | grep __startup_secondary
[16] .text.__startup_secondary_64 PROGBITS     0000000000000000 00000c40 00000003  0 AX     0   0  1

ld does multiple passes, in both objectfile on first pass dot after .iplt section is 0xffffffff814055c8, on second one it is 0xffffffff814055c1 because .iplt has ignored set and thus is not included in the output. In case of size-optimized binary these are the dot values for is .text.__startup_secondary_64 and so it is considered a backwards movement, but with perf-optimized binary this address is getting aligned and dot is set to 0xffffffff814055d0 in both cases.

It looks like in 4.18 this section has proper alignment even with CONFIG_CC_OPTIMIZE_FOR_SIZE so I'll try bisecting it.

@sm00th
Copy link
Contributor

sm00th commented Nov 22, 2018

It looks like in 4.18 this section has proper alignment even with CONFIG_CC_OPTIMIZE_FOR_SIZE

No it is reproducible even on 4.15

@joe-lawrence
Copy link
Contributor

String table index out of bounds

Uh, I started getting this as well yesterday (no idea what have changed in my environment) and it has nothing to do with -Os, this one is reproducible for me with just KCFLAGS="-ffunction-sections" and CONFIG_X86_NEED_RELOCS=y

This is really weird -- on older upstream kernels (v4.10, v4.11, etc.), copying RHEL-7 config + make olddefconfig + make localmodconfig and export KCFLAGS="-ffunction-sections" results in the linker segfaulting. Add -fdata-sections and I get the "string table index out of bounds" error. How is this any different than kpatch-build's invocations?

@aliceinwire
Copy link
Contributor Author

aliceinwire commented Nov 25, 2018

kpatch-build looks relay on the GCC -ffunction-sections flag.

export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections $ARCH_KCFLAGS"

using instead

export KCFLAGS="-I$DATADIR/patch -fno-function-sections -fdata-sections $ARCH_KCFLAGS"

it compile but i got
/usr/libexec/kpatch/create-diff-object: ERROR: meminfo.o: find_local_syms: 174: find_local_syms for meminfo.c: couldn't find in vmlinux symbol table

kernel: 4.19.2
GCC: gcc (Gentoo Hardened 7.3.0-r3 p1.4) 7.3.0

@sm00th
Copy link
Contributor

sm00th commented Nov 26, 2018

How is this any different than kpatch-build's invocations?

The answer is "targets", kpatch-build does make vmlinux modules which is less then default target and thus the 'relocs' testing is skipped.

kpatch-build looks relay on the GCC -ffunction-sections flag

Yes, kpatch-build won't work without this flag as this is how we determine which functions are changed.

@sm00th
Copy link
Contributor

sm00th commented Nov 26, 2018

The answer is "targets", kpatch-build does make vmlinux modules which is less then default target and thus the 'relocs' testing is skipped.

posttests are triggered by bzImage target, which is added to default list as a default arch target in arch/x86/Makefile.

@joe-lawrence
Copy link
Contributor

How is this any different than kpatch-build's invocations?

The answer is "targets", kpatch-build does make vmlinux modules which is less then default target and thus the 'relocs' testing is skipped.

kpatch-build looks relay on the GCC -ffunction-sections flag

Yes, kpatch-build won't work without this flag as this is how we determine which functions are changed.

So two different issues:

  1. When running kpatch-build, we're hitting the "dot moved backwards" linker error, as described in this comment.

  2. when setting CONFIG_X86_NEED_RELOCS=y, manually specifying KCFLAGS="-ffunction-sections", and running make we're blowing up in arch/x86/tools/relocs.c with "string table index out of bounds" error.

In both cases, these are general kernel build problems, not kpatch bugs. @sm00th , since you've been doing the detective work here, do you want to continue pursuing these upstream? Should kpatch check for (1) in kpatch-build and report that the configuration combination is not supported (yet)?

@aliceinwire
Copy link
Contributor Author

Should kpatch check for (1) in kpatch-build and report that the configuration combination is not supported (yet)?
It would be useful, to warning users for now.

@aliceinwire aliceinwire changed the title sibling call from callable instruction with modified stack frame ld: final link failed: File truncated Nov 28, 2018
@sm00th
Copy link
Contributor

sm00th commented Nov 28, 2018

@sm00th , since you've been doing the detective work here, do you want to continue pursuing these upstream?

The first issue seems to be a linker problem, I've managed to hack up a reproducer for it and bisect it down to a specific commit in ld, filed a bug here: https://sourceware.org/bugzilla/show_bug.cgi?id=23930

Should kpatch check for (1) in kpatch-build and report that the configuration combination is not supported (yet)?

Since it is not kpatch's issue I see no reason to work around it, I think this issue is enough for those who might hit it.

@sm00th
Copy link
Contributor

sm00th commented Nov 29, 2018

Proposed a patch for the second issue: https://lore.kernel.org/lkml/20181129135133.31369-1-asavkov@redhat.com/T/#u

@jpoimboe
Copy link
Member

I'm getting a linker seg fault when running kpatch-build against a stock Fedora 28 kernel (4.19.8-200.fc28.x86_64)

scripts/link-vmlinux.sh: line 85: 11952 Segmentation fault      (core dumped) ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} -T ${lds} ${objects}

@sm00th
Copy link
Contributor

sm00th commented Jul 30, 2019

Both issues should be resolved now, binutils fix is in 2.32, kernel patch is in kernels 5.2+.

Is anyone willing to retest this or can we just close this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants