0

clang 使用以下方案在 llvm ir 中定义具体类型:

%"mytype" = type {virtual_method_types, field_types, super_types}

为了调用虚拟方法(例如 virtual int f(){}),使用了以下方案:

%0 = load %"mytype"** %this
%1 = bitcast %"mytype"* %0 to i32 (%"mytype"*)***
%vtable = load i32 (%"mytype"*)*** %1
%method = getelementptr inbounds i32 (%"mytype"*)** %vtable, i64 0 (index of f() in vt)
%ld = load i32 (%"mytype"*)** %method 
%call = call i32 (%"mytype"*)* %ld (%"mytype"* %0) 

但是,如果改用下面的方案,上面的代码应该做些什么来防止 seg fault 呢?

 %"mytype" = type {field_types, super_types, virtual_method_types}
4

1 回答 1

0

此行获取对象开头的指针,即 vptr(指向虚拟表的指针):

%1 = bitcast %"mytype"* %0 to i32 (%"mytype"*)***

如果您将 vptr 放在对象的末尾,则此代码将需要更改为使用extractvalueon%0来获取指向 vptr 正确位置的指针(或者使用getelementptron %this,但无论如何您都需要 load %this,它不会真的没有帮助)。例如,如果 vptr 将是 中的第 12 个字段%"mytype",您将需要类似以下内容:

%1 = extractvalue %"mytype" %0, 12
于 2013-07-31T07:53:47.530 回答