Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove file paths from TEXT directives in go binaries

Tags:

go

elf

I want to remove all path information like /Users/myuser/dev/go/src/fooapi/spikes/mongoapi.go from the executable that I created with go build.

I'm compiling the code like this:

CGO_ENABLED=0 go build -v -a -ldflags="-w -s" -o ./fooapi spikes/mongoapi.go

Some part of the example assembly from the go build command above:

$ go tool objdump ./fooapi
.
.
TEXT main.init(SB) /Users/myuser/dev/go/src/api/spikes/mongoapi.go
mongoapi.go:60  0x12768c0   65488b0c25a0080000  GS MOVQ GS:0x8a0, CX
mongoapi.go:60  0x12768c9   483b6110        CMPQ 0x10(CX), SP
mongoapi.go:60  0x12768cd   7663            JBE 0x1276932
.
.

Note that: strip is not recommended and can lead to broken executables if you're going to recommend it as a solution.

like image 739
Inanc Gumus Avatar asked Jul 24 '17 11:07

Inanc Gumus


2 Answers

Use -trimpath flags to remove path information:

CGO_ENABLED=0 go build -v -a -ldflags="-w -s" \
    -gcflags=-trimpath=/Users/myuser/dev/go/src \
    -asmflags=-trimpath=/Users/myuser/dev/go/src \
    -o ./fooapi spikes/mongoapi.go

More Information:

Passing -trimpath to -gcflags and -asmflags will remove any path information from the elf binary.

$ go tool asm -help 2>&1 | grep -A1 trimpath
-trimpath string
    remove prefix from recorded source file paths

$ go tool compile -help|grep -A1 trimpath
-trimpath string
    remove prefix from recorded source file paths

You can check the result with go tool objdump:

$ go tool objdump ./fooapi
.
.
TEXT main.init(SB) api/spikes/mongoapi.go
mongoapi.go:60  0x12768c0   65488b0c25a0080000  GS MOVQ GS:0x8a0, CX
mongoapi.go:60  0x12768c9   483b6110        CMPQ 0x10(CX), SP
mongoapi.go:60  0x12768cd   7663            JBE 0x1276932
.
.

Using strip tool has still some controversies in go community, although it's been said that it's been fixed. Some say that unknown and unpredictable bugs occur sometimes. Read here and here for examples.

like image 170
Inanc Gumus Avatar answered Nov 18 '22 02:11

Inanc Gumus


trimpath is a good approach, but had issues like go issue 24976

It appears that, when multiple -trimpath flags are passed to go tool compile, the last one wins

Indeed; from what I can tell the trimpath flag is defined as an ordinary string flag, not a list.

But with CL 173344, this is now fixed (for the upcoming Go 1.13)

cmd/internal/objabi: expand -trimpath syntax

This CL affects the low-level -trimpath flag provided by both cmd/asm and cmd/compile.

Previously, the flag took the name of a single directory that would be trimmed from recorded paths in the resulting object file.

This CL makes the flag take a semicolon-separated list of paths.

Further, each path can now end in an optional "=>replacement" to specify what to replace that leading path prefix with, instead of only dropping it.

A followup CL will add a mode to cmd/go that uses this richer -trimpath to build binaries that do not contain any local path names.

This is CL 173345:

cmd/go: add -trimpath build flag

"go build -trimpath" trims the recorded file paths in the resulting packages and executables to avoid recording the names of any local directories.
Instead, the files appear to be stored in directories named either "go/src/..." (for the standard library) or named after the module or package in which the files appear.

This fixes issue 16860, which is about Go ability to generate bit-for-bit identical binaries, as noted by Ivan Daniluk.

like image 20
VonC Avatar answered Nov 18 '22 02:11

VonC