test.h
struct test_desc {
const char *name;
}
#define PFM_TEST(a,name) struct test_desc a \
__attribute__((section("test"))) = {name}
test.c
PFM_TEST(name1,abc);
PFM_TEST(name2,dec);
main.c
#pragma section = "test"
void main(void)
{
struct struct test_desc *start,*stop;
start = (struct test_desc *)__section_begin("test");
stop = (struct test_desc *)__section_end("test");
printf("start->name = %s\n",start->name);
}
test.icf
define symbol __ICFEDIT_region_TEST_start__ = (0x10080000);
define symbol __ICFEDIT_region_TEST_end__ = (0x100DFFFF);
define region TEST_region = mem:[from __ICFEDIT_region_TEST_start__ to __ICFEDIT_region_TEST_end__];
keep { section test};
place at start of TEST_region {readwrite,section test};
actual result
hard fault patch...
expect result
start->name = abc
i can read the test section start address and stop address,i think i could cast them as test_desc type. but the actual result is error.
i think maybe i can't put the section into the .data,how can i do that?
Finally, i set the section next to the .data section.like this
define block .ram_image2.data with fixed order{ section .data*,
section DATA,
section test*,
section .iar.init_table,
section __DLIB_PERTHREAD,
block CPP_INIT,
};
expect result i can get,and the param is not the const type.
modify
before
#define PFM_TEST(a,name) struct test_desc a \
__attribute__((section("test"))) = {name}
later
#define PFM_TEST(a,name) const struct test_desc a \
__attribute__((section("test"))) = {name}
it could get my expect result,but i don't want the struct to be const.
I think i should take the section into the right memory like .data.but i don't know how can i do that.
Related
I coded an Arduino project for my son and learned about C in the process. All works fine but after dividing up the code into ten files and grouping the variables into structs in each file I'm not able to solve one wish for clarity. We need to empirically determine the best size of an array for storing and averaging port reads so this is what I want:
struct Alarms {
// Configurable parameters
const unsigned int number_of_reads = 24;
// State variables
int reads[number_of_reads]; // Error: invalid use of non-static data member 'Alarms::num_of_reads'
};
It’s simple but doesn't work. I tried flexible array members until I found that that feature is not supported in C++. Arduino compiles with C++. I tried many examples of the 'struct hack' but they all returned errors like this one:
struct Alarms {
// Configurable parameters
int number_of_reads = 24;
// State variables
int reads[];
} ar;
void setup_alarm() {
ar.reads = malloc(sizeof(int) * ar.number_of_reads); // Error: incompatible types in assignment of 'void*' to 'int [0]'
}
That looked promising but I suspect my ignorance is glowing brightly. Most struct hack examples call for declaring the struct and later initializing the struct variables. I’m hoping to not duplicate the struct.
I considered splitting the struct but that would be error prone and, well, another compile error:
struct Alarms2 {
int reads[ar.num_of_reads]; // Error: array bound is not an integer constant before ']' token
} ar2;
An alternative is to size the array and get the size later but it needs an explanation:
struct Alarms {
// Configurable parameters
int reads[ 24 ]; // Put number of reads to average between brackets
// State variables
int number_of_reads;
};
void setup_alarm() {
ar.number_of_reads = sizeof(ar.reads) / sizeof(ar.reads[0]); // this works
}
Is there a way to work the struct hack or some similar solution in Arduino to like achieve the first example?
The size of the struct must be known at compilation time. Const data types in structs can change per instance of the structure, that is why you are getting the invalid use of non-static data member 'Alarms::num_of_reads' when you try to initialize your array. The best way to solve this is to have an init_alarm and destroy_alarm functions. Like so ...
#include <stdio.h>
#include <stdlib.h>
#define DEFAULT_NUM_OF_READS (24)
struct alarm {
// Configurable parameters
const int number_of_reads;
// State variables
int *reads;
};
void init_alarm(struct alarm *alarm)
{
alarm->reads = (int *) malloc(alarm->number_of_reads * sizeof(int));
}
void destroy_alarm(struct alarm *alarm)
{
free(alarm->reads);
}
int main(int argc, char **argv)
{
// When we create our struct, set number_of_reads to default
struct alarm alarm = {.number_of_reads = DEFAULT_NUM_OF_READS, .reads = NULL};
init_alarm(&alarm);
alarm.reads[0] = 13;
alarm.reads[23] = 100;
printf("alarm.reads[0] = %d, alarm.reads[23] = %d\n", alarm.reads[0], alarm.reads[23]);
destroy_alarm(&alarm);
return 0;
}
Note: Inorder to use the designated initializer to initialize a structure you must compile with ANSI (C99) like so ...
gcc --std=c99 test.c -o test
I have error typedefs as follows.
typedef enum { Connection_Error
, Parity_Error
, Data_Read_Error
} error_t;
And I have a function returning the "error_t". I would like to change the enum to string (preferably without using switch(case)).
Eg.
char str[20];
str = function_to_convert_to_string (error_t);
Something like that.
Any suggestions?
The C language does not have any built-in provision for storing symbol-names as strings in the output binary program (unlike Java and C# which have the .ToString() method) so you must manually do this in your code - fortunately it's made easier with the preprocessor's ability to convert symbols to string-literals ("stringification").
Note that typedef enum { ... } name is unnecessary, and avoid using _t as a suffix as it is reserved by the POSIX specifications.
Try this:
enum errorType {
Connection_Error,
Parity_Error,
Data_Read_Error
};
#define ERRMSG( ARG ) \
case ARG: \
return "Error: " #ARG ".";
char* getErrorMessage(errorType e) {
switch(e) {
ERRMSG( Connection_Error )
ERRMSG( Parity_Error )
ERRMSG( Data_Read_Error )
default: exit(1); // or some other error handler
}
}
Note how you see the enum is manually listed twice in code: first in the enum definition, and again in the switch block. For small enums this is fine, but if your enum list is large or changes frequently you'll want to adopt a DRY approach. You can simplify it by listing all of the enums in their own text file, like so:
ErrorTypeEnum.inc
ENTRY( Connection_Error )
ENTRY( Parity_Error )
ENTRY( Data_Read_Error )
ErrorTypeEnum.h
#define ENTRY(NAME) NAME,
enum errorType {
#include "ErrorTypeEnum.inc"
_Last
}
#undef ENTRY
The _Last entry is needed because of the trailing comma, also provides a means to get the count f elements because _Last will have a numeric value equal to the last ENTRY + 1.
ErrorTypeEnum.c
char* getErrorMessage(errorType e) {
switch(e) {
#define ENTRY(NAME) case NAME: return "Error: " #NAME ".";
#include "ErrorTypeEnum.inc"
default: exit(1); // or some other error handler
#undef
}
}
Further
You can expand upon this by adding other values to the ENTRY macro, such as custom human-readable error messages (instead of using stringification). That is an exercise left up to the reader :)
#define GPIO_CHIP(_bank) { \
.irq_base = IRQ_GPIO_BASE_ ## _bank, \
.gpio_chip = { \
.label = "Bank " # _bank, \
.owner = THIS_MODULE, \
.set = gpio_set_value, \
.get = gpio_get_value, \
.direction_output =gpio_direction_output, \
.direction_input = gpio_direction_input, \
.base = GPIO_BASE_ ## _bank, \
.ngpio =GPIO_NUM_ ## _bank, \
}, \
}
What's this define with .label and .set and others?
static void gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
{
uint32_t __iomem *reg = CHIP_TO_REG(chip, REG_GPIO_DATA_SET);
reg += !value;
writel(BIT(gpio), reg);
}
This function with writel, __iomen, BIT() , where are they referenced from in Linux?
GPIO_CHIP is used to initialize a struct for a bank of GPIO (General Purpose I/O). If you have
struct s {
int a, b, c;
char * d;
}
then you can initialize a variable like
struct s example = { .a = 1, .b = 2, .c = 3, .d = "Hello!" };
You could also do it like
struct s example = { 1, 2, 3, "Hello!" };
but in that case you need to keep track of the order of the members of the struct, it isn't obvious at a glance what 1, 2, etc. actually being used for, and it can get out of sync easily.
If you need to initialize a lot of variables like this you can use a #define which is just the initializer, like
#define S_INIT(num) { .a = num, .b = 2, .c = 3 }
struct s example = S_INIT(0);
struct s examples[] = { S_INIT(1), S_INIT(2), S_INIT(3) };
GPIO_CHIP sets the function pointer .gpio_chip.set in the structure to point to gpio_set_value, so any call to that function is likely through that function pointer.
Consult the kernel documentation for the GPIO driver interface for details.
Basically, I want to write a kernel module that adds a possible filter to ebtables. Then I need to tell ebtables to use my filter on a bridge I have set up.
The reason I need to write my own module is that I want to introduce delay between consecutive packages (for some testing reason). To demonstrate, my network originally has a traffic like this:
+++-----------------+++-----------------+++-----------------+++-----------------
where + shows traffic of a package and - means no package on the line. I want to put a bridge in between so that the pattern of the packets would change to this:
+----+----+---------+----+----+---------+----+----+---------+----+----+---------
This means that I would make sure there would be a certain amount of delay between arrival of each packet.
Now I have written the following simple code which I basically took from linux-source/net/bridge/netfilter/ebt_ip.c:
static bool match(const struct sk_buff *skb, const struct xt_match_param *par)
{
printk(KERN_INFO"match called\n");
return true; // match everything!
}
static bool check(const struct xt_mtchk_param *par)
{
printk(KERN_INFO"check called\n");
return true; // pass everything!
}
static struct xt_match reg __read_mostly = {
.name = "any", // I made this up, but I tried also putting ip for example which didn't change anything.
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = match,
.checkentry = check,
.matchsize = XT_ALIGN(4), // don't know what this is, so I just gave it an `int`
.me = THIS_MODULE
};
int init_module(void)
{
return xt_register_match(®);
}
void cleanup_module(void)
{
xt_unregister_match(®);
}
I successfully load the module. But it's as if it's not there. I'm not getting the logs inside match and check functions so the bridge is clearly not considering my filter. What am I doing wrong?
I have tried many combinations of loading my filter first, setting up the bridge first or setting ebtables rules first, but none of them change anything.
P.S. The bridge itself works. I am certain that ebtables is also in effect because if I add a policy to drop packages, I don't receive them on the final computer. What I can't figure out is how to tell ebtables to consider my filter also.
I got this working, not in the most elegant way, but anyway, I am writing it here for a future wanderer:
Let's say your filter name is: "any"
User-space plugin
You need headers that are not available outside the ebtables source. So, get the source code, and go to extensions folder. In the Makefile, add any to EXT_FUNC (that is targets to be built) and write the source file ebt_any.c like the following:
#include <stdio.h>
#include <getopt.h>
#include "../include/ebtables_u.h"
/*struct whatever
{
int a;
};*/
static struct option _any_opts[] =
{
{"use-any", required_argument, 0, 0},
{'\0'}
};
static void _any_help(void)
{
printf("any match options: nothing!\n");
}
static void _any_init(struct ebt_entry_match *match)
{
printf("any_init\n");
}
static void _any_check(const struct ebt_u_entry *entry, const struct ebt_entry_match *match, const char *name,
unsigned int hookmask, unsigned int time)
{
printf("any_check\n");
}
static int _any_parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, struct ebt_entry_match **match)
{
printf("any_parse: %d\n", c);
if (c == 0)
return 1;
return 0; // return true for anything
}
static int _any_compare(const struct ebt_entry_match *m1, const struct ebt_entry_match *m2)
{
/* struct whatever *w1 = (struct whatever *)m1->data;
struct whatever *w2 = (struct whatever *)m2->data;
if (w1->a != w2->a)
return 0;*/
return 1;
}
static void _any_print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match)
{
printf("any_print");
}
static struct ebt_u_match _reg = {
.name = "any",
// .size = sizeof(struct whatever),
.help = _any_help,
.init = _any_init,
.parse = _any_parse,
.final_check = _any_check,
.print = _any_print,
.compare = _any_compare,
.extra_ops = _any_opts,
};
void _init(void)
{
ebt_register_match(&_reg);
}
Note: if you have data going from user-space to kernel space, write something instead of struct whatever. I have commented it out because I am not using anything.
Note: even if your program doesn't require an option (such as mine which was supposed to match everything), you need to give an option anyway because that's how ebtables knows to use your filter.
Note: some of these functions seem unnecessary, but if you don't write them, you get a "BUG: bad merge" error.
Kernel-space module
The kernel-space module is simpler:
#include <linux/netfilter/x_tables.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Shahbaz Youssefi");
MODULE_ALIAS("ebt_any");
/*struct whatever
{
int a;
};*/
static bool match(const struct sk_buff *skb, const struct xt_match_param *par)
{
printk(KERN_INFO"Matching\n");
return true;
}
static bool check(const struct xt_mtchk_param *par)
{
printk(KERN_INFO"Checking\n");
return true;
}
static struct xt_match reg __read_mostly = {
.name = "any",
.match = match,
// .matchsize = sizeof(struct whatever),
.checkentry = check,
.me = THIS_MODULE
};
int init_module(void)
{
int ret = 0;
printk("Bridge initializing...\n");
ret = xt_register_match(®);
printk("Bridge initializing...done!\n");
return ret;
}
void cleanup_module(void)
{
printk("Bridge exiting...\n");
xt_unregister_match(®);
printk("Bridge exiting...done!\n");
}
Note: if you use struct whatever in user-space, you must use the same in kernel-space.
Note: unlike user-space plugin that use ebtables headers/functions, the kernel module uses xtables instead!!
Compile the module (fairly standard) and install it for automatic loading. Alternatively, you can insmod and rmmod the module yourself before adding/after removing ebtables rules.
How to make ebtables use your filter
Just add a rule that contains --use-any some_value and you're good. For example:
ebtables -A FORWARD --use-any 1 -j ACCEPT
Note: this --use-any is the option that was given in ebt_u_match reg.extra_ops (which was defined in array _any_opts) in the user space plugin.
To use a kernel module, you also need to write an appropriate plugin for the userspace program, and afterwards, insert a rule invoking it.
If you do not have any options, do not specify any .matchsize parameter in struct xt_match (equal to specifying 0).
Background is I have an existing application which lists directory entries; strace reveals it just calls getdents and lists them in the order returned. I would like them displayed in the same order as a call to ls with no arguments. Is it possible to update the directory data in some way to achieve this?
FS is ext4, if that makes any difference.
If you really are determined to change this program's behaviour (of which I assume that you don't have the source code available), you can use LD_PRELOAD to hook the call to opendir and readdir and replace it with your own, sorting wrapper. An example how such a hook could look like is the following:
#define _GNU_SOURCE 1
#include <stdio.h>
#include <dirent.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
struct __dirstream
{
int __fd;
char *__data;
size_t __allocation;
size_t __offset;
size_t __size;
struct dirent __entry;
};
typedef struct _dirent_list {
struct dirent *value;
struct _dirent_list *next;
} dirent_list;
typedef struct _my_DIR {
struct __dirstream orig;
dirent_list *first_entry;
int first_readdir;
} my_DIR;
DIR *opendir(const char *name) {
DIR *(*orig_opendir)(const char*) = dlsym(RTLD_NEXT, "opendir");
DIR *dir = orig_opendir(name);
// save additional information along with the
// original DIR structure
my_DIR *my_dir = calloc(1, sizeof(*my_dir));
my_dir->first_readdir = 1;
memcpy(my_dir, dir, sizeof(*dir));
return (DIR*)my_dir;
}
struct dirent *readdir(DIR *dir) {
struct dirent *(*orig_readdir)(DIR*) = dlsym(RTLD_NEXT, "readdir");
my_DIR *my_dir = (my_DIR*)dir;
dirent_list *item;
if (my_dir->first_readdir) {
struct dirent *entry;
while ((entry = orig_readdir(dir))) {
// exercise for the reader:
// implement insertion sort here
item = calloc(1, sizeof(*item));
item->value = entry;
item->next = my_dir->first_entry;
my_dir->first_entry = item;
}
my_dir->first_readdir = 0;
}
if (!my_dir->first_entry)
return NULL;
item = my_dir->first_entry;
struct dirent *result = item->value;
my_dir->first_entry = item->next;
free(item);
return result;
}
It overrides opendir and readdir to return the entries in reverse order (you can adapt this for sorting too). This is how you use it with a program test that simply lists the directory entries in the order they are received:
$ gcc -Wall -shared -fPIC -o libhookdir.so hookdir.c -ldl
$ ./test
..
test
.
hookdir.c
libhookdir.so
test.c
$ LD_PRELOAD=./libhookdir.so ./test
test.c
libhookdir.so
hookdir.c
.
test
..
Hah! This works. We just hooked a libc function.
No, there is no way you can manipulate the filesystem metadata to have getdents(2) return directory entires in the same order as the sort order that ls(1) applies to the directory entires.
You can always modify your program to sort entries using the same algorithms that ls(1) provides, though this requires at least O(N) memory and O(N Log N) time for sorting a directory with N entries. You'll have to decide if it is worth the implementation, memory, and time, to sort in the same manner as ls(1).