This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
attempt to move .org backwards
- From: "S, Pitchumani" <Pitchumani dot S at atmel dot com>
- To: <binutils at sourceware dot org>
- Date: Mon, 5 Mar 2012 18:22:40 +0800
- Subject: attempt to move .org backwards
Hi,
I have a doubt regarding '.org' processing in relax_segment function.
Binutils-2.22
gas/write.c : relax_segment
--- code ---
2622 case rs_org:
2623 {
2624 addressT target = offset;
2625 addressT after;
2626
2627 if (symbolP)
2628 {
2629 /* Convert from an actual address to an octet offset
2630 into the section. Here it is assumed that the
2631 section's VMA is zero, and can omit subtracting it
2632 from the symbol's value to get the address offset. */
2633 know (S_GET_SEGMENT (symbolP)->vma == 0);
2634 target += S_GET_VALUE (symbolP) * OCTETS_PER_BYTE;
2635 }
2636
2637 know (fragP->fr_next);
2638 after = fragP->fr_next->fr_address + stretch;
2639 growth = target - after;
2640 if (growth < 0)
2641 {
2642 growth = 0;
2643
2644 /* Don't error on first few frag relax passes.
2655 ... */
2656 if (pass < 2)
2657 {
2658 /* Force another pass. */
2659 ret = 1;
2660 break;
2661 }
2662
2663 /* Growth may be negative, but variable part of frag
2664 cannot have fewer than 0 chars. That is, we can't
2665 .org backwards. */
2666 as_bad_where (fragP->fr_file, fragP->fr_line,
2667 _("attempt to move .org backwards"));
2668
2669 /* We've issued an error message. Change the
2670 frag to avoid cascading errors. */
2671 fragP->fr_type = rs_align;
2672 fragP->fr_subtype = 0;
2673 fragP->fr_offset = 0;
2674 fragP->fr_fix = after - address;
2675 }
2676 }
2677 break;
--- code ---
The above code checks for "attempt to move .org backwards" error.
To find the growth, next instruction's address (+ stretch) is subtracted
from offset of .org directive.
Next instruction's address will be same as .org offset after calculating
address in the first iteration. So, growth will become negative if any
instruction present before .org is stretched.
Example:
0x0000 func1
0x0000 call func2 <== 2/4 byte instruction
0x0002 .org 0x0404
0x0404 func2
0x0404 nop
If call instruction size is stretched to 4 bytes (from 2 bytes),
growth will become -2 ((0x404 + 2) - 0x0404)
But, .org is not moved backwards.
So, I think, growth should be calculated based on previous instruction
address.
Example:
growth = (prev. insn address (including stretch) + prev. insn size) -
offset
Please correct me if I'm wrong.
Regards,
Pitchumani.S