You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2017/03/06 21:17:04 UTC
[30/50] [abbrv] incubator-mynewt-newt git commit: MYNEWT-651;
newt - include package size info in manifest file.
MYNEWT-651; newt - include package size info in manifest file.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/38d3bc22
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/38d3bc22
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/38d3bc22
Branch: refs/heads/master
Commit: 38d3bc222bcb190fb35861cfe3116a7ab1aee57a
Parents: a404a47
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Thu Mar 2 12:59:43 2017 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Thu Mar 2 12:59:43 2017 -0800
----------------------------------------------------------------------
newt/builder/size.go | 209 +++++++++++++++++++++++++++++++--------
newt/builder/targetbuild.go | 10 ++
newt/image/image.go | 80 ++++++++++++++-
3 files changed, 257 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/38d3bc22/newt/builder/size.go
----------------------------------------------------------------------
diff --git a/newt/builder/size.go b/newt/builder/size.go
index 5ce2939..70b4dc2 100644
--- a/newt/builder/size.go
+++ b/newt/builder/size.go
@@ -28,6 +28,7 @@ import (
"strconv"
"strings"
+ "mynewt.apache.org/newt/newt/image"
"mynewt.apache.org/newt/util"
)
@@ -41,6 +42,8 @@ type MemSection struct {
}
type MemSectionArray []*MemSection
+var globalMemSections map[string]*MemSection
+
func (array MemSectionArray) Len() int {
return len(array)
}
@@ -71,11 +74,23 @@ func (m *MemSection) PartOf(addr uint64) bool {
}
/*
+ * Info about specific symbol size
+ */
+type SymbolData struct {
+ Name string
+ ObjName string /* Which object file it came from */
+ Sizes map[string]uint32 /* Sizes indexed by mem section name */
+}
+
+type SymbolDataArray []*SymbolData
+
+/*
* We accumulate the size of libraries to elements in this.
*/
type PkgSize struct {
Name string
- Sizes map[string]uint32 /* Sizes indexed by mem section name */
+ Sizes map[string]uint32 /* Sizes indexed by mem section name */
+ Syms map[string]*SymbolData /* Symbols indexed by symbol name */
}
type PkgSizeArray []*PkgSize
@@ -92,33 +107,76 @@ func (array PkgSizeArray) Swap(i, j int) {
array[i], array[j] = array[j], array[i]
}
-func MakePkgSize(name string, memSections map[string]*MemSection) *PkgSize {
+func (array SymbolDataArray) Len() int {
+ return len(array)
+}
+
+func (array SymbolDataArray) Less(i, j int) bool {
+ return array[i].Name < array[j].Name
+}
+
+func (array SymbolDataArray) Swap(i, j int) {
+ array[i], array[j] = array[j], array[i]
+}
+
+func MakeSymbolData(name string, objName string) *SymbolData {
+ sym := &SymbolData{
+ Name: name,
+ ObjName: objName,
+ }
+ sym.Sizes = make(map[string]uint32)
+ for _, sec := range globalMemSections {
+ sym.Sizes[sec.Name] = 0
+ }
+ return sym
+}
+
+func MakePkgSize(name string) *PkgSize {
pkgSize := &PkgSize{
Name: name,
}
pkgSize.Sizes = make(map[string]uint32)
- for secName, _ := range memSections {
- pkgSize.Sizes[secName] = 0
+ for _, sec := range globalMemSections {
+ pkgSize.Sizes[sec.Name] = 0
}
+ pkgSize.Syms = make(map[string]*SymbolData)
return pkgSize
}
+func (ps *PkgSize) addSymSize(symName string, objName string, size uint32, addr uint64) {
+ for _, section := range globalMemSections {
+ if section.PartOf(addr) {
+ name := section.Name
+ size32 := uint32(size)
+ if size32 > 0 {
+ sym := ps.Syms[symName]
+ if sym == nil {
+ sym = MakeSymbolData(symName, objName)
+ ps.Syms[symName] = sym
+ }
+ ps.Sizes[name] += size32
+ sym.Sizes[name] += size32
+ }
+ break
+ }
+ }
+}
+
/*
* Go through GCC generated mapfile, and collect info about symbol sizes
*/
-func ParseMapFileSizes(fileName string) (map[string]*PkgSize,
- map[string]*MemSection, error) {
+func ParseMapFileSizes(fileName string) (map[string]*PkgSize, error) {
var state int = 0
file, err := os.Open(fileName)
if err != nil {
- return nil, nil,
- util.NewNewtError("Mapfile failed: " + err.Error())
+ return nil, util.NewNewtError("Mapfile failed: " + err.Error())
}
- memSections := make(map[string]*MemSection)
- pkgSizes := make(map[string]*PkgSize)
+ var symName string = ""
+ globalMemSections = make(map[string]*MemSection)
+ pkgSizes := make(map[string]*PkgSize)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
switch state {
@@ -138,13 +196,13 @@ func ParseMapFileSizes(fileName string) (map[string]*PkgSize,
array := strings.Fields(scanner.Text())
offset, err := strconv.ParseUint(array[1], 0, 64)
if err != nil {
- return nil, nil, util.NewNewtError("Can't parse mem info")
+ return nil, util.NewNewtError("Can't parse mem info")
}
size, err := strconv.ParseUint(array[2], 0, 64)
if err != nil {
- return nil, nil, util.NewNewtError("Can't parse mem info")
+ return nil, util.NewNewtError("Can't parse mem info")
}
- memSections[array[0]] = MakeMemSection(array[0], offset,
+ globalMemSections[array[0]] = MakeMemSection(array[0], offset,
size)
case 3:
if strings.Contains(scanner.Text(),
@@ -177,6 +235,7 @@ func ParseMapFileSizes(fileName string) (map[string]*PkgSize,
*
* ignore these for now
*/
+ symName = array[0]
continue
case 2:
/*
@@ -214,6 +273,7 @@ func ParseMapFileSizes(fileName string) (map[string]*PkgSize,
addrStr = array[1]
sizeStr = array[2]
srcFile = array[0]
+ symName = array[0]
} else {
addrStr = array[0]
sizeStr = array[1]
@@ -230,6 +290,7 @@ func ParseMapFileSizes(fileName string) (map[string]*PkgSize,
* crud, e.g.:
* 0x8 (size before relaxing)
*/
+ symName = array[0]
addrStr = array[1]
sizeStr = array[2]
srcFile = array[3]
@@ -248,44 +309,49 @@ func ParseMapFileSizes(fileName string) (map[string]*PkgSize,
continue
}
tmpStrArr := strings.Split(srcFile, "(")
- srcLib := filepath.Base(tmpStrArr[0])
- for name, section := range memSections {
- if section.PartOf(addr) {
- pkgSize := pkgSizes[srcLib]
- if pkgSize == nil {
- pkgSize =
- MakePkgSize(srcLib, memSections)
- pkgSizes[srcLib] = pkgSize
- }
- pkgSize.Sizes[name] += uint32(size)
- break
+ srcLib := tmpStrArr[0]
+ objName := ""
+ if srcLib != "*fill*" {
+ tmpStrArr = strings.Split(tmpStrArr[1], ")")
+ objName = tmpStrArr[0]
+ }
+ tmpStrArr = strings.Split(symName, ".")
+ if len(tmpStrArr) > 2 {
+ if tmpStrArr[1] == "rodata" && tmpStrArr[2] == "str1" {
+ symName = ".rodata.str1"
+ } else {
+ symName = tmpStrArr[2]
}
}
+ pkgSize := pkgSizes[srcLib]
+ if pkgSize == nil {
+ pkgSize = MakePkgSize(srcLib)
+ pkgSizes[srcLib] = pkgSize
+ }
+ pkgSize.addSymSize(symName, objName, uint32(size), addr)
+ symName = ".unknown"
default:
}
}
file.Close()
- for name, section := range memSections {
+ for name, section := range globalMemSections {
util.StatusMessage(util.VERBOSITY_VERBOSE, "Mem %s: 0x%x-0x%x\n",
name, section.Offset, section.EndOff)
}
- return pkgSizes, memSections, nil
+ return pkgSizes, nil
}
/*
* Return a printable string containing size data for the libraries
*/
-func PrintSizes(libs map[string]*PkgSize,
- sectMap map[string]*MemSection) (string, error) {
- ret := ""
-
+func PrintSizes(libs map[string]*PkgSize) error {
/*
* Order sections by offset, and display lib sizes in that order.
*/
- memSections := make(MemSectionArray, len(sectMap))
+ memSections := make(MemSectionArray, len(globalMemSections))
var i int = 0
- for _, sec := range sectMap {
+ for _, sec := range globalMemSections {
memSections[i] = sec
i++
}
@@ -303,16 +369,17 @@ func PrintSizes(libs map[string]*PkgSize,
sort.Sort(pkgSizes)
for _, sec := range memSections {
- ret += fmt.Sprintf("%7s ", sec.Name)
+ fmt.Printf("%7s ", sec.Name)
}
- ret += "\n"
+ fmt.Printf("\n")
for _, es := range pkgSizes {
for i := 0; i < len(memSections); i++ {
- ret += fmt.Sprintf("%7d ", es.Sizes[memSections[i].Name])
+ fmt.Printf("%7d ", es.Sizes[memSections[i].Name])
}
- ret += fmt.Sprintf("%s\n", es.Name)
+ fmt.Printf("%s\n", filepath.Base(es.Name))
}
- return ret, nil
+
+ return nil
}
func (t *TargetBuilder) Size() error {
@@ -336,6 +403,67 @@ func (t *TargetBuilder) Size() error {
return err
}
+func (b *Builder) FindPkgNameByArName(arName string) string {
+ for rpkg, bpkg := range b.PkgMap {
+ if (b.ArchivePath(bpkg) == arName) {
+ return rpkg.Lpkg.FullName()
+ }
+ }
+ return filepath.Base(arName)
+}
+
+func (b *Builder) PkgSizes() (*image.ImageManifestSizeCollector, error) {
+ if b.appPkg == nil {
+ return nil, util.NewNewtError("app package not specified for this target")
+ }
+
+ if b.targetBuilder.bspPkg.Arch == "sim" {
+ return nil, util.NewNewtError("'newt size' not supported for sim targets")
+ }
+ mapFile := b.AppElfPath() + ".map"
+
+ libs, err := ParseMapFileSizes(mapFile)
+ if err != nil {
+ return nil, err
+ }
+
+ /*
+ * Order libraries by name.
+ */
+ pkgSizes := make(PkgSizeArray, len(libs))
+ i := 0
+ for _, es := range libs {
+ pkgSizes[i] = es
+ i++
+ }
+ sort.Sort(pkgSizes)
+
+ c := image.NewImageManifestSizeCollector()
+ for _, es := range pkgSizes {
+ p := c.AddPkg(b.FindPkgNameByArName(es.Name))
+
+ /*
+ * Order symbols by name.
+ */
+ symbols := make(SymbolDataArray, len(es.Syms))
+ i := 0
+ for _, sym := range es.Syms {
+ symbols[i] = sym
+ i++
+ }
+ sort.Sort(symbols)
+ for _, sym := range symbols {
+ for area, areaSz := range sym.Sizes {
+ if areaSz != 0 {
+ p.AddSymbol(sym.ObjName, sym.Name, area, areaSz)
+ }
+ }
+ }
+ }
+
+ return c, nil
+}
+
func (b *Builder) Size() error {
if b.appPkg == nil {
return util.NewNewtError("app package not specified for this target")
@@ -351,15 +479,14 @@ func (b *Builder) Size() error {
}
mapFile := b.AppElfPath() + ".map"
- pkgSizes, memSections, err := ParseMapFileSizes(mapFile)
+ pkgSizes, err := ParseMapFileSizes(mapFile)
if err != nil {
return err
}
- output, err := PrintSizes(pkgSizes, memSections)
+ err = PrintSizes(pkgSizes)
if err != nil {
return err
}
- fmt.Printf("%s", output)
c, err := b.newCompiler(b.appPkg, b.FileBinDir(b.AppElfPath()))
if err != nil {
@@ -367,7 +494,7 @@ func (b *Builder) Size() error {
}
fmt.Printf("\nobjsize\n")
- output, err = c.PrintSize(b.AppElfPath())
+ output, err := c.PrintSize(b.AppElfPath())
if err != nil {
return err
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/38d3bc22/newt/builder/targetbuild.go
----------------------------------------------------------------------
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 2576764..06bbee1 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -577,6 +577,16 @@ func (t *TargetBuilder) createManifest() error {
manifest.TgtVars = append(manifest.TgtVars, tgtSyscfg)
}
+ c, err := t.AppBuilder.PkgSizes()
+ if err == nil {
+ manifest.PkgSizes = c.Pkgs
+ }
+ if t.LoaderBuilder != nil {
+ c, err = t.LoaderBuilder.PkgSizes()
+ if err == nil {
+ manifest.LoaderPkgSizes = c.Pkgs
+ }
+ }
file, err := os.Create(t.AppBuilder.ManifestPath())
if err != nil {
return util.FmtNewtError("Cannot create manifest file %s: %s",
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/38d3bc22/newt/image/image.go
----------------------------------------------------------------------
diff --git a/newt/image/image.go b/newt/image/image.go
index c63eb2e..f396d7c 100644
--- a/newt/image/image.go
+++ b/newt/image/image.go
@@ -117,6 +117,30 @@ const (
/*
* Data that's going to go to build manifest file
*/
+type ImageManifestSizeArea struct {
+ Name string
+ Size uint32
+}
+
+type ImageManifestSizeSym struct {
+ Name string `json:"name"`
+ Areas []*ImageManifestSizeArea `json:"areas"`
+}
+
+type ImageManifestSizeFile struct {
+ Name string `json:"name"`
+ Syms []*ImageManifestSizeSym `json:"sym"`
+}
+
+type ImageManifestSizePkg struct {
+ Name string `json:"name"`
+ Files []*ImageManifestSizeFile `json:"files"`
+}
+
+type ImageManifestSizeCollector struct {
+ Pkgs []*ImageManifestSizePkg
+}
+
type ImageManifest struct {
Name string `json:"name"`
Date string `json:"build_time"`
@@ -127,9 +151,12 @@ type ImageManifest struct {
Loader string `json:"loader"`
LoaderHash string `json:"loader_hash"`
Pkgs []*ImageManifestPkg `json:"pkgs"`
- LoaderPkgs []*ImageManifestPkg `json:"loader_pkgs"`
+ LoaderPkgs []*ImageManifestPkg `json:"loader_pkgs,omitempty"`
TgtVars []string `json:"target"`
Repos []ImageManifestRepo `json:"repos"`
+
+ PkgSizes []*ImageManifestSizePkg `json:"pkgsz"`
+ LoaderPkgSizes []*ImageManifestSizePkg `json:"loader_pkgsz,omitempty"`
}
type ImageManifestPkg struct {
@@ -688,3 +715,54 @@ func (r *RepoManager) AllRepos() []ImageManifestRepo {
return repos
}
+
+func NewImageManifestSizeCollector() *ImageManifestSizeCollector {
+ return &ImageManifestSizeCollector{}
+}
+
+func (c *ImageManifestSizeCollector) AddPkg(pkg string) *ImageManifestSizePkg {
+ p := &ImageManifestSizePkg {
+ Name: pkg,
+ }
+ c.Pkgs = append(c.Pkgs, p)
+
+ return p
+}
+
+func (c *ImageManifestSizePkg) AddSymbol(file string, sym string, area string,
+ symSz uint32) {
+ f := c.addFile(file)
+ s := f.addSym(sym)
+ s.addArea(area, symSz)
+}
+
+func (p *ImageManifestSizePkg) addFile(file string) *ImageManifestSizeFile {
+ for _, f := range p.Files {
+ if f.Name == file {
+ return f
+ }
+ }
+ f := &ImageManifestSizeFile {
+ Name: file,
+ }
+ p.Files = append(p.Files, f)
+
+ return f
+}
+
+func (f *ImageManifestSizeFile) addSym(sym string) *ImageManifestSizeSym {
+ s := &ImageManifestSizeSym {
+ Name: sym,
+ }
+ f.Syms = append(f.Syms, s)
+
+ return s
+}
+
+func (s *ImageManifestSizeSym) addArea(area string, areaSz uint32) {
+ a := &ImageManifestSizeArea {
+ Name: area,
+ Size: areaSz,
+ }
+ s.Areas = append(s.Areas, a)
+}