MCPcopy Index your code
hub / github.com/tinygo-org/tinygo / loadProgramSize

Function loadProgramSize

builder/sizes.go:421–870  ·  view source on GitHub ↗

loadProgramSize calculate a program/data size breakdown of each package for a given ELF file. If the file doesn't contain DWARF debug information, the returned program size will still have valid summaries but won't have complete size information per package.

(path string, packagePathMap map[string]string)

Source from the content-addressed store, hash-verified

419// size will still have valid summaries but won't have complete size information
420// per package.
421func loadProgramSize(path string, packagePathMap map[string]string) (*programSize, error) {
422 // Open the binary file.
423 f, err := os.Open(path)
424 if err != nil {
425 return nil, err
426 }
427 defer f.Close()
428
429 // This stores all chunks of addresses found in the binary.
430 var addresses []addressLine
431
432 // Load the binary file, which could be in a number of file formats.
433 var sections []memorySection
434 if file, err := elf.NewFile(f); err == nil {
435 var codeAlignment uint64
436 switch file.Machine {
437 case elf.EM_ARM:
438 codeAlignment = 4 // usually 2, but can be 4
439 }
440 // Read DWARF information. The error is intentionally ignored.
441 data, _ := file.DWARF()
442 if data != nil {
443 addresses, err = readProgramSizeFromDWARF(data, 0, codeAlignment, true)
444 if err != nil {
445 // However, _do_ report an error here. Something must have gone
446 // wrong while trying to parse DWARF data.
447 return nil, err
448 }
449 }
450
451 // Read the ELF symbols for some more chunks of location information.
452 // Some globals (such as strings) aren't stored in the DWARF debug
453 // information and therefore need to be obtained in a different way.
454 allSymbols, err := file.Symbols()
455 if err != nil {
456 return nil, err
457 }
458 for _, symbol := range allSymbols {
459 symType := elf.ST_TYPE(symbol.Info)
460 if symbol.Size == 0 {
461 continue
462 }
463 if symType != elf.STT_FUNC && symType != elf.STT_OBJECT && symType != elf.STT_NOTYPE {
464 continue
465 }
466 if symbol.Section >= elf.SHN_LORESERVE {
467 // Not a regular section, so skip it.
468 // One example is elf.SHN_ABS, which is used for symbols
469 // declared with an absolute value such as the memset function
470 // on the ESP32 which is defined in the mask ROM.
471 continue
472 }
473 section := file.Sections[symbol.Section]
474 if section.Flags&elf.SHF_ALLOC == 0 {
475 continue
476 }
477 if packageSymbolRegexp.MatchString(symbol.Name) || symbol.Name == "__isr_vector" {
478 addresses = append(addresses, addressLine{

Callers 3

TestBinarySizeFunction · 0.85
TestSizeFullFunction · 0.85
BuildFunction · 0.85

Calls 12

getPackageMethod · 0.95
readProgramSizeFromDWARFFunction · 0.85
readMachOSymbolAddressesFunction · 0.85
readSectionFunction · 0.85
OpenMethod · 0.80
addSizeMethod · 0.80
CloseMethod · 0.65
MatchStringMethod · 0.65
SizeMethod · 0.65
ErrorfMethod · 0.65
ParseMethod · 0.45
SliceMethod · 0.45

Tested by 2

TestBinarySizeFunction · 0.68
TestSizeFullFunction · 0.68