Demystifying LOWORD macro pseudocode into valid C - c

From IDA decompilation of a subroutine into C pseudocode, I encountered this line of code:
LOWORD(v9) = *(BYTE *)v6);
Where v9, v6 are 32-bit integers.
LOWORD is a macro defined in windef.h as follows:
#define LOWORD(l) ((WORD)(((DWORD_PTR)(l)) & 0xffff))
Obviously it's a macro, so I can't assign things to it. I am interested an implementation which would be valid C, but I am unsure of the decompiler's intent here. From my guess, the intent is to dereference the LOWORD of v9, and assign the byte value pointed by v6, but I would like to make sure.
In the event that it may be necessary, here is the context of the pseudocode. All types are 32-bit integers:
if (*(BYTE *)v6) {
LOWORD(v9) = *(BYTE *)v6);
do {
v7 = v7 & 0xFFFF0000 | (unsigned __int16)(v7 + v9);
v9 = *++v8;
if (*v8) {
v7 = (unsigned __int16)v7 | ((*v8++ + (v7 >> 16)) << 16);
v9 = *v8;
}
} while (v9);
}

The windef.h macro you show is not the one being used by IDA, since as you noticed you cannot use the result of such a macro as an lvalue.
From my guess, the intent is to dereference the LOWORD of v9, and assign the byte value pointed by v6
Not quite. The intent is to replace the low word (that is the lower 2 bytes) of the variable v9 (which is an int) with the right hand side.
So in IDA, this:
LOWORD(a) = b;
Can be seen as this:
a = (a & 0xffff0000) | b;
The way to write such a macro in C would be something like:
#define LOWORD(x) (*((uint16_t*)&(x)))
Which is a possibly more convoluted, yet more versatile way of doing the same thing, and can be used both as an lvalue and an rvalue.

Related

I try to switch a specific struct by creating an int of it and can't find a fault

I defined this structure:
struct Command_Type {
uint8_t A,B,Command;
}; // struct Command_Type
and some constants like:
#define _HeartBeat ((struct Command_Type) {0x10,0x01,0})
I did use it in some funktions and could as well use it how I wanted to do but now I want to do a switch funtion where the case should use the labels. There for I defined a int_of_Command_Type as this:
#define int_of_Command_Type(A) ((unsigned int) (((int) ((A).A)) << 16) |\
(unsigned int) (((int) ((A).B)) << 8) | \
(unsigned int) (((int) ((A).Command))))
when I use this function to print out an %u value from a Variable of type struct Command_Type it works perfect.
now I did want to do something like this:
struct Command_Type Command_type_var=_HearBeat;
....some code ....
switch(Command_type_var)
{
case inf_of_Command_Type(_HeartBeat): .....
break;
default:
};
and I get the following fault message: case label does not reduce to an integer constant. Does someone know, how I can get round that problem with an easy way, because I do not understand at all what is wrong when it works for testprints and only not in the case label position. I've got lots of defined commands and don't want to change all of them but anyway I don't understand how I could handle it. Maybe with (const int) or what ever is needed?
Hope anyone does know quick what is really the fault and if there is a way round.
The constraint of the switch statement is that it requires according to C11 standard an integer expression::
6.8.4.2/1 The controlling expression of a switch statement shall have integer type.
Command_type_var doesn't match this constraint, as it is a struct (even if the struct holds in an integer, and even if you would hold only integer bit fields).
How to solve it:
It's quite simple: convert your struct to an int in the switch, by using your macro:
switch(int_of_Command_Type(Command_type_var)) // here we use an int
{
case int_of_Command_Type(_HeartBeat): // this is fortunately a constant
break;
default:
break;
};
Of course, this works only if the macro is defined correctly: the parameter can't take the name of one of the struct member, or otherwhise you'll end up with weird errors due to unexpected substitutions (the A parameter should be renamed X):
#define int_of_Command_Type(X) ((unsigned int) (((int) ((X).A)) << 16) |\
(unsigned int) (((int) ((X).B)) << 8) | \
(unsigned int) (((int) ((X).Command))))
Live demo
Edit: If, despite the fact that int_of_Command_Type(_HeartBeat) could be calculated at compile time, your compiler doesn't recognize it as a constant integer expression, you should replace the switch with if/else sequences. This is the case for MSVC 2015, who seems to use the stricter rules of 6.6/6 that do not require the implementation to provide for the possibility to use the . operator on structure constants.

Changing one given bit in a binary address in C

I'm working on the "buddy-allocation" for a memory management project in C (see page 14 of this .pdf).
I'd like to find the "buddy" of a given address, knowing that the two buddies are only one-bit-different (the size of the chunk tells us which bit changes). For example, if one of the two 32-bits buddy chunks has the binary address 0b110010100, the second one will be located at 0b110110100 (the 6th bit from the right changes, as 32=2^(6-1)).
I'd like to implement that in C, without exponentiation algorithms because I'm trying to make my program as fast-executing as possible. At best I'd use a tool to manipulate bits, if that exists. Any hints?
EDIT: the type of the addresses is void*. With the solutions posted below, gcc won't let me compile.
EDIT2: I've tried the answers posted below with the XOR operator, but I can't compile because of the type of the addresses. Here's what I've tried :
void* ptr1 = mmap(NULL, 640000, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_FILE | MAP_PRIVATE, -1, 0);
printf("%p\n", ptr1);
void* ptr2 = ptr1+0x15f6d44;
printf("%p\n", ptr2);
void* ptr3 = (void*)(ptr2-ptr1);
printf("%p\n", ptr3);
void* ptr4 = ptr3 ^ (1 << 6);
printf("%p\n", ptr4);
and the gcc error :
invalid operands to binary ^ (have ‘void *’ and ‘int’)
It looks like you just want to toggle a given bit, which is achieved using an XOR operation:
buddy_adr = (unsigned long)adr ^ (1 << bit_location);
The cast to unsigned long is required to avoid errors of undefined XOR operation on type void*.
Depending on your compiler settings, you may also get a warning about creating a pointer (i.e., an address) by casting an integer, which is obviously dangerous in the general case (you could pass an invalid address value). To silent this warning, cast back the result to void* to let the compiler know that you know what you are doing:
buddy_adr = (void *)((unsigned long(adr ^ (1 << bit_location));
Note that in embedded system programming (where I've used this technique most of the time since many peripherals are memory-mapped) you would usually "simplify" this line of code using macros like TOGGLE_BIT(addr, bit) and INT_TO_ADDR(addr).
You can set one bit with a | bitwise or.
adr = adr | 0x10;
A tool? To manipulate bits? You don't need a "tool", that's about as primitive an operation as you can do.
uint32_t address = 0x0194;
address |= 1 << 5; /* This sets the sixth bit. */
If you really want to toggle the bit, i.e. set if if it's clear, but clear it if it's set, you use the bitwise XOR operator:
address ^= 1 << 5;
This is not "exponentiation", it's just a bitwise XOR.
If the address is held in a pointer register, either cast or copy to integer (uintptr_t) and the copy back.
This is case of bit manipulation which is very common in c programming
if you want to change xxbxxxxx simply XOR this with xx1xxxxx. XOR topple the given bit. If you want to make it 1 just use OR (|) with all bits 0 except that bit 1 which you want to turn on
a more compact way to do this
#define BIT_ON(x,bit) (x |= ( 1 << (bit-1)) )
#define BIT_TOGGLE(x,bit) (x ^= ( 1 << (bit-1)) )
#define BIT_OFF(x,bit) (x &= ~( 1 << (bit-1)) )

Is there a convenient way of writing simple but long hex values in c?

I'm currently writing a code where I need to modify an 8 Byte variable 1 bit at a time. I was wondering, if there's a more convenient way to write a long but simple hex value like:
Variable & 0x8000000000000000
I know i can declare a char as 0x80 and then cast it to a different type and shift it. I'm just looking for something simpler and more practical.
You can use the bit-wise left shift operator to make it more clear:
variable & 1ULL << 63
well, though it's a shift, but you can use arduino's BV() macro, that is short and convenient:
#define _BV(bit) (1ULL << (bit))
which is used that way:
var & (0x8 * _BV(60));
if you want to work on the byte furthest left or directly:
var & _BV(63);
to access 63rd bit.

C bitfield element with non-contiguous layout

I'm looking for input on the most elegant interface to put around a memory-mapped register interface where the target object is split in the register:
union __attribute__ ((__packed__)) epsr_t {
uint32_t storage;
struct {
unsigned reserved0 : 10;
unsigned ICI_IT_2to7 : 6; // TOP HALF
unsigned reserved1 : 8;
unsigned T : 1;
unsigned ICI_IT_0to1 : 2; // BOTTOM HALF
unsigned reserved2 : 5;
} bits;
};
In this case, accessing the single bit T or any of the reserved fields work fine, but to read or write the ICI_IT requires code more like:
union epsr_t epsr;
// Reading:
uint8_t ici_it = (epsr.bits.ICI_IT_2to7 << 2) | epsr.bits.ICI_IT_0to1;
// Writing:
epsr.bits.ICI_IT_2to7 = ici_it >> 2;
epsr.bits.ICI_IT_0to1 = ici_it & 0x3;
At this point I've lost a chunk of the simplicity / convenience that the bitfield abstraction is trying to provide. I considered the macro solution:
#define GET_ICI_IT(_e) ((_e.bits.ICI_IT_2to7 << 2) | _e.bits.ICI_IT_0to1)
#define SET_ICI_IT(_e, _i) do {\
_e.bits.ICI_IT_2to7 = _i >> 2;\
_e.bits.ICI_IT_0to1 = _i & 0x3;\
while (0);
But I'm not a huge fan of macros like this as a general rule, I hate chasing them down when I'm reading someone else's code, and far be it from me to inflict such misery on others. I was hoping there was a creative trick involving structs / unions / what-have-you to hide the split nature of this object more elegantly (ideally as a simple member of an object).
I don't think there's ever a 'nice' way, and actually I wouldn't rely on bitfields... Sometimes it's better to just have a bunch of exhaustive macros to do everything you'd want to do, document them well, and then rely on them having encapsulated your problem...
#define ICI_IT_HI_SHIFT 14
#define ICI_IT_HI_MASK 0xfc
#define ICI_IT_LO_SHIFT 5
#define ICI_IT_LO_MASK 0x02
// Bits containing the ICI_IT value split in the 32-bit EPSR
#define ICI_IT_PACKED_MASK ((ICI_IT_HI_MASK << ICI_IT_HI_SHIFT) | \
(ICI_IT_LO_MASK << ICI_IT_LO_SHIFT))
// Packs a single 8-bit ICI_IT value x into a 32-bit EPSR e
#define PACK_ICI_IT(e,x) ((e & ~ICI_IT_PACKED_MASK) | \
((x & ICI_IT_HI_MASK) << ICI_IT_HI_SHIFT) | \
((x & ICI_IT_LO_MASK) << ICI_IT_LO_SHIFT)))
// Unpacks a split 8-bit ICI_IT value from a 32-bit EPSR e
#define UNPACK_ICI_IT(e) (((e >> ICI_IT_HI_SHIFT) & ICI_IT_HI_MASK) | \
((e >> ICI_IT_LO_SHIFT) & ICI_IT_LO_MASK)))
Note that I haven't put type casting and normal macro stuff in, for the sake of readability. Yes, I get the irony in mentioning readability...
If you dislike macros that much just use an inline function, but the macro solution you have is fine.
Does your compiler support anonymous unions?
I find it an elegant solution which gets rid of your .bits part. It is not C99 compliant, but most compilers do support it. And it became a standard in C11.
See also this question: Anonymous union within struct not in c99?.

Casting troubles when using bit-banding macros with a pre-cast address on Cortex-M3

TL;DR:
Why isn't (unsigned long)(0x400253FC) equivalent to (unsigned long)((*((volatile unsigned long *)0x400253FC)))?
How can I make a macro which works with the former work with the latter?
Background Information
Environment
I'm working with an ARM Cortex-M3 processor, the LM3S6965 by TI, with their StellarisWare (free download, export controlled) definitions. I'm using gcc version 4.6.1 (Sourcery CodeBench Lite 2011.09-69). Stellaris provides definitions for some 5,000 registers and memory addresses in "inc/lm3s6965.h", and I really don't want to redo all of those. However, they seem to be incompatible with a macro I want to write.
Bit Banding
On the ARM Cortex-M3, a portion of memory is aliased with one 32-bit word per bit of the peripheral and RAM memory space. Setting the memory at address 0x42000000 to 0x00000001 will set the first bit of the memory at address 0x40000000 to 1, but not affect the rest of the word. To change bit 2, change the word at 0x42000004 to 1. That's a neat feature, and extremely useful. According to the ARM Technical Reference Manual, the algorithm to compute the address is:
bit_word_offset = (byte_offset x 32) + (bit_number × 4)
bit_word_addr = bit_band_base + bit_word_offset
where:
bit_word_offset is the position of the target bit in the bit-band memory region.
bit_word_addr is the address of the word in the alias memory region that maps to the
targeted bit.
bit_band_base is the starting address of the alias region.
byte_offset is the number of the byte in the bit-band region that contains the targeted bit.
bit_number is the bit position, 0 to 7, of the targeted bit
Implementation of Bit Banding
The "inc/hw_types.h" file includes the following macro which implements this algorithm. To be clear, it implements it for a word-based model which accepts 4-byte-aligned words and 0-31-bit offsets, but the resulting address is equivalent:
#define HWREGBITB(x, b) \
HWREGB(((unsigned long)(x) & 0xF0000000) | 0x02000000 | \
(((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2))
This algorithm takes the base which is either in SRAM at 0x20000000 or the peripheral memory space at 0x40000000) and ORs it with 0x02000000, adding the bit band base offset. Then, it multiples the offset from the base by 32 (equivalent to a five-position left shift) and adds the bit number.
The referenced HWREG simply performs the requisite cast for writing to a given location in memory:
#define HWREG(x) \
(*((volatile unsigned long *)(x)))
This works quite nicely with assignments like
HWREGBITW(0x400253FC, 0) = 1;
where 0x400253FC is a magic number for a memory-mapped peripheral and I want to set bit 0 of this peripheral to 1. The above code computes (at compile-time, of course) the bit offset and sets that word to 1.
What doesn't work
Unfortunately, the aforememntioned definitions in "inc/lm3s6965.h" already perform the cast done by HWREG. I want to avoid magic numbers and instead use provided definitions like
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
An attempt to paste this into HWREGBITW causes the macro to no longer work, as the cast interferes:
HWREGBITW(GPIO_PORTF_DATA_R, 0) = 1;
The preprocessor generates the following mess (indentation added):
(*((volatile unsigned long *)
((((unsigned long)((*((volatile unsigned long *)0x400253FC)))) & 0xF0000000)
| 0x02000000 |
((((unsigned long)((*((volatile unsigned long *)0x400253FC)))) & 0x000FFFFF) << 5)
| ((0) << 2))
)) = 1;
Note the two instances of
(((unsigned long)((*((volatile unsigned long *)0x400253FC)))))
I believe that these extra casts are what is causing my process to fail. The following result of preprocessing HWREGBITW(0x400253FC, 0) = 1; does work, supporting my assertion:
(*((volatile unsigned long *)
((((unsigned long)(0x400253FC)) & 0xF0000000)
| 0x02000000 |
((((unsigned long)(0x400253FC)) & 0x000FFFFF) << 5)
| ((0) << 2))
)) = 1;
The (type) cast operator has right-to-left precedence, so the last cast should apply and an unsigned long used for the bitwise arithmetic (which should then work correctly). There's nothing implicit anywhere, no float to pointer conversions, no precision/range changes...the left-most cast should simply nullify the casts to the right.
My question (finally...)
Why isn't (unsigned long)(0x400253FC) equivalent to (unsigned long)((*((volatile unsigned long *)0x400253FC)))?
How can I make the existing HWREGBITW macro work? Or, how can a macro be written to do the same task but not fail when given an argument with a pre-existing cast?
1- Why isn't (unsigned long)(0x400253FC) equivalent to (unsigned long)((*((volatile unsigned long *)0x400253FC)))?
The former is an integer literal and its value is 0x400253FCul while the latter is the unsigned long value stored in the (memory or GPIO) address 0x400253FC
2- How can I make the existing HWREGBITW macro work? Or, how can a macro be written to do the same task but not fail when given an argument with a pre-existing cast?
Use HWREGBITW(&GPIO_PORTF_DATA_R, 0) = 1; instead.

Resources