Repository: incubator-mynewt-newt
Updated Branches:
  refs/heads/develop 386c08789 -> dce8b5cd0


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/develop
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)
+}

Reply via email to