[llvm-bugs] [Bug 47351] New: Invalid StructType element type {}* for function pointer

via llvm-bugs llvm-bugs at lists.llvm.org
Sat Aug 29 06:32:20 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=47351

            Bug ID: 47351
           Summary: Invalid StructType element type {}* for function
                    pointer
           Product: clang
           Version: 10.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Frontend
          Assignee: unassignedclangbugs at nondot.org
          Reporter: roemheld at sec.in.tum.de
                CC: llvm-bugs at lists.llvm.org, neeilans at live.com,
                    richard-llvm at metafoo.co.uk

Created attachment 23904
  --> https://bugs.llvm.org/attachment.cgi?id=23904&action=edit
Readable LLVM IR of module lkm.ko

I'm not sure where the origin of this issue is, please move this ticket if you
think that it was filed in the wrong category.

When using wllvm with clang build built from source a custom Linux kernel
module LLVM IR seems to be malformed as its IR shows several struct element
types, which are supposed to be function pointers, simply as {}*.

The minimal example looks as follows:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/cred.h>
#include <linux/kallsyms.h>

#include <linux/cpu.h>

struct lkm_state {
        struct file_operations lkm_fops;
} __attribute__((packed)) lkm_state;

int lkm_open(struct inode *inode, struct file *file) {
        return 0;
}

static __init int lkm_init(void) {
        lkm_state.lkm_fops.open = lkm_open;

        return 0;
}

static __exit void lkm_exit(void) {

}

module_init(lkm_init);
module_exit(lkm_exit);

MODULE_LICENSE("GPL");

Of the attachment, the example I'm focusing on is the struct.file_operations
(formatted for better readability):

%struct.file_operations = type {
    %struct.module*,
    i64 (%struct.file*, i64, i32)*,
    i64 (%struct.file*, i8*, i64, i64*)*,
    i64 (%struct.file*, i8*, i64, i64*)*,
    i64 (%struct.kiocb*, %struct.iov_iter*)*,
    i64 (%struct.kiocb*, %struct.iov_iter*)*,
    i32 (%struct.kiocb*, i1)*,
    i32 (%struct.file*, %struct.dir_context*)*,
    i32 (%struct.file*, %struct.dir_context*)*,
    i32 (%struct.file*, %struct.poll_table_struct*)*,
    i64 (%struct.file*, i32, i64)*,
    i64 (%struct.file*, i32, i64)*,
    i32 (%struct.file*, %struct.vm_area_struct*)*,
    i64,
    {}*, <-- should be "i32 (%struct.inode*, %struct.file*)*"
[...]
}

In the attachment I sent (lkm.ko.ll, from llvm-dis lkm.ko.bc) there is a single
function pointer assignment to a struct member, but according to the LLVM IR
the type of the struct member is {}*, which is why in the store instruction it
has to use a bitcast in order to perform the store operation (@init_module):

store i32 (%struct.inode*, %struct.file*)* @lkm_open, i32 (%struct.inode*,
%struct.file*)** bitcast ({}** getelementptr inbounds (%struct.lkm_state,
%struct.lkm_state* @lkm_state, i64 0, i32 0, i32 14) to i32 (%struct.inode*,
%struct.file*)**), align 1

This causes problems as I'm trying to determine the type of the struct element
(I have a small code stub that determines if the struct element type is a
function pointer or not). The type of {}* is PointerTypeID, which is correct,
but it is not reported to be a function pointer, which according to the struct
itself it is one.

Clang version: clang version 10.0.0 [...], commit
91827ebf5e3d9eb633ba909e8f50a3d402698cce
LKM built against Linux version 5.4.0

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200829/a2a743aa/attachment.html>


More information about the llvm-bugs mailing list