aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/csource
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-02-19 19:35:04 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-02-19 21:48:20 +0100
commit75a7c5e2d1f09a4a58e7e1f1f4ef0b0f55a33413 (patch)
treed44c2457c44b53192005f0b89cd6633a2a2b0ff9 /pkg/csource
parent90fd6503136121e9494761a460898e83bc0b6b3e (diff)
prog: rework address allocation
1. mmap all memory always, without explicit mmap calls in the program. This makes lots of things much easier and removes lots of code. Makes mmap not a special syscall and allows to fuzz without mmap enabled. 2. Change address assignment algorithm. Current algorithm allocates unmapped addresses too frequently and allows collisions between arguments of a single syscall. The new algorithm analyzes actual allocations in the program and places new arguments at unused locations.
Diffstat (limited to 'pkg/csource')
-rw-r--r--pkg/csource/csource.go47
1 files changed, 36 insertions, 11 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go
index bede09122..5c1b0208e 100644
--- a/pkg/csource/csource.go
+++ b/pkg/csource/csource.go
@@ -26,7 +26,19 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
w: new(bytes.Buffer),
calls: make(map[string]uint64),
}
- for _, c := range p.Calls {
+
+ calls, nvar, err := ctx.generateProgCalls(ctx.p)
+ if err != nil {
+ return nil, err
+ }
+
+ mmapProg := p.Target.GenerateUberMmapProg()
+ mmapCalls, _, err := ctx.generateProgCalls(mmapProg)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, c := range append(mmapProg.Calls, p.Calls...) {
ctx.calls[c.Meta.CallName] = c.Meta.NR
}
@@ -41,16 +53,6 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
ctx.generateSyscallDefines()
- exec := make([]byte, prog.ExecBufferSize)
- progSize, err := ctx.p.SerializeForExec(exec)
- if err != nil {
- return nil, fmt.Errorf("failed to serialize program: %v", err)
- }
- decoded, err := ctx.target.DeserializeExec(exec[:progSize])
- if err != nil {
- return nil, err
- }
- calls, nvar := ctx.generateCalls(decoded)
if nvar != 0 {
ctx.printf("long r[%v];\n", nvar)
}
@@ -62,6 +64,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
ctx.generateTestFunc(calls, nvar, "loop")
ctx.print("int main()\n{\n")
+ for _, c := range mmapCalls {
+ ctx.printf("%s", c)
+ }
if opts.HandleSegv {
ctx.printf("\tinstall_segv_handler();\n")
}
@@ -83,6 +88,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
ctx.generateTestFunc(calls, nvar, "test")
if opts.Procs <= 1 {
ctx.print("int main()\n{\n")
+ for _, c := range mmapCalls {
+ ctx.printf("%s", c)
+ }
if opts.HandleSegv {
ctx.print("\tinstall_segv_handler();\n")
}
@@ -108,6 +116,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) {
ctx.print("\t}\n}\n")
} else {
ctx.print("int main()\n{\n")
+ for _, c := range mmapCalls {
+ ctx.printf("%s", c)
+ }
if opts.UseTmpDir {
ctx.print("\tchar *cwd = get_current_dir_name();\n")
}
@@ -254,6 +265,20 @@ func (ctx *context) generateSyscallDefines() {
ctx.printf("\n")
}
+func (ctx *context) generateProgCalls(p *prog.Prog) ([]string, uint64, error) {
+ exec := make([]byte, prog.ExecBufferSize)
+ progSize, err := p.SerializeForExec(exec)
+ if err != nil {
+ return nil, 0, fmt.Errorf("failed to serialize program: %v", err)
+ }
+ decoded, err := ctx.target.DeserializeExec(exec[:progSize])
+ if err != nil {
+ return nil, 0, err
+ }
+ calls, nvar := ctx.generateCalls(decoded)
+ return calls, nvar, nil
+}
+
func (ctx *context) generateCalls(p prog.ExecProg) ([]string, uint64) {
var calls []string
csumSeq := 0