nm results with trailing numbers in symbol names - nm

I have an empty program:
int main(int argc, char **argv)
{
return 0;
}
When I run nm path/to/exe --format=sysv I get numbers in the symbol names
e.g file_mtx_85 and free_fn_89.
With different program I can get duplicates like var_101 and var_102.
I think the duplication is because I have more than one symbol with that name, but why do I get numbers in the symbol names and what do they mean?
I'm compiling with Xtensa compiler.

Related

How to cast double value to first characters

Hello brothers I have work for along time to show the first 6 character from double value so I couldn't do that and I need a simple method, Ex:
Here's my double value I need to cast it: 14.7534343267653.
I need to show the first 7 characters only: 14.7534.
So any body can solve this with a simple way.
The example of doing what you are looking for in C:
#include <stdio.h>
int main(int argc, char *argv[]) {
double number = 14.7534343267653;
printf("%2.4f", number);
return 0;
}
Other languages have identical or very similar format specifiers, so esentially "%2.4f" and some string format() might be what you are looking for.

Invalid location in Frama-c value analysis

I am trying to analyze some program that resemble the following using the value analysis:
int main(int argc, char **argv){
char *argv0 = argv[0];
char x = argv0[1];
char y = argv0[2];
return 0;
}
After normalization and analysis the program looks like:
int main(int argc, char **argv){
int __retres;
char *argv0;
char x;
char y;
/*# assert Value: mem_access: \valid_read(argv + 0); */
argv0 = *(argv + 0);
/*# assert Value: mem_access: \valid_read(argv0 + 1); */
x = *(argv0 + 1);
/*# assert Value: mem_access: \valid_read(argv0 + 2); */
y = *(argv0 + 2);
__retres = 0;
return __retres;
}
where the status of the first two assert is 'unknown' and the status of the third one is 'invalid'. Moreover the value analysis tells me that *(argv0 + 2) is an invalid location and flags all code after it as dead.
I'd like to understand why the last assert is invalid (and not the first two) and why *(argv0 + 2) is an invalid location.
I'm using Frama-c Silicon-20161101
Thanks to anol's comment I was able to find the relevant section in the user manual of Value Analysis (http://frama-c.com/download/frama-c-value-analysis.pdf).
Here is an extract:
5.2.4 Tweaking the automatic generation of initial values (p58)
(...)
For a variable of a pointer type, there is no way for the analyzer to guess whether the pointer
should be assumed to be pointing to a single element or to be pointing at the beginning of
an array — or indeed, in the middle of an array, which would mean that it is legal to take
negative offsets of this pointer.
By default, a pointer type is assumed to point at the beginning of an array of two elements.
This number can be changed with option
-context-width.

Necessity of declaration of function in c and cpp

From bruce eckel --" although u should always declare functions by including header file , functions declarations aren't' essential in c . Its possible in c but not cpp to call a function u havent declared. This is a dangerous practise because the c compiler may assume that a function that u call with an integer argument has an argument list containing integer even if it may actually contain float . This can produce bugs" my question is that even if a function is not declared , during its definition we have to mention the data type of arguments [ VOID FUNC( INT A)] , so how can a compiler assumes a float to be an integer??
The compiler makes assumption on supplied parameters if a function is not declared or defined prior to the point the assumption should be made. Try the following code and check the result (checked with gcc):
#include <stdio.h>
int main (int argc, char * argv[])
{
x(1);
x(1.);
x(1);
return 0;
}
void x(double y)
{
printf ("%f\n", y);
}

Failing to convert raw binary/hex to int interpretation

I'm trying to convert raw hex/binary data to different file types.
#include <QByteArray>
#include <QDebug>
int main(int argc, char *argv[])
{
QByteArray package;
package.append( QByteArray::fromHex("a1"));
// "a1" is what is written to the memory, not the string representation of "a1"
qDebug() << package.toHex(); // "a1"
qDebug() << package; // "�"
qDebug() << package.toInt(); // 0
}
Why is the int representation 0 and not 161?
toInt has totally different purpose. It parses string representation of integer. If you want integer representing the value of the first byte of the array, use package[0]. It has char type. I don't remember how qDebug() represents char type, but if you have any problems with it, just static_cast it to unsigned int.
QByteArray::toInt expects that QByteArray contains a string of characters (in ASCII probably), not the binary representation of the number.
If you want to convert binary representation to integer you can use reinterpret_cast:
int i = *reinterpret_cast<quint8*>(package.constData());
Or better use qFromBigEndian/qFromLittleEndian:
int i = qFromLittleEndian<quint8>((const uchar*)package.constData())
In both cases you must know exactly in what format the number is stored and use proper type and endianness.

Storing a char in a char pointer

I have a global variable that is a *char. My main function header reads as int main(int argc, char* argv[argc]){...}. These two lines of code have to remain the way they are. The first argument of my main function is a number of type *char, that I convert to a char using atoi(...);. I am basically changing the ASCII value to its corresponding character. Now I want to store this local variable character I have into the global variable that is a char pointer. I know the problem is related to allocation of memory, but I am not sure how to go about this.
My code:
char* delim;
int main(int argc, char* argv[argc])
{
char delimCharacter;
if (isdigit(*(argv[3])) == 0) delim = argv[3]; //you can pass in a character or its ascii value
else { //if the argument is a number, then the ascii value is taken
delimCharacter = atoi((argv[3]));
printf("%s\t,%c,\n", argv[3], delimCharacter);
//sprintf( delim, "%c", delimCharacter ); // a failed attempt to do this
*delim = delimCharacter;
//strncpy(delim, delimCharacter, 1); // another failed attempt to do this
}
//printf("%s\n",delim);
This yields a seg fault.
You need to verify you have got (at least) 3 arguments before you start using them.
if (argc < 4)
{
printf("Need 3 args");
exit(1);
}
Then you need to allocate some memory to put the character in.
delim = malloc(2);
// TODO: Should check the result of malloc before using it.
*delim = delimCharacter;
delim[1] = 0; // Need to NULL terminate char*
You're dereferencing an uninitialized pointer. delim never gets initialized when it goes into the else block.
char delim[] = ","; // anything really, as long as as it's one character string
...
delim[0] = delimCharacter;
In addition to your memory issue, I think you are confused about what atoi does. It parses a string representation of a number and returns the equivalent int value, e.g. "10000" => 10,000. I think that you think it will give you the ASCII value of a character, e.g. "A" =>65.
Since you have a char *, and you are (I think) assuming that it contains a single character, you could simply do this:
delimCharacter = *(argv[3]);
However, there really seems to be no need to use the intermediate step of assigning this value to a char variable at all. If the end goal is to have delim point to the char that is the delimiter, then it seems this is all you need to do:
delim = argv[3];
Not only does this remove unnecessary code, but it means you would no longer need to allocate additional memory for delim to point to.
I would also declare delim as a const char * since I assume there is no reason to change it.

Resources