all: use internal objcopy implementation
This lessens the dependency on binutils (e.g. arm-none-eabi-objcopy).
Этот коммит содержится в:
родитель
3538ba943c
коммит
4f932b6e66
6 изменённых файлов: 90 добавлений и 19 удалений
9
Gopkg.lock
сгенерированный
9
Gopkg.lock
сгенерированный
|
@ -1,6 +1,14 @@
|
|||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:00b45e06c7843541372fc17d982242bd6adfc2fc382b6f2e9ef9ce53d87a50b9"
|
||||
name = "github.com/marcinbor85/gohex"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "7a43cd876e46e0f6ddc553f10f91731a78e6e949"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ba70784a3deee74c0ca3c87bcac3c2f93d3b2d27d8f237b768c358b45ba47da8"
|
||||
|
@ -25,6 +33,7 @@
|
|||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
input-imports = [
|
||||
"github.com/marcinbor85/gohex",
|
||||
"golang.org/x/tools/go/ast/astutil",
|
||||
"golang.org/x/tools/go/ssa",
|
||||
"tinygo.org/x/go-llvm",
|
||||
|
|
13
main.go
13
main.go
|
@ -259,19 +259,12 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
|
|||
}
|
||||
}
|
||||
|
||||
if outext == ".hex" || outext == ".bin" {
|
||||
// Get an Intel .hex file or .bin file from the .elf file.
|
||||
if outext == ".hex" || outext == ".bin" {
|
||||
tmppath = filepath.Join(dir, "main"+outext)
|
||||
format := map[string]string{
|
||||
".hex": "ihex",
|
||||
".bin": "binary",
|
||||
}[outext]
|
||||
cmd := exec.Command(spec.Objcopy, "-O", format, executable, tmppath)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
err := Objcopy(executable, tmppath)
|
||||
if err != nil {
|
||||
return &commandError{"failed to extract " + format + " from", executable, err}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return action(tmppath)
|
||||
|
|
78
objcopy.go
Обычный файл
78
objcopy.go
Обычный файл
|
@ -0,0 +1,78 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"debug/elf"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/marcinbor85/gohex"
|
||||
)
|
||||
|
||||
// ObjcopyError is an error returned by functions that act like objcopy.
|
||||
type ObjcopyError struct {
|
||||
Op string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e ObjcopyError) Error() string {
|
||||
if e.Err == nil {
|
||||
return e.Op
|
||||
}
|
||||
return e.Op + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
// ExtractTextSegment returns the .text segment and the first address from the
|
||||
// ELF file in the given path.
|
||||
func ExtractTextSegment(path string) (uint64, []byte, error) {
|
||||
f, err := elf.Open(path)
|
||||
if err != nil {
|
||||
return 0, nil, ObjcopyError{"failed to open ELF file to extract text segment", err}
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
text := f.Section(".text")
|
||||
if text == nil {
|
||||
return 0, nil, ObjcopyError{"file does not contain .text segment: " + path, nil}
|
||||
}
|
||||
data, err := text.Data()
|
||||
if err != nil {
|
||||
return 0, nil, ObjcopyError{"failed to extract .text segment from ELF file", err}
|
||||
}
|
||||
return text.Addr, data, nil
|
||||
}
|
||||
|
||||
// Objcopy converts an ELF file to a different (simpler) output file format:
|
||||
// .bin or .hex. It extracts only the .text section.
|
||||
func Objcopy(infile, outfile string) error {
|
||||
f, err := os.OpenFile(outfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Read the .text segment.
|
||||
addr, data, err := ExtractTextSegment(infile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write to the file, in the correct format.
|
||||
switch filepath.Ext(outfile) {
|
||||
case ".bin":
|
||||
// The address is not stored in a .bin file (therefore you
|
||||
// should use .hex files in most cases).
|
||||
_, err := f.Write(data)
|
||||
return err
|
||||
case ".hex":
|
||||
mem := gohex.NewMemory()
|
||||
mem.SetStartAddress(uint32(addr)) // ignored in most cases (Intel-specific)
|
||||
err := mem.AddBinary(uint32(addr), data)
|
||||
if err != nil {
|
||||
return ObjcopyError{"failed to create .hex file", err}
|
||||
}
|
||||
mem.DumpIntelHex(f, 32) // TODO: handle error
|
||||
return nil
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
|
@ -31,7 +31,6 @@ type TargetSpec struct {
|
|||
CFlags []string `json:"cflags"`
|
||||
LDFlags []string `json:"ldflags"`
|
||||
ExtraFiles []string `json:"extra-files"`
|
||||
Objcopy string `json:"objcopy"`
|
||||
Emulator []string `json:"emulator"`
|
||||
Flasher string `json:"flash"`
|
||||
OCDDaemon []string `json:"ocd-daemon"`
|
||||
|
@ -72,9 +71,6 @@ func (spec *TargetSpec) copyProperties(spec2 *TargetSpec) {
|
|||
spec.CFlags = append(spec.CFlags, spec2.CFlags...)
|
||||
spec.LDFlags = append(spec.LDFlags, spec2.LDFlags...)
|
||||
spec.ExtraFiles = append(spec.ExtraFiles, spec2.ExtraFiles...)
|
||||
if spec2.Objcopy != "" {
|
||||
spec.Objcopy = spec2.Objcopy
|
||||
}
|
||||
if len(spec2.Emulator) != 0 {
|
||||
spec.Emulator = spec2.Emulator
|
||||
}
|
||||
|
@ -217,7 +213,6 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||
BuildTags: []string{goos, goarch},
|
||||
Compiler: commands["clang"],
|
||||
Linker: "cc",
|
||||
Objcopy: "objcopy",
|
||||
GDB: "gdb",
|
||||
GDBCmds: []string{"run"},
|
||||
}
|
||||
|
@ -230,13 +225,11 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
|||
// Some educated guesses as to how to invoke helper programs.
|
||||
if goarch == "arm" && goos == "linux" {
|
||||
spec.Linker = "arm-linux-gnueabihf-gcc"
|
||||
spec.Objcopy = "arm-linux-gnueabihf-objcopy"
|
||||
spec.GDB = "arm-linux-gnueabihf-gdb"
|
||||
spec.Emulator = []string{"qemu-arm", "-L", "/usr/arm-linux-gnueabihf"}
|
||||
}
|
||||
if goarch == "arm64" && goos == "linux" {
|
||||
spec.Linker = "aarch64-linux-gnu-gcc"
|
||||
spec.Objcopy = "aarch64-linux-gnu-objcopy"
|
||||
spec.GDB = "aarch64-linux-gnu-gdb"
|
||||
spec.Emulator = []string{"qemu-aarch64", "-L", "/usr/aarch64-linux-gnu"}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
"goarch": "wasm",
|
||||
"compiler": "avr-gcc",
|
||||
"linker": "avr-gcc",
|
||||
"objcopy": "avr-objcopy",
|
||||
"ldflags": [
|
||||
"-T", "targets/avr.ld",
|
||||
"-Wl,--gc-sections"
|
||||
|
|
|
@ -16,6 +16,5 @@
|
|||
"ldflags": [
|
||||
"--gc-sections"
|
||||
],
|
||||
"objcopy": "arm-none-eabi-objcopy",
|
||||
"gdb": "arm-none-eabi-gdb"
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче