Can anyone explain the structure of IMAGE_THUNK_DATA?
I just know it has 4 elements, but I want the explanation of these elements.
IMAGE_THUNK_DATA is defined like so:
typedef struct _IMAGE_THUNK_DATA {
union {
uint32_t* Function; // address of imported function
uint32_t Ordinal; // ordinal value of function
PIMAGE_IMPORT_BY_NAME AddressOfData; // RVA of imported name
DWORD ForwarderStringl // RVA to forwarder string
} u1;
} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;
The comments should explain it well enough
Related
I've run into a strange problem where if I load my data structure from EEPROM it casts it incorrectly. But, if I have both my function calls to the function responsible for saving the data structure and the function responsible for reading the data structure it casts the data into my structure successfully.
I've played around with the problem a bit and I've noticed that the data saved and the data read from the EEPROM is always correct if you read it as uint8_t. But for some reason it fails to cast the data into my data structure (BareKeyboardKey2) when the save function is not used in the program and we only read the data from the EEPROM.
The following structure is what I believe causes the problem:
// testStruct.h
struct IKey2
{
int pin;
};
struct BareKeyboardKey2 : virtual IKey2
{
int keyCode;
BareKeyboardKey2() {}
BareKeyboardKey2(int _pin, int _keyCode)
{
pin = _pin;
keyCode = _keyCode;
}
};
Example output of when I first call SaveStruct then LoadStruct. (The data I save to EEPROM is a BareKeyboardKey2(2, 4):
Reading: 0x68 0x1 0x4 0x0 0x2 0x0
pin: 2, keycode: 4
as you can see it casts the BareKeyboardKey2 correctly, but...
Here is an example output of when ONLY LoadStruct is called (and the same data from the previous example is stored on the EEPROM):
Reading: 0x68 0x1 0x4 0x0 0x2 0x0
pin: -18248, keycode: 4
As you can see the data read from the EEPROM (i.e 0x68 0x1 0x4 0x0 0x2 0x0) is the same between both examples, but in the latter example it fails to properly cast the data into a BareKeyboardKey2 (pin: -18248, keycode: 4).
I have found that if I change the structure into the following it works regardless if I use SaveStruct and LoadStruct consequently or only use LoadStruct:
// testStruct.h
struct IKey2
{
};
struct BareKeyboardKey2 : virtual IKey2
{
int pin;
int keyCode;
BareKeyboardKey2() {}
BareKeyboardKey2(int _pin, int _keyCode)
{
pin = _pin;
keyCode = _keyCode;
}
};
I also found that if I move both variables into the IKey2 like this...:
struct IKey2
{
int pin;
int keyCode;
};
struct BareKeyboardKey2 : virtual IKey2
{
BareKeyboardKey2() {}
BareKeyboardKey2(int _pin, int _keyCode)
{
pin = _pin;
keyCode = _keyCode;
}
};
... this causes the program to cast both variables wrong. Example output: pin: -18248, keycode: -18248
What is causing this behavior and what can I do to make it consistent?
I found a solution to my problem. I'm not 100% sure it's right, but this is my theory...
When saving down non-POD structs as bytes to an EEPROM it does not save down the connection between the main struct and the virtual object connected to the struct. Thus, the data is the same, but if you look into the object using a debugger (in my case gdb) you will see that the virtual ptr that connects the main struct and the virtual object is an invalid pointer. Although, the rest of the data that is originally present in the main struct is still intact.
So in my case to solve the problem I converted my struct into a POD type by removing the virtual inheritance from my struct. Instead, I used a "Has a" relationship, and so far my data is reading correctly from the EEPROM regardless of the different cases used above.
Does the "auto" keyword in C++ have anything to do with storage class
For example:
void foo() {
auto ptr = new int[9]
}
Does the pointer to int above have is automatic(stack), or dynamic(heap)?
Until c++11, auto was used to specify automaticstorage duration. But since c++11 its only meaning is that the type of the variable is automatically deduced. It has nothing to do wiith the storage-class of the variable itself.
In your case ptr is a local variable (int * ptr) pointing to a location on the heap. You can always get the same effect by explicitely writing the types of the variables as in the following:
void foo() {
int* ptr = new int[9];
}
Please take a look at this link for more details and on how the deduction process works.
http://en.cppreference.com/w/cpp/language/auto
Is it possible to display value of module_param when read, in hex?
I have this code in my linux device driver:
module_param(num_in_hex, ulong, 0644)
$cat /sys/module/my_module/parameters/num_in_hex
1234512345
Would like to see that value in hex, instead of decimal. Or, should I use different way like debugfs for this?
There is no ready parameter type (2nd argument of module_param macro), which output its argument as hexadecimal. But it is not difficult to implement it.
Module parameters are driven by callback functions, which extract parameter's value from string and write parameter's value to string.
// Set hexadecimal parameter
int param_set_hex(const char *val, const struct kernel_param *kp)
{
return kstrtoul(val, 16, (unsigned long*)kp->arg);
}
// Read hexadecimal parameter
int param_get_hex(char *buffer, const struct kernel_param *kp)
{
return scnprintf(buffer, PAGE_SIZE, "%lx", *((unsigned long*)kp->arg));
}
// Combine operations together
const struct kernel_param_ops param_ops_hex = {
.set = param_set_hex,
.get = param_get_hex
};
/*
* Macro for check type of variable, passed to `module_param`.
* Just reuse already existed macro for `ulong` type.
*/
#define param_check_hex(name, p) param_check_ulong(name, p)
// Everything is ready for use `module_param` with new type.
module_param(num_in_hex, hex, 0644);
Check include/linux/moduleparam.h for implementation module_param macro and kernel/params.c for implementation of operations for ready-made types (macro STANDARD_PARAM_DEF).
Just installed MPLAB X and imported a project I'm working on. I got this error, and because it's an application library file, I'm not too keen on modifying it. The code it refers to is:
// BDT Entry Layout
typedef union __BDT
{
union
{
struct
{
BYTE CNT __attribute__ ((packed));
BD_STAT STAT __attribute__ ((packed));
};
struct
{
WORD count:10; //test
BYTE :6;
WORD ADR; //Buffer Address
};
};
DWORD Val;
WORD v[2];
} BDT_ENTRY;
I'd like to know how to modify this or my settings so that I can compile. I do not get this error in MPLAB.
__attribute__ ((packed)) is safe to comment out.
// BDT Entry Layout
typedef union __BDT
{
union
{
struct
{
BYTE CNT ; //__attribute__ ((packed)); suppress compiler warnings
BD_STAT STAT __attribute__ ((packed));
};
struct
{
WORD count:10; //test
BYTE :6;
WORD ADR; //Buffer Address
};
};
DWORD Val;
WORD v[2];
} BDT_ENTRY;
I had to modify the USB hardware abstraction layer to get things to compile.
I have been studying I2C driver (client) code for a while.
I have seen this function "i2c_get_clientdata" and "i2c_set_clientdata" every where.
I have seen the this question here .
Use of pointer to structure instead of creating static local copy
Some times i think like it is like "container_of" macro to get a pointer to the structure.
But still i didn't understood properly why to use it and when to use it.
Below i am posting a sample code where I see its usage.
If any one could help me understand why it is used there and when we shall use it when we write our own drivers.
struct max6875_data {
struct i2c_client *fake_client;
struct mutex update_lock;
u32 valid;
u8 data[USER_EEPROM_SIZE];
unsigned long last_updated[USER_EEPROM_SLICES];
};
static ssize_t max6875_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct i2c_client *client = kobj_to_i2c_client(kobj);
struct max6875_data *data = i2c_get_clientdata(client);
int slice, max_slice;
if (off > USER_EEPROM_SIZE)
return 0;
if (off + count > USER_EEPROM_SIZE)
count = USER_EEPROM_SIZE - off;
/* refresh slices which contain requested bytes */
max_slice = (off + count - 1) >> SLICE_BITS;
for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++)
max6875_update_slice(client, slice);
memcpy(buf, &data->data[off], count);
return count;
}
Those functions are used to get/set the void *driver_data pointer that is part of the struct device, itself part of struct i2c_client.
This is a void pointer that is for the driver to use. One would use this pointer mainly to pass driver related data around.
That is what is happening in your example. The max6875_read is a callback getting a structu kobject. That kobject is an i2c_client which is enough to communicate with the underlying device using the driver_data pointer here allows to get back the driver related data (instead of using global variables for example).