www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/04/16/19:33:05

Date: Fri, 16 Apr 1999 20:32:20 -0400
Message-Id: <199904170032.UAA10579@envy.delorie.com>
From: DJ Delorie <dj AT delorie DOT com>
To: djgpp AT delorie DOT com
In-reply-to: <01be8861$4f03b1c0$LocalHost@thendren> (paradox@gye.satnet.net)
Subject: Re: RELOC_REL32
References: <01be8861$4f03b1c0$LocalHost AT thendren>
Reply-To: djgpp AT delorie DOT com
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

> say i allocate the data for "section" at 0x100, and it's original paddr was
> 0x4. say the symbol has a vaddr of 0x32 in the relocation entry, and in
> real-life it's at say 0x200.
>
> then, if i understand this, is should come up with:
> 
> address = 0x200 - 0x100;
> 
> or,
> 
> *(long *)0x100+0x32 += 0x200 - 0x100;

Not enough unique numbers.  Let me try:

Let's say you have an object with a section set up with a base address
of 11 (decimal).  There's a reloc against symbol "foo" at offset 3 in
that section (address 14), which currently contains the value 47.
When you link the object, the section which was set up for a base of
11 is moved to have a base of 100 (thus, address 103 now contains the
value 47).  We look up symbol "foo" and find that it's at address 65.
Here's the math, for a jmp instruction example:

* start with the 47 that's now stored at address 103.  This is some
  offset that gcc determined it needed, like a field in a struct or an
  element of an array.  For REL32 it also accounts for the offset of
  the reloc in the section, but for now just worry that it's an offset
  gcc put there.  This is often negative for REL32s.

* The section was moved 100-11 bytes, or 89 bytes.  Subtract 89 from
  the 47 to get -42.  We were pointing 47 bytes ahead of the jmp, but
  we moved the jmp ahead, so now we must point backwards to refer to
  that location.

* Now we apply the symbol's address.  foo is at 65, so add 65 to -42
  to get 23.

* Store the 23 back into the jmp instruction.

Of course, you'll have to try and see.  This stuff is pretty hairy.

> long *p = (long *)malloc;
> 
> *(long *)section+r->r_vaddr += p - section;

Probably, but you might need *(long *)(section+r->r_vaddr) to avoid
pointer math problems.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019