Date: Fri, 16 Apr 1999 20:32:20 -0400 Message-Id: <199904170032.UAA10579@envy.delorie.com> From: DJ Delorie 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 Precedence: bulk > 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.