With reference to this:
calculating FLASH utilisation by C code
I have decided to check the calculations of actual assembly instructions.
so my script counts the assembly instructions, lies in the assembly listing file of the feature enable code.
e.g.
if(TRUE == feature1_enable)
{
// instruction counting starts here
doSomething;
.
.
.
// instruction counting stops here
}
This gives me some counts x from which I can figure out the size of the code.
To cross check the result I decided to nm the object file of the feature code but nm gives the size of entire function and not the individual statements.
So I copied the code part for that feature in separate file, made the function of it, included necessary headers and declared variables to get this file compile (by taking care of locals would remain locals and globals would remain globals).
so the new file looks like this:
#include "header1.h"
#include "header2.h"
global_variables;
void checkSize( void )
{
local_variables;
// feature1_enable code
doSomething;
.
.
.
}
Now the function checkSize contains only the feature enable code so after compiling, if I nm the obj file, I should be able to get almost same result as assembly counts (apart from some extra size utilized by the function setup).
But that not the case, I have received huge difference. (1335 bytes in the case of assembly instructions and 1458 bytes in the case of nm of obj file).
To get the further clarification, I have created assembly of the file with function checkSize and compared with original assembly file.
I understand there is some extra stuff due to the addition of checkSize function but instructions of the feature enable code expected to be same (with the same compiler optimization and other options).
But they were not the same.
Now the question is why is there such difference in the assembly instructions for feature code inside big function and when I move it to the other file with the feature code alone.
Is there anything to predict the extra size in either case?
There could be several things happening here. To be sure you are going to have to read the actual assembly code and figure out what it is doing. The compiler is VERY clever when you have it set to a high optimization level. For example in your first code segment it is very possible for the compiler to have assembly statements out side of your
// instruction counting starts here
// instruction counting stops here
comments that perform work in between the comments. In your second example that optimization is not possible and all work needs to be done in the function. Also do not discount the amount of space the prolog and epilog of functions take. Depending on the instruction set of your processor and its stack and register usage it can be quite large. For example on Power PC there is no push many registers instruction and you have to push each individual register and pop each individual register off of the stack frame when enter and leaving a function. When you're dealing with 32 registers that can be quite a bit of code.
You could try a trick when you have high optimization levels set for you compiler. The compiler cannot optimize across "asm" statements as it does not know what happens in them. What you could do is put some dummy code in the "asm" statements. I personally like creating global symbols that are in the object file. That way I can get the address of the starting symbol and ending symbol and calculate the size of code in between. It looks something like this...
asm(" .globl sizeCalc_start");
asm(" sizeCalc_start: ");
// some code
asm(" .globl sizeCalc_end");
asm(" sizeCalc_end:");
Then you can do something in a function like
extern int sizeCalc_start;
extern int sizeCalc_end;
printf("Code Segment Size %d\r\n", &sizeCalc_end - &sizeCalc_start);
I've done this in the past and it worked. Have not tried to compile this so dunno you may need to mess around with it a bit to get what you want.
Optimization is tricky. Within a big function (and the big file) the compiler has wider context, and may optimize more aggressively - reuse common expressions, pick shorter forms of branches, etc (hard to say exactly without knowing your target architecture).
PS: I am not quite sure how do you go from assembly count to the byte count.
Related
I am trying to run some MC9S12DP256 example files, but I want to see the code to understand it. Are there any ways to convert a .s19 or .abs file to a C code?
An ".s19" or an ".abs" file contains mainly the machine code of the application. The source code of it is not included, independent of the language used to write it. Even if it were written in assembly language, all symbolic informations and comments are excluded.
However, you can try to de-compile the machine code. This is not a trivial or quick task, you need to know the target really well. I did this with software for other processors, it is feasible for code up to some KB.
These are the steps I recommend:
Get a disassembler and an assembler for the target processor, optimally from the vendor.
Let it disassemble the machine code into assembly source code. You might need to convert the ".s19" file into a binary file, one possible tool for this is "srecord".
Assemble the resulting source code again into ".s19" or ".abs", and make sure that it generates the same contents as your original.
Insert labels for the reset and interrupt entry points. Start at the reset entry point with your analysis.
Read the source code, think about what it does.
You will quickly "dive" into subroutines that execute small functions, like reading ADC or sending data. Place a label and replace the numerical value at the call sites with the label.
Expect sections of (constant) data mixed with executable code.
Repeat often from point 3. If you have a difference, undo your last step and redo it in another way until you produce the same contents.
If you want C source, it is commonly much more difficult. You need a lot of experience how C is compiled into machine code. Be aware that variables or even functions are commonly placed in another sequence than they are declared. If you want to go that route, you usually also have to use the exact version of the compiler used to generate the original machine code.
Be aware that the original might be produced with any other language.
I'm debugging the goldfish android kernel (version 3.4), with kernel sources.
Now I found that gdb sometimes jump back and forth between lines, e.g consider c source code like the following:
char *XXX;
int a;
...
if (...)
{
}
When I reached the if clause, I type in n and it will jump back to the int a part. Why is that?
If I execute that command again, it would enter the brackets in the if.
If possible, I want to avoid that part, and enter the if directly (of course, if condition matches)
When I reached the if clause, I type in n and it will jump back to the int a part. Why is that?
Because your code is compiled with optimization on, and the compiler can (and often does) re-arrange instructions of your program in such a way that instructions "belonging" to different source lines are interleaved (code motion optimizations attempt (among other things) to move load instructions to long before their results are needed; this helps to hide memory latency).
If you are using gcc-4.8 or later, build your sources with -Og. Else, see this answer.
I am working on a firmware project in which i have to do a crc16 check for flash integrity.
The crc is calculated using IAR Xlink linker and kept at the end of the flash. Again crc is calculated at run time from the code and compared with the stored value in the flash to check integrity. However, we can only calculate crc on the code segment of the flash memory. It's size may change whenever we make some changes in the code. Can i automate this process which i am manually doing right now?
from the .xcl linker file:
// ---------------------------------------------------------
// CRC16 Essentials: -H for fill,-J for checksum calculation
// ---------------------------------------------------------
-HFF
-J2,crc16,,,CHECKSUM2,2=(CODE)5C00-FF7F;(CODE)10000-0x20A13
Here i need to change the end value of second code segment which is 0x20A13 right now.
I get this value from the .map file, i.e on how much memory range my code is residing inside the flash.
This is the 1st change i make.
Here i need to make 2nd change from code:
sum = fast_crc16(sum, 0x5C00, 0xFF7F-0x5C00+1);
sum = fast_crc16(sum, 0x10000,0x20A13-0x10000+1);
//Check the crc16 values
if(sum != __checksum)
{
// Action to be taken if checksum doesn't match
}
Please help automating this process!!
You can try to use the __segment_begin and __segment_size or __segment_end intrinsics in IAR which are explained in the "C/C++ Compiler Reference Guide", which you can get to from your Help menu in IAR EW430. The manual says they work with segments defined in the linker file, and plenty of the people around the internet seem to be using it like that, but I tried and got compiler errors (IAR EW430 5.40.7). If that is somehow broken you might want to report it to IAR and get a fix (assuming you have a support contract).
You can use them like this:
sum = fast_crc16(sum, __segment_begin("CODE"), __segment_size("CODE"));
I don't know what happens with split segments. But why would you exclude your reset vectors from your checksum calculation? You could just go from the start of CODE to the end and include the reset vectors.
I guess you could structure your code like this:
sum = fast_crc16(sum, __segment_begin("CODE"), (char *)__segment_begin("INTVEC") - (char *)__segment_begin("CODE") + 1);
sum = fast_crc16(sum, 0x10000, (char *)__segment_end("CODE") - 0x10000);
Also, you may or may not have noticed that the __checksum variable is put into memory wherever it fits. I found it lurking after my DATA16_ID segment, which put it right in the middle of the range of my checksum code, and I did not know of a way to automate skipping sections of memory for the checksum calculation. What I did was forced __checksum to the first two bytes in flash by defining a segment for those first two bytes and putting it in there.
Edit: Missed the first change. If you are manually adjusting the range of the IAR linker checksum routine then to be able to use the segment intrinsics from the compiler your would need to define a custom segment that uses the end of your code in your linker.
I don't know if there's any way to automate that. You might need to compile your code twice (ugh) once with the segment unlimited to get the end of the code, then use a script to extract the end of code and then update a linker script. You could probably run the initial build on a pre-build command line event and just build the IAR project with an unrestricted linker file. But that seems pretty ugly.
Perhaps you can also change your solution to build the crc over the complete flash reserved for the application, not only for the used part.
Then you never need to change your linker file nor your c-code, and even a bootloader could calculating the crc without knowledge about the actual size of the application.
I've compiled a C file that does absolutely nothing (just a main that returns... not even a "Hello, world" gets printed), and I've compiled it with various compilers (MinGW GCC, Visual C++, Windows DDK, etc.). All of them link with the C runtime, which is standard.
But what I don't get is: When I open up the file in a hex editor (or a disassembler), why do I see that almost half of the 16 KB is just huge sections of either 0x00 bytes or 0xCC bytes? It seems rather ridiculous to me... is there any way to prevent these from occurring? And why are they there in the first place?
Thank you!
Executables in general contain a code segment and at least one data segment. I guess each of these has a standard minimum size, which may be 8K. And unused space is filled up with zeros. Note also that an EXE written in a higher level (than assembly) language contains some extra stuff on top of the direct translation of your own code and data:
startup and termination code (in C and its successors, this handles the input arguments, calls main(), then cleans up after exiting from main())
stub code and data (e.g. Windows executables contain a small DOS program stub whose only purpose is to display the message "This program is not executable under DOS").
Still, since executables are usually supposed to do something (i.e. their code and data segment(s) do contain useful stuff), and storage is cheap, by default noone optimizes for your case :-)
However, I believe most of the compilers have command line parameters with which you can force them to optimize for space - you may want to check the results with that setting.
Here is more details on the EXE file formats.
As it turns out, I should've been able to guess this beforehand... the answer was the debug symbols and code; those were taking up most of the space. Not compiling with /DEBUG and /PDB (which I always do by default) reduced the 13 K down to 3 K.
How to protect c++ output file(pe file) from editing using crc(Cyclic Redundancy Check)?
**Best Regards**
You can use CRC's to effectively check to see if a file was accidentally altered, but they are not effective for copy protection, or preventing cheats on a game.
Usually, when I program has some sort of CRC check, I find the code which does the check, and change the assembly instruction from a conditional branch to an unconditional branch. This is usually quite easy to find, because normally after a CRC fail, the program displays a message and exits. I place a break point when the message occurs, and examine all the frames in the stack. I then put break points on each point in the stack, run the program again, and see which one does the CRC check.
This isn't particularly difficult, and people often bundle little programs which will apply the same changes to the software of your choice.
You need a static variable in your code. The variable needs to be initialized to a value that can easily found with an hex editor (e.g. DEADBEEF)
you need a crc-algorithm (try searching google)
The tricky part. You need to get pointer in memory to the start and to the end of your exe. You can parse the pe file header for the code location and run the crc-algorithm from start of code to end of code. Then you have the value.
Of course you have to check the calculated value with the one in the static variable.
Inserting the value - depending on how often you build, you might want to programm a tool. You can always run your program and set a breakpoint on the comparison. Then you note down the value and hex-edit it into the executable. Or you create a standalone program that parses the pe-header as well, uses the same function (this time on the file) and patches it in. This could be complicated though, because I don't know what is changed by the OS during loading.