Program Behaviour
Program Behaviour semantics .c .c .c source program code inputs
Program Behaviour semantics .c .c .c source program code inputs Next Talk: other things
Program Behaviour semantics .c .c .c source program code inputs Next Talk: This Talk: other things the linker
.c .c .c .c
.c .c .c .c compile .o .o
.c .c .c .c compile .o .o link exe
concatenate .c .c .c .c compile .c .o .o link exe
concatenate .c .c .c .c compile .c .o .o compile link exe exe
≠ concatenate .c .c .c .c compile .c .o .o compile link exe exe
Correctness can depend on how the program was linked
.c
compile .c .o
Sections compile .c .o
Sections .text compile .c .o
Sections .text compile .c .data .o
Sections .text compile .c .data .o .debug
Sections .text compile .c .data .o .debug
Sections .text compile .c .data .o .debug X R W
.text .text .data .data .o .o .debug .debug
.text .text .text .data .data .o .o .data .debug .debug .o link .debug
.text .text .text .data .data .o .o .data .debug .debug .o link .debug - Join sections together - Resolve symbols
Executable 0x0000
Executable 0xb000
Executable 0xb400
Executable 0xc000
Executable 0xca00
.text .text Executable 0x0000 .data .data .debug .debug
.text .text Executable 0x0000 .data .data .debug .debug .text : { *(.text*) } . = . + 0x400 .data : { *(.data*) }
.text .text Executable 0x0000 .data .data .debug .debug .text : { *(.text*) } . = . + 0x400 .data : { *(.data*) }
.text .text Executable .data .data .debug .debug .text : { *(.text*) } . = . + 0x400 .data : { *(.data*) }
.text .text Executable .data .data .debug .debug .text .text : { 0xb000 *(.text*) } . = . + 0x400 .data : { *(.data*) }
.text .text Executable .data .data .debug .debug .text .text : { 0xb000 *(.text*) } . = . + 0x400 .data : { *(.data*) }
.text .text Executable .data .data .debug .debug .text .text : { *(.text*) 0xb400 } . = . + 0x400 .data : { *(.data*) }
.text .text Executable .data .data .debug .debug .text .text : { *(.text*) 0xb400 } . = . + 0x400 .data : { *(.data*) }
.text .text Executable .data .data .debug .debug .text .text : { *(.text*) } . = . + 0x400 .data .data : { *(.data*) 0xd000 }
.text : { Executable text_start = . *(.text*) text_end = . 0xd000 } text_size = SIZEOF(.text)
.text : { Executable text_start = . *(.text*) text_end = . 0xd000 } text_size = SIZEOF(.text)
.text : { Executable text_start = . *(.text*) text_end = . text_start } 0xd000 text_size = SIZEOF(.text)
.text : { Executable text_start = . *(.text*) text_end = . text_start } 0xd000 text_size = SIZEOF(.text)
.text : { Executable text_start = . *(.text*) text_end = . text_start } 0xd000 text_size = .text SIZEOF(.text) 0xd400
.text : { Executable text_start = . *(.text*) text_end = . text_start } 0xd000 text_size = .text SIZEOF(.text) 0xd400
.text : { Executable text_start = . *(.text*) text_end = . text_start } 0xd000 text_size = .text SIZEOF(.text) text_end 0xd400
.text : { Executable text_start = . *(.text*) text_end = . text_start } 0xd000 text_size = .text SIZEOF(.text) text_end 0xd400
.text : { Executable text_start = . text_size *(.text*) 0x400 text_end = . text_start } 0xd000 .text text_end 0xd400
extern char Executable text_size[], text_size text_start[], 0x400 text_end[]; text_start int main() { 0xd000 assert(&text_size .text == (char*)0x400); assert(&text_start text_end == (char*)0xd000); 0xd400 }
extern char Executable text_size[], text_size text_start[], 0x400 text_end[]; text_start int main() { 0xd000 memcpy( .text buf, (void *)&text_start, (size_t)&text_size); text_end } 0xd400
extern char text_size[], text_start[], text_end[]; int main() { memcpy( buf, (void *)&text_start, (size_t)&text_size); }
extern char text_size[], text_start[], text_end[]; int main() { memcpy( buf, (void *)&text_start, (size_t)&text_size); }
extern char Symbol Table text_size[], foo 12 text_start[], text_end[]; bar 0 int main() { ... ... text_start ??? memcpy( buf, text_size ??? (void *)&text_start, (size_t)&text_size); }
extern char linker_syms.h text_size[], text_start[], char text_start[]; text_end[]; &text_start int main() { = 0xd000; memcpy( buf, char text_size[]; (void *)&text_start, (size_t)&text_size); &text_size = 0x400; }
extern char linker_syms.h text_size[], text_start[], char text_start[]; text_end[]; &text_start int main() { = 0xd000; memcpy( buf, char text_size[]; (void *)&text_start, (size_t)&text_size); &text_size = 0x400; }
extern char linker_syms.h text_size[], text_start[], size_t text_start; text_end[]; text_start int main() { = 0xd000; memcpy( buf, size_t text_size; (void *) text_start, (size_t) text_size); text_size = 0x400; }
extern char linker_syms.h text_size[], text_start[], size_t text_start; text_end[]; text_start int main() { = 0xd000; memcpy( buf, size_t text_size; (void *) text_start, (size_t) text_size); text_size = 0x400; }
Symbol Table foo 12 bar 0 .ld ... ... text_start text_size exe
OOPSLA'16
OOPSLA'16 .o .o .ld exe
OOPSLA'16 .o .o .ld .ld exe Symbol Table exe text_start 0xd text_size 0xc
Four Functions
Four Functions addr S addr E : ident ⇀ ℕ symb S symb E : ident ⇀ ident
Four Functions text_size addr S addr E 0x400 : ident ⇀ ℕ text_start 0xd000 symb S symb E : ident ⇀ ident .text text_end 0xd400
Four Functions text_size addr S addr E 0x400 : ident ⇀ ℕ text_start 0xd000 symb S symb E : ident ⇀ ident .text symb S = .text ↦ text_start text_end 0xd400 symb E = .text ↦ text_end
Four Functions text_size addr S addr E 0x400 : ident ⇀ ℕ text_start 0xd000 symb S symb E : ident ⇀ ident .text addr S = .text ↦ 0xd000 text_end text_size ↦ 0x400 0xd400 text_end ↦ 0xd400 text_start ↦ 0xd000
Four Functions text_size addr S addr E 0x400 : ident ⇀ ℕ text_start 0xd000 symb S symb E : ident ⇀ ident .text text_end addr E = 0xd400 .text ↦ 0xd400
Grammar
Grammar MEMORY { Memory Directives }
Grammar MEMORY { Memory Directives } SECTIONS { Section Directives }
Grammar MEMORY { Memory Directives } SECTIONS { Section Directives } Global Assignments
Grammar MEMORY { .text : { text_start = .; } *(.text*) text_end = .; SECTIONS { } }
Grammar MEMORY { text_size = SIZEOF(.text); } SECTIONS { }
Grammar MEMORY { rom : ORIGIN = } 0x2000, LENTGH = SECTIONS { 0x400; }
Expressions
Expressions
Expressions
Expressions
Interpretation addr S MEMORY { symb S } SECTIONS { symb E } addr E
Interpretation addr S ⇀ MEMORY { symb S } SECTIONS { symb E } addr E
Interpretation addr S ⇀ MEMORY { symb S } SECTIONS { symb E } addr E
Interpretation addr S ⇀ ⇀ MEMORY { symb S } SECTIONS { symb E } addr E
Interpretation addr S ⇀ ⇀ MEMORY { symb S ⇀ } SECTIONS { symb E } addr E ⇀
Interpretation addr S ⇀ ⇀ MEMORY { symb S ⇀ } SECTIONS { symb E } addr E ⇀
Interpretation addr S ⇀ ⇀ MEMORY { symb S ⇀ } ⇀ SECTIONS { symb E ⇀ } addr E ⇀
Interpretation addr S ⇀ ⇀ MEMORY { symb S ⇀ } ⇀ ⇀ SECTIONS { symb E ⇀ ⇀ } addr E ⇀ ⇀
Interpretation addr S ⇀ ⇀ MEMORY { symb S ⇀ } ⇀ ⇀ SECTIONS { symb E ⇀ ⇀ } addr E ⇀ ⇀
Interpretation addr S ⇀ ⇀ MEMORY { ⇀ symb S ⇀ } ⇀ ⇀ SECTIONS { symb E ⇀ ⇀ } addr E ⇀ ⇀
Interpretation addr S ⇀ ⇀ MEMORY { ⇀ symb S ⇀ } ⇀ ⇀ SECTIONS { symb E ⇀ ⇀ } addr E ⇀ ⇀
text_size 0x400 text_start 0xd000 .text text_end 0xd400
CAV'18 Implemented in CBMC
- Static analysers need to understand program behaviour - Linker scripts introduce information unavailable to static analyser - Solution: parse linker scripts, integrate into static analysis
Recommend
More recommend