diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-12-22 11:47:04 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-12-22 11:59:46 +0100 |
| commit | 3645389673af4c62a636cfe36f258ae770e8fb6b (patch) | |
| tree | 356f9337e5ca323babef0e43fc345b0017dda798 /pkg/csource/csource.go | |
| parent | 6f298a18e582be006780954d6b0c30cbe2f568f4 (diff) | |
pkg/csource: fix handling of proc types
Generated program always uses pid=0 even when there are multiple processes.
Make each process use own pid.
Unfortunately required to do quite significant changes to prog,
because the current format only supported fixed pid.
Fixes #490
Diffstat (limited to 'pkg/csource/csource.go')
| -rw-r--r-- | pkg/csource/csource.go | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index 1fb00d1c0..38814c3b2 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -42,7 +42,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.generateSyscallDefines() exec := make([]byte, prog.ExecBufferSize) - progSize, err := ctx.p.SerializeForExec(exec, 0) + progSize, err := ctx.p.SerializeForExec(exec) if err != nil { return nil, fmt.Errorf("failed to serialize program: %v", err) } @@ -54,6 +54,9 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { if nvar != 0 { ctx.printf("long r[%v];\n", nvar) } + if opts.Procs > 1 { + ctx.printf("uint64_t procid;\n") + } if !opts.Repeat { ctx.generateTestFunc(calls, nvar, "loop") @@ -102,6 +105,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { ctx.print("\tint i;") ctx.printf("\tfor (i = 0; i < %v; i++) {\n", opts.Procs) ctx.print("\t\tif (fork() == 0) {\n") + ctx.printf("\t\t\tprocid = i;\n") if opts.HandleSegv { ctx.printf("\t\t\tinstall_segv_handler();\n") } @@ -256,16 +260,6 @@ func (ctx *context) generateSyscallDefines() { } func (ctx *context) generateCalls(p prog.ExecProg) ([]string, uint64) { - resultRef := func(arg prog.ExecArgResult) string { - res := fmt.Sprintf("r[%v]", arg.Index) - if arg.DivOp != 0 { - res = fmt.Sprintf("%v/%v", res, arg.DivOp) - } - if arg.AddOp != 0 { - res = fmt.Sprintf("%v+%v", res, arg.AddOp) - } - return res - } var calls []string csumSeq := 0 for ci, call := range p.Calls { @@ -275,15 +269,16 @@ func (ctx *context) generateCalls(p prog.ExecProg) ([]string, uint64) { switch arg := copyin.Arg.(type) { case prog.ExecArgConst: if arg.BitfieldOffset == 0 && arg.BitfieldLength == 0 { - fmt.Fprintf(w, "\tNONFAILING(*(uint%v_t*)0x%x = (uint%v_t)0x%x);\n", - arg.Size*8, copyin.Addr, arg.Size*8, arg.Value) + fmt.Fprintf(w, "\tNONFAILING(*(uint%v_t*)0x%x = %v);\n", + arg.Size*8, copyin.Addr, ctx.constArgToStr(arg)) } else { - fmt.Fprintf(w, "\tNONFAILING(STORE_BY_BITMASK(uint%v_t, 0x%x, 0x%x, %v, %v));\n", - arg.Size*8, copyin.Addr, arg.Value, arg.BitfieldOffset, arg.BitfieldLength) + fmt.Fprintf(w, "\tNONFAILING(STORE_BY_BITMASK(uint%v_t, 0x%x, %v, %v, %v));\n", + arg.Size*8, copyin.Addr, ctx.constArgToStr(arg), + arg.BitfieldOffset, arg.BitfieldLength) } case prog.ExecArgResult: fmt.Fprintf(w, "\tNONFAILING(*(uint%v_t*)0x%x = %v);\n", - arg.Size*8, copyin.Addr, resultRef(arg)) + arg.Size*8, copyin.Addr, ctx.resultArgToStr(arg)) case prog.ExecArgData: fmt.Fprintf(w, "\tNONFAILING(memcpy((void*)0x%x, \"%s\", %v));\n", copyin.Addr, toCString(arg.Data), len(arg.Data)) @@ -349,9 +344,9 @@ func (ctx *context) generateCalls(p prog.ExecProg) ([]string, uint64) { } switch arg := arg.(type) { case prog.ExecArgConst: - fmt.Fprintf(w, "0x%xul", arg.Value) + fmt.Fprintf(w, "%v", ctx.constArgToStr(arg)) case prog.ExecArgResult: - fmt.Fprintf(w, "%v", resultRef(arg)) + fmt.Fprintf(w, "%v", ctx.resultArgToStr(arg)) default: panic(fmt.Sprintf("unknown arg type: %+v", arg)) } @@ -382,6 +377,29 @@ func (ctx *context) generateCalls(p prog.ExecProg) ([]string, uint64) { return calls, p.NumVars } +func (ctx *context) constArgToStr(arg prog.ExecArgConst) string { + mask := (uint64(1) << (arg.Size * 8)) - 1 + val := fmt.Sprintf("0x%x", arg.Value&mask) + if ctx.opts.Procs > 1 && arg.PidStride != 0 { + val += fmt.Sprintf("+procid*0x%xul", arg.PidStride) + } + if arg.BigEndian { + val = fmt.Sprintf("htobe%v(%v)", arg.Size*8, val) + } + return val +} + +func (ctx *context) resultArgToStr(arg prog.ExecArgResult) string { + res := fmt.Sprintf("r[%v]", arg.Index) + if arg.DivOp != 0 { + res = fmt.Sprintf("%v/%v", res, arg.DivOp) + } + if arg.AddOp != 0 { + res = fmt.Sprintf("%v+%v", res, arg.AddOp) + } + return res +} + func toCString(data []byte) []byte { if len(data) == 0 { return nil |
