Why a variable would not be allocated as local in stack - c

I'm trying to force a buffer overflow to change the value of a variable. The idea is to overflow var_a to change var_b in the following code, which runs Contiki-NG operating system in an ARM Cortex-M4:
#include "contiki.h"
#include "board.h"
#include <dev/leds.h>
#include <stdio.h>
#include <string.h>
PROCESS(main_process, "main_process");
AUTOSTART_PROCESSES(&main_process);
PROCESS_THREAD(main_process, ev, data) {
uint8_t data_buffer[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
uint32_t var_b;
uint8_t var_a[4];
PROCESS_BEGIN();
var_b = 0;
printf("var_b = %08lx\n", var_b);
memcpy(var_a, data_buffer, 8);
printf("var_b = %08lx\n", var_b);
if (var_b) {
leds_arch_set(LEDS_RED);
}
PROCESS_END();
}
The problem is that overflow is not affecting var_b, but data_buffer. I used a debugger to check the addresses of the local variables in the process, and got the following:
Looking at this explains why the overflow is affecting to data_buffer, since it is located right after var_a. But what I didn't expect was that the address of var_b is <outofscope>, which suggests that this variable might be allocated in other memory region different from the current stack frame.
What's the reason for this happening when allocating var_b? Is there any way I can make it local?

A couple suggestions:
You could try disable compiler optimization with -O0 cflags.
Add volatile

But what I didn't expect was that the address of var_b is <outofscope>, which suggests that this variable might be allocated in other memory region different from the current stack frame.
What's the reason for this happening when allocating var_b? Is there any way I can make it local?
When it comes to debugging, there's really no other way to read variables except to compile with -ggdb -O0. ie: turn ON debug flags with -g or -ggdb or similar, and turn OFF optimization with -O0. You must do both. See my answer here: What's the difference between a compiler's -O0 option and -Og option?
Memory pools and pointer arithmetic
Whatever it is you're trying to do is very confusing. Some questions for you to think about:
Why are you trying to "overflow a buffer" to change variable var_b? Why don't you just change var_b directly?
memcpy(var_a, data_buffer, 8); copies the first 8 bytes from data_buffer into var_a. Since var_a is only 4 bytes, the first 4 bytes go into it successfully, and then the latter 4 bytes have undefined behavior by writing out of the bounds of the variable. Why don't you just write the first 4 bytes of data_buffer into var_a and the next 4 bytes into var_b?
If you think writing past the bounds of var_a should write into var_b, why did you put var_b first instead of var_a first? You did:
uint32_t var_b;
uint8_t var_a[4];
The compiler can do whatever it wants when determining where to place variables in memory, so there's no guarantee here, but it seems more logical that you would have at least put var_a first, like this:
uint8_t var_a[4];
uint32_t var_b;
Why didn't you?
Alright, that about covers it. Let's go over some things.
1. If you want to have guaranteed relative locations of variables, force it via a memory pool!
No matter what order you write your variables, the compiler is not compelled to abide by that order nor location, unless you use memory pools or otherwise manually specify the address for a given variable, such as a hardware register.
// How to force a memory layout of 4 bytes of `uint8_t var_a[4]` followed by 4
// bytes of `uint32_t var_b` (8 bytes total)
#define MEM_POOL_SIZE 8 // 8 bytes
// Step 1. Create an 8 byte memory pool. Choose **one** of the following
// options:
// Option 1: 8 byte memory pool **on the stack** (statically allocated)
uint8_t mem_pool[MEM_POOL_SIZE];
// Option 2: 8 byte memory pool **on the heap** (dynamically allocated)
uint8_t* mem_pool = malloc(MEM_POOL_SIZE);
if (mem_pool == NULL)
{
// do error handling here: out of memory
}
// Option 3: 8 byte memory pool **neither on the stack nor the heap**
// (`static` makes it take global RAM not allocated for either)
static uint8_t mem_pool[MEM_POOL_SIZE];
// Step 2: point `var_a` and `var_b` into the memory pool. Voila! They now
// magically take this pool of memory, with `var_b` **guaranteed** to be
// right after `var_a`.
uint8_t* var_a = mem_pool; // 4 byte array of uint8_t
// Note: the `+ 4` is pointer math: since `mem_pool` is a ptr to `uint8_t`,
// this moves forward `4*sizeof(uint8_t)` bytes.
uint32_t* var_b = mem_pool + 4;
// Step 3: use the variables! Here are some examples:
// write some bytes into the `var_a` array
var_a[0] = 0x01;
var_a[1] = 0x02;
var_a[2] = 0x03;
var_a[3] = 0x04;
// write a value into `var_b`
*var_b = 12345;
// write the first 4 bytes of data_buffer into `var_a` and the next 4 into
// `var_b`
memcpy(var_a, data_buffer, MEM_POOL_SIZE);
2. Just write the first 4 bytes of data_buffer into var_a and the next 4 bytes into var_b directly
See my questions at the top of my answer. I don't understand what you are doing, or why. If you want to write the first 4 bytes of data_buffer into var_a and the next 4 bytes into var_b, just do that! No need for any undefined-behavior "overflow" tricks, nor memory pools!
uint8_t var_a[4];
uint32_t var_b;
uint8_t data_buffer[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
memcpy(var_a, data_buffer, 4);
// remember, the `+ 4` is pointer arithmetic, and moves forward 4 x the size
// of the thing being pointed to, which is `uint8_t` (1 byte) in this case
memcpy(&var_b, data_buffer + 4, 4);
// Or (better), same thing as just above, but written more-clearly:
memcpy(var_a, data_buffer, sizeof(var_a);
memcpy(&var_b, data_buffer + sizeof(var_a), sizeof(var_b));

Related

How to prepare data for use with MMX/SSE intrinsics for shifting 16bit values?

No matter what I do with {0,8,16,0}(16bit vector, representation for copying into a big endian 64bit value) I am unable to properly bit shift a test value of { 0x00, 0x01, (...) 0x07 };
The result I get in the debugger is always 0x0.
I tried to convert the value in a couple of different ways, but I am unable to get this right.
Executed on a little endian:
#include <mmintrin.h>
#include <stdint.h>
int main(int argc, char** argv) {
__m64 input;
__m64 vectors;
__m64 output;
_Alignas(8) uint16_t bit16Vectors[1*4] = {
0x0000,0x0008,0x0010,0x0000
// Intent: {0,8,16,0} 16 bit array
// Convert for copy: {0,16,8,0} 64bit one item
// 8bit data, Bytes need to rotate: {0,8,16,0}
};
_Alignas(8) uint8_t in[8] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
};
input = _m_from_int64(*((long long*)in) );
vectors = _m_from_int64 (*((long long*)bit16Vectors));
output = _mm_sll_pi16(input, vectors);
__asm__("int3");
}
I wrote down a simple MMX-only RGB24 plane separation pseudoAssembly[which processes 8x1 values], but I am unable to convert all the 16+32bit bit shift vectors to "real world", or I do something wrong with the intrinsics.
I am unable to pin it down exactly, I just know it fails at the very first bit shift and returns the value of 0x0.

C contiguous data arrays

Say I have 2 arrays of data:
const uint8_t data1[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
const uint8_t data2[] = {0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
I would like to be able to read these individually, but also as one contiguous block of data.
eg: I could access data1[8] in the same way as data[0].
Reason: I have various const data definitions in some individual .c files that I'd rather not touch (font bitmaps) but I'd like to append some extra data to them (extra special characters). So I'd like to
#include <original font file>
const uint8_t extrafonts[] = {<more font bitmaps>};
Can this be done?
The only way to guarantee contiguous allocation in C is to use arrays of arrays. In this case it would seem that a const uint8_t [2][8] would solve all your problems, so use that if possible.
Otherwise, more advanced solutions could use structs and unions. These guarantee an order of allocation but come with the disadvantage that the compiler can insert padding anywhere. In this specific case it wouldn't be a problem on any real-world computer, since chunks of 8 bytes are aligned. If you have a standard C compiler, you can do this:
#include <inttypes.h>
#include <stdio.h>
typedef union
{
struct
{
uint8_t data1 [8];
uint8_t data2 [8];
};
uint8_t data [16];
} data_t;
int main (void)
{
const data_t data =
{
.data1 = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07},
.data2 = {0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
};
for(size_t i=0; i<16; i++)
{
printf("%.2"PRIx8" ", data.data[i]);
}
}
Now you can access the arrays individually through data.data1/data.data2 or as one, with data.data.
In cases where you worry about struct padding, you'll have to add some non-standard #pragma pack(1) or similar compiler-specific instruction.
There is another alternative that might be applicable to your use case: Use external preprocessing.
Use your favorite scripting language with some regular expression magic to read original font source file, and append extra font data at the end of array. Then save it to new file and use that in compilation instead.
This might seem a lot of work at first, but c files which are generated by tools (which I assume is the case with your font bitmaps) tend to have predictable format that is not too hard to parse.
You could probably use:
struct ArrayPair
{
uint8_t data1[8];
uint8_t data2[8];
};
const struct ArrayPair data =
{
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
{ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }
};
Now you can probably get away with using:
data.data1[8]
It isn't very elegant. Your requirement is not sensible.
You said that these are 2 global arrays on different source files. So I am ignoring any options where you can group these with unions or structures.
Now the bad news: There is absolutely no guarantee that 2 global variables will end up next to each other in memory with standard C rules.
You can do this, but you need to use compiler specific extensions instead. You need to:
Use manual memory placement to place variables next to each other.
Disable any optimizations or other compiler features that might break your code because you are accessing array out of bounds.
Note that I am assuming that you are in system where resources are limited, for example, some embedded system. If that is not the case, then simply create third array, and merge 2 arrays at program startup.

How to append another HEX value at the end of an existing byte array in C

I have searched on google and checked my findings on https://www.onlinegdb.com/
But so far, I am not satisfied with my trials and errors. Perhaps, I didn't know how to ask.
I am sure that this could be already very known by many people.
Normally I am reading HEX values from UART communication and placing in a buffer array.
But, for making things simpler, I give you that code snippet;
uint8_t buffer[20] = {0x7E, 0x00, 0x07, 0xAA, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xCC};
uint8_t newValue = 0x55;
My goal is to append newValue on buffer and that new value has to be seen after the last array value which is 0xCC in this case.
So, my question is how to do that efficiently?
Note that: One of my trials (works OK but not as I wanted);
buffer[11] = newValue ;
for(int i=0;i<sizeof(buffer);i++)
printf("%02x", buffer[i]);
But, then I need to know the position of the last value and increase the position by one which is 11 (0 based counting) in this case.

How to create bitfield out of existing variables in C

I am working on a Motorola HCS08 µCU in CodeWarrior V10.6, I am trying to create an extern bitfield which has bits from existing registers. The way the bitfields are created in the µCU header is like
typedef unsigned char byte;
typedef union {
byte Byte;
struct {
byte PTAD0 :1;
byte PTAD1 :1;
byte PTAD2 :1;
byte PTAD3 :1;
byte PTAD4 :1;
byte PTAD5 :1;
byte PTAD6 :1;
byte PTAD7 :1;
} Bits;
} PTADSTR;
extern volatile PTADSTR _PTAD #0x00000000;
#define PTAD _PTAD.Byte
#define PTAD_PTAD0 _PTAD.Bits.PTAD0
#define PTAD_PTAD1 _PTAD.Bits.PTAD1
#define PTAD_PTAD2 _PTAD.Bits.PTAD2
#define PTAD_PTAD3 _PTAD.Bits.PTAD3
#define PTAD_PTAD4 _PTAD.Bits.PTAD4
#define PTAD_PTAD5 _PTAD.Bits.PTAD5
#define PTAD_PTAD6 _PTAD.Bits.PTAD6
#define PTAD_PTAD7 _PTAD.Bits.PTAD7
Which will let the register value be changed either by PTAD = 0x01, or PTAD_PTAD0 = 1, for example. This definition is basically the same for PTAD, PTBD, PTCD, ... PTGD, the only thing changing is the address.
My attemp to create a custom bitfield out of the previous existing variables is
typedef union {
byte Byte;
struct {
byte *DB0;
byte *DB1;
byte *DB2;
byte *DB3;
byte *DB4;
byte *DB5;
byte *DB6;
byte *DB7;
} Bits;
} LCDDSTR;
I would create and initialize the bitfield as LCDDSTR lcd = {{&PTGD_PTGD6, &PTBD_PTBD5, ...}}, because by some reason, the initialization like LCDSTR lcd = {*.Bits.DB0 = &PTGD_PTGD6, *.Bits.DB1 = &PTBD_PTBD5, ...} (treating it as a struct, please correct me again) advice in How to initialize a struct in accordance with C programming language standards does not work with this compiler (it does work on an online compiler).
However, as you may see I am sort of grouping the bits, and (if it would work) I would be able to change the values of the actual register by doing *lcd.Bits.DB0 = 1, or something like that, but if I do lcd.Byte = 0x00, I would be changing the last (I think) byte of the memory address contained in lcd.Bits.DB0, you know, because the struct doesn't actually contains the data, but the pointers instead.
How would I go on achieving a struct that is able to contain and modify bits from several registers? (I guess the problem here is that in memory the bits are not one next to the other, which I guess would make it easier). Is it even possible? I hope it is.
How would I go on achieving a struct that is able to contain and modify bits from several registers? (I guess the problem here is that in memory the bits are not one next to the other..
I don't think you can do it with a struct. That is because bitfields by definition have to occupy the same or contiguous addresses.
However macros may be useful here
#define DB0 PTGD_PTGD6
#define DB1 PTBD_PTBD5
....
And to clear the bits to all 0's or set to all 1's you can use a multiline macro
#define SET_DB(x) do { \
PTGD_PTGD6 = x; \
PTBD_PTBD5 = x; \
...... \
} while(0)
How would I go on achieving a struct that is able to contain and modify bits from several registers?
You can't.
A structure must represent a single, continuous block of memory -- otherwise, operations like taking the sizeof the structure, or performing operations on a pointer to one would make no sense.
If you want to permute the bits of a value, you will need to find some way of doing so explicitly. If the order of your bits is relatively simple, this may be possible with a few bitwise operations; if it's weirder, you may need to use a lookup table.
Beyond that: bitfields in C are pretty limited. The language does not make a lot of guarantees about how a structure containing bitfields will end up laid out in memory; they are generally best avoided for portable code. (Which doesn't apply here, as you're writing code for a specific compiler/microcontroller combination, but it's worth keeping in mind in general.)
Your union does unfortunately not make any sense, because it forms a union of one byte and 8 byte*. Since a pointer is 16 bit on HCS08, this ends up as 8*2 = 16 bytes of data, which can't be used in any meaningful way.
Please note that the C structure called bit-fields is very poorly specified by the standard and therefore should be avoided in any program. See this.
Please note that the Codewarrior register maps aren't remotely close to following the C standard (nor MISRA-C).
Please note that structs in general are problematic for hardware register mapping, since structs can contain padding. You don't have that problem on HCS08 specifically, since it doesn't require alignment of data. But most MCUs do require that.
It is therefore better to roll out your own register map in standard C if you have that option. The port A data register could simply be defined like this:
#define PTAD (*(volatile uint8_t*)0x0000U)
#define PTAD7 (1U << 7)
#define PTAD6 (1U << 6)
#define PTAD5 (1U << 5)
#define PTAD4 (1U << 4)
#define PTAD3 (1U << 3)
#define PTAD2 (1U << 2)
#define PTAD1 (1U << 1)
#define PTAD0 (1U << 0)
As we can tell, defining the bit masks is mostly superfluous anyway, as PTAD |= 1 << 7; is equally readable to PTAD |= PTAD7;. This is because this was a pure I/O port. Defining textual bit masks for status and control registers on the other hand, increases the readability of the code significantly.
If you want to modify bits from several registers, you'd do something like the following:
Assume we have a RGB (red-green-blue) LED, common cathode, with 3 colors connected to 3 different pins on 3 different ports. Instead of beating up the PCB designer, you could do this:
#define RGB_RED_PTD PTAD
#define RGB_RED_PTDD PTADD
...
#define RGB_BLUE_PTD PTBD
#define RGB_BLUE_PTDD PTBDD
...
#define RGB_GREEN_PTD PTDD
#define RGB_GREEN PTDD PTDDD
#define RGB_RED_PIN 1
#define RGB_BLUE_PIN 5
#define RGB_GREEN_PIN 3
You can now set these independently of where they happen to be located on the hardware:
void rgb_init (void)
{
RGB_RED_PTDD |= (1 << RGB_RED_PIN);
RGB_BLUE_PTDD |= (1 << RGB_BLUE_PIN);
RGB_GREEN_PTDD |= (1 << RGB_GREEN_PIN);
}
void rgb_yellow (void)
{
RGB_RED_PTD |= (1 << RGB_RED_PIN);
RGB_BLUE_PTD &= ~(1 << RGB_BLUE_PIN);
RGB_GREEN_PTD |= (1 << RGB_GREEN_PIN);
}
And so on. Examples were for HCS08 but the same can of course be used universally on any MCU with direct port I/O.
It sounds like an approach such as the following is along the lines of where you would like to go with a solution.
I have not tested this as I do not have the hardware however this should provide an alternative to look at.
This assumes that you want to turn on particular pins or turn off particular pins but there will not be a case where you will want to turn on some pins and turn off other pins for a particular device in a single operation. If that should be the case I would consider making the type of RegPinNo be an unsigned short to include an op code for each register/pin number combination.
This also assumes that timing of operations is not a critical constraint and that the hardware has sufficient horsepower such that small loops are not much of a burden on throughput and hogging CPU time needed for other things. So this code may need changes to improve optimization if that is a consideration.
I assume that you want some kind of a easily readable way of expressing a command that will turn on and off a series of bits scattered across several areas of memory.
The first thing is to come up with a representation of what such a command would look like and it seems to me that borrowing from a char array to represent a string would suffice.
typedef byte RegPinNo; // upper nibble indicates register number 0 - 7, lower nibble indicates pin number 0 - 7
const byte REGPINNOEOS = 0xff; // the end of string for a RegPinNo array.
And these would be used to define an array of register/pin numbers as in the following.
RegPinNo myLed[] = { 0x01, 0x12, REGPINNOEOS }; // LED is addressed through Register 0, Pin 0 and Register 1, Pin 1 (zero based)
So at this point we have a way to describe that a particular device, an LED in this case, is addressed through a series of register/pin number items.
Next lets create a small library of functions that will use this representation to actually modify the specific pins in specific registers by traversing this array of register/pin numbers and performing an operation on it such as setting the bit in the register or clearing the bit in the register.
typedef unsigned char byte;
typedef union {
byte Byte;
struct {
byte PTAD0 : 1;
byte PTAD1 : 1;
byte PTAD2 : 1;
byte PTAD3 : 1;
byte PTAD4 : 1;
byte PTAD5 : 1;
byte PTAD6 : 1;
byte PTAD7 : 1;
} Bits;
} PTADSTR;
// Define a pointer to the beginning of the register area. This area is composed of
// 8 different registers each of which is one byte in size.
// We will address these registers as Register 0, Register 1, ... Register 7 which just happens
// to be how C does its zero based indexing.
// The bits representing pins on the PCB we will address as Pin 0, Pin 1, ... Pin 7.
extern volatile PTADSTR (* const _PTAD) = 0x00000000;
void SetRegPins(RegPinNo *x)
{
byte pins[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 4) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0x07; // get the pin number, 0 - 7
_PTAD[bRegNo].Byte |= pins[bPinNo];
}
}
void ClearRegPins(RegPinNo *x)
{
byte pins[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 4) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0x07; // get the pin number, 0 - 7
_PTAD[bRegNo].Byte &= ~pins[bPinNo];
}
}
void ToggleRegPins(RegPinNo *x)
{
byte pins[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 4) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0x07; // get the pin number, 0 - 7
_PTAD[bRegNo].Byte ^= pins[bPinNo];
}
}
You would use the above something like the following. Not sure what a time delay function would look like in your environment so I am using a function Sleep() which takes an argument as to the number of milliseconds to delay or sleep.
void LightLed (int nMilliSeconds)
{
RegPinNo myLed[] = { 0x01, 0x12, REGPINNOEOS }; // LED is addressed through Register 0, Pin 0 and Register 1, Pin 1 (zero based)
SetRegPins(myLed); // turn on the LED
Sleep(nMilliSeconds); // delay for a time with the LED lit
ClearRegPins(myLed); // turn the LED back off
}
Edit - A Refinement
A more efficient implementation that would allow multiple pins to be set in a particular register at the same time would be to define the use of RegPinNo as being an unsigned short` with the upper byte being the register number and the lower byte being the pins to manipulate as a bit mask for the byte.
With this approach you would have a SetRegPins() function that would look like the following. A similar change would be needed for the other functions.
void SetRegPins(RegPinNo *x)
{
int i;
for (i = 0; x[i] != REGPINNOEOS; i++) {
byte bRegNo = (x[i] >> 8) & 0x07; // get the register number, 0 - 7
byte bPinNo = x[i] & 0xFF; // get the pin mask
_PTAD[bRegNo].Byte |= bPinNo;
}
}
And the typedefs would look like:
typedef unsigned short RegPinNo; // upper byte indicates register number 0 - 7, lower byte provides pin mask
const byte REGPINNOEOS = 0xffff; // the end of string for a RegPinNo array.
And these elements would be used like:
void LightLed (int nMilliSeconds)
{
RegPinNo myLed[] = { 0x0002, 0x0103, REGPINNOEOS }; // LED is addressed through Register 0, Pin 1 and Register 1, Pin 0 and Pin 1 (zero based)
SetRegPins(myLed); // turn on the LED
Sleep(nMilliSeconds); // delay for a time with the LED lit
ClearRegPins(myLed); // turn the LED back off
}

structure members are taking wrong data

i coded a small program to show you the casting problem
#include <stdlib.h>
struct flags {
u_char flag1;
u_char flag2;
u_short flag3;
u_char flag4;
u_short flag5;
u_char flag7[5];
};
int main(){
char buffer[] = "\x01\x02\x04\x03\x05\x07\x06\xff\xff\xff\xff\xff";
struct flags *flag;
flag = (struct flags *) buffer;
return 0;
}
my problem is when i cast the flag 5 wrongly takes the "\x06\xff" bytes ignoring the "\x07" and the flag 7 wrongly takes the next 4 "\xff" bytes plus a nul which is the next byte.I also run gdb
(gdb) p/x flag->flag5
$1 = 0xff06
(gdb) p/x flag->flag7
$2 = {0xff, 0xff, 0xff, 0xff, 0x0}
(gdb) x/15xb flag
0xbffff53f: 0x01 0x02 0x04 0x03 0x05 0x07 0x06 0xff
0xbffff547: 0xff 0xff 0xff 0xff 0x00 0x00 0x8a
why this is happening and how i can handle it correctly?
thanks
It seems like structure member alignment issues. Unless you know how your compiler packs structure members, you should not make assumptions about the positions of those members in memory.
The reason that the 0x07 is apparently lost, is because the compiler is probably aligning the flag5 member on a 16-bit boundary, skipping the odd memory location that holds the 0x07 value. That value is lost in the padding. Also, what you are doing is overflowing the buffer, a big no-no. In other words:
struct flags {
u_char flag1; // 0x01
u_char flag2; // 0x02
u_short flag3; // 0x04 0x03
u_char flag4; // 0x05
// 0x07 is in the padding
u_short flag5; // 0x06 0xff
u_char flag7[5]; // 0xff 0xff 0xff 0xff ... oops, buffer overrun, because your
// buffer was less than the sizeof(flags)
};
You can often control the packing of structure members with most compilers, but the mechanism is compiler specific.
The compiler is free to put some unused padding between members of the structure to (for instance) arrange the alignment to it's conveneince. Your compiler may provide a #pragma packed or a command line argument to insure tight structure packing.
How structures are stored is implementation defined, and thus, you can't rely on a specific memory layout for serialization like that.
To serialize your structure to a byte array, write a function which serializes each field in a set order.
You might need to pack the struct:
struct flags __attribute__ ((__packed__)) {
u_char flag1;
u_char flag2;
u_short flag3;
u_char flag4;
u_short flag5;
u_char flag7[5];
};
Note: This is GCC -- I don't know how portable it is.
This has to do with padding. The compiler is adding garbage memory into your struct in order to get it to align with your memory correctly for efficiency.
See the following examples:
http://msdn.microsoft.com/en-us/library/71kf49f1(v=vs.80).aspx
http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86

Resources