What Is the Hex Address of the Relocated Reference to Swap in Line 5?

Linking

Linking is the procedure of collecting and combining various pieces of code and data into a single file that can be loaded (copied) into retentivity and executed. Linking is performed automatically by programs called linkers, which enable separate compilation.

Table of contents

  1. Overview of compiler drivers
  2. Object files
  3. Symbol resolution
  4. Relocation
  5. Executable object files
  6. Loading executable obj files
  7. Dynamic linking with shared libraries
  8. Appendix

1. Overview of compiler drivers ↑meridian

Near compilation systems provide a compiler driver that invokes the language preprocessor, compiler, assembler, and linker.

invoke GCC driver to build the program: $gcc -O2 -g -o p main.c swap.c

The Pulpit Rock
Fig.i - Phases of compiler driver. Suppose source code is "prog.c".

Steps to translate source file into executable:

  • step1: the driver runs C preprocessor (cpp), translating C file master.c into an ASCII intermediate file chief.i, which is still C code (gcc -E);

                $cpp [other arguments] main.c /tmp/main.i  $cpp main.c primary.i          
  • step2: the commuter runs C compiler (ccl), which translates main.i into an ASCII assembly langu file principal.due south, where various optimizations are performed for the specific arch (gcc -S);

                $ccl /tmp/main.i master.c -O2 [other arguments] -o /tmp/main.s  $gcc -S main.c          
  • step3: the driver runs the assembler (equally), which translates main.south into a relocatable obj file chief.o;

                $every bit [other arguments] -o /tmp/main.o /tmp/principal.s  $gcc -c primary.c $nm principal.o          
  • step4: the driver goes through the aforementioned process to get swap.o;

  • step 5: finally, it runs the linker program ld, which combines principal.o and swap.o, along with the necessary system obj files, to create the executable obj file p.

                $ld -o p [sys obj files and args] /tmp/main.o /tmp/bandy.o          
  • step 6: to run the executable p, type its proper name in shell, which invokes a func in the Os called the loader, which creates a procedure by reading the file and creating an addr space for the procedure. Page table entries for the instrs, data and program stack are created and the register set is inited. And so the loader executes a spring instr to the first instr in the program.

preprocessor (*.c → *.i)

