1 / 104

Operating Systems Principles Memory Management Lecture 9: Sharing of Code and Data in Main Memory

Operating Systems Principles Memory Management Lecture 9: Sharing of Code and Data in Main Memory. 主講人:虞台文. Content. Single-Copy Sharing Reasons of Sharing Requirements for Sharing Static Linking and Sharing Sharing in Systems w/o Segmentation or Paging Sharing in Paging Systems

massimo
Télécharger la présentation

Operating Systems Principles Memory Management Lecture 9: Sharing of Code and Data in Main Memory

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Operating Systems PrinciplesMemory ManagementLecture 9: Sharing of Code and Data in Main Memory 主講人:虞台文

  2. Content • Single-Copy Sharing • Reasons of Sharing • Requirements for Sharing • Static Linking and Sharing • Sharing in Systems w/o Segmentation or Paging • Sharing in Paging Systems • Sharing in Segmented Systems • Dynamic Linking and Sharing • Principles of Distributed Shared Memory (DSM) • The User's View of DSM • Implementations of DSM • Implementing Unstructured DSM • Implementing Structured DSM

  3. Operating Systems PrinciplesMemory ManagementLecture 9: Sharing of Code and Data in Main Memory Single-Copy Sharing

  4. Sharing • Reusing Software Modules • Individual software modules are constructed separately. • Develop applications by linking with other well-developed software modules. • Reduce software developing cost. • Each process owns private copy of shared objects • Single-Copy Sharing • Processes share a single copy of code or data in memory • Why? • What? • How?

  5. Why? • Processes need to access common data, e.g., • Communication btw producer & consumer • Cooperation among divide-and-conquer processes • Competition on resources • Better utilization of memory (code & data) • Several active processes use the same code or data at the same time, e.g., many users running the same editor or debugger in a time-sharing system • Without sharing, • memory requirement would increase dramatically and, thus, reduce the number of login users. • increase I/O overhead to load excess copies • increase the page fault rate and, thus, the risk of thrashing.

  6. What? • OS kernelroutines • I/O drivers • System services, e.g., • memory management and file manipulation routines. • System utilities, e.g., • Compiler, linker, loader and debugger. • User-lever applications • A single copy of the same code applies to different data sets.

  7. How? • How to express what is shared? • System Components • Designated at the time of system design or initialization • User-Level Applications • Shared code must be reentrant (read-only, “pure”) • Stack and heap must be replicated per process

  8. Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Compile

  9. int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . .

  10. esp int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . .

  11. esp int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . .

  12. esp int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . .

  13. esp 7 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . .

  14. esp 7 5 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . .

  15. esp Return Address Return Address 7 5 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . .

  16. esp Return Address 7 5 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _AddMul2: push ebp mov ebp,esp mov eax, [bp+8] add eax, [bp+8+4] shl eax, 1 mov esp,ebp pop ebp ret

  17. esp Return Address 7 5 old ebp int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _AddMul2: push ebp mov ebp,esp mov eax, [bp+8] add eax, [bp+8+4] shl eax, 1 mov esp,ebp pop ebp ret

  18. ebp ebp+12 ebp+8 esp Return Address 7 old ebp 5 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing i j _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _AddMul2: push ebp mov ebp,esp mov eax, [bp+8] add eax, [bp+8+4] shl eax, 1 mov esp,ebp pop ebp ret

  19. ebp ebp+12 ebp+8 Return Address 5 old ebp 7 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing i j _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _AddMul2: push ebp mov ebp,esp mov eax, [bp+8] add eax, [bp+8+4] shl eax, 1 mov esp,ebp pop ebp ret eax=5

  20. ebp ebp+12 ebp+8 Return Address 5 old ebp 7 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing i j _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _AddMul2: push ebp mov ebp,esp mov eax, [bp+8] add eax, [bp+8+4] shl eax, 1 mov esp,ebp pop ebp ret eax=12

  21. ebp ebp+12 ebp+8 Return Address 5 old ebp 7 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing i j _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _AddMul2: push ebp mov ebp,esp mov eax, [bp+8] add eax, [bp+8+4] shl eax, 1 mov esp,ebp pop ebp ret eax=24

  22. ebp esp ebp+12 ebp+8 Return Address old ebp 7 5 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing i j _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _AddMul2: push ebp mov ebp,esp mov eax, [bp+8] add eax, [bp+8+4] shl eax, 1 mov esp,ebp pop ebp ret eax=24

  23. esp Return Address 7 5 old ebp int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _AddMul2: push ebp mov ebp,esp mov eax, [bp+8] add eax, [bp+8+4] shl eax, 1 mov esp,ebp pop ebp ret eax=24

  24. esp Return Address Return Address 7 5 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _AddMul2: push ebp mov ebp,esp mov eax, [bp+8] add eax, [bp+8+4] shl eax, 1 mov esp,ebp pop ebp ret _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . . eax=24

  25. esp 7 5 int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . . eax=24

  26. esp int x, y, z; int AddMul2(int i, int j) { return (i+j)*2; } main() { x=5; y=7; z=AddMul2(x, y); . . . . . . . . } Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS . . . 5 7 24 _main: mov ds:[x],5 mov ds:[y],7 push ds:[y] push ds:[x] call _AddMul2 add esp,8 mov ds:[z],eax . . . . . . eax=24

  27. Example: Simple Code Sharing _STACK SEGMENT PUBLIC ‘STACK’ DB 4096 dup(?) Bottom: _STACK ENDS _DATA SEGMENT PULBIC ‘DATA’ x dd 1 dup(?) y dd 1 dup(?) z dd 1 dup(?) _DATA ENDS _TEXT SEGMENT PUBLIC ‘CODE’ _AddMul2: . . . // code for AddMul2 _main: . . . // code for main _TEXT ENDS Each process has its own stack segment Each process has its own data segment Pure code is sharable

  28. Example: Simple Code Sharing Translate to the same physical process for different processes Access different data areas for different processes

  29. Linking and Sharing • Sharing are closely related to linking • Linking resolves externalreferences • Sharing links to the same module • Static linking/sharing: • Resolve references before execution starts • Dynamic linking/sharing: • Resolve references whileexecuting

  30. Operating Systems PrinciplesMemory ManagementLecture 9: Sharing of Code and Data in Main Memory Static Linking and Sharing

  31. All memory of a process is contiguous physically. Sharing without Virtual Memory • With one or noRelocation Register (RR) • Sharing user programs: • Possible only by partial overlapping • Too restrictive and difficult; generally not used • Sharing system components: • Agree on a starting positions • Linker resolves references to those locations • Can also use a block of “transfer addresses,”but this involves additional memory references. • Issues  difficult to identify the invoking processes by system components. Physical Memory System Components User Programs User Program 1 User Program 2

  32. All memory of a process is contiguous physically. Sharing without Virtual Memory • With one or noRelocation Register (RR) • Sharing user programs: • Possible only by partial overlapping • Too restrictive and difficult; generally not used • Sharing system components: • Agree on a starting positions • Linker resolves references to those locations • Can also use a block of “transfer addresses,”but this involves additional memory references. • Issues  difficult to identify the invoking processes by system components. Physical Memory System Components User Programs

  33. Sharing without Virtual Memory • With multiple RR’s CBR = Code Base Reg. Point to shared copy of code SBR = Stack Base Reg. Point to private copy of stack DBR = Data Base Reg. Point to private copy of data Sharing of code

  34. process1 process2 code1    CBR1 CBR2 code2 SBR1 SBR2    DBR1 DBR2       stack1    stack2    data Sharing without Virtual Memory • With multiple RR’s CBR = Code Base Reg. Point to private copy of code SBR = Stack Base Reg. Point to private copy of stack DBR = Data Base Reg. Point to shared copy of data Sharing of data

  35. Database Sharing in Paging Systems Sharing of Data Common data (without address) Data

  36. Database Physical Memory Sharing in Paging Systems Sharing of Data Data3 Data Data1 Data2 Data1 Data3 Data2

  37. PT2 PT1 0 0 . . . . . . n1 n2 . . . . . . Database Physical Memory Sharing in Paging Systems Sharing of Data n1, w n2, w Data3 Data1 Data2

  38. Database Physical Memory Sharing in Paging Systems Sharing of Data The page numbers of sharing processes can be different. PT2 PT1 n1, w 0 0 . . . . . . n2, w n2 n1 Data3 . . . . . . Data1 Data2

  39. 0x0000 0x0000 . . . . . . bra (2,w) label1: bra label1 label1: 4k 0x1000 0x1000 . . . . . . 4k 0x2000 0x2000 . . . . . . w 4k Sharing in Paging Systems Sharing of Code Assemble

  40. 0x0000 . . . . . . bra (2,w) label1: bra (n+2,w) label1: 0x1000 . . . . . . 0x2000 . . . . . . Sharing in Paging Systems Sharing of Code nthpage Shared code Virtual Memory

  41. . . . bra (n+2,w) label1: . . . Label1: . . . bra (n+2,w) . . . . . . . . . Sharing in Paging Systems Sharing of Code p nthpage q r Virtual Memory Physical Memory

  42. PT . . . bra (n+2,w) label1: . . . Label1: . . . bra (n+2,w) . . . n r n+1 . . . q n+2 . . . p Sharing in Paging Systems Sharing of Code p nthpage q r Virtual Memory Physical Memory

  43. PT PT1 PT2 . . . 0 0 Label1: 0 0 . . . bra (n+2,w) n r n1 n2 r r n+1 . . . q n1+1 n2+1 q q n+2 p n1+2 n2+2 p p Physical Memory Sharing in Paging Systems Sharing of Code n1, w n2, w p q r

  44. PT PT1 PT2 . . . 0 0 Label1: 0 0 . . . bra (n+2,w) n r n1 n2 r r n+1 . . . q n1+1 n2+1 q q n+2 p n1+2 n2+2 p p Physical Memory If absolute virtual address is used for coding, such a code sharing scheme is workable if n1= n2 = n Sharing in Paging Systems Sharing of Code n1, w n2, w p q r

  45. . . . Label1: . . . bra (n+2,w) . . . Physical Memory PT Sharing in Paging Systems Sharing of Code n r n+1 q n+2 p Can we assign different starting page numbers to a different processes? n1, w PT1 PT2 n2, w p 0 0 0 0 q n1 n2 r r n1+1 n2+1 q q n1+2 n2+2 p p r

  46. . . . bra (n+2,w) label1: . . . . . . Sharing in Paging Systems Sharing of Code Can we assign different starting page numbers to a different processes? Yes, if … nthpage 1. Shared code is self-contained 2. Avoid using absolute address (page number) in share code, i.e., using address relative to CBRinstead. Virtual Memory

  47. Sharing in Paging Systems Short Summary • PT entries of differentprocesses point to the samepage frame • Data pages: No Restrictions • Code pages: • Must have the samepage numbers in allPTs. • For generalization, avoid using page numbers in shared code (self-contained), i.e., using address relative to CBR instead.

  48. Sharing in Paging Systems Short Summary • PT entries of differentprocesses point to the samepage frame • Data pages: No Restrictions • Code pages: • Must have the samepage numbers in allPTs. • How to know the page numbers of shared components? Solutions: • The total set of shared modules is known a priori. • Resolved by an effectiveloader  done just-in-time and only once.

  49. 0 ... ... stub 1 stub i stub n1 stub Linkingjust-in-time and only once. Dynamic Linking via Transfer Vector Currently Executing Code ... bri tv[i] ... bri tv[i] ... call the same shared function by indirect branch instruction. Transfer Vectors

  50. Linkingjust-in-time and only once. Dynamic Linking via Transfer Vector Currently Executing Code ... bri tv[i] ... bri tv[i] ... When the shared function is called first time, the external reference is resolved by the corresponding stub. 0 Transfer Vectors ... ... stub 1 stub i stub n1 stub

More Related