This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]