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]

RE: attempt to move .org backwards


Hi All,

In further analysis, I understood that 
- I was wrong. 'growth' should be calculated based on next instruction
only
- 'stretch' shall not be added to the address of instructions that
follows '.org' directive.

An '.org' directive advances the location counter of the current section
to offset specified. So, shrinking or expanding instructions before
'.org' directive shall not cause any change for instructions that follos
'.org' directive.

Binutils-2.22
gas/write.c : relax_segment

> 2637   know (fragP->fr_next);
> 2638   after = fragP->fr_next->fr_address + stretch;
> 2639   growth = target - after;
> 2640   if (growth < 0)

The above code shall be modified as follows:
2637   know (fragP->fr_next);
2638   after = fragP->fr_next->fr_address; // stretch shall not be added
2639   stretch = 0; // stretch should be reset as '.org' defines new
offset
2640   growth = target - after;
2641   if (growth < 0)

Is my understanding about 'relax_segment' function correct?

Regards,
Pitchumani.S

> -----Original Message-----
> From: binutils-owner@sourceware.org
[mailto:binutils-owner@sourceware.org]
> On Behalf Of S, Pitchumani
> Sent: Monday, March 05, 2012 3:53 PM
> To: binutils@sourceware.org
> 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


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