cpp expands all macro definitions and include statements (and anything else starting with a #) and passes the event to the bodily compiler.

compiler (*.i → *.southward)

The Pulpit Rock
Fig.2 - Compiler phases.
  • Lexical analyasis (scanner): reads stream of chars making upward the source code and groups into tokens, including keywords, identifiers, integers, operators and special symbols, etc.

                int a; a = a + ii;  //return: int(keyword), a(id), ;(special symbol) ...          
  • Syntax analysis (parser): the tokens during scanning are grouped together using a context-costless grammer. Ouput is a parse tree or a derivation.

                //to parse a+2 Expr   -> Expr + Expr        -> Variable + Expr        -> T_IDENTIFIER + Expr        -> T_IDENTIFIER + Constant        -> T_IDENTIFIER + T_INTCONSTANT          
  • Semantic analysis: the parse tree or derivation is side by side checked for semantic errors.

                //scanned valid tokens and successfully match rules int arr[2], c; c = arr * ten; //blazon-cheque error: incompatible type          
  • Intermediate code generation: creates intermediate representation for the source code; the representation is easy to generate and easy to interpret into the final assembly lawmaking. Commonly used is 3-accost code (TAC), which is a generic assembly language.

                //source code      |   //TAC codes a = b * c + b * d  |    _t1 = b * c                    |    _t2 = b * d                    |    _t3 = _t1 + _t2                    |    a = _t3          
  • Intermediate code optimization: optimizes the TAC codes to produce the smallest, fastest and most efficient course, still in TAC codes.

                //before opt           |   //after opt _t1 = b * c            |   _t1 = b * c _t3 = _t1 + 0          |   a = _t2 _t3 = b * c _t4 = _t2 + _t3 a = _t4          
  • Object code generation: translate TAC codes into assembly ones. Memory locations are selected for each variable, and instructions are called for each operation.

  • Object code optimization: transforms the obj code into tighter, more efficient obj code, to make efficient use of precessor(s) and registers.

symbol table
a symbol table contains info about all the ids in the program forth with important attributes like blazon and scope. Ids can be found in the lexical analysis phase and added to the symbol table. During the ii phases that follow (syntax and semantic analysis), the compiler updates the id entry in the table to include info nigh its blazon and scope. When generating intermediate code, the type of the var is used to make up one's mind which instrs to aid in annals allocation. The mem loc determined in the code gen stage might too be kept in the symbol tabular array.

assembler (*.s → *.o)

Assembler takes as input the assembly lawmaking generated by the compilation step, and translates it into auto code as an obj file. An obj file is a binary representation of the source program.

        //assembly          |   //auto lawmaking push %ebp           |   0:  55 mov %esp, %ebp      |   1: 89 ec xor %eax, %eax      |   3:  31 c0      

The assembler gives a retentiveness location to each variable and didactics, and the location is actually represented symbolically or via offsets. Information technology also make a list of all the unresolved references that presumably divers in other obj file or libraries, due east.k. printf. A typical obj file contains the program text (instructions) and data (constants and strings), info about instrs and data that depend on absolute addr, a symbol table of unresolved references, and psbly some debugging info. (nm main.o)

static linking (*.o → *[.exe])

Static linkers such as the Unix ld programme takes as input a collection of relocatable obj files and command-line arguments and generate as output a fully linked executable obj file that tin be loaded and run. The input relocatable obj files consist of various code and data sections. Instructions / initialized global variables / uninit variables are in different sections.

To build the executable, the linker must perform two master tasks:

  • symbol resolution. Obj files define and reference symbols. The purpose of symbol resolution is to associate each symbol reference with exactly one symbol definition.
  • relocation. Compilers and assemblers generate code and data sections that kickoff at addr 0. The linker relocates these sections by associating a mem location with each symbol definition, and so modifying all of the references to those symbols so that they point to this mem loc.

2. Object files ↑elevation

Object files come in three forms:

  • relocatable obj file. Contains binary code and data in a form that can exist combined with other relocatable obj files at compile time to create an exe obj file.
  • executable obj file. Contains binary lawmaking and information in a class that can be copied direct into mem and executed.
  • shared obj file. A special type of relocatable obj file that can be loaded into mem and linked dynamically, at either load time or run time.

Compilers and assemblers generate relocatable obj files (including shared obj files). Linkers generate executable obj files. Technically, an obj module is a sequence of bytes, and an obj file is an obj module stored on disk in a file.

relocatable obj files

The Pulpit Rock
Fig.three - Typical ELF relocatable object file.

symbols and symbol tables

Each relocatable obj module, m, has a symbol table that contains info nigh the symbols that are defined and referenced past m. In the context of a linker, there are three different kinds of symbols:

The Pulpit Rock
Fig.iv - Dissimilar kinds of symbols. Local linker symbols (static) are unlike from local plan variables, which are managed at run time on stack.
  • global: global symbols that are defined past module yard and that can exist referenced by other modules. Global linker symbols correspond to nonstatic funcs and global vars that are divers without the static attribute.
  • external: global symbols that are referenced by module m simply defined by another module. Such symbols are chosen externals and correspond to funcs and vars that are defined in other modules.
  • local (static): local symbols that are defined and referenced exclusively by module 1000 . Some local linker symbols correspond funcs and global vars that are defined with the static attribute. These symbols are visible anywhere within module m, only cannot be referenced by other modules.

Symbol tables are congenital by assemblers, using symbols exported by the compiler into the associates-linguistic communication .s file. An ELF symbol table is independent in the .symtab section. It contains an array of entries.

        typedef struct {     int proper noun;           //byte offset into str table that points to symbol name     int value;          //symbol's addr: department offset, or VM addr     int size;           //obj size in bytes     char type:4,        //information, func, sec, or src file name (iv $.25)         bounden:four;      //local or global (four bits)     char reserved;      //unused     char department;       //department header alphabetize, ABS, UNDEF or COMMON } Elf_symbol;      

Each symbol is associated with some department of the obj file, denoted by the section field, which is an alphabetize into the section header tabular array. There are iii special pseudo sections that don't have entries in the section header table:

  • ABS is for symbols that should not be relocated;
  • UNDEF is for undefined symbols, that are referenced in this obj module but defined elsewhere;
  • Mutual is for uninited data objs that are not yet allocated; value gives the alignment requirement, and size gives the min size.

symbol tabular array entries

        //COMMAND: objdump -r -d -t main.o //Alt CMD: readelf -southward primary.o principal.o:     file format elf32-i386  //l=local, g=global;  //d=debug, f=file, O=object, F=function SYMBOL TABLE: 00000000 l    df *ABS*  00000000 chief.c 00000000 l    d  .text  00000000 .text 00000000 l    d  .data  00000000 .data 00000000 50    d  .bss   00000000 .bss 00000000 50    d  .note.GNU-stack    00000000 .note.GNU-stack 00000000 50    d  .comment   00000000 .comment 00000000 k     O .information  00000008 buf  00000000 k     F .text  00000014 master 00000000         *UND*  00000000 bandy      

The start 9 entries in the symbol tabular array are local symbols that the linker uses internally, and nosotros intendance more about the remaining ones:

buf is an 8B object located at an beginning (i.e., value) of zero in the .information department. main is a 20B func located at an starting time of zippo in the .text section. swap is an external variable (UND).

symbol table entries for swap.o:

        swap.o:     file format elf32-i386  SYMBOL Tabular array: 00000000 l    df *ABS*  00000000 bandy.c 00000000 l    d  .text  00000000 .text 00000000 fifty    d  .data  00000000 .information 00000000 50    d  .bss   00000000 .bss 00000000 l    d  .note.GNU-stack    00000000 .note.GNU-stack 00000000 l    d  .comment   00000000 .comment 00000000 g     O .data  00000004 bufp0 00000000         *UND*  00000000 buf 00000004       O *COM*  00000004 bufp1 00000000 k     F .text  00000035 bandy      

bufp0 is a 4B inited obj starting at get-go 0 in .data; adjacent is a reference to the external buf symbol in the initialization lawmaking for bufp0; and, bufp1 is a 4B uninited information obj (with a 4B alignment requirement) that volition eventually be allocated as a .bss obj when this module is linked; swap is a 53B func at an starting time of zero in .text.

three. Symbol resolution ↑elevation

The linker resolves symbol references by associating each ref with exactly one symbol definition from the symbol tables of its input relocatable obj files. Symbol resolution is easy for references to local variables that are divers in the same module equally the ref.

Resolving ref to global symbols is trickier. When the compiler encounters a symbol (either a var or func name) that is not divers in the current module, it assumes that information technology is defined in some other module, generally a linker symbol tabular array entry, and leaves it for the linker to handle. If the linker is unable to find a def for the referenced symbol in any of its input modules, information technology prints an error msg and terminates.

linking with static libraries

Related funcs can be compiled into divide obj modules and so packaged in a single static library file. Awarding programs can then use any of the funcs defined in the library by specifying a single file proper name on the command line:

        $gcc main.c /usr/lib/libm.a /usr/lib/libc.a      

At link time, the linker will only copy obj modules that are referenced by the program, which reduces the size of the executable on disk and in retentiveness.

On Unix systems, static libraries are stored on disk as archive, which is a collection of concatentated relocatable obj files, with a header that describes the size and loc of each member obj file.

-static tells the compiler driver that the linker should build a fully linked executable obj file that tin can be loaded into memory and run without any farther linking at load fourth dimension.

linkers apply static libraries to resolve references

During the symbol resolution phase, the linker scans the relocatable obj files and archives left to right in the same sequential order that they appear on the compiler driver's command line. (The driver automatically translates any .c files on the cmd line into .o files.) During this scan, the linker maintains a set E of relocatable obj files that volition exist merged to class the executable, a set up U of unresolved symbols (i.due east., symbols referred to, but not nonetheless defined), and a set D of symbols that accept been divers in previous input files. Initially, Due east/U/D are empty.

  • for each input file f on the cmd line, the linker determines if f is an obj file or an annal. If f is an obj file, the linker adds f to E, updates U and D to reflect the symbol defs and refs in f, and proceeds to the next input file;
  • if f is an archive, the linker attempts to friction match the unresolved symbol in U against the symbols defined past the members of the annal. If some archive member, thou, defines a symbol that resolves a ref in U, then m is added to Eastward, and the linker updates U and D to reflect the symbol defs and refs in m. This process iterates over the member obj files in the archive until a stock-still point is reached where U and D no long change. At this point, any member obj files non independent in E are simply discarded and the linker proceeds to the next input file;
  • if U is nonempty when the linker finishes scanning the input files on the cmd line, information technology prints an fault and terminates. Ow, it merges and relocates the obj files in East to build the executable file.

The ordering of libraries and obj files on the cmd line is significant, and the general rule is to place libraries at the finish of cmd line. And, if libraries are not independent, they must be ordered and then that for symbol s that is referenced externally by a member of an archive, at least one def of due south follows a ref to s on the cmd line. East.g., suppose foo.c calls funcs in libx.a and libz.a that call funcs in liby.a. So, libx.a and libz.a must precede liby.a on the cmd line:

        $gcc foo.c libx.a libz.a liby.a      

Libraries can exist repeated on the cmd line if necessary to satisfy the dependence requirements. E.thou., suppose foo.c calls a func in libx.a that calls a func in liby.a that calls a func in libx.a. And so libx.a must be repeated on the cmd line:

        $gcc foo.c libx.a liby.a libx.a      

four. Relocation ↑top

Once the linker has completed the symbol resolution step, it has associated each symbol ref in the code with exactly one symbol def (i.eastward., a symbol table entry in one of its input obj modules). At this point, the linker knows the exact sizes of the lawmaking and data sections in its input obj modules. It is at present ready to begin the relocation step, where it merges the input modules and assigns run-time addr to each symbol. Relocation consists of two steps:

The Pulpit Rock
Fig.five - Relocating code and information.
  • Relocating sections and symbol definitions. In this step, the linker merges all sections of the same type into a new aggregate section of the same type. The linker and then assigns run-fourth dimension mem addres to the new aggregate sections, to each section defined by the input modules, and to each symbol divers by the input modules. When this step is complete, every instr and global var in the program has a unique run-time mem addr.
  • Relocating symbol references within sections. In this footstep, the linker modifies every symbol ref in the bodies of the code and data sections so that they signal to the correct run-time addres. To perform this step, the linker relies on data structures in the relocatable obj modules known equally relocation entries.

relocation entries

When an assembler generates an obj module, it does non know where the code and data will ultimately exist stored in memory. Nor does it know the locs of any externally defined funcs or global vars that are referenced by the module. So, whenever the assembler encounters a ref to an obj whose ultimate loc is unknown, it generates a relocation entry that tells the linker how to modify the ref when it merges the obj file into an executable. Relocation entries for code are placed in .rel.text, and for inited data are in .rel.data.

        typedef struct {     int offset;     //offset to the ref to relocate     int symbol:24,  //symbol the ref should indicate to         blazon:8;     //relocation type, tell the linker how to modify the new ref } Elf32_Rel;      

Whereas 11 dissimilar relocation types are divers past ELF, we mainly concern two basic ones:

  • R_386_PC32: relocate a ref that uses a 32-fleck PC-relative addr, which is an starting time from the electric current run-fourth dimension value of the PC. When CPU executes an instr using PC-relative addressing, information technology forms the effective addr by adding the 32-scrap value encoded in the instr to the electric current run-fourth dimension value of the PC, which is always the addr of the side by side instr in mem.
  • R_386_32: relocate a ref that uses a 32-scrap absolute addr, which makes CPU directly uses the 32-flake value encoded in the instr as the constructive addr, without further modifications.

relocating symbol references

        foreach section s {              //iterate over each department     foreach relocation entry r { //iterate over each reloc entry in each sec         refptr=s+r.start;       //ptr to ref to exist relocated                  //relocate a PC-relative ref         if(r.type == R_386_PC32) {             //ADDR(s): run-time addr for the sec             refaddr = ADDR(due south)+r.kickoff; //ref'due south runtime addr             //ADDR(r.symbol): run-time addr of the symbol             *refptr = (unsigned) (ADDR(r.symbol)) + *refptr - refaddr);         }              //relocate an absolute ref         if(r.type == R_386_32)             *refptr = (unsigned) (ADDR(r.symbol) + *refptr);     } }      

relocating PC-relative references

chief routine in the .text sec of primary.o calls the bandy routine, which is defined in swap.o.

        Disassembly of section .text:  00000000 <main>:    0:   55                      push   %ebp    1:   89 e5                   mov    %esp,%ebp    3:   83 e4 f0                and    $0xfffffff0,%esp    6:   e8 fc ff ff ff          call   7 <master+0x7>  //bandy()             vii: R_386_PC32   swap                     //reloc entry    b:   b8 00 00 00 00          mov    $0x0,%eax   x:   89 ec                   mov    %ebp,%esp   12:   5d                      pop    %ebp   13:   c3                      ret              

call instr begins at sec commencement 0x6 and consists of the one-byte opcode 0xe8, followed past the 32-scrap ref 0xfffffffc (-iv decimal), which is stored in niggling-endian byte order.

The relocation entry r consists of 3 fields:

        r.offset = 0x7 r.symbol = swap r.blazon = R_386_PC32      

These fields tell the linker to modify the 32-flake PC-relative ref starting at offset 0x7 so that information technology volition indicate to the swap routine at run fourth dimension. Now suppose the linker has adamant that

        ADDR(s) = ADDR(.text) = 0x80483b4 ADDR(r.symbol) = ADDR(swap) = 0x80483c8      

The linker get-go computes the run-time addr of the ref:

        refaddr = ADDR(s)   + r.first         = 0x80483b4 + 0x7         = 0x80483bb      

It then updates the ref from its current value (-4) to 0x9 so that it will point to the swap routine at run time:

        *refptr = (unsigned) (ADDR(r.symbol) + *refptr - refaddr)         = (unsigned) (0x80483c8      + (-4)    - 0x80483bb)         = (unsigned) (0x9)      

In the resulting executable obj file, the call instr has the post-obit relocated form:

        80483ba:    e8  09 00 00 00     telephone call 80483c8 <swap> //swap;      

At run fourth dimension, the telephone call instr will be stored at addr 0x80483ba. When the CPU executes the telephone call instr, the PC has a value of 0x80483bf, which is the addr of the instr immediately following phone call instr. To execute the instr, the CPU performs the post-obit steps:

        push button PC onto stack PC <- PC + 0x9 = 0x80483bf + 0x9 = 0x80483c8      

Thus, the next instr to execute is the first instr of the swap routine, which is simply what nosotros want.

relocating absolute references
the bandy.o module inits the global ptr bufp0 to the addr of the first chemical element of the global buf array:

        Disassembly of section .text:  00000000 <swap>:    0:   55                      push   %ebp    1:   89 e5                   mov    %esp,%ebp    iii:   83 ec 10                sub    $0x10,%esp    6:   c7 05 00 00 00 00 04    movl   $0x4,0x0    d:   00 00 00             8: R_386_32 bufp1             c: R_386_32 buf   10:   a1 00 00 00 00          mov    0x0,%eax             11: R_386_32    bufp0   15:   8b 00                   mov    (%eax),%eax   17:   89 45 fc                mov    %eax,-0x4(%ebp)   1a:   a1 00 00 00 00          mov    0x0,%eax             1b: R_386_32    bufp0   1f:   8b 15 00 00 00 00       mov    0x0,%edx             21: R_386_32    bufp1   25:   8b 12                   mov    (%edx),%edx   27:   89 10                   mov    %edx,(%eax)   29:   a1 00 00 00 00          mov    0x0,%eax             2a: R_386_32    bufp1   2e:   8b 55 fc                mov    -0x4(%ebp),%edx   31:   89 ten                   mov    %edx,(%eax)   33:   c9                      leave   34:   c3                      ret      
        int *bufp0 = &buf[0];      

Since bufp0 is an initialized obj, it volition be stored in the .data sec of bandy.o relocatable obj module. Since it is inited to the addr of a global array, information technology'll need to be relocated.

        00000000 <bufp0>:     0:  00 00 00 00                     //int *bufp0 = &buf[0];                         0: R-386_32 buf //Relocation entry      

.data sec contains a unmarried 32-fleck ref, the bufp0 ptr, which has a value of 0x0. The relocation entry tells the linker that this is a 32-bit absolute ref, beginning at get-go 0, which must exist relocated so that information technology points to the symbol buf. Now, suppose the linker had determined that

        ADDR(r.symbol) = ADDR(buf) = 0x8049454  *refptr = (unsigned) (ADDR(r.symbol)) + *refptr)         = (unsigned) (0x8049454       + 0)         = (unsigned) (0x8049454)      

In the resulting exe obj file, the ref has the following relocated form:

        0804945c    <bufp0>:  804945c:   54 94 04 08     Relocated!      

The linker has decided that at run fourth dimension the var bufp0 will be located at mem addr 0x804945c and will be inited to 0x8049454, which is the run-time addr of the buf array.

5. Executable object files ↑peak

The Pulpit Rock
Fig.half dozen - Typical ELF executable object file.

The format of an executable obj file is similar to that of a relocatable obj file. The ELF header describes the overall format of the file. Information technology besides includes the program'south entry point, which is the addr of the first instr to execute when the program runs. The .text, .rodata and .information sections are like to those in a relocatable obj file, except that these sections have been relocated to their eventual run-fourth dimension mem addr. The .init section defines a small func, chosen _init, that will be called by the program's init code. Since the executable is fully linked (relocated), it needs no .rel sections.

The Pulpit Rock
Fig.vii - Segment header tabular array for the example executable (objdump -t p). off: file starting time, vaddr/paddr: virtual/physical addr, marshal: segment alignment, filesz: segment size in the obj file, memsz: segment size in mem, flags: run-time permissions

ELF executables are designed to be easy to load into mem, with face-to-face chunks of the exe file mapped to contiguous mem segments. This mapping is described past the segment header table. From Fig. 7, we encounter that two mem segments will be inited with the contents of the exe obj file. Lines 1 and ii shows that the code segment is aligned to a 4KB boundary, has r/x permissions, starts at mem addr 0x8048000, has a total mem size of 0x448 bytes, and is inited with the first 0x448 bytes of the exe obj file, which includes the ELF header, the segment header tabular array, and the .init, .text and .rodata sections.

Lines three and 4 tell us that the data segment is aligned to a 4KB boundary, has r/w permissions, starts at mem addr 0x8049448, has a full mem size of 0x104 bytes, and is inited with the 0xe8 bytes starting at file starting time 0x448, which in this case is the beginning of the .information section. The remaining bytes in the segment crspds to .bss data that will be inited to goose egg at run time.

6. Loading executable obj files ↑acme

Any Unix plan can invoke the loader past calling the execve role, which copies the code and data in the executable object file from disk into memory, and and so runs the program past jumping to its first teaching, or entry point. This process of copying the program into memory and then running it is known every bit loading.

Every Unix programme has a run-time memory image similar to the ane in Fig. viii. On a 32-bit Linux systems, the lawmaking segment starts at accost 0x8048000. The information segment follows at the next 4KB aligned address. The run-time heap follows on the start 4KB aligned address past the read/write segment and grows up via calls to the malloc library. In that location is also a segment that is reserved for shared libraries. The user stack e'er starts at the largest legal user addr and grows downward. The segment above the stack is reserved for the lawmaking and information in the retention-resident function of the OS kernel.

The Pulpit Rock
Fig.8 - Linux run-time memory prototype.

When the loader runs, information technology creates the memory image shown in Fig. 8. Guided past the segment header table in the executable, it copies chunks of the executable into the code and information segments. Next, the loader jumps to the program's entry bespeak, which is always the address of the _start symbol. The startup code at the _start addr is defined in the obj file crt1.o and is the same for all C programs.

7. Dynamic linking with shared libraries ↑tiptop

A shared library is an object module that, at run fourth dimension, can be loaded at an capricious memory address and linked with a program in memory. The process is known as dynamic linking and is performed past a program called a dynamic linker. Shared libraries are also referred to as shared objects (.so).

Shared libraries are "shared" in two different ways:

  • there is exactly one .so file for a item library. The lawmaking and information in this .then file are shared by all of the exe obj files that reference the library.
  • a single copy of the .text section of a shared library in memory tin can be shared by unlike running processes.
        #build a library $gcc -shared -fPIC -o libvector.then addvec.c multvec.c #link the library into the programme $gcc -o p2 main2.c ./libvector.so      
The Pulpit Rock
Fig.9 - Dynamic linking with shared libraries.

This creates an exe obj file p2 in a form that can exist linked with libvector.so at run time. Do some of the linking statically when the exe file is created, and then complete the linking process dynamically when the program is loaded. Note that none of the code or data sections from libvector.so are actually copied into the exe p2 at this point. Instead, the linker copies some relocation and symbol tabular array info that will allow reference to code and data in libvector.so to be resolved at run time.

When the loader loads and runs the exe p2, information technology loads the partially linked exe p2. Side by side, it notices that p2 contains a .interp section, which contains the path name of the dynamic linker, which is itself a shared object. The dynamic linker so finishes the linking task by performing the following relocations:

  • relocating the text and data of libc.so into some memory segment;
  • relocating the text and information of libvector.so into some other memory segment;
  • relocating any reference in p2 to symbols defined by libc.then and libvector.so.

Finally, the dynamic linker passes control to the application. From this point on, the locations of the shared libraries are fixed and practice non modify during execution of the program.

Loading and linking shared libraries from applications

To a higher place sections discussed the scenario in which the dynamic linker loads and links shared libraries when an app is loaded, just before it executes. Nevertheless, it is likewise psbl for an app to request the dynamic linker to load and link capricious shared libraries while the app is running, without having to link in the app confronting those libraries at compile time.

8. Appendix ↑height

1) Preprocessor examples

  • including files
        #include <stdio.h>  int master(){     printf("Hi earth!\n");     return 0;  }      

The preprocessor replaces the line #include <stdio.h> with the text of the file 'stdio.h'. #include often compels with the use of #include guards or #pragma one time to prevent double inclusion.

        //pragma in one case #pragma once   struct foo {     int member; }; ------------- //include guards #ifndef _HEADER_H #define _HEADER_H          struct foo {     int fellow member; };          

0 Response to "What Is the Hex Address of the Relocated Reference to Swap in Line 5?"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel