5

It's said Position Independent Code only uses relative position instead of absolute positions, how's this implemented in c and assembly respectively?

Let's take char test[] = "string"; as an example, how to reference it by relative address?

makes
  • 6,438
  • 3
  • 40
  • 58
mysql_go
  • 2,269
  • 4
  • 20
  • 20

3 Answers3

2

In C, position-independent code is a detail of the compiler's implementation. See your compiler manual to determine whether it is supported and how.

In assembly, position-independent code is a detail of the instruction set architecture. See your CPU manual to find out how to read the PC (program counter) register, how efficient that is, and what the recommended best practices are in translating a code address to a data address.

Position-relative data is less popular now that code and data are separated into different pages on most modern operating systems. It is a good way to implement self-contained executable modules, but the most common such things nowadays are viruses.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • @mysql: I'm referring to data, not object code. Subroutine calls are usually PC-relative, like all jumps. (Calls into DLLs can be exceptions, though.) PIC refers to accesses to globals, see the GCC manpage or your compiler manual. – Potatoswatter Apr 04 '11 at 07:47
  • @Potatoswatter,I still don't get it,maybe a detailed question will make things clear...why does this answer say that the original solution in the question used absolute address `str`? http://stackoverflow.com/questions/5094934/loading-raw-code-from-c-program/5095573#5095573 – mysql_go Apr 04 '11 at 11:06
  • @mysql_go: The instruction `movl $str, %ecx`, specifically operand `$str`, attempts to load from an absolute address. However, the linker cannot determine an address in a code segment, and therefore cannot assemble that instruction. The solution to that question implements PIC as a kind of hack. The question itself specifies the way that the string became position-independent, which is what's missing from your question. `char test[] = "string";` by itself will be allocated however the platform does it by default, which may bear no relation to PIC. – Potatoswatter Apr 04 '11 at 11:45
  • @Potatoswatter,how does it refer to that string if `$str` can't be used? – mysql_go Apr 07 '11 at 15:22
  • @mysql: In that question? By arranging for `$str` to immediately follow a `call` instruction so it is pushed to the stack as a return address. Note that the label `str` is not actually used at all. – Potatoswatter Apr 07 '11 at 17:22
2

On x86, position-independent code in principle looks like this:

        call 1f
1:      popl %ebx

followed by use of ebx as a base pointer with a displacement equal to the distance between the data to be accessed and the address of the popl instruction.

In reality it's often more complicated, and typically a tiny thunk function might be used to load the PIC register like this:

load_ebx:
        movl 4(%esp),%ebx
        addl $some_offset,%ebx
        ret

where the offset is chosen such that, when the thunk returns, ebx contains a pointer to a designated special point in the program/library (usually the start of the global offset table), and then all subsequent ebx-relative accesses can simply use the distance between the desired data and the designated special point as the offset.

On other archs everything is similar in principle, but there may be easier ways to load the program counter. Many simply let you use the pc or ip register as an ordinary register in relative addressing modes.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
0

In pseudo code it could look like:

lea str1(pc), r0 ; load address of string relative to the pc (assuming constant strings, maybe)
st r0, test  ; save the address in test (test could also be PIC, in which case it could be relative
             ; to some register)

A lot depends on your compiler and CPU architecture, as the previous answer stated. One way to find out would be to compile with the appropriate flags (-PIC -S for gcc) and look at the assembly language you get.

Richard Pennington
  • 19,673
  • 4
  • 43
  • 72