Fix PR ld/20545 - relaxation bugs in avr backend
Prior to the patch, addends for relocs were being adjusted even if
they went beyond an alignment boundary. This is wrong - to
preserve alignment constraints, the relaxation logic adds as many padding
bytes at the alignment boundary as was deleted, so addends beyond the
boundary should not be adjusted. avr-prop-7.s reproduces this
scenario.
Also, prior to this patch, the relaxation logic assumed that the addr
parameter pointed to the middle of the instruction to be deleted, and
that addr - count would therefore be the shrinked instruction's
address. This is true when actually shrinking instructions.
The alignment constraints handling logic also invokes the same logic
though, with addr as the starting offset of padding bytes and
with count as the number of bytes to be deleted. Calculating the
shrinked insn's address as addr - count is obviously wrong in this
case - that offset would point to count bytes before the last
non-padded byte. avr-prop-8.s reproduces this scenario.
To fix scenario 1, the patch adds an additional check to ensure reloc addends
aren't adjusted if they cross a shrink boundary. The shrink boundary
is either the section size or an alignment boundary. Addends pointing
at an alignment boundary don't need to be adjusted, as padding would
occur and keep the boundary the same. Addends pointing at section size
need to be adjusted though, as no padding occurs and the section size
itself would get decremented. The patch records whether padding
occured (did_pad) and uses that to detect and handle this condition.
To fix scenario 2, the patch adds an additional parameter
(delete_shrinks_insn) to elf32_avr_relax_delete_bytes to distinguish
instruction bytes deletion from padding bytes deletion. It then uses that to
correctly set shrinked_insn_address.
bfd/ChangeLog:
2016-09-02 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
PR ld/20545
* elf32-avr.c (elf32_avr_relax_delete_bytes): Add parameter
delete_shrinks_insn. Modify computation of shrinked_insn_address.
Compute shrink_boundary and adjust addend only if
addend_within_shrink_boundary.
(elf32_avr_relax_section): Modify calls to
elf32_avr_relax_delete_bytes to pass extra parameter.
ld/ChangeLog:
2016-09-02 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
PR ld/20545
* testsuite/ld-avr/avr-prop-7.d: New test.
* testsuite/ld-avr/avr-prop-7.s: New test.
* testsuite/ld-avr/avr-prop-8.d: New test.
* testsuite/ld-avr/avr-prop-8.s: New test.
Fix PR ld/20545 - relaxation bugs in avr backend
Prior to the patch, addends for relocs were being adjusted even if
they went beyond an alignment boundary. This is wrong - to
preserve alignment constraints, the relaxation logic adds as many padding
bytes at the alignment boundary as was deleted, so addends beyond the
boundary should not be adjusted. avr-prop-7.s reproduces this
scenario.
Also, prior to this patch, the relaxation logic assumed that the addr
parameter pointed to the middle of the instruction to be deleted, and
that addr - count would therefore be the shrinked instruction's
address. This is true when actually shrinking instructions.
The alignment constraints handling logic also invokes the same logic
though, with addr as the starting offset of padding bytes and
with count as the number of bytes to be deleted. Calculating the
shrinked insn's address as addr - count is obviously wrong in this
case - that offset would point to count bytes before the last
non-padded byte. avr-prop-8.s reproduces this scenario.
To fix scenario 1, the patch adds an additional check to ensure reloc addends
aren't adjusted if they cross a shrink boundary. The shrink boundary
is either the section size or an alignment boundary. Addends pointing
at an alignment boundary don't need to be adjusted, as padding would
occur and keep the boundary the same. Addends pointing at section size
need to be adjusted though, as no padding occurs and the section size
itself would get decremented. The patch records whether padding
occured (did_pad) and uses that to detect and handle this condition.
To fix scenario 2, the patch adds an additional parameter
(delete_shrinks_insn) to elf32_avr_relax_delete_bytes to distinguish
instruction bytes deletion from padding bytes deletion. It then uses that to
correctly set shrinked_insn_address.
bfd/ChangeLog:
2016-09-02 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
PR ld/20545
* elf32-avr.c (elf32_avr_relax_delete_bytes): Add parameter
delete_shrinks_insn. Modify computation of shrinked_insn_address.
Compute shrink_boundary and adjust addend only if
addend_within_shrink_boundary.
(elf32_avr_relax_section): Modify calls to
elf32_avr_relax_delete_bytes to pass extra parameter.
ld/ChangeLog:
2016-09-02 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
PR ld/20545
* testsuite/ld-avr/avr-prop-7.d: New test.
* testsuite/ld-avr/avr-prop-7.s: New test.
* testsuite/ld-avr/avr-prop-8.d: New test.
* testsuite/ld-avr/avr-prop-8.s: New test.
Fix PR 13402
Fix incorrect adjustment of diff relocs when relaxing, and thus the
resulting source line to address mismatch.
Fix two issues when adjusting diff relocs to account for
deleted bytes.
1. Don't adjust the difference if the end address is the shrinked
insn's address i.e. use < instead of <=. The relaxation code deletes
count bytes from or after shrinked_insn_address, so the difference
between start_address and end_address should remain unchanged in this
case.
2. Adjust the reloc addend if the difference is to be adjusted and
symval + reloc addend is past the shrinked insn address. This is
because for a typical sym1 - sym2 diff reloc, sym1 is .text +
irel->r_addend, and the addend should be reduced to account for the
shrinked insn.
For example, assume the reloc value is .text + 0x8 with .text = 0, the
diff value in the object file = 0x4, and shrinked_insn_address = 0x4
with count = 0x2. Then the existing code writes 0x2 into the object
file to account for the deleted bytes, as shrinked_insn_address lies
between 0x8 and 0x8 - 0x4 = 0x4, but leaves the addend as is. The next
time the reloc is looked at, the code sees if a shrinked_insn_address
lies between 0x8 and 0x8 - 0x2 = 0x6, instead of 0x6 and 0x4. If there
happens to be one, then the diff value in the object file ends up
getting reduced again.
bfd/
2017-06-27 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
PR ld/13402
* elf32-avr.c (elf32_avr_adjust_diff_reloc_value): Adjust
reloc addend if necessary. Adjust diff only if
shrinked_insn_address < end_address.
ld/
2017-06-27 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
PR ld/13402
* testsuite/ld-avr/pr13402.d: New test.
* testsuite/ld-avr/pr13402.s: New test.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
Fix PR21404 - assertion fail when calculating symbol size
Fix a host of problems related to adjustment of
symbol values and sizes when relaxing for avr.
1. Adjust symbol size first before adjusting symbol
value. Otherwise, a symbol whose value just got adjusted to the
relaxed address also ends up getting resized. See pr21404-1.s.
2. Reduce symbol sizes only if their span is below an
alignment boundary. Otherwise, the size gets decremented once when the
actual instruction is relaxed and padding bytes are added, and again
when the padding bytes are deleted (if padding ends up being unnecessary).
pr21404-2.s addresses that, and this bug is really the root cause of PR21404.
3. Adjust all symbol values before an alignment boundary.
Previous code did not adjust symbol values if they fell in the
would-be padded area, resulting in incorrect symbol values in some
cases (see pr21404-3.s).
4. Increase symbol sizes if alignment directives require so.
As pr21404-4.s shows
.global nonzero_sym
L1:
jmp L1
nonzero_sym:
nop
nop
.p2align 2
.size nonzero_sym, .-nonzero_sym
The two nops satisfy the 4 byte alignment at assembly time and
therefore the size of nonzero_sym is 4. Relaxation shortens
the 4 byte jmp to a 2 byte rjmp, and to satisfy 4 byte alignment
the code places 2 extra padding bytes after the nops, increasing
nonzero_sym's size by 2. This wasn't handled before.
If the assembly code does not have any align directives, then the
boundary is the section size, and symbol values and sizes == boundary
should also get adjusted. To handle that case, add a did_pad variable
and use that to determine whether it should use < boundary or <= boundary.
Also get rid of reloc_toaddr, which is now redundant. toaddr is now not
adjusted to handle the above case - the newly added
did_pad variable does the job.
pr21404-{5,6,7,8} are the same testcases written for local symbols, as
the code handles them slightly differently.
AVR/ld: Propagate link-relax elf header flag correctly.
The AVR target has an elf header flag to indicate if an object was
assembler ready for linker relaxation. If a partial link is performed
then it is important that the link-relax flag in the output object is
set correctly, otherwise, during the final link, we might try to perform
linker relaxation on code that was not assembled suitably.
As the link-relax elf header covers the entire object file we must be
conservative when setting the flag in the output object, so, for a
partial link, any input object that does not have the link-relax flag
set will cause the output object to also not have the link-relax flag
set.
This conservative approach could be softened in future, we only need to
disable the link relax flag if an input file is not marked link-relax
ready, and the input file contains a relaxable section. However, I've
left this optimisation for a later day.
For the final link I've overloaded the use of the link-relax elf header
flag, in a final executable, the flag now indicates if the executable
was built with linker relaxation on or not.
ld/ChangeLog:
* emultempl/avrelf.em: Add include of elf/avr.h.
(avr_finish): New function.
(LDEMUL_FINISH): Added.
ld/testsuite/ChangeLog:
* ld-avr/relax-elf-flags-01.d: New file.
* ld-avr/relax-elf-flags-02.d: New file.
* ld-avr/relax-elf-flags-03.d: New file.
* ld-avr/relax-elf-flags-04.d: New file.
* ld-avr/relax-elf-flags-05.d: New file.
* ld-avr/relax-elf-flags-06.d: New file.
* ld-avr/relax-elf-flags-07.d: New file.
* ld-avr/relax-elf-flags-08.d: New file.
* ld-avr/relax-elf-flags-a.s: New file.
* ld-avr/relax-elf-flags-b.s: New file.
AVR/ld: Propagate link-relax elf header flag correctly.
The AVR target has an elf header flag to indicate if an object was
assembler ready for linker relaxation. If a partial link is performed
then it is important that the link-relax flag in the output object is
set correctly, otherwise, during the final link, we might try to perform
linker relaxation on code that was not assembled suitably.
As the link-relax elf header covers the entire object file we must be
conservative when setting the flag in the output object, so, for a
partial link, any input object that does not have the link-relax flag
set will cause the output object to also not have the link-relax flag
set.
This conservative approach could be softened in future, we only need to
disable the link relax flag if an input file is not marked link-relax
ready, and the input file contains a relaxable section. However, I've
left this optimisation for a later day.
For the final link I've overloaded the use of the link-relax elf header
flag, in a final executable, the flag now indicates if the executable
was built with linker relaxation on or not.
ld/ChangeLog:
* emultempl/avrelf.em: Add include of elf/avr.h.
(avr_finish): New function.
(LDEMUL_FINISH): Added.
ld/testsuite/ChangeLog:
* ld-avr/relax-elf-flags-01.d: New file.
* ld-avr/relax-elf-flags-02.d: New file.
* ld-avr/relax-elf-flags-03.d: New file.
* ld-avr/relax-elf-flags-04.d: New file.
* ld-avr/relax-elf-flags-05.d: New file.
* ld-avr/relax-elf-flags-06.d: New file.
* ld-avr/relax-elf-flags-07.d: New file.
* ld-avr/relax-elf-flags-08.d: New file.
* ld-avr/relax-elf-flags-a.s: New file.
* ld-avr/relax-elf-flags-b.s: New file.
AVR/ld: Propagate link-relax elf header flag correctly.
The AVR target has an elf header flag to indicate if an object was
assembler ready for linker relaxation. If a partial link is performed
then it is important that the link-relax flag in the output object is
set correctly, otherwise, during the final link, we might try to perform
linker relaxation on code that was not assembled suitably.
As the link-relax elf header covers the entire object file we must be
conservative when setting the flag in the output object, so, for a
partial link, any input object that does not have the link-relax flag
set will cause the output object to also not have the link-relax flag
set.
This conservative approach could be softened in future, we only need to
disable the link relax flag if an input file is not marked link-relax
ready, and the input file contains a relaxable section. However, I've
left this optimisation for a later day.
For the final link I've overloaded the use of the link-relax elf header
flag, in a final executable, the flag now indicates if the executable
was built with linker relaxation on or not.
ld/ChangeLog:
* emultempl/avrelf.em: Add include of elf/avr.h.
(avr_finish): New function.
(LDEMUL_FINISH): Added.
ld/testsuite/ChangeLog:
* ld-avr/relax-elf-flags-01.d: New file.
* ld-avr/relax-elf-flags-02.d: New file.
* ld-avr/relax-elf-flags-03.d: New file.
* ld-avr/relax-elf-flags-04.d: New file.
* ld-avr/relax-elf-flags-05.d: New file.
* ld-avr/relax-elf-flags-06.d: New file.
* ld-avr/relax-elf-flags-07.d: New file.
* ld-avr/relax-elf-flags-08.d: New file.
* ld-avr/relax-elf-flags-a.s: New file.
* ld-avr/relax-elf-flags-b.s: New file.
AVR/ld: Propagate link-relax elf header flag correctly.
The AVR target has an elf header flag to indicate if an object was
assembler ready for linker relaxation. If a partial link is performed
then it is important that the link-relax flag in the output object is
set correctly, otherwise, during the final link, we might try to perform
linker relaxation on code that was not assembled suitably.
As the link-relax elf header covers the entire object file we must be
conservative when setting the flag in the output object, so, for a
partial link, any input object that does not have the link-relax flag
set will cause the output object to also not have the link-relax flag
set.
This conservative approach could be softened in future, we only need to
disable the link relax flag if an input file is not marked link-relax
ready, and the input file contains a relaxable section. However, I've
left this optimisation for a later day.
For the final link I've overloaded the use of the link-relax elf header
flag, in a final executable, the flag now indicates if the executable
was built with linker relaxation on or not.
ld/ChangeLog:
* emultempl/avrelf.em: Add include of elf/avr.h.
(avr_finish): New function.
(LDEMUL_FINISH): Added.
ld/testsuite/ChangeLog:
* ld-avr/relax-elf-flags-01.d: New file.
* ld-avr/relax-elf-flags-02.d: New file.
* ld-avr/relax-elf-flags-03.d: New file.
* ld-avr/relax-elf-flags-04.d: New file.
* ld-avr/relax-elf-flags-05.d: New file.
* ld-avr/relax-elf-flags-06.d: New file.
* ld-avr/relax-elf-flags-07.d: New file.
* ld-avr/relax-elf-flags-08.d: New file.
* ld-avr/relax-elf-flags-a.s: New file.
* ld-avr/relax-elf-flags-b.s: New file.
AVR/ld: Propagate link-relax elf header flag correctly.
The AVR target has an elf header flag to indicate if an object was
assembler ready for linker relaxation. If a partial link is performed
then it is important that the link-relax flag in the output object is
set correctly, otherwise, during the final link, we might try to perform
linker relaxation on code that was not assembled suitably.
As the link-relax elf header covers the entire object file we must be
conservative when setting the flag in the output object, so, for a
partial link, any input object that does not have the link-relax flag
set will cause the output object to also not have the link-relax flag
set.
This conservative approach could be softened in future, we only need to
disable the link relax flag if an input file is not marked link-relax
ready, and the input file contains a relaxable section. However, I've
left this optimisation for a later day.
For the final link I've overloaded the use of the link-relax elf header
flag, in a final executable, the flag now indicates if the executable
was built with linker relaxation on or not.
ld/ChangeLog:
* emultempl/avrelf.em: Add include of elf/avr.h.
(avr_finish): New function.
(LDEMUL_FINISH): Added.
ld/testsuite/ChangeLog:
* ld-avr/relax-elf-flags-01.d: New file.
* ld-avr/relax-elf-flags-02.d: New file.
* ld-avr/relax-elf-flags-03.d: New file.
* ld-avr/relax-elf-flags-04.d: New file.
* ld-avr/relax-elf-flags-05.d: New file.
* ld-avr/relax-elf-flags-06.d: New file.
* ld-avr/relax-elf-flags-07.d: New file.
* ld-avr/relax-elf-flags-08.d: New file.
* ld-avr/relax-elf-flags-a.s: New file.
* ld-avr/relax-elf-flags-b.s: New file.