Need for relocations in an exe

This is a discussion on Need for relocations in an exe within the Windows Programming forums, part of the Platform Specific Boards category; Why is there a need for relocation table when every element in an exe is at a relative offset from ...

  1. #1
    Registered User
    Join Date
    Aug 2011
    Posts
    385

    Need for relocations in an exe

    Why is there a need for relocation table when every element in an exe is at a relative offset from the base of the image?? I mean even if the image gets dispacled by a positive offset of say 0X60000, where is the need for relocation table, as we would anyways be using RVA's which would be relative to the new base??
    Last edited by juice; 03-15-2012 at 12:33 AM.

  2. #2
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,597
    I'm a bit rusty on some of this low level stuff but here goes. My friends here can correct me where I'm wrong.

    You essentially answered your own question. It does not affect the code because addresses are relative to the base address of where the image is loaded. The need for relocation is to allow an image to be loaded in at any address and run correctly regardless of the base address. If you built code that had to be at a specific address it might not run on certain machines since it is highly likely that address will be in use. You can specify base addresses of DLLs and EXEs in MSVS and this is extremely useful for certain types of debugging as long as you know what you are doing and the general memory layout of your particular machine at a given time. This can be useful when doing remote debugging on embedded systems since it is likely the embedded system (read: Win XPE or Windows Embedded Standard) will not have nearly as many programs and services running as a normal everyday system. It is relatively safe, easy, and sometimes necessary to specify the base address on embedded systems.

    The EXE doesn't need to be relocated by itself but the EXE supports relocation b/c the OS will definitely relocate it. So the file format supports relocation but really only requires that it be loaded at some base address. For more information about the Windows PE file format you can check MSDN. There is also a lot of information about other executable file formats on the internet.

    Note that this info applies to native code. I am not sure of the exact loading and fixup process for managed assemblies.

  3. #3
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Ya, but where is the need for relocation table, because all the refernces are anyways relative??

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    I think relocations are mostly for object files, not executables.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  5. #5
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    612
    Quote Originally Posted by juice View Post
    Ya, but where is the need for relocation table, because all the refernces are anyways relative??
    Except for the calling of imported functions. I suggest you read the info on MSDN that you've been pointed to several times (Part 1, Part 2) It contains 12 paragraphs on the subject of relocations.

  6. #6
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,263
    Quote Originally Posted by juice View Post
    Ya, but where is the need for relocation table, because all the refernces are anyways relative??
    Only code references are PC-relative. The x86 architecture does not provide PC-relative data addressing. In other words if you have some static data like a global variable, it must be addressed with an absolute, not relative, address.

    On Windows, executables have a fixed base address unless otherwise specified. Therefore an EXE does not need data relocation entries. DLLs, on the other hand, can be rebased at runtime and therefore must include relocations for all of their static data items.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Right. I forgot about DLLs.

  8. #8
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Quote Originally Posted by brewbuck View Post
    Only code references are PC-relative. The x86 architecture does not provide PC-relative data addressing. In other words if you have some static data like a global variable, it must be addressed with an absolute, not relative, address.
    Why can't the global data be at relative offsets?? Doesn't all the data go into the .data section which itself is at a relative offset from the base of the image..

  9. #9
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,263
    Quote Originally Posted by juice View Post
    Why can't the global data be at relative offsets?? Doesn't all the data go into the .data section which itself is at a relative offset from the base of the image..
    How does the EXECUTING CODE know where it is? As I said, there is no such thing as PC-relative data addressing on x86 architectures.

    If you still don't get it, do the following: write me an assembly language instruction (a single instruction) which accesses the DWORD a distance of 1000 bytes away from the instruction. You'll find that it is not possible.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,359
    Why can't the global data be at relative offsets?
    O_o

    They can be. It just happens that some platforms directly support it, some don't, and others require some expensive trickery.

    Doesn't all the data go into the .data section which itself is at a relative offset from the base of the image.
    You have missed something important in what brewbuck is saying.

    The program loader, the bit of the operating system that reads a "PE" format executable and loads it into memory, patches offsets, what he said as "rebased", for global data.

    That is something that the operating system is doing. If the hardware fully supported "PIC" that trickery wouldn't be necessary. The compiler could, for example, stuff global data entries relative to an offset, store an additional offset per function using that global data at a known offset from a specific instruction within that function, and combine those offsets to get a true offset from the program counter.

    a single instruction
    o_O

    Why does it have to be a single instruction?

    I'm not joking; I don't get the requirement.

    I could write some assembler to address data relative to the program counter even on x86. (Granted, I'd have to modify the linker to patch the relative offset for it to be practical.) The code would certainly take a lot more than one instruction. I think it takes more than one to get the program counter. (I'm not going to do this kludge; I have no interest in counting instructions over and over again to debug code for something I don't see as useful.) The "one instruction" thing seems like weird requirement. (I guess you probably can do it with one instruction on x86-64.) It isn't practical to do this by hand anyway.

    Soma

  11. #11
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,263
    Quote Originally Posted by phantomotap View Post
    Why does it have to be a single instruction?

    I'm not joking; I don't get the requirement.
    Because on Windows static data is always addressed with absolute addresses. This is just a convention, but one which is completely adhered to.

    On Linux it actually works differently and uses a mechanism that involves this idiom:

    Code:
    call @1
    @1:
    pop ebx # get PC
    mov eax, [ebx+offset] # index relative to PC
    In actuality there is more involved, but this is what I meant by using a single instruction because that's how Windows does things.

    EDIT: Also, I was trying to highlight the fact that x86 doesn't have direct support for PC-relative addressing. Sure, you can achieve it but then again you can achieve almost anything you want if you work at it.
    Last edited by brewbuck; 03-16-2012 at 10:16 PM.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  12. #12
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,359
    Because on Windows static data is always addressed with absolute addresses.
    Ah, I see. I didn't realize you were literally talking about something that would work in "real life" with the Windows program loader. I was just thinking a viable x86 strategy.

    Soma

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21