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.
Этот коммит содержится в:
родитель
4cf8ad2bee
коммит
d4b1467e4c
1 изменённых файлов: 32 добавлений и 1 удалений
|
@ -205,6 +205,10 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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:
|
case 0:
|
||||||
switch lowBits {
|
switch lowBits {
|
||||||
case 0: // DW_CFA_nop
|
case 0: // DW_CFA_nop
|
||||||
|
@ -218,7 +222,22 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) {
|
||||||
}
|
}
|
||||||
fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor
|
fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor
|
||||||
entries = append(entries, fi.newLine())
|
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
|
case 0x05: // DW_CFA_offset_extended
|
||||||
// Semantics are the same as DW_CFA_offset, but the encoding is
|
// Semantics are the same as DW_CFA_offset, but the encoding is
|
||||||
// different. Ignore it just like DW_CFA_offset.
|
// different. Ignore it just like DW_CFA_offset.
|
||||||
|
@ -239,6 +258,18 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
case 0x0c: // DW_CFA_def_cfa
|
||||||
register, err := readULEB128(r)
|
register, err := readULEB128(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче