MCPcopy
hub / github.com/google/gvisor / loadObjdump

Function loadObjdump

tools/checkescape/checkescape.go:364–569  ·  view source on GitHub ↗

loadObjdump reads the objdump output. This records if there is a call any function for every source line. It is used only to remove false positives for escape analysis. The call will be elided if escape analysis is able to put the object on the heap exclusively. Note that the map uses <basename.go

(binary io.Reader)

Source from the content-addressed store, hash-verified

362// Note that the map uses <basename.go>:<line> because that is all that is
363// provided in the objdump format. Since this is all local, it is sufficient.
364func loadObjdump(binary io.Reader) (map[string]map[string]struct{}, error) {
365 // Do we have a binary? If it's missing, then the nil will simply be
366 // plumbed all the way down here.
367 if binary == nil {
368 return nil, fmt.Errorf("no binary provided")
369 }
370
371 // Construct & start our command. The 'go tool objdump' command
372 // requires a seekable input passed on the command line. Therefore, we
373 // may need to generate a temporary file here.
374 input, ok := binary.(*os.File)
375 if ok {
376 // Ensure that the file is seekable and that the offset is
377 // zero, since we can't control that.
378 if offset, err := input.Seek(0, io.SeekCurrent); err != nil || offset != 0 {
379 ok = false // Not usable.
380 }
381 }
382 if !ok {
383 // Copy to a temporary path.
384 f, err := os.CreateTemp("", "")
385 if err != nil {
386 return nil, fmt.Errorf("unable to create temp file: %w", err)
387 }
388 // Ensure the file is deleted.
389 defer os.Remove(f.Name())
390 // Populate the file contents.
391 if _, err := io.Copy(f, binary); err != nil {
392 return nil, fmt.Errorf("unable to populate temp file: %w", err)
393 }
394 // Seek to the beginning.
395 if _, err := f.Seek(0, os.SEEK_SET); err != nil {
396 return nil, fmt.Errorf("unable to seek in temp file: %w", err)
397 }
398 input = f
399 }
400
401 ctx, cancel := context.WithCancel(context.Background())
402 defer cancel()
403
404 // Execute go tool objdump given the input.
405 cmd := exec.CommandContext(ctx, flags.Go, "tool", "objdump", input.Name())
406 if goroot, ok := os.LookupEnv("GOROOT"); ok && strings.HasPrefix(goroot, "bazel-out/") {
407 // Under Bazel, our nogo machinery sets GOROOT to a stdlib output tree,
408 // which does not include the prebuilt objdump tool. Some Go versions
409 // may build objdump on-demand via `go tool objdump`, which requires a
410 // writable build cache.
411 //
412 // See https://go.dev/issue/71867 and
413 // https://github.com/bazel-contrib/rules_go/issues/4535.
414 cacheDirRel := filepath.Join("bazel-out", ".checkescape-gocache")
415 if err := os.MkdirAll(cacheDirRel, 0755); err != nil {
416 return nil, fmt.Errorf("unable to create build cache dir %q: %w", cacheDirRel, err)
417 }
418 // GOCACHE must be an absolute path.
419 cacheDirAbs, err := filepath.Abs(cacheDirRel)
420 if err != nil {
421 return nil, fmt.Errorf("unable to get absolute path of build cache dir %q: %w", cacheDirRel, err)

Callers 1

runFunction · 0.85

Calls 15

deleteStruct · 0.85
fixOffsetFunction · 0.70
ErrorfMethod · 0.65
SeekMethod · 0.65
NameMethod · 0.65
CopyMethod · 0.65
JoinMethod · 0.65
CloseMethod · 0.65
StartMethod · 0.65
StringMethod · 0.65
WaitMethod · 0.65
RemoveMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…