Skip to content

Oversize leaq operand in stack chaining MacOS x86_64 #406

@AndrewTolmach

Description

@AndrewTolmach

If a stack frame size exceeds 2^32, e.g. due to large local arrays, the offset link is set incorrectly, because its value is calculated using an leaq using the frame size as an offset, but such offsets are restricted to 32-bit (signed) ints.
(The relevant code is generated at x86/Asmexpand.ml line 574).

The assembler should reject such invalid offset arguments, but unfortunately, MacOS as
(at least as of Apple LLVM version 10.0.0) does not do so. (Although gas on a recent debian linux does.)
Instead, it just silently throws away the high-order bits, in this case leading to a negative offset.

OK, so perhaps these large stack frames are officially undefined behavior (max 65K bytes per object and 512 declarations per block), and certainly a noisy failure would be fine here, but a silent one seems unfortunate.

Demonstrated by the following code, which should print 7 but prints 0:

#include <stdio.h>

char f(char x1, char x2, char x3, char x4, char x5, char x6, char x7) {
  char b[0x100000000];
  return x7;
}

int main() {
  char c = f(1,2,3,4,5,6,7);
  printf("%d\n",c);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions