GCC Compiler, Plugins and structures - c

I have scenario like this:
int open_ext2 () {}
int close_ext2 () {}
int read_ext2 () {}
int write_ext2 () {}
const struct fs_callbacks FS = {
open_file: open_ext2,
close_file: close_ext2,
read_bytes: read_ext2,
write_bytes: write_ext2
};
void main(){
FS.close_file();
}
When I look at the gimple representation (compiled with -fdump-tree-all)
I see something like this:
D.1796 = close_ext2;
D.1796 ();
What I do not get is where happens the assignment open_file: open_ext2
My questions
How GCC is doing this?
In what pass does it happen ?
Is there a way to figure out the mapping label -> member function?

Found the answer
The gcc option -fdump-tree-original-raw dumps the info
With GCC plugin:
Use the pass PLUGIN_FINISH_DECL
Have a look in GCC source for the function debug_variable in file: gcc/tree-dfa.c

Related

How to disable stack canaries for specific functions?

With gcc, is it possible to compile with -fstack-protector, but omit for a specific function.
For example, say i have two functions.
void a() {
...
}
void b() {
...
}
Can I tell the compiler to compile a program that will use a canary before the saved return address of a, but no canary for b?
You'd have to test if it works (inspect the generated code at Godbolt) but it looks like you can do, for example:
__attribute__ ((no_stack_protector)) void foo () { ... }
no_sanitize looks like an intriguing option, I wonder who uses that.

zig creates a C library but not usable by C

I'm able to get Zig to create a C library but when I attempt to use said library from a C program, it fails to find the definition of the included function.
My library definition:
const std = #import("std");
export fn removeAll(name: [*]const u8, len: u32) u32 {
const n: []const u8 = name[0..len];
std.fs.cwd().deleteTree(n) catch |err| {
return 1;
};
return 0;
}
test "basic remove functionality" {
}
build.zig
const Builder = #import("std").build.Builder;
pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions();
const lib = b.addStaticLibrary("removeall", "src/main.zig");
lib.setBuildMode(mode);
switch (mode) {
.Debug, .ReleaseSafe => lib.bundle_compiler_rt = true,
.ReleaseFast, .ReleaseSmall => lib.disable_stack_probing = true,
}
lib.force_pic = true;
lib.setOutputDir("build");
lib.install();
var main_tests = b.addTest("src/main.zig");
main_tests.setBuildMode(mode);
const test_step = b.step("test", "Run library tests");
test_step.dependOn(&main_tests.step);
}
zig build creates the build directory with the libremoveall.a static library.
My C program:
#include <stdio.h>
int removeAll(char *, int);
int main(int argc, char **argv)
{
removeAll("/tmp/mytest/abc", 15);
return 0;
}
When I attempt to include it in my C program, it get the following error:
gcc -o main build/libremoveall.a main.c
/usr/bin/ld: /tmp/cckS27fw.o: in function 'main':
main.c:(.text+0x20): undefined reference to 'removeAll'
Any ideas on what I'm doing wrong?
Thanks
EDIT
Thanks Paul R and stark, flipping the order worked. Can you help me understand why the order matter?
The linker searches a library for unresolved references encountered so far in the process.
If you put your program after the library, there are no unresolved references when the linker reads the library. And then when it reads your program, there is no library to resolve the reference.
Swap your program and the library, and you are all set.

Clang C Block : block function definition after call

I'm trying to port some GCC nested function to clang. As gcc nested function is not supported in clang, i need to use c-block instead.
But i want to have the block definition after the call to it. (I need this order because code is generated from MACRO and i can not arrange this order)
So in gcc i have this pseudo code :
foo(){
auto void bar (void);
...
bar()
...
void bar(void) {
...some stuff
}
}
You i can do this in C-block clang function ?
This code works fine
int main() {
void (^hello)(void);
hello = ^(void){
printf("Hello, block!\n");
};
hello();
return 0;
}
But the following code
int main() {
void (^hello)(void);
hello();
hello = ^(void){
printf("Hello, block!\n");
};
return 0;
}
failed with an segfault.
In your second example, hello has not been defined before you call it, so it is an undefined symbol. You have to tell the compiler what something is before you can use it.
In your pseudocode, a function prototype preceeds everything, which gets around the error by telling the compiler "this will be defined later on."

