Skip to content

Commit

Permalink
Merge pull request #2797 from saschagrunert/link-mode
Browse files Browse the repository at this point in the history
Add `LinkMode()` to binary implementation
  • Loading branch information
k8s-ci-robot authored Dec 12, 2022
2 parents 83e74f5 + 43af3d7 commit 350c637
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 5 deletions.
22 changes: 18 additions & 4 deletions pkg/binary/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,10 @@ type Options struct {
Path string
}

// DefaultOptions set of options
var DefaultOptions = &Options{}

// New creates a new binary instance.
func New(filePath string) (bin *Binary, err error) {
// Get the right implementation for the specified file
return NewWithOptions(filePath, DefaultOptions)
return NewWithOptions(filePath, &Options{Path: filePath})
}

// NewWithOptions creates a new binary with the specified options
Expand Down Expand Up @@ -121,6 +118,9 @@ type binaryImplementation interface {

// GetOS Returns a string with the GOOS of the binary
OS() string

// LinkMode returns the linking mode of the binary.
LinkMode() (LinkMode, error)
}

// SetImplementation sets the implementation to handle this sort of executable
Expand All @@ -138,6 +138,20 @@ func (b *Binary) OS() string {
return b.binaryImplementation.OS()
}

// LinkMode is the enum for all available linking modes.
type LinkMode string

const (
LinkModeUnknown LinkMode = "unknown"
LinkModeStatic LinkMode = "static"
LinkModeDynamic LinkMode = "dynamic"
)

// LinkMode returns the linking mode of the binary.
func (b *Binary) LinkMode() (LinkMode, error) {
return b.binaryImplementation.LinkMode()
}

// ContainsStrings searches the printable strings un a binary file
func (b *Binary) ContainsStrings(s ...string) (match bool, err error) {
// We cannot search for 0 items:
Expand Down
72 changes: 72 additions & 0 deletions pkg/binary/binaryfakes/fake_binary_implementation.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 27 additions & 1 deletion pkg/binary/elf.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package binary

import (
"bufio"
debugelf "debug/elf"
"encoding/binary"
"fmt"
"os"
Expand Down Expand Up @@ -55,7 +56,8 @@ func NewELFBinary(filePath string, opts *Options) (*ELFBinary, error) {
}

return &ELFBinary{
Header: header,
Header: header,
Options: opts,
}, nil
}

Expand Down Expand Up @@ -170,3 +172,27 @@ func (elf *ELFBinary) Arch() string {
func (elf *ELFBinary) OS() string {
return LINUX
}

// LinkMode returns the linking mode of the binary.
func (elf *ELFBinary) LinkMode() (LinkMode, error) {
file, err := os.Open(elf.Options.Path)
if err != nil {
return LinkModeUnknown, fmt.Errorf("open binary path: %w", err)
}

elfFile, err := debugelf.NewFile(file)
if err != nil {
return LinkModeUnknown, fmt.Errorf("unable to parse elf: %w", err)
}

for _, programHeader := range elfFile.Progs {
// If the elf program header refers to an interpreter, then the binary
// is not statically linked. See `file` implementation reference:
// https://github.com/file/file/blob/FILE5_36/src/readelf.c#L1581
if programHeader.Type == debugelf.PT_INTERP {
return LinkModeDynamic, nil
}
}

return LinkModeStatic, nil
}
5 changes: 5 additions & 0 deletions pkg/binary/mach-o.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,8 @@ func (macho *MachOBinary) Arch() string {
func (macho *MachOBinary) OS() string {
return DARWIN
}

// LinkMode returns the linking mode of the binary.
func (macho *MachOBinary) LinkMode() (LinkMode, error) {
return LinkModeUnknown, nil
}
5 changes: 5 additions & 0 deletions pkg/binary/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,8 @@ func (pe *PEBinary) Arch() string {
func (pe *PEBinary) OS() string {
return WIN
}

// LinkMode returns the linking mode of the binary.
func (pe *PEBinary) LinkMode() (LinkMode, error) {
return LinkModeUnknown, nil
}
9 changes: 9 additions & 0 deletions pkg/release/binaries.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ func (impl *defaultArtifactCheckerImpl) CheckVersionArch(
binData.Path, binData.Arch, binData.Platform, bin.Arch(), bin.OS(),
)
}

linkMode, err := bin.LinkMode()
if err != nil {
logrus.Warnf("Unable to get linkmode from binary %s: %v", binData.Path, err)
} else if linkMode == binary.LinkModeDynamic {
// TODO: fail hard if not all binaries are static (or unknown)
// Ref: https://github.com/kubernetes/release/issues/2786
logrus.Warnf("Binary is dynamically linked, which should be nothing we release: %s", binData.Path)
}
}
return nil
}

0 comments on commit 350c637

Please sign in to comment.