darwin: support -size= flag
This is just basic support. It doesn't add support for reading DWARF, because that's a bit complicated on MacOS (it isn't stored in the file itself but separately in the object files). But at least this change makes it possible to easily print executable sizes by section type like for other operating systems.
Этот коммит содержится в:
родитель
b8e433821a
коммит
c23a5b65ef
2 изменённых файлов: 55 добавлений и 2 удалений
4
Makefile
4
Makefile
|
@ -634,8 +634,8 @@ endif
|
|||
@$(MD5SUM) test.hex
|
||||
GOOS=linux GOARCH=arm $(TINYGO) build -size short -o test.elf ./testdata/cgo
|
||||
GOOS=windows GOARCH=amd64 $(TINYGO) build -size short -o test.exe ./testdata/cgo
|
||||
GOOS=darwin GOARCH=amd64 $(TINYGO) build -o test ./testdata/cgo
|
||||
GOOS=darwin GOARCH=arm64 $(TINYGO) build -o test ./testdata/cgo
|
||||
GOOS=darwin GOARCH=amd64 $(TINYGO) build -size short -o test ./testdata/cgo
|
||||
GOOS=darwin GOARCH=arm64 $(TINYGO) build -size short -o test ./testdata/cgo
|
||||
ifneq ($(OS),Windows_NT)
|
||||
# TODO: this does not yet work on Windows. Somehow, unused functions are
|
||||
# not garbage collected.
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"debug/dwarf"
|
||||
"debug/elf"
|
||||
"debug/macho"
|
||||
"debug/pe"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
@ -368,6 +369,58 @@ func loadProgramSize(path string, packagePathMap map[string]string) (*programSiz
|
|||
})
|
||||
}
|
||||
}
|
||||
} else if file, err := macho.NewFile(f); err == nil {
|
||||
// TODO: read DWARF information. On MacOS, DWARF debug information isn't
|
||||
// stored in the executable but stays in the object files. The
|
||||
// executable does however contain the object file paths that contain
|
||||
// debug information.
|
||||
|
||||
// Read segments, for use while reading through sections.
|
||||
segments := map[string]*macho.Segment{}
|
||||
for _, load := range file.Loads {
|
||||
switch load := load.(type) {
|
||||
case *macho.Segment:
|
||||
segments[load.Name] = load
|
||||
}
|
||||
}
|
||||
|
||||
// Read MachO sections.
|
||||
for _, section := range file.Sections {
|
||||
sectionType := section.Flags & 0xff
|
||||
sectionFlags := section.Flags >> 8
|
||||
segment := segments[section.Seg]
|
||||
// For the constants used here, see:
|
||||
// https://github.com/llvm/llvm-project/blob/release/14.x/llvm/include/llvm/BinaryFormat/MachO.h
|
||||
if sectionFlags&0x800000 != 0 { // S_ATTR_PURE_INSTRUCTIONS
|
||||
// Section containing only instructions.
|
||||
sections = append(sections, memorySection{
|
||||
Address: section.Addr,
|
||||
Size: uint64(section.Size),
|
||||
Type: memoryCode,
|
||||
})
|
||||
} else if sectionType == 1 { // S_ZEROFILL
|
||||
// Section filled with zeroes on demand.
|
||||
sections = append(sections, memorySection{
|
||||
Address: section.Addr,
|
||||
Size: uint64(section.Size),
|
||||
Type: memoryBSS,
|
||||
})
|
||||
} else if segment.Maxprot&0b011 == 0b001 { // --r (read-only data)
|
||||
// Protection doesn't allow writes, so mark this section read-only.
|
||||
sections = append(sections, memorySection{
|
||||
Address: section.Addr,
|
||||
Size: uint64(section.Size),
|
||||
Type: memoryROData,
|
||||
})
|
||||
} else {
|
||||
// The rest is assumed to be regular data.
|
||||
sections = append(sections, memorySection{
|
||||
Address: section.Addr,
|
||||
Size: uint64(section.Size),
|
||||
Type: memoryData,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if file, err := pe.NewFile(f); err == nil {
|
||||
// Read DWARF information. The error is intentionally ignored.
|
||||
data, _ := file.DWARF()
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче