嵌套 structs/arrays 的 LLVM 对齐

LLVM alignment of nested structs/arrays

我想获得嵌套 struct/array 数据类型的准确字节表示。例如下面的 C 结构:

typedef struct zTy {
    int x;
    char c[2];
    struct  { char d; } v;
} z;

它被转换为以下 LLVM IR:

%struct.zTy = type { i32, [2 x i8], %struct.anon }
%struct.anon = type { i8 }

%a = alloca %struct.zTy, align 4

从 alloca 指令可以看出对齐方式(4 字节)。但我不知道这个对齐插入到哪里,也不知道嵌套结构的对齐是如何计算的。 我使用 getTypeAllocSize():

获取目标三元组的结构总大小
AllocaInst* AI;
Module &M;
Type* T = AI->getAllocatedType();
int size = M.getDataLayout()->getTypeAllocSize(T) // 8 Byte

有没有一种方法可以通过 LLVM pass 为我的目标体系结构确定任意嵌套数据类型的确切布局?

这是特定于 ABI 的,因此取决于目标。 Clang 通常会将 C/C++ 计算为各个成员对齐的最大值。 这里的整数是最大的字段,默认对齐约束为 4,这就是你得到的。

Clang 有 -fdump-record-layouts 作为 cc1 选项来帮助确定 struct/class 的布局,例如这里:

$ echo "struct zTy {
    int x;
    char c[2];
    struct  { char d; } v;
} z;" | clang -x c  -w - -Xclang -fdump-record-layouts  -c

*** Dumping AST Record Layout
         0 | struct zTy::(anonymous at <stdin>:4:5)
         0 |   char d
           | [sizeof=1, align=1]

*** Dumping AST Record Layout
         0 | struct zTy
         0 |   int x
         4 |   char [2] c
         6 |   struct zTy::(anonymous at <stdin>:4:5) v
         6 |     char d
           | [sizeof=8, align=4]

在 LLVM 中,你失去了 "C" 类型,但如果你想检查一个结构,你需要使用:

const StructLayout *getStructLayout(StructType *Ty) const;

然后使用返回的 StructLayout,您可以使用以下方法获取每个元素的偏移量:

uint64_t StructLayout::getElementOffsetInBits(unsigned Idx) const