aboutsummaryrefslogtreecommitdiffhomepage
path: root/stacksize
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2022-03-03 18:20:03 +0100
committerRon Evans <[email protected]>2022-03-12 12:55:38 +0100
commitd4b1467e4c7f1c9e89a8b9efb89a25e9cd6067b2 (patch)
tree32a32cf50a432f2290090c0fadf449a455ee72c9 /stacksize
parent4cf8ad2bee058e98aaa49fbc36fb24ae220e78d0 (diff)
downloadtinygo-d4b1467e4c7f1c9e89a8b9efb89a25e9cd6067b2.tar.gz
tinygo-d4b1467e4c7f1c9e89a8b9efb89a25e9cd6067b2.zip
build: support machine outlining pass in stacksize calculation
The machine outliner introduces a few new opcodes that weren't previously emitted by LLVM. We need to support these. This doesn't trigger very often, but it sometimes does. It triggers a lot more often with ThinLTO enabled.
Diffstat (limited to 'stacksize')
-rw-r--r--stacksize/dwarf.go33
1 files changed, 32 insertions, 1 deletions
diff --git a/stacksize/dwarf.go b/stacksize/dwarf.go
index 0ba880a4c..9287b1b60 100644
--- a/stacksize/dwarf.go
+++ b/stacksize/dwarf.go
@@ -205,6 +205,10 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) {
if err != nil {
return nil, err
}
+ case 3: // DW_CFA_restore
+ // Restore a register. Used after an outlined function call.
+ // It should be possible to ignore this.
+ // TODO: check that this is not the stack pointer.
case 0:
switch lowBits {
case 0: // DW_CFA_nop
@@ -218,7 +222,22 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) {
}
fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor
entries = append(entries, fi.newLine())
- // TODO: DW_CFA_advance_loc2 etc
+ case 0x03: // DW_CFA_advance_loc2
+ var offset uint16
+ err := binary.Read(r, binary.LittleEndian, &offset)
+ if err != nil {
+ return nil, err
+ }
+ fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor
+ entries = append(entries, fi.newLine())
+ case 0x04: // DW_CFA_advance_loc4
+ var offset uint32
+ err := binary.Read(r, binary.LittleEndian, &offset)
+ if err != nil {
+ return nil, err
+ }
+ fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor
+ entries = append(entries, fi.newLine())
case 0x05: // DW_CFA_offset_extended
// Semantics are the same as DW_CFA_offset, but the encoding is
// different. Ignore it just like DW_CFA_offset.
@@ -239,6 +258,18 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) {
if err != nil {
return nil, err
}
+ case 0x09: // DW_CFA_register
+ // Copies a register. Emitted by the machine outliner, for example.
+ // It should be possible to ignore this.
+ // TODO: check that the stack pointer is not affected.
+ _, err := readULEB128(r)
+ if err != nil {
+ return nil, err
+ }
+ _, err = readULEB128(r)
+ if err != nil {
+ return nil, err
+ }
case 0x0c: // DW_CFA_def_cfa
register, err := readULEB128(r)
if err != nil {