Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a linker generate absolute virtual addresses when linking

Assume a simple hello world in C, compiled using gcc -c to an object file and disassembled using objdump will looks like this:

_main:
       0:   55  pushq   %rbp
       1:   48 89 e5    movq    %rsp, %rbp
       4:   c7 45 fc 00 00 00 00    movl    $0, -4(%rbp)
       b:   c7 45 f8 05 00 00 00    movl    $5, -8(%rbp)
      12:   8b 05 00 00 00 00   movl    (%rip), %eax

As you can see the memory addresses are 0, 1, 4, .. and so on. They are not actual addresses.

Linking the object file and disassembling it looks like this:

_main:
100000f90:  55  pushq   %rbp
100000f91:  48 89 e5    movq    %rsp, %rbp
100000f94:  c7 45 fc 00 00 00 00    movl    $0, -4(%rbp)
100000f9b:  c7 45 f8 05 00 00 00    movl    $5, -8(%rbp)
100000fa2:  8b 05 58 00 00 00   movl    88(%rip), %eax

My question is, is 100000f90 an actual address of a byte of virtual memory or is it an offset?

How can the linker give an actual address prior to execution? What if that memory address isn't available when executing? What if I execute it on another machine with much less memory (maybe paging kicks in here).

Is't it the job of the loader to assign actual addresses?

Is the linker generating actual addresses for he final executable file?

like image 383
Joe Avatar asked Mar 16 '19 17:03

Joe


People also ask

How are virtual addresses generated?

Each address generated by a thread (called a virtual address) is translated in hardware to a physical address. This happens during every memory reference. Results in two views of memory, called address spaces: Virtual address space is what the program sees.

Can references to two different virtual addresses map to the same physical address?

This is because both 0 to 4 MB and 2 GB to (2 GB + 4 MB) in the virtual address space are mapped to the same memory location (0 to 4 MB) in the physical address space. Hence, it is possible for two virtual addresses VA1 and VA2 to point to the same physical address PA.

How are virtual addresses translated to physical addresses?

The CPU manages translation of virtual to physical addresses using its Memory Management Unit (MMU). A virtual address is specified as a offset from the start of a memory segment; these segments are used by the kernel and user processes to hold their text, stack, data, and other regions.


1 Answers

(The following answers assume that the linker is not creating a position-independent executable.)

My question is, is 100000f90 an actual address of a byte of virtual memory or is it an offset?

It's the actual virtual address. Strictly speaking, it is the offset from the base of the code segment, but since modern operating systems always set the base of the code segment to 0, it is effectively the actual virtual address.

How can the linker give an actual address prior to execution? What if that memory address isn't available when executing? What if I execute it on another machine with much less memory (maybe paging kicks in here).

Each process gets its own separate virtual address space. Because it is virtual memory, the amount of physical memory in the machine doesn't matter. Paging is the process by which virtual addresses get mapped to physical address.

Isn't it the job of the loader to assign actual addresses?

Yes, when creating a process, the operating system loader allocates physical page frames for the process and maps the pages into the process's virtual address space. But the virtual addresses are those assigned by the linker.

like image 105
prl Avatar answered Oct 14 '22 16:10

prl