Continue microlibs alignment
This commit is contained in:
parent
12bc9774e0
commit
fa9c5399a9
4 changed files with 208 additions and 29 deletions
|
@ -35,16 +35,16 @@ func RunBinaryAnalyser(homeDir string) {
|
|||
|
||||
// Check if a json file is used or if it is via command line
|
||||
manager := new(ukManager.Manager)
|
||||
manager.MicroLibs = make(map[string]*ukManager.MicroLib)
|
||||
if len(*args.StringArg[listArg]) > 0 {
|
||||
manager.Unikernels = new(ukManager.Unikernels)
|
||||
manager.Unikernels.Unikernel = make([]ukManager.Unikernel, len(*args.StringArg[listArg]))
|
||||
manager.Unikernels = make([]ukManager.Unikernel, len(*args.StringArg[listArg]))
|
||||
mapping := false
|
||||
if *args.BoolArg[mappingArg] {
|
||||
mapping = true
|
||||
}
|
||||
list := strings.Split(*args.StringArg[listArg], ",")
|
||||
for i, arg := range list {
|
||||
manager.Unikernels.Unikernel[i] = ukManager.Unikernel{
|
||||
manager.Unikernels[i] = ukManager.Unikernel{
|
||||
BuildPath: arg,
|
||||
DisplayMapping: mapping,
|
||||
}
|
||||
|
@ -62,9 +62,10 @@ func RunBinaryAnalyser(homeDir string) {
|
|||
var comparison elf64analyser.ComparisonElf
|
||||
comparison.GroupFileSegment = make([]*elf64analyser.ElfFileSegment, 0)
|
||||
|
||||
for i, uk := range manager.Unikernels.Unikernel {
|
||||
for i, _ := range manager.Unikernels {
|
||||
|
||||
uk.Analyser = new(elf64analyser.ElfAnalyser)
|
||||
manager.Unikernels[i].Analyser = new(elf64analyser.ElfAnalyser)
|
||||
uk := manager.Unikernels[i]
|
||||
if len(uk.BuildPath) > 0 {
|
||||
if uk.BuildPath[len(uk.BuildPath)-1] != os.PathSeparator {
|
||||
uk.BuildPath += u.SEP
|
||||
|
@ -91,15 +92,6 @@ func RunBinaryAnalyser(homeDir string) {
|
|||
fmt.Println("=====================================================")
|
||||
}
|
||||
|
||||
if uk.ComputeLibsMapping && len(uk.LibsMapping) > 0 {
|
||||
|
||||
if err != nil {
|
||||
u.PrintErr(err)
|
||||
} else {
|
||||
uk.Analyser.ComputeAlignedMapping(uk.ElfFile, uk.LibsMapping)
|
||||
}
|
||||
}
|
||||
|
||||
if uk.DisplayStatSize {
|
||||
uk.Analyser.DisplayStatSize(uk.ElfFile)
|
||||
}
|
||||
|
@ -112,7 +104,9 @@ func RunBinaryAnalyser(homeDir string) {
|
|||
uk.Analyser.FindSectionByAddress(uk.ElfFile, uk.FindSectionByAddress)
|
||||
}
|
||||
|
||||
if uk.CompareGroup > 0 {
|
||||
manager.ComputeAlignment(uk)
|
||||
|
||||
/*if uk.CompareGroup > 0 {
|
||||
|
||||
foundSection := false
|
||||
section := uk.SectionSplit
|
||||
|
@ -153,12 +147,24 @@ func RunBinaryAnalyser(homeDir string) {
|
|||
comparison.GroupFileSegment = append(comparison.GroupFileSegment,
|
||||
&elf64analyser.ElfFileSegment{Filename: uk.ElfFile.Name,
|
||||
NbPages: len(uk.Analyser.ElfPage), Pages: uk.Analyser.ElfPage})
|
||||
} else {
|
||||
} else if len(uk.SectionSplit) > 0 {
|
||||
u.PrintWarning("Section '" + section + "' is not found in the ELF file")
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
manager.PerformAlignement()
|
||||
|
||||
/*
|
||||
if uk.ComputeLibsMapping && len(uk.LibsMapping) > 0 {
|
||||
|
||||
if err != nil {
|
||||
u.PrintErr(err)
|
||||
} else {
|
||||
uk.Analyser.ComputeAlignedMapping(uk.ElfFile, uk.LibsMapping)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if len(comparison.GroupFileSegment) > 1 {
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func ReadJsonFile(path string) (*Unikernels, error) {
|
||||
func ReadJsonFile(path string) ([]Unikernel, error) {
|
||||
jsonFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -25,7 +25,7 @@ func ReadJsonFile(path string) (*Unikernels, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return unikernels, nil
|
||||
return unikernels.Unikernel, nil
|
||||
}
|
||||
|
||||
func stringInSlice(name string, plats []string) bool {
|
||||
|
|
|
@ -1,17 +1,144 @@
|
|||
package ukManager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"tools/srcs/binarytool/elf64analyser"
|
||||
u "tools/srcs/common"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
Unikernels *Unikernels
|
||||
MicroLibs map[string]MicroLibs
|
||||
Unikernels []Unikernel
|
||||
MicroLibs map[string]*MicroLib
|
||||
SortedMicroLibs []*MicroLib //Used for the display
|
||||
}
|
||||
|
||||
type MicroLibs struct {
|
||||
Name string
|
||||
StartAddr uint64
|
||||
Size uint64
|
||||
type MicroLib struct {
|
||||
name string
|
||||
startAddr uint64
|
||||
size uint64
|
||||
instance int
|
||||
sectionSize SectionMicroLibs
|
||||
}
|
||||
|
||||
func checkInstance() {
|
||||
|
||||
type SectionMicroLibs struct {
|
||||
rodataSize uint64
|
||||
dataSize uint64
|
||||
BssSize uint64
|
||||
}
|
||||
|
||||
func (manager *Manager) ComputeAlignment(unikernel Unikernel) {
|
||||
|
||||
for _, libs := range unikernel.Analyser.ElfLibs {
|
||||
if val, ok := manager.MicroLibs[libs.Name]; ok {
|
||||
if manager.MicroLibs[libs.Name].size != libs.Size {
|
||||
//u.PrintWarning(fmt.Sprintf("Different size between %s (0x%x) (0x%x)", libs.Name, libs.Size, val.size))
|
||||
if val.size < libs.Size {
|
||||
u.PrintWarning(fmt.Sprintf("Bigger size found %s (0x%x) > (0x%x)", libs.Name, libs.Size, val.size))
|
||||
manager.MicroLibs[libs.Name].size = libs.Size
|
||||
}
|
||||
}
|
||||
manager.MicroLibs[libs.Name].instance += 1
|
||||
} else {
|
||||
mlib := &MicroLib{
|
||||
name: libs.Name,
|
||||
startAddr: libs.StartAddr,
|
||||
size: libs.Size,
|
||||
instance: 1,
|
||||
}
|
||||
manager.MicroLibs[libs.Name] = mlib
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *Manager) sortMicroLibs() {
|
||||
type kv struct {
|
||||
key string
|
||||
instance int
|
||||
addr uint64
|
||||
}
|
||||
|
||||
i := 0
|
||||
var kvSlice = make([]kv, len(manager.MicroLibs))
|
||||
for k, v := range manager.MicroLibs {
|
||||
kvSlice[i] = kv{k, v.instance, v.startAddr}
|
||||
i++
|
||||
}
|
||||
|
||||
sort.Slice(kvSlice, func(i, j int) bool {
|
||||
if kvSlice[i].instance != kvSlice[j].instance {
|
||||
return kvSlice[i].instance > kvSlice[j].instance
|
||||
}
|
||||
return kvSlice[i].addr < kvSlice[j].addr
|
||||
})
|
||||
|
||||
manager.SortedMicroLibs = make([]*MicroLib, len(manager.MicroLibs))
|
||||
for i, lib := range kvSlice {
|
||||
manager.SortedMicroLibs[i] = manager.MicroLibs[lib.key]
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *Manager) DisplayMicroLibs() {
|
||||
manager.sortMicroLibs()
|
||||
for i, lib := range manager.SortedMicroLibs {
|
||||
|
||||
if lib.instance < len(manager.Unikernels) {
|
||||
fmt.Printf("%d %s: %x - %x - %d\n", i, lib.name, lib.startAddr, lib.size, lib.instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *Manager) PerformAlignement() {
|
||||
var startValue uint64 = 0x106000
|
||||
//manager.Unikernels[0].Analyser.ElfLibs
|
||||
|
||||
manager.sortMicroLibs()
|
||||
commonMicroLibs := make([]*MicroLib, 0)
|
||||
for _, lib := range manager.SortedMicroLibs {
|
||||
if lib.instance == len(manager.Unikernels) {
|
||||
lib.startAddr = startValue
|
||||
commonMicroLibs = append(commonMicroLibs, lib)
|
||||
//fmt.Printf("%s -> 0x%x (0x%x) - 0x%x\n", lib.name, startValue, startValue, startValue+lib.size)
|
||||
startValue += lib.size
|
||||
} else if lib.instance > 1 {
|
||||
//fmt.Printf("---%s -> 0x%x (0x%x) - 0x%x\n", lib.name, startValue, startValue, startValue+lib.size)
|
||||
startValue = roundAddr(startValue)
|
||||
for i, _ := range manager.Unikernels {
|
||||
if manager.Unikernels[i].alignedLibs == nil {
|
||||
// Init structure
|
||||
manager.Unikernels[i].InitAlignment()
|
||||
}
|
||||
manager.Unikernels[i].AddAlignedMicroLibs(startValue, lib)
|
||||
}
|
||||
startValue += lib.size
|
||||
//fmt.Printf("%s -> 0x%x (0x%x) - 0x%x\n", lib.name, startValue, roundAddr(startValue), startValue+lib.size)
|
||||
} else if lib.instance == 1 {
|
||||
for i, _ := range manager.Unikernels {
|
||||
manager.Unikernels[i].AddSingleMicroLibs(roundAddr(startValue), lib)
|
||||
}
|
||||
//fmt.Printf("%s -> 0x%x (0x%x) - 0x%x\n", lib.name, startValue, roundAddr(startValue), startValue+lib.size)
|
||||
}
|
||||
}
|
||||
|
||||
// Find max value through unikernels
|
||||
for i, _ := range manager.Unikernels {
|
||||
manager.Unikernels[i].alignedLibs.AllCommonMicroLibs = commonMicroLibs
|
||||
if startValue < manager.Unikernels[i].alignedLibs.startValueUk {
|
||||
startValue = manager.Unikernels[i].alignedLibs.startValueUk
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("END SECTIONS: 0x%x\n", roundAddr(startValue))
|
||||
|
||||
/*println(commonMicroLibs.String())
|
||||
for _, uk := range manager.Unikernels {
|
||||
println(uk.microLibsInstance.String())
|
||||
}*/
|
||||
}
|
||||
|
||||
func roundAddr(value uint64) uint64 {
|
||||
x := float64(value)
|
||||
unit := float64(elf64analyser.PageSize)
|
||||
return uint64(math.Round(x/unit+0.5) * unit)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package ukManager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
@ -49,6 +50,15 @@ type Unikernel struct {
|
|||
ElfFile *elf64core.ELF64File
|
||||
ListObjs []*elf64core.ELF64File
|
||||
Analyser *elf64analyser.ElfAnalyser
|
||||
|
||||
alignedLibs *AlignedLibs
|
||||
}
|
||||
|
||||
type AlignedLibs struct {
|
||||
startValueUk uint64
|
||||
AllCommonMicroLibs []*MicroLib
|
||||
OnlyFewMicroLibs []*MicroLib
|
||||
SingleMicroLibs []*MicroLib
|
||||
}
|
||||
|
||||
func parseFile(path, name string) (*elf64core.ELF64File, error) {
|
||||
|
@ -157,3 +167,39 @@ func (uk *Unikernel) DisplayElfInfo() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (uk *Unikernel) InitAlignment() {
|
||||
uk.alignedLibs = &AlignedLibs{
|
||||
startValueUk: 0,
|
||||
AllCommonMicroLibs: make([]*MicroLib, 0), //todo update with fixed entry
|
||||
OnlyFewMicroLibs: make([]*MicroLib, 0),
|
||||
SingleMicroLibs: make([]*MicroLib, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (uk *Unikernel) AddAlignedMicroLibs(startValue uint64, lib *MicroLib) {
|
||||
|
||||
for _, ukLibs := range uk.Analyser.ElfLibs {
|
||||
if ukLibs.Name == lib.name {
|
||||
fmt.Printf("%s -> 0x%x - 0x%x\n", lib.name, startValue, startValue+lib.size)
|
||||
uk.alignedLibs.OnlyFewMicroLibs = append(uk.alignedLibs.SingleMicroLibs, lib)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (uk *Unikernel) AddSingleMicroLibs(startValue uint64, lib *MicroLib) {
|
||||
|
||||
for _, ukLibs := range uk.Analyser.ElfLibs {
|
||||
if ukLibs.Name == lib.name {
|
||||
|
||||
uk.alignedLibs.SingleMicroLibs = append(uk.alignedLibs.SingleMicroLibs, lib)
|
||||
if uk.alignedLibs.startValueUk == 0 {
|
||||
uk.alignedLibs.startValueUk = startValue
|
||||
}
|
||||
fmt.Printf("%s -> 0x%x - 0x%x\n", lib.name, uk.alignedLibs.startValueUk, uk.alignedLibs.startValueUk+lib.size)
|
||||
uk.alignedLibs.startValueUk += lib.size
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue