Skip to content

Commit d4b1467

Browse files
aykevldeadprogram
authored andcommitted
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.
1 parent 4cf8ad2 commit d4b1467

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

stacksize/dwarf.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) {
205205
if err != nil {
206206
return nil, err
207207
}
208+
case 3: // DW_CFA_restore
209+
// Restore a register. Used after an outlined function call.
210+
// It should be possible to ignore this.
211+
// TODO: check that this is not the stack pointer.
208212
case 0:
209213
switch lowBits {
210214
case 0: // DW_CFA_nop
@@ -218,7 +222,22 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) {
218222
}
219223
fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor
220224
entries = append(entries, fi.newLine())
221-
// TODO: DW_CFA_advance_loc2 etc
225+
case 0x03: // DW_CFA_advance_loc2
226+
var offset uint16
227+
err := binary.Read(r, binary.LittleEndian, &offset)
228+
if err != nil {
229+
return nil, err
230+
}
231+
fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor
232+
entries = append(entries, fi.newLine())
233+
case 0x04: // DW_CFA_advance_loc4
234+
var offset uint32
235+
err := binary.Read(r, binary.LittleEndian, &offset)
236+
if err != nil {
237+
return nil, err
238+
}
239+
fi.loc += uint64(offset) * fi.cie.codeAlignmentFactor
240+
entries = append(entries, fi.newLine())
222241
case 0x05: // DW_CFA_offset_extended
223242
// Semantics are the same as DW_CFA_offset, but the encoding is
224243
// different. Ignore it just like DW_CFA_offset.
@@ -239,6 +258,18 @@ func (fi *frameInfo) exec(bytecode []byte) ([]frameInfoLine, error) {
239258
if err != nil {
240259
return nil, err
241260
}
261+
case 0x09: // DW_CFA_register
262+
// Copies a register. Emitted by the machine outliner, for example.
263+
// It should be possible to ignore this.
264+
// TODO: check that the stack pointer is not affected.
265+
_, err := readULEB128(r)
266+
if err != nil {
267+
return nil, err
268+
}
269+
_, err = readULEB128(r)
270+
if err != nil {
271+
return nil, err
272+
}
242273
case 0x0c: // DW_CFA_def_cfa
243274
register, err := readULEB128(r)
244275
if err != nil {

0 commit comments

Comments
 (0)