From f9bdc3a6181fb250dcaec21d552f56693438336e Mon Sep 17 00:00:00 2001 From: Mefistotelis Date: Sat, 12 Mar 2022 01:09:06 +0100 Subject: [PATCH] parser: Improved getting unique names Unified the functions for getting unique names, and added one for getting struct tag (unused yet). --- csym/parse_decls.go | 2 +- csym/parse_fixups.go | 52 ++++++++++++++++++++++++++++++++++++-------- csym/parse_types.go | 5 ++++- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/csym/parse_decls.go b/csym/parse_decls.go index 2bcd0fd..650a56f 100644 --- a/csym/parse_decls.go +++ b/csym/parse_decls.go @@ -322,7 +322,7 @@ func findFunc(p *Parser, name string, addr uint32) (*c.FuncDecl, *c.FuncType) { if f == nil { f = p.emptyFunc(name, addr) if nameExists { - f.Var.Name = UniqueFuncName(p.curOverlay, f) + f.Var.Name = UniqueFuncName(p.curOverlay.funcNames, f) } log.Printf("unable to locate function %q, created void", name) } diff --git a/csym/parse_fixups.go b/csym/parse_fixups.go index f70619e..2ba5aa9 100644 --- a/csym/parse_fixups.go +++ b/csym/parse_fixups.go @@ -7,7 +7,6 @@ import ( ) //TODO make unique names of types -//TODO make unique names of functions //TODO remove duplicate items // MakeNamesUnique goes through parsed symbols and renames duplicate ones. @@ -37,7 +36,7 @@ func (p *Parser) makeVarNamesUniqueInOverlay(overlay *Overlay) { for i := 0; i < len(variables); i++ { v := variables[i] if v.Class == c.Extern { continue } - v.Var.Name = UniqueVarName(overlay, v) + v.Var.Name = UniqueVarName(overlay.varNames, v) } } } @@ -50,7 +49,7 @@ func (p *Parser) makeFuncNamesUniqueInOverlay(overlay *Overlay) { if real_len < 2 { continue } for i := 0; i < len(funcs); i++ { f := funcs[i] - f.Var.Name = UniqueFuncName(overlay, f) + f.Var.Name = UniqueFuncName(overlay.funcNames, f) } } } @@ -60,12 +59,47 @@ func UniqueName(name string, addr uint32) string { return fmt.Sprintf("%s_addr_%08X", name, addr) } -// UniqueVarName returns a unique name for a variable declaration -func UniqueVarName(overlay *Overlay, v *c.VarDecl) string { - return fmt.Sprintf("%s_addr_%08X", v.Var.Name, v.Addr) +// UniqueTag returns a unique tag based on the given tag and duplicate index. +func UniqueTag(tag string, idx int) string { + return fmt.Sprintf("%s_duplicate_%d", tag, idx) } -// UniqueFuncName returns a unique name for a variable declaration -func UniqueFuncName(overlay *Overlay, f *c.FuncDecl) string { - return fmt.Sprintf("%s_addr_%08X", f.Var.Name, f.Addr) +// SliceIndex returns index within slece for which the func returns true +func SliceIndex(limit int, predicate func(i int) bool) int { + for i := 0; i < limit; i++ { + if predicate(i) { + return i + } + } + return -1 +} + +// UniqueVarName returns a unique variable name based on the given variable +// and set of present variables mapped by names. +func UniqueVarName(varNames map[string][]*c.VarDecl, v *c.VarDecl) string { + newName := v.Var.Name + newName = UniqueName(newName, v.Addr) + return newName +} + +// UniqueFuncName returns a unique function name based on the given function +// and set of present functions mapped by names. +func UniqueFuncName(funcNames map[string][]*c.FuncDecl, f *c.FuncDecl) string { + newName := f.Var.Name + newName = UniqueName(newName, f.Addr) + return newName +} + +// UniqueStructName returns a unique struct tag based on the given struct +// and set of present structs mapped by names. +func UniqueStructName(structNames map[string][]*c.StructType, s *c.StructType) string { + newTag := s.Tag + for { + structs, ok := structNames[newTag] + if !ok { break } // the name is unique - done + k := SliceIndex(len(structs), func(i int) bool { return structs[i] == s }) + if k < 0 { k = len(structs) } + newTag = UniqueTag(newTag, k) + } + return newTag } diff --git a/csym/parse_types.go b/csym/parse_types.go index c4ee29c..8527c25 100644 --- a/csym/parse_types.go +++ b/csym/parse_types.go @@ -42,7 +42,10 @@ func (p *Parser) ParseTypes(syms []*sym.Symbol) { // such verification is made when parsing declarations (`parse_decls.go`) } } - if p.opts.Verbose { fmt.Printf("Created %d structs, %d enums, %d unions, %d types.\n", len(p.Structs), len(p.Enums), len(p.Unions), len(p.Types)) } + if p.opts.Verbose { + fmt.Printf("Created %d structs, %d enums, %d unions, %d types.\n", + len(p.Structs), len(p.Enums), len(p.Unions), len(p.Types)) + } } func (p *Parser) emptyStruct(tag string, size uint32) *c.StructType {