I have been studying BPF recently, but it is not proceeding because of a very basic problem.
I included linux/bpf.h as described in man bpf(2), but GCC can not find bpf function. This code is just for the test to make sure that GCC can find bpf function.
#include <linux/bpf.h>
int main()
{
bpf(0,(void *)0,0);
return 0;
}
GCC output is this.
$ gcc -o test bpf.c
bpf.c: In function ‘main’:
bpf.c:5:2: warning: implicit declaration of function ‘bpf’ [-Wimplicit-function-declaration]
bpf(0,(void *)0,0);
^~~
/usr/bin/ld: /tmp/cc4tjrUh.o: in function `main':
bpf.c:(.text+0x19): undefined reference to `bpf'
collect2: error: ld returned 1 exit status
I'm using Archlinux and linux kernel version is 4.20.11-arch1-1-ARCH.
Please help me how to include bpf function.
The manual page documents the system call bpf. While this is not intuitive, there is actually no function defined in the header <linux/bpf.h> that is simply called bpf(). Instead, you can do an indirect syscall with syscall(__NR_bpf, ...) (see also man syscall).
Projects relying on this syscall often define a wrapper that looks like this:
int bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size)
{
return syscall(__NR_bpf, cmd, attr, size);
}
Here is an example from libbpf.
Related
The following code works fine under Modelsim when the unused localparam is removed. It produces the error below if it is left in. If it is possible to use a struct to pass parameters to a module, what am I doing wrong? Many thanks.
typedef bit [7:0] myarr[2];
typedef struct { int a; myarr bytes; } mystruct;
module printer #(mystruct ms)();
// works fine if this is removed
localparam myarr extracted = ms.bytes;
initial
$display("Got %d and %p", ms.a, ms.bytes);
endmodule
parameter mystruct ms = '{ a:123, bytes:'{5, 6}};
module top;
printer #(.ms(ms)) DUT ();
endmodule
Here is the error. Compilation using vlog -sv -sv12compat produces no errors or warnings.
$ vsim -c -do "run -all; quit" top
Model Technology ModelSim - Intel FPGA Edition vlog 10.5c Compiler 2017.01 Jan 23 2017
(.......)
# ** Error: (vsim-8348) An override for an untyped parameter ('#dummyparam#0') must be integral or real.
I think the problem here is that you are assigning a whole unpacked array in one statement, which is not allowed. Try changing the myarr typedef to a packed array instead.
My workaround was to use a packed array. I didn't need to pack the whole struct.
I would happily upvote/accept someone else's answer if one appears. In particular, it would be helpful to confirm whether this is really a bug in Modelsim, or just an instance of a correct compilation error that could be made more helpful by including the location and parameter name.
I'm writing some code that interfaces an existing library written in C. In my Rust code I'd like to be able to use values from CPP macros. If I have a C include.h that looks like this:
#define INIT_FLAG 0x00000001
I'd like to be able to use it in Rust like this:
#[link(name="mylib")]
extern {
pub static init_flag: c_int = INIT_FLAG;
}
I've looked at other FFI code and I see a lot of people
duplicating these values in Rust instead of getting them from the FFI.
This seems a little brittle, and I'd also like to be able to handle
more complicated things that are defined via CPP macros.
Running cpp over my Rust files would only work if I'm sure my
CPP macros are only used for simple things.
It is impossible, and I don't think it will be possible in the future. C macros bring too many problems with them. If you want to run cpp over your Rust sources, you can do it manually.
If you don't want to do it and if there is a lot of constants and you also don't want to copy their values from C code to Rust you can make a C wrapper which will provide global variables with these values:
#define INIT_FLAG 0x00000001
...
const int init_flag = INIT_FLAG;
You compile this file, create a static library from it and link to it as usual:
$ gcc -c init_flag.c
$ ar r libinitflag.a init_flag.o
Rust source:
use std::libc;
#[link(name="initflag", kind="static")]
extern {
pub static init_flag: libc::c_int;
}
Rust source is nearly identical to what you tried to achieve. You will need C glue object file, however.
That's merely impossible because a C macro constant doesn't represent any object or entity at runtime. That's because the cpp preprocessor performs macro expansion (and handles the rest directives) even before compilation takes place. Consider the following snippet:
#define INIT_FLAG 0x00000001
/* some code */
unsigned dummy() { return INIT_FLAG; }
/* some other code */
Running cpp on the snippet yields preprocessed code (so called compilation unit, or translation unit) which has all occurences of INIT_FLAG replaced by the literal 0x00000001:
unsigned dummy() { return 0x00000001; }
The compilation unit then gets compiled, resulting in the object file, but now there's no trace of INIT_FLAG in it. Therefore, you cannot refer to INIT_FLAG when linking against the object file: it simply doesn't contain such symbol.
In Code Composer, you can define new symbols in the linker command file simply:
_Addr_start = 0x5C00;
_AppLength = 0x4C000;
before the memory map and section assignment. This is done in the bootloader example from TI.
You can then refer to the address (as integers) in your c-code as this
extern uint32_t _Addr_start; // note that uint32_t is fake.
extern uint32_t _AppLength; // there is no uint32_t object allocated
printf("start = %X len= %X\r\n", (uint32_t)&_Addr_start, (uint32_t)&_AppLength);
The problem is that if you use the 'small' memory model, the latter symbol (at 0x45C00) gives linker warning, because it tries to cast it to a 16-bit pointer.
"C:/lakata/hardware-platform/CommonSW/otap.c", line 78: warning #17003-D:
relocation from function "OtapGetExternal_CRC_Calc" to symbol "_AppLength"
overflowed; the 18-bit relocated address 0x3f7fc is too large to encode in
the 16-bit field (type = 'R_MSP_REL16' (161), file = "./otap.obj", offset =
0x00000002, section = ".text:OtapGetExternal_CRC_Calc")
I tried using explicit far pointers, but code composer doesn't understand the keyword far. I tried to make the dummy symbol a function pointer, to trick the compiler into thinking that dereferencing it would.... The pointer points to code space, and the code space model is "large" while the data space model is "small".
I figured it out before I finished entering the question!
Instead of declaring the symbol as
extern uint32_t _AppLength; // pretend it is a dummy data
declare it as
void _AppLength(void); // pretend it is a dummy function
Then the pointer conversion works properly, because &_AppLength is assumed to be far now. (When it declared as an integer, &_AppLength is assumed to be near and the linker fails.)
I have written a Perl XS wrapper for a C library consisting of about ~80
functions. Right now my general strategy is to substitute the error from a C
function with PL_sv_undef and the calling Perl code has to check explicitly
whether the return is not undef. (For some C functions it is more complicated
as I convert their output into a HV/AV and use empty list to report the error.)
Now as I moved to writing bigger Perl scripts using that library, I want to
simplify the error handling and use e.g. the usual eval {}/die exception-like
mechanism to handle errors.
At the moment a simple XSUB in my XS look like that:
SV *
simple_function( param1, param2 = 0, param3 = 0)
int param1
int param2
int param3
CODE:
int rc;
rc = simple_function( param1, param2, param3 );
RETVAL = (rc == 0) ? &PL_sv_yes : &PL_sv_undef;
OUTPUT:
RETVAL
I have seen that some modules have global flag like "RaiseError" to die on
errors but failed to find any example I can borrow from. The few modules I have
found handle the "RaiseError" flag inside the .pm, not inside the .xs, and
thus allowed to use the Perl's die. In my case that is rather hard to
implement inside the .pm as many functions require special error checks. That
would also lead to code duplication as the checks are already present inside the XS.
I found nothing relevant in the perlxs/perlguts documentation. In particular, I have seen calls to Perl_croak() in the .c generated from my .xs, but failed to locate any documentation for the function.
What is the XS' analog of the Perl's die? Or how else can the XSUB report to Perl
run-time that the function has failed and there is no RETVAL to return? How to properly set the $#?
Perl_croak() is documented here on the perlapi man page. As the example on that page shows, you can either pass it a message string, or you can manually set $# to an exception object and pass NULL.
I am truing to use a c function in a .c file from within my objective-c class.
I have imported the header for the c file. but I am still getting a problem and my program would not compile.
Undefined symbols:
"gluUnProject(float, float, float, float const*, float const*, int const*, float*, float*, float*)", referenced from:
-[GLView checkCollission:object:] in GLView.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Any idea how I can resolve this issue ?
Any help is certainly appreciated.
Qutaibah
This error is posted by the linker and not the compiler. Often this is caused by the code being compiled as C and included from C++ or the other way around.
You can normally fix this by ensuring that the function definitions in the header file enforces any C++ compiler to use C syntax by adding the following to the header:
#ifdef __cplusplus
extern "C" {
#endif
... definitions goes here ...
#ifdef __cplusplus
}
#endif
This method also ensures that the .c file itself is treating the function definitions as C and not by accident get compiled as C++.
If you do not wish to alter the header, you can encapsulate the #include statement in the same way. This will however not ensure correct compilation of the .c file itself.
EDIT:
Just a thought: I presume that you are actually compiling the .c file?