How to obtain the value of the fd returned by fopen

Hello all,
I’m working an llvm plugin and currenctly I need to understand how to get the value returned by an fopen function. Suppose that the I variable is referring to the CallInst instruction. How can get the fileno associated with the file descriptor?

The IR instruction is

%4 = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))

I would like to have 3 as a result of some opeeration on the I CallInst instruction.

Thanks a lot

I think what you probably want is just the CallInst itself. CallInst is a subclass of Value and the value it represents is whatever the function returns. So you can use I as one of the operands to an fread or fwrite call (in IR).

Alternatively, do you want what the underlying open call returned, buried somewhere in the FILE * descriptor returned by fopen?

If so, that’s supported in POSIX, but not plain C. You have to call the fileno function to convert it.

2 Likes

Hi @TNorthover ,
thanks for your answer. The fact is that I need the actual fileno associated with the CallInst instruction.

Considering that CallInst is a subclass of Value and I should be able to dyn_cast it and get the value isn’t it?

If you could show me how to do it it would be great. In the end I would like to be able to create an output like the one from strace where the actual number id shown.

openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@n\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1839792, ...}) = 0

Thanks

Hi @TNorthover ,
I think i finally understood what you really meant to I add a function call to another function getfileno and all worked:

%4 = call %struct._IO_FILE* @fopen(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
call void @getfileno(%struct._IO_FILE* %4)
➜  /development git:(dev) ✗ ./tests/file     
fileno: 3
reading: 3

Thanks a lot

1 Like