diff options
Diffstat (limited to 'src/cmd/objdump/elf.go')
-rw-r--r-- | src/cmd/objdump/elf.go | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/cmd/objdump/elf.go b/src/cmd/objdump/elf.go new file mode 100644 index 000000000..906e90353 --- /dev/null +++ b/src/cmd/objdump/elf.go @@ -0,0 +1,65 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Parsing of ELF executables (Linux, FreeBSD, and so on). + +package main + +import ( + "debug/elf" + "os" +) + +func elfSymbols(f *os.File) (syms []Sym, goarch string) { + p, err := elf.NewFile(f) + if err != nil { + errorf("parsing %s: %v", f.Name(), err) + return + } + + elfSyms, err := p.Symbols() + if err != nil { + errorf("parsing %s: %v", f.Name(), err) + return + } + + switch p.Machine { + case elf.EM_X86_64: + goarch = "amd64" + case elf.EM_386: + goarch = "386" + case elf.EM_ARM: + goarch = "arm" + } + + for _, s := range elfSyms { + sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'} + switch s.Section { + case elf.SHN_UNDEF: + sym.Code = 'U' + case elf.SHN_COMMON: + sym.Code = 'B' + default: + i := int(s.Section) + if i < 0 || i >= len(p.Sections) { + break + } + sect := p.Sections[i] + switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) { + case elf.SHF_ALLOC | elf.SHF_EXECINSTR: + sym.Code = 'T' + case elf.SHF_ALLOC: + sym.Code = 'R' + case elf.SHF_ALLOC | elf.SHF_WRITE: + sym.Code = 'D' + } + } + if elf.ST_BIND(s.Info) == elf.STB_LOCAL { + sym.Code += 'a' - 'A' + } + syms = append(syms, sym) + } + + return +} |