>That address seems to come from >here: https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/boot/pm.c#L124 > >``` >protected_mode_jump(boot_params.hdr.code32_start, > (u32)&boot_params + (ds() << 4)); >``` > >That boot_params.hdr.code32_start field is probably either invalid (bad reloc or something else causing the bootloader to >calculate the wrong address) or valid but the thing it thinks it is pointing to wasn't loaded (missing PT_LOAD etc.).boot_params.hdr.code32_start field is valid :) It is 0x100000, like expected (btw thanks for those links on info how kernel boots, they were pretty useful). I checked it is valid using trace: void go_to_protected_mode(void) { if (boot_params.hdr.code32_start == 0x100000) puts("go_to_protected_mode 1\n"); else puts("go_to_protected_mode 2\n"); while (1) {}; I had to use infinite loop here, because QEMU does not crash for me, but do domething what looks like reboot and clears all my traces output. Infinite loop helps to see traces text, if placed before dead point.> >Btw, how did you narrow it down to that specific instruction? That's pretty handy.I used very simple approach, did not know how to do that properly :), so inserted infinite loops in asm code: foo: jmp foo And watched for behavior of QEMU. If it just hanged that was fine, I knew I am inside my loop, if QEMU rebooted, I knew it crashed at point I was looking for. So tracing bfd linked kernel and using documentation I found that startup_64 ?is next destination POI, and found that this instruction is the last before QEMU reboots for me.>I think you can also get DSO with -pie I think, but I don't see that either. This is quite mysterious. I also did a quick look at the >linker script and didn't see anything at first glance that would cause DSO output (can linker scripts even control EType?). The >bootloader might not even look at the EType though. > >-- Sean SilvaI think best way would be to look at what is invocation for BFD here. I am pretty sure -shared/-pie flag is just lost because of some configuration issue, probably it checks that we are running bfd may be. Just a guess. George. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170209/e379b810/attachment.html>
>>I think you can also get DSO with -pie I think, but I don't see that either. This is quite mysterious. I also did a quick look at the >>linker script and didn't see anything at first glance that would cause DSO output (can linker scripts even control EType?). The >>bootloader might not even look at the EType though.>> >>-- Sean Silva > >I think best way would be to look at what is invocation for BFD here. I am pretty sure -shared/-pie flag is just lost because of >some configuration issue, probably it checks that we are running bfd may be. Just a guess. > >George.Because reproduce linked with bfd also produced executable for me. George. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170209/b4994c91/attachment.html>
On Thu, Feb 9, 2017 at 1:27 AM, George Rimar <grimar at accesssoftek.com> wrote:> >That address seems to come from >here: https://github.com/ > torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b > 5075173a25/arch/x86/boot/pm.c#L124 > > > >``` > >protected_mode_jump(boot_params.hdr.code32_start, > > (u32)&boot_params + (ds() << 4)); > >``` > > > >That boot_params.hdr.code32_start field is probably either invalid (bad > reloc or something else causing the bootloader to >calculate the wrong > address) or valid but the thing it thinks it is pointing to wasn't loaded > (missing PT_LOAD etc.). > > boot_params.hdr.code32_start field is valid :) It is 0x100000, like > expected >Then I suspect that that segment isn't being loaded. Is there a PT_LOAD that covers that address? Is the bootloader loading it?> (btw thanks for those links on info how kernel boots, they were pretty > useful). >I'm glad you found it useful! Those articles are amazing.> I checked it is valid using trace: > > void go_to_protected_mode(void) > { > if (boot_params.hdr.code32_start == 0x100000) > puts("go_to_protected_mode 1\n"); > else > puts("go_to_protected_mode 2\n"); > while (1) {}; > > I had to use infinite loop here, because QEMU does not crash for me, but > do domething what looks like reboot and clears all my traces output. > Infinite loop helps to see traces text, if placed before dead point. > > > > >Btw, how did you narrow it down to that specific instruction? That's > pretty handy. > > I used very simple approach, did not know how to do that properly :), so inserted > infinite loops in asm code: > foo: > jmp foo > >I suspected something like this :) I've had to do that in the past. btw if you are ever in a tight spot, a good thing to remember is EB FE (jmp -2) which encodes an infinite loop on x86 (all modes, even 16bit I believe). It is small so can easily be patched over most instruction using a hex editor if necessary. -- Sean Silva> And watched for behavior of QEMU. If it just hanged that was fine, I knew > I am inside my loop, if QEMU rebooted, I knew it crashed at point I was > looking for. So tracing bfd linked kernel and using documentation I found > that startup_64 is next destination POI, and found that this instruction > is the last before QEMU reboots for me. > > >I think you can also get DSO with -pie I think, but I don't see that > either. This is quite mysterious. I also did a quick look at the >linker > script and didn't see anything at first glance that would cause DSO output > (can linker scripts even control EType?). The >bootloader might not even > look at the EType though. > > > >-- Sean Silva > > I think best way would be to look at what is invocation for BFD here. I am > pretty sure -shared/-pie flag is just lost because of some configuration > issue, probably it checks that we are running bfd may be. Just a guess. > > George. > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170209/38445e98/attachment.html>
>Then I suspect that that segment isn't being loaded. Is there a PT_LOAD that covers that address? Is the bootloader loading it?I had had to switch to an another task for now and did not had chance to investigate deeper this issue yet. I'll let you know if have something new here.>I suspected something like this :) I've had to do that in the past. btw if you are ever in a tight spot, a good thing to remember is EB FE (jmp -2) which encodes an >infinite loop on x86 (all modes, even 16bit I believe). It is small so can easily be patched over most instruction using a hex editor if necessary. > >-- Sean SilvaNice. I saw this 2 byte jump it was used in 16 bits mode when did something for R_386_PC8 relocations: https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S#L297 George. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170210/4172ac8e/attachment.html>
>>That boot_params.hdr.code32_start field is probably either invalid (bad reloc or something else causing the bootloader to >>calculate the wrong address) or valid but the thing it thinks it is pointing to wasn't loaded (missing PT_LOAD etc.). >boot_params.hdr.code32_start field is valid :) It is 0x100000, like expected > >Then I suspect that that segment isn't being loaded. Is there a PT_LOAD that covers that address? Is the bootloader loading it?That issue is gone. Not sure what changed, but looks something was fixed in LLD during last week. Latest status of booting linux kernel is next currently: At this location, https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/boot/compressed/head_64.S#L424 kernel calls extract_kernel(). And 2 lines below it tries to jmp to the address of decompressed kernel and fails to do that for me. extract_kernel() method is: https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/boot/compressed/misc.c#L334 I added next lines before return: __putstr("hi from extract_kernel"); if ((int) output == 0x1000000) __putstr("== 0x1000000"); output[0] = 0xEB; output[1] = 0xFE; return output; And during boot in shows all text from above and enters infinite loop as expected. So, that means it successfully jumps to 0x1000000, but looks something is wrong in decompressed code. Next destination point should be startup_64?. https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/kernel/head_64.S#L50<https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/arch/x86/kernel/head_64.S#L48> Though as I mentioned it does not reach it for me. Next step I probably going to do is dump/printf-trace that memory area of decompressed kernel to compare with what produced there when BFD is used. Have no better ideas now. George. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170217/a358ea3a/attachment.html>