parse error before '*' token

const EPGState* NewEPGState[] =
{
&bootupState,
&standbyState,
&watchtvState,
&guideState,
&settingsState,
&easState,
&diagnosticsState
};
What is wrong in this code? I am getting an error parse error before '*' token
Your answers will be appreciated.
Check which version of the compiler are you using , This code compiles well on
g++ version 4.1.2 20071124.
but fails when compiled with gcc
I assume you have defined class/struct EPGState correctly and all the variables used below are of same type i.e EPGState.
class EPGState
{
};
int main()
{
EPGState bootupState,standbyState;
const EPGState* NewEPGState[] =
{
&bootupState,
&standbyState
};
}
Are you getting "parse Error" at the compilation step or at run time.
This is not clear from the question.
I written some sample code to test.
#include<iostream>
int main()
{
int a;
int b;
int *ac[]={&a,&b};
return 0;
}
Above code fails on gcc and compiles on g++.
gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)
/tmp/cc6829sJ.o: In function __static_initialization_and_destruction_0(int, int)':
test1.cpp:(.text+0x4f): undefined reference to std::ios_base::Init::Init()
You probaly have
struct EPGState
{
...
struct EPGState bootupState =
{
...
somewhere.
Then is shall be
const struct EPGState * NewEPGState[] =
{
&bootupState,
...

enumerated datatypes and gcc

I have a function in which one of the function arguments is an integer. During function invocation I am passing an enumerated datatype to this function. After building using gcc, any access to the INTEGER variable inside the function causes a segmentation fault.
Sample code:
void somefun (unsigned int nState)
{
switch (nState) // <-- Crashes on this line
{
//
// functionality here ...
//
}
}
enum {
UNDEFINED = -1,
STATE_NICE,
STATE_GREEDY
} E_STATE;
int main (int argc, char *argv [])
{
somefun (STATE_NICE);
}
First off, The enum is defined in main() and does not exist for somefun(). You should define the enum outside of main, although I cannot see how this is causing a crash.
After defining the enum outside of the main you should define somefun to be somefun( E_STATE nState ) and test again.
I compiled and ran that code exactly (cut & paste) on my computer, using gcc version 4.2.4, with no errors or segmentation fault. I believe the problem might be somewhere else.
Actually runs for me:
bash $ cat bar.c
#include <stdio.h>
void somefun (unsigned int nState)
{
switch (nState) // <-- Crashes on this line
{
//
// functionality here ...
//
default:
printf("Hello?\n");
}
}
int main (int argc, char *argv [])
{
enum {
UNDEFINED = -1,
STATE_NICE,
STATE_GREEDY
} E_STATE;
somefun (STATE_NICE);
return 0;
}
bash $ gcc -Wall bar.c -o bar
bar.c: In function 'main':
bar.c:22: warning: unused variable 'E_STATE'
bash $ ./bar
Hello?
bash $
Made a couple of changes, but it ran without them. (1) added a tag in the switch just so it had something; (2) added the #include <stdio.h> and printf so I could tell that it had run; (3) added the return 0; to eliminate an uninteresting warning.
It did run successfully with none of the changes, it just didn't do anything visible.
So, what's the OS, what's the hardware architecture?
Update
The code changed while I was trying it, so here's a test of the updated version:
bash $ cat bar-prime.c
#include <stdio.h>
void somefun (unsigned int nState)
{
switch (nState) // <-- Crashes on this line
{
//
// functionality here ...
//
default:
printf("Hello?\n");
}
}
enum {
UNDEFINED = -1,
STATE_NICE,
STATE_GREEDY
} E_STATE;
int main (int argc, char *argv [])
{
somefun (STATE_NICE);
return 0;
}
bash $ gcc -Wall bar-prime.c -o bar-prime && ./bar-prime
Hello?
bash $
Still works. Are you getting a core file in your version? Have you tried getting a stack trace?
Your situation is like specific to sun sparc hardware or similar. Please post uname -a and output of dmesg
From all your answers it seems that the code is logically correct, and I need to investigate the real reason for the crash. I will investigate it and post it soon.

Resources