bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gold/22233] [2.29 Regression] gold segfault in relocate_erratum_stu


From: peter.smith at linaro dot org
Subject: [Bug gold/22233] [2.29 Regression] gold segfault in relocate_erratum_stub on aarch64-linux-gnu
Date: Mon, 13 Nov 2017 14:21:48 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=22233

--- Comment #2 from Peter Smith <peter.smith at linaro dot org> ---
This is related to PR21868, the fix for that PR has a bug that triggers when
the stub_owner section also needs erratum fixes. In this case the address of
the thunks is not calculated correctly, resulting in a segfault for the example
in this PR. 

This fault is also visible in the example for PR21868, although in that case it
doesn't cause a segfault due to the incorrect address being within the bounds
of the program. We can observe this in PR21868 by disassembling the shared
library (from PR21868) with and without patches:

Without patches:
    5ffc:       d00000c0        adrp    x0, 1f000 <__FRAME_END__+0x16fa8>
    6000:       f946bc00        ldr     x0, [x0,#3448]
    6004:       f901d001        str     x1, [x0,#928]

With patches:
    5ffc:       100c8020        adr     x0, 1f000 <__FRAME_END__+0x16fa0>
    6000:       f946bc00        ldr     x0, [x0,#3448]
    6004:       f901d001        str     x1, [x0,#928]
    ....
    8050:       f901d001        str     x1, [x0,#928]
    8054:       14000000        b       8054
<asn1zmencodingzm0zi9zi5zmHjPVpmCG8yiHLrShsHhCjx_DataziASN1ziInternal_intOfBytes2_entry+0xb4>

We can see that the adrp at 5ffc has been converted to an adr. We can also see
the addition of the patch at 8050 (the str to x1 has been copied). Note that
the branch in the patch points to itself, if the
fix_errata_and_relocate_erratum_stubs had been applied correctly then the b
should have been to 0x6008 (after the str). Had the patch been more than an ADR
range away from 0x5ffc (so the adrp to adr transformation could not be applied)
then this would have caused a hang at run time.

In the example attached to this case the incorrect address causes a segfault.

I think that the offending bit of code is in
fix_errata_and_relocate_erratum_stubs(). There is some code that detects when
the (pview.is_input_output_view) is set, which means that the pview and
pview.address need to be adjusted by the view_offset. Unfortunately this
adjustment is missing in one case:  

stub_table->relocate_erratum_stub(
            stub,
            pview.view + view_offset + 
            (stub_table->address() - pview.address));

Note that the pview.address on the last line is not adjusted for the
view_offset so it will contain the base address of the output section and not
the stub_table section. This will mean that relocate_erratum_stub gets the
wrong address to relocate. 

I think that this function call should be:
stub_table->relocate_erratum_stub(
            stub,
            pview.view + view_offset + 
            (stub_table->address() - (pview.address + view_offset)));

With this adjustment both PR21868 and the example in this PR look to be patched
correctly.

For people stuck with old versions of the tools possible workarounds are:
- Compile with -ffunction-sections, this should reduce the size of sections
which will lower the probability that the stub-owner needs patching.
- Add or arrange for a non-zero sized input section that definitely does not
need patches to be the end of the OutputSection. In most cases this seems to be
one of the sections from crtn.o, crtendS.o, but in these examples they are of 0
size which prevents them from being the stub owner.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]