Both the LHS and RHS variables are uint8_t variable, but the issue is reported as " casting from int to unsigned char". I am not understanding how this can be an issue?
The same is applicable for an 8-bit numbers
All the variables listed in both issues are uint8_t
Issue 1)
CID 147563 (#2 of 2): Coding standard violation (CERT INT31-C)3. cert_violation:
Casting (uint8_t)apX_compY_bitmask from int to unsigned char without checking its
value may result in lost or misinterpreted data.
/* AP_X_Flash_Component_Y_Authenticated */
static uint8_t AP_component_require_auth;
//Local variable:
uint8_t apX_compY_bitmask = 0u, port;
// other operations
AP_component_require_auth |= (uint8_t)apX_compY_bitmask;
Issue 2)
CID 148170 (#1 of 1): Coding standard violation (CERT INT31-C)5. cert_violation:
Casting major_revision >> 3 from int to unsigned char without checking its
value may result in lost or misinterpreted data.
Function argument:
void sb_rollb_prot_AP_FW_in_use_update(uint8_t img_idx, uint8_t port, uint8_t major_revision, bool primary_image)
//Local Variable
uint8_t x_loc, y_loc;
y_loc = major_revision >> 3;
To understand what has caused teh warning, you have to understand (or at least be aware) of C's somewhat arcane and sometimes surprising type promotion rules.
The C bit-wise and arithmetic operators operate on int or unsigned int or larger types, so when presented with operands of a a smaller type an implicit promotion occurs:
Consider this "experiment" for example:
#include <stdint.h>
#include <stdio.h>
int main()
{
uint8_t a ;
uint8_t b ;
printf( "sizeof(a) = %zu\n", sizeof(a) ) ;
printf( "sizeof(b) = %zu\n", sizeof(b) ) ;
printf( "sizeof(a | b) = %zu\n", sizeof(a | b) ) ;
printf( "sizeof((uint8_t)(a | b)) = %zu\n", sizeof((uint8_t)(a | b)) ) ;
printf( "sizeof(a >> 3) = %zu\n", sizeof(a >> 3) ) ;
printf( "sizeof((uint8_t)(a >> 3)) = %zu\n", sizeof((uint8_t)(a >> 3)) ) ;
return 0;
}
The output (where int is 32-bit) is:
sizeof(a) = 1
sizeof(b) = 1
sizeof(a | b) = 4
sizeof((uint8_t)(a | b)) = 1
sizeof(a >> 3) = 4
sizeof((uint8_t)(a >> 3)) = 1
So in the first case:
AP_component_require_auth |= (uint8_t)apX_compY_bitmask;
The uint8_t cast serves no purpose since it already is that type, and certainly does not defeat the implicit conversion.
I am not familiar with CERT-C or Coverity, but in similar tools I have used, an implicit cast may be used to assert that the expression is deliberate:
AP_component_require_auth = (uint_8_t)(AP_component_require_auth | apX_compY_bitmask) ;
y_loc = (uint8_t)(major_revision >> 3) ;
As you can see it is not possible to resolve this using |= because you cannot then cast the result of the | expression before assignment.
However often it is better to maintain type agreement and avoid either implicit or explicit conversions and use int, unsigned or equal/larger sized integer type if there is no compelling reason to use a smaller type.
The issue in both cases is the assignment of an int sized type to a uint8_t. Though the first warning is somewhat confusing - probably due to the use of |= - preventing it form presenting the implicitly cast expression; you should get the same error without the unnecessary cast I think. The static analysis tool I am familiar with, would say something like:
implicit conversion to smaller type in assignment
in both these cases, which is I think is much clearer.
The Coverity warning is terse and minimal; if you go directly to the standard it is enforcing, it is much more explicit and gives rationale, examples and solutions: https://wiki.sei.cmu.edu/confluence/display/c/INT31-C.+Ensure+that+integer+conversions+do+not+result+in+lost+or+misinterpreted+data
Related
I'm working on Keil software and using LM3S316 microcontroller. Usually we address registers in microcontrollers in form of:
#define GPIO_PORTC_DATA_R (*((volatile uint32_t *)0x400063FC))
My question is how can I access to single pin of register for example, if I have this method:
char process_key(int a)
{ PC_0 = a ;}
How can I get PC_0 and how to define it?
Thank you
Given say:
#define PIN0 (1u<<0)
#define PIN1 (1u<<1)
#define PIN2 (1u<<2)
// etc...
Then:
char process_key(int a)
{
if( a != 0 )
{
// Set bit
GPIO_PORTC_DATA_R |= PIN0 ;
}
else
{
// Clear bit
GPIO_PORTC_DATA_R &= ~PIN0 ;
}
}
A generalisation of this idiomatic technique is presented at How do you set, clear, and toggle a single bit?
However the read-modify-write implied by |= / &= can be problematic if the register might be accessed in different thread/interrupt contexts, as well as adding a possibly undesirable overhead. Cortex-M3/4 parts have a feature known as bit-banding that allows individual bits to be addressed directly and atomically. Given:
volatile uint32_t* getBitBandAddress( volatile const void* address, int bit )
{
__IO uint32_t* bit_address = 0;
uint32_t addr = reinterpret_cast<uint32_t>(address);
// This bit maniplation makes the function valid for RAM
// and Peripheral bitband regions
uint32_t word_band_base = addr & 0xf0000000u;
uint32_t bit_band_base = word_band_base | 0x02000000u;
uint32_t offset = addr - word_band_base;
// Calculate bit band address
bit_address = reinterpret_cast<__IO uint32_t*>(bit_band_base + (offset * 32u) + (static_cast<uint32_t>(bit) * 4u));
return bit_address ;
}
Then you can have:
char process_key(int a)
{
static volatile uint32_t* PC0_BB_ADDR = getBitBandAddress( &GPIO_PORTC_DATA_R, 0 ) ;
*PC0_BB_ADDR = a ;
}
You could of course determine and hard-code the bit-band address; for example:
#define PC0 (*((volatile uint32_t *)0x420C7F88u))
Then:
char process_key(int a)
{
PC0 = a ;
}
Details of the bit-band address calculation can be found ARM Cortex-M Technical Reference Manual, and there is an on-line calculator here.
I have a trivial program:
int main(void)
{
const char sname[]="xxx";
sem_t *pSemaphor;
if ((pSemaphor = sem_open(sname, O_CREAT, 0644, 0)) == SEM_FAILED) {
perror("semaphore initilization");
exit(1);
}
sem_unlink(sname);
sem_close(pSemaphor);
}
When I run it under valgrind, I get the following error:
==12702== Syscall param write(buf) points to uninitialised byte(s)
==12702== at 0x4E457A0: __write_nocancel (syscall-template.S:81)
==12702== by 0x4E446FC: sem_open (sem_open.c:245)
==12702== by 0x4007D0: main (test.cpp:15)
==12702== Address 0xfff00023c is on thread 1's stack
==12702== in frame #1, created by sem_open (sem_open.c:139)
The code was extracted from a bigger project where it ran successfully for years, but now it is causing segmentation fault.
The valgrind error from my example is the same as seen in the bigger project, but there it causes a crash, which my small example doesn't.
I see this with glibc 2.27-5 on Debian. In my case I only open the semaphores right at the start of a long-running program and it seems harmless so far - just annoying.
Looking at the code for sem_open.c which is available at:
https://code.woboq.org/userspace/glibc/nptl/sem_open.c.html
It seems that valgrind is complaining about the line (270 as I look now):
if (TEMP_FAILURE_RETRY (__libc_write (fd, &sem.initsem, sizeof (sem_t)))
== sizeof (sem_t)
However sem.initsem is properly initialised earlier in a fairly baroque manner, firstly by explicitly setting fields in the sem.newsem (part of the union), and then once that is done by a call to memset (L226-228):
/* Initialize the remaining bytes as well. */
memset ((char *) &sem.initsem + sizeof (struct new_sem), '\0',
sizeof (sem_t) - sizeof (struct new_sem));
I think that this particular shenanigans is all quite optimal, but we need to make sure that all of the fields of new_sem have actually been initialised... we find the definition in https://code.woboq.org/userspace/glibc/sysdeps/nptl/internaltypes.h.html and it is this wonderful creation:
struct new_sem
{
#if __HAVE_64B_ATOMICS
/* The data field holds both value (in the least-significant 32 bytes) and
nwaiters. */
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define SEM_VALUE_OFFSET 0
# elif __BYTE_ORDER == __BIG_ENDIAN
# define SEM_VALUE_OFFSET 1
# else
# error Unsupported byte order.
# endif
# define SEM_NWAITERS_SHIFT 32
# define SEM_VALUE_MASK (~(unsigned int)0)
uint64_t data;
int private;
int pad;
#else
# define SEM_VALUE_SHIFT 1
# define SEM_NWAITERS_MASK ((unsigned int)1)
unsigned int value;
int private;
int pad;
unsigned int nwaiters;
#endif
};
So if we __HAVE_64B_ATOMICS then the structure has a data field which contains both the value and the nwaiters, otherwise these are separate fields.
In the initialisation of sem.newsem we can see that these are initialised correctly, as follows:
#if __HAVE_64B_ATOMICS
sem.newsem.data = value;
#else
sem.newsem.value = value << SEM_VALUE_SHIFT;
sem.newsem.nwaiters = 0;
#endif
/* pad is used as a mutex on pre-v9 sparc and ignored otherwise. */
sem.newsem.pad = 0;
/* This always is a shared semaphore. */
sem.newsem.private = FUTEX_SHARED;
I'm doing all of this on a 64-bit system, so I think that valgrind is complaining about the initialisation of the 64-bit sem.newsem.data with a 32-bit value since from:
value = va_arg (ap, unsigned int);
We can see that value is defined simply as an unsigned int which will usually still be 32 bits even on a 64-bit system (see What should be the sizeof(int) on a 64-bit machine?), but that should just be an implicit cast to 64-bits when it is assigned.
So I think this is not a bug - just valgrind getting confused.
I'm trying to port the code for calculating OpenSubtitles hash and I'm using the Objective-C example as reference (http://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes#Objective-C). The formula for the hash is file size + 64bit checksum of the first 64k of the file + 64bit checksum of the last 64k of the file.
I'm having trouble with the bit of code that calculates the checksums. This is the important part of the code in Objective-C:
const NSUInteger CHUNK_SIZE=65536;
NSData *fileDataBegin, *fileDataEnd;
uint64_t hash=0;
fileDataBegin = [handle readDataOfLength:(NSUInteger)CHUNK_SIZE];
[handle seekToEndOfFile];
unsigned long long fileSize = [handle offsetInFile];
uint64_t * data_bytes= (uint64_t*)[fileDataBegin bytes];
for( int i=0; i< CHUNK_SIZE/sizeof(uint64_t); i++ )
hash+=data_bytes[i];
I tried converting most of the code ti Swift by just rewriting it in a similar fashion. I'm having trouble with coming up with the replacement code for this little bit:
uint64_t * data_bytes= (uint64_t*)[fileDataBegin bytes];
for( int i=0; i< CHUNK_SIZE/sizeof(uint64_t); i++ )
hash+=data_bytes[i];
Any help would be great.
uint64_t * data_bytes= (uint64_t*)[fileDataBegin bytes];
can be translated as
let data_bytes = UnsafeBufferPointer<UInt64>(
start: UnsafePointer(fileDataBegin.bytes),
count: fileDataBegin.length/sizeof(UInt64)
)
which has the additional advantage that data_bytes is not just
a pointer, but also stores the number of elements. An
UnsafeBufferPointer can be treated almost like a Swift Array.
Therefore
for( int i=0; i< CHUNK_SIZE/sizeof(uint64_t); i++ )
hash+=data_bytes[i];
can be written simply as
var hash : UInt64 = 0
// ...
hash = reduce(data_bytes, hash) { $0 &+ $1 }
using
/// Return the result of repeatedly calling `combine` with an
/// accumulated value initialized to `initial` and each element of
/// `sequence`, in turn.
func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U
and the "overflow operator" &+:
Unlike arithmetic operators in C, arithmetic operators in Swift do not
overflow by default. Overflow behavior is trapped and reported as an
error. To opt in to overflow behavior, use Swift’s second set of
arithmetic operators that overflow by default, such as the overflow
addition operator (&+). All of these overflow operators begin with an
ampersand (&).
I am willing to transfer data from unsigned char hash[512 + 1] to char res[512 + 1] safely.
My C hashing library MHASH returns a result so it can be printed as listed below.
for (int i = 0; i < size /*hash block size*/; i++)
printf("%.2x", hash[i]); // which is unsigned char - it prints normal hash characters in range [a-z,0-9]
printf("\n");
I am willing to do something like that (see below).
const char* res = (const char *)hash; // "hash" to "res"
printf("%s\n", res); // print "res" (which is const char*) - if i do this, unknown characters are printed
I know the difference between char and unsigned char, but I don't know how to transfer data. Any answer would be greatly appreciated, thanks in advance. But please do not recommend me C++ (STD) code, I am working on a project that is not STD-linked.
Given that the contents of the unsigned char array are printable characters, you can always safely convert it to char. Either a hardcopy with memcpy or a pointer reference as in the code you have already written.
I'm guessing that the actual problem here is that the unsigned char array contents are not actually printable characters, but integers in some format. You'll have to convert them from integer to ASCII letters. How to do this depends on the format of the data, which isn't clear in your question.
Assuming the following:
#define ARR_SIZE (512 + 1)
unsigned char hash[ARR_SIZE];
char res[ARR_SIZE];
/* filling up hash here. */
Just do:
#include <string.h>
...
memcpy(res, hash, ARR_SIZE);
Well, thank you guys for your answers, but unfortunately nothing worked yet. I am now sticking with the code below.
char res[(sizeof(hash) * 2) + 1] = { '\0' };
char * pPtr = res;
for (int i = 0; i < hashBlockSize; i++)
sprintf(pPtr + (i * 2), "%.2x", hash[i]);
return (const char *)pPtr;
Until there is any other much more performant way to get this done. It's right, my question is strongly related to MHASH Library.
I have the following code which progressively goes through a string of bits and rearrange them into blocks of 20bytes. I'm using 32*8 blocks with 40 threads per block. However the process takes something like 36ms on my GT630M. Are there any further optimization I can do? Especially with regard to removing the if-else in the inner most loop.
__global__ void test(unsigned char *data)
{
__shared__ unsigned char dataBlock[20];
__shared__ int count;
count = 0;
unsigned char temp = 0x00;
for(count=0; count<(streamSize/8); count++)
{
for(int i=0; i<8; i++)
{
if(blockIdx.y >= i)
temp |= (*(data + threadIdx.x*(blockIdx.x + gridDim.x*(i+count)))&(0x01<<blockIdx.y))>>(blockIdx.y - i);
else
temp |= (*(data + threadIdx.x*(blockIdx.x + gridDim.x*(i+count)))&(0x01<<blockIdx.y))<<(i - blockIdx.y);
}
dataBlock[threadIdx.x] = temp;
//do something
}
}
It's not clear what your code is trying to accomplish, but a couple obvious opportunities are:
1) if possible, use 32-bit words instead of unsigned char.
2) use block sizes that are multiples of 32.
3) The conditional code may not be costing you as much as you expect. You can check by compiling with --cubin --gpu-architecture sm_xx (where xx is the SM version of your target hardware), and using cuobjdump --dump-sass on the resulting cubin file to look at the generated assembly. You may have to modify the source code to loft the common subexpression into a separate variable, and/or use the ternary operator ? : to hint to the compiler to use predication.