Download as pdf or txt
Download as pdf or txt
You are on page 1of 2

Linking (ld is the linux linker)

- Text comes first, then data, then bss. Order of symbols within these sections will match the order of files in compilation command
- Local variables do not appear in the symbol table or object file (unless static)
- Multiple strong symbols of the same name are not allowed
- Strong symbols override weak with same name, i.e uninitialized var “int x” will be overwritten by “int x=345” in a diff file and be given value 345
- Weak symbols are resolved with first identified matching strong symbol. If no strong symbol, linker picks and keeps an arbitrary weak symbol.

Symbol Table Guide


.bss: strong symbol, store initialized at 0 static and global vars, store uninitialized static vars, COMMON pseudotype stored here in object file
.text: strong symbol, store machine code/function names
.data: strong symbol, store initialized global vars and static C vars, external symbols are also stored here?
COMMON: weak symbol, pseudosection for uninitialized global vars, appears in .bss section but in COMMON at symtab
Other Sections: .rodata = read-only data (ie struct jump tables), symtab (symbol table); rel.text = relocation info for code; .rel.data =
relocation info for data section; .debug = debugging symbol table (only with -g); .line = similar to .debug for code lines (only with -g)
Symbol Types:
- global - defined by module and referenced by other modules, nonstatic C funcs/global vars
- extern - globals reference by a module and defined in another, correspond to non static C funcs/global vars belonging to other modules
- local - defined/used only by module, static C funs/global static vars (DO NOT CONFUSE W/ LOCAL VARIABLES i.e ones in scope of function)

Systems level functions


- fork(): spawn identical child, return 0 in child, return child-pid in parent, return -1 on err
- When determining possible races, diagram out the order of the instruction execution using a graph
- When a child process is spawned:
- copies of mm_struct are made for child
- data structures are made for child
- all pages are marked as read only
- kill(pid, SIGNAL): manually sends to, pgid (absolute value of process id) if pid < 0, current pgid if pid == 0, pid if pid > 0
- wait(&status): waits until child terminates, updates status int:
- waitpid(cpid, &status WUNTRACED | WCONTINUED) - reaps process in wait set if terminated, else returns automatically
- child processes wait for parent to reap them, if left unreaped after parent exits, the child process is inherited by the init process (pid = 1)
- signal(SIGNAL, function): replaces default exception handler for SIGNAL with chosen function
- getppid() = get parent process id
- execve(filename, argv, envp): run new program from current process, return -1 on error else return never
- old area structs of existing process are removed
- new area structs are created for the code, data, and so on
- .text and .data mapped to executable
- the program counter is set to the starting address

Signals
- SIGCHLD: Child process has stopped or terminated
- SIGINT: Interrupt from keyboard (ctrl+c)
- SIGTSTP: Stop until next SIGCONT (ctrl+z)
- SIGUSR1: Terminate (by default), but more commonly is a “user-defined signal”

Virtual Memory: Necessary to segregate memory of one process from another


- TLB: acts as a cache for page table entries, is accessed on each memory reference
- PTE (page table entry): Consists of: valid bit (is entry valid?), SUP bit (can the page be accessed from user mode or only kernel mode?), READ
bit, WRITE bit (controls permissions to that specific page, either 0 or 1), and n-bit address
- Multi-level page table: For each level, the page table will reference the next level down in its own “pages” for easier access in large page tables,
used for implementing large address spaces, reduce Virtual Memory overhead
- VPO == PPO does NOT imply VAS = PAS (spaces can be large or smaller than other)
- First-fit and Best-fit are O(n) of total allocated/freed items, if the table is ordered according to increasing block sizes, they are equivalent
- Next-fit - from previous, find next payload fitting block; best-fit - find smallest block that fits; first-fit - choose first fitting block from start of list
- Steps taken by MMU: 1. CPU generates virtual address, 2: MMU fetches appropriate PTE from TLB, 3: MMU translates virtual address into
physical address, 4: the data is retrieved from memory

Garbage Collection:
- Mark&Sweep: Conservative implementation treats all pointer like objects as ptrs | Collection algorithm: Part 1 - Mark all reachable pointers from
a root node (stack ptr), Part 2 - Delete all unreachable memory location

Implicit Free List


- store info of all blocks in headers + footers
- header contains block size + allocated bit
- (4 byte header + payload from malloc(payload) + 4 byte footer) boundary tag method (footers are applied to all blocks)
- lab implicit allocator: minimum payload size is 8 bytes, overhead is 8 bytes (as many as 7 of 16 bytes can be wasted due to fragmentation)
Explicit free list
- store only free blocks in Circular DLL, allocated blocks hold no info
Memory Reading Step By Step (don’t forget valid bit, page table maps VA to PA)
1. Translate virtual address to binary
2. VPO = value contained in the log_2(page size) bits from right of virtual address
3. VPN = value in the remaining bits
4. TLBI = value in the log_2(# TLB sets) bits from right of VPN
5. TLBT = value contained in remaining bits of VPN
6. Look in TLB for set # TLBI and tag TLBT to find PPN. If exist, TLB hit.
7. If TLB miss, look up VPN in the page table directly for the PPN. If exist, page hit.
8. Combine PPN and PPO (e.g PPN/VPN=001, PPO=110, Addr=001110) to form the final Physical Address. PPO = VPO.

fork() race conditions malloc example with free()


(keep in mind the 4 bytes for header and 4 bytes for footer)
(memory allocator will put *p4 where *p2 was before it was freed)

Total sigchld calls: 2


Assuming child process exits before
parent sleeps:
For parent process that started main
if user presses ctrl+_, what are values?
If ctrl+c: Count1=3, Count2=0
If ctrl+z: Count1=2, Count2=1

Symbol Table Guide Example


If global/static variable initialized to 0 | uninitialized static variable: strong symbol, defined, goes into .bss
If global variable initialized to not 0: strong symbol, defined, goes into .data
If uninitialized global variable: weak symbol, defined, goes into COMMON
If function: strong symbol, defined, goes into .text
If extern variable: undefined, goes in .data of the module it is defined in, NONE if module referenced in. For a “generic” symbol table question,
say the section is .data

If local variable: not in symbol table

main.c weight_sum.c Symbol table (main.o) Symbol table (weight_sum.o)


weight_sum(); extern int *array; weight_sum: undefined, NO section weight1: defined, .data
int array[] = {4,2}; int *weight2; main: defined, .text weight2: defined, COMMON
int main(){...} int weight1=1; array: defined, .data weight_sum: defined, .text
int weight_sum() {...} array: undefined, NO section

You might also like