I wrote a program in C and I want to get .hex file from it.
My C program for testing:
int main(){
int j = 9;
int k = 10;
int l = j + k;
int m = j - k;
}
This is ouptut that i'm looking for:
fe010113
00112e23
00812c23
02010413
00900513
...
In terminal, I compiled my code using riscv-none-gcc compiler with these --specs=nosys.specs main.c -o main.o arguments.
But when i opened the main.o file i saw this:
��������≤�
������ˇˇˇˇ�|
���� ���t�� ���BFàÅ���ˇˇˇˇ�|
� ���H���º�:���BJàNÅâX»B¡B…B����ˇˇˇˇ�|
�(���|���ˆ�l���BDàíXÅâD¡B»B…B“B�������ˇˇˇˇ�|
�4���∏���
�ö���B BàFâLíìîÅ8
¡B»B…B“B”B‘B�B������ˇˇˇˇ�|
�������î�����H������§�‘���B0BñFïXìîó ôÅàâíò
B
»F¡B…B“B”B‘B’B÷B◊BÿBŸB�B������ˇˇˇˇ�|
����l��x�������l��z�������l��|�������l��~�������l��Ä�������l��Ç�������l��Ñ�������l��à�������l��å�������l��é�������ˇˇˇˇ�|
������ê������������������������t������������î�����������ò�����������ú�����������§�����������®�����������–�����������‹�����������‡������ ��������������
���������������ˇ������������Òˇ������������Òˇ���î�������������������Òˇ����ò�������*���ÿ��������,���Ù��������?����������U���‹�������d���§�������ã���N�������ó���‡������ �£���†�������¬������������ÒˇÓ������������Òˇ…������������Òˇ–������������ÒˇŸ���®�(����Â������������ÒˇÏ������������Òˇ˜������������Òˇ˛������������Òˇ������������Òˇ��ò��������������������Òˇ��®��������%��§��������8��§��������I��ú��������]��ú��������p��ú��������Ü��®������Òˇò��¯����� �∏��¸����� �ü��ÿ������“��|������Ë��–�������¯��–��������–�������������� �.������� �M��î������`��ˆ�l�����¡��÷�������r��º�:�����Ñ������� �§��é������∆��à������Ï��§�‘�����Ä��™��,�����˝��Ñ��������
�ö�����-��~������M�������� �Y��Ç������{��‹�������á��b�®�����é��x�:�����ì��z������≤��x���������÷�������«��≤�
�����T��‘������Œ��®�������›��‹������� �������� �‰������� �2��t�� �������Ä��������å������1��ê������7������� �N������� �`������� ��__call_atexit.c�register_fini�crtstuff.c�deregister_tm_clones�__do_global_dtors_aux�completed.3272�__do_global_dtors_aux_fini_array_entry�frame_dummy�object.3277�__frame_dummy_init_array_entry�main.c�fini.c�impure.c�impure_data�init.c�__atexit.c�lock.c�_exit.c�__FRAME_END__�__fini_array_end�__fini_array_start�__init_array_end�__preinit_array_end�__init_array_start�__preinit_array_start�__global_pointer$�__lock___atexit_recursive_mutex�__lock___arc4random_mutex�__retarget_lock_close�__SDATA_BEGIN__�__TMC_END__�__dso_handle�__lock___env_recursive_mutex�__lock___sinit_recursive_mutex�_global_impure_ptr�__libc_init_array�__libc_fini_array�__lock___malloc_recursive_mutex�__retarget_lock_release_recursive�__retarget_lock_try_acquire_recursive�__call_exitprocs�__retarget_lock_try_acquire�__register_exitproc�__retarget_lock_close_recursive�__BSS_END__�__retarget_lock_acquire_recursive�__bss_start�memset�main�__retarget_lock_init_recursive�__retarget_lock_init�atexit�__DATA_BEGIN__�_edata�__lock___at_quick_exit_mutex�__retarget_lock_acquire�__retarget_lock_release�_exit�__lock___dd_hash_mutex�__lock___tz_mutex�__lock___sfp_recursive_mutex��.symtab�.strtab�.shstrtab�.text�.sdata2�.eh_frame�.init_array�.fini_array�.data�.sdata�.sbss�.bss�.comment�.debug_frame����������������������������������������������������t��t��������������������!���������î�î��������������������)���������ò�ò��������������������3���������ú�ú�������������������?���������§�§�������������������K���������®�®��(�����������������Q���������–�–��������������������X���������‹�‹��������������������^���������‡�‹��<������������������c������0�������‹��9�����������������l�������������� ��<�������������������������������T��`��
���+��������� ��������������¥��}�������������������������������1��y������������������
Maybe not a great question, but is there somewhere my compild code? if yes, how can i find and extract or hexdump it? I am using Mac.
Thanks.
Related
#include<stdio.h>
int main()
{
int a , b;
a = 2;
b = 3;
printf("%d , %d", a , b);
return 0;
}
The output comes out to be ->
PS E:\Coding\C\C C++> cd "e:\Coding\C\C C++" ; if ($?) { gcc hello.c -o hello } ; if ($?) { .\hello }
4214884
Why is this happening? Is there something wrong with the compiler?
The code seems okay, it should give the correct output.
After saving the code, compile the program again.
gcc file_name_with_extension
It'll create an execitable file. Then run that file by simply giving the name of the executable file without any extension.
Consider the following code:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("main\n");
int a;
scanf("%d", &a);
printf("a = %d\n", a);
return 0;
}
int main1() {
printf("main1\n");
int a;
scanf("%d", &a);
printf("a = %d\n", a);
exit(0);
return 0;
}
int main2() {
printf("main2\n");
int a = getchar() - '0';
int b = getchar() - '0';
int c = getchar() - '0';
printf("a = %d\n", 100 * a + 10 * b + c);
exit(0);
return 0;
}
Assuming that the code resides in a file called test.c, the following works fine (it prints "a = 123"):
gcc -o test test.c
echo 123 | ./test
If, however, I run the program with a custom entry point, I get the dreaded Segmentation fault:
gcc -o test test.c -e"main1"
echo 123 | ./test
But if I replace the scanf with three getchars, the program runs fine again despite being run with a custom entry point:
gcc -o test test.c -e"main2"
echo 123 | ./test
To make things even more interesting, these problems occur with gcc 7.4.0 but not with gcc 4.8.4.
Any ideas?
The -e command line flag redefines the actual entry point of your program, not the “user” entry point. By default, using GCC with the GNU C standard library (glibc) this entry point is called _start, and it performs further setup before invoking the user-provided main function.
If you want to replace this entry point and continue using glibc you’ll need to perform further setup yourself. But alternatively you can use the following method to replace the main entry point, which is much simpler:
gcc -c test.c
objcopy --redefine-sym main1=main test.o
gcc -o test test.o
Note, this will only work if you don’t define main in your code, otherwise you’ll get a “multiple definition of `main'” error from the linker.
I am trying to write a program to approximate pi. It basically takes random points between 0.00 and 1.00 and compares them to the bound of a circle, and the ratio of points inside the circle to total points should approach pi (A very quick explanation, the specification goes in depth much more).
However, I am getting the following error when compiling with gcc:
Undefined first referenced
symbol in file
pow /var/tmp//cc6gSbfE.o
ld: fatal: symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status
What is happening with this? I've never seen this error before, and I don't know why it's coming up. Here is my code (though I haven't fully tested it since I can't get past the error):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void) {
float x, y;
float coordSquared;
float coordRoot;
float ratio;
int n;
int count;
int i;
printf("Enter number of points: ");
scanf("%d", &n);
srand(time(0));
for (i = 0; i < n; i++) {
x = rand();
y = rand();
coordSquared = pow(x, 2) + pow(y, 2);
coordRoot = pow(coordSquared, 0.5);
if ((x < coordRoot) && (y < coordRoot)) {
count++;
}
}
ratio = count / n;
ratio = ratio * 4;
printf("Pi is approximately %f", ratio);
return 0;
}
use -lm during compilation(or linking) to include math library.
Like this: gcc yourFile.c -o yourfile -lm
need to Link with -lm.
gcc test.c -o test -lm
The error is produced by the linker, ld. It is telling you that the symbol pow cannot be found (is undefined in all the object files handled by the linker). The solution is to include the library which includes the implementation of the pow() function, libm (m for math). [1] Add the -lm switch to your compiler command line invocation (after all the source file specifications) to do so, e.g.
gcc -o a.out source.c -lm
[1] Alternatively, you could have your own implementation of pow() in a separate translation unit or a library, but you would still have to tell the compiler/linker where to find it.
i am having a macro whose definition runs into around 50 lines and has lot of 'if else' statements. This macro def'n appears in a .h file. I am running 'gdb in TUI mode', but when the execution reaches that macro, the code window goes blank and returns back only after the macro code gets executed. I want to see line by line execution of the full macro code. Please let me know how can that be done (one way is to replace the macro with its definition in the code and then recompile it. i don't want to use this option as there are several such macros in my code).
Any help will be greatly appreciated. looking forward to get the solution for this problem. Please let me know if there is some other way for this issue rather than the usage of preprocessed file ? i am having a code which runs into several hundred .c & .h files.
One option is to fully preprocess your C file, expanding all macros in it, and then compile the resulting preprocessed file.
For example, consider this simple C program:
// file: prep.c
#include <stdio.h>
#define MY_BIG_MACRO \
int i; \
printf("integers from 0 to 9:\n"); \
for (i = 0; i < 10; i++) \
printf("%d ", i); \
printf("\n");
int main(void)
{
MY_BIG_MACRO
return 0;
}
Compile it, saving the temporary files (including the preprocessed source code):
gcc -Wall -O2 -g -std=c99 prep.c -o prep.exe -save-temps
This should give you a preprocessed version of prep.c, prep.i (shortened for brevity):
# 1 "prep.c"
# 1 "C:\\MinGW\\msys\\1.0\\home\\Alex//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "prep.c"
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.6.2/../../../../include/stdio.h" 1 3
...
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (const wchar_t * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list);
# 3 "prep.c" 2
# 11 "prep.c"
int main(void)
{
int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) printf("%d ", i); printf("\n");
return 0;
}
Now you want to get rid of the #-lines. One way or another, if they are left in, they will affect the debug info. Surprisingly, that means that the macro won't appear expanded in gdb.
Thankfully, grep can help (I'm not a grep pro, so check whether the params are correct, but they seem to work for me on Windows with MinGW x86):
grep ^[^\#].*$ prep.i > prepi.c
This will give you a stripped version of prep.i in prepi.c:
typedef unsigned int size_t;
typedef short unsigned int wchar_t;
typedef short unsigned int wint_t;
...
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (const wchar_t * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list);
int main(void)
{
int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) printf("%d ", i); printf("\n");
return 0;
}
Now you can compile it:
gcc -Wall -O2 -g -std=c99 prepi.c -o prepi.exe
And run it in gdb:
gdb prepi.exe
Issue the following commands:
b main
r
l
This will execute the app until main() and list the source code related to the reached breakpoint:
(gdb) b main
Breakpoint 1 at 0x40643f: file prepi.c, line 184.
(gdb) r
Starting program: C:\MinGW\msys\1.0\home\Alex\prepi.exe
[New Thread 7340.0x20c4]
Breakpoint 1, main () at prepi.c:184
184 int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) pri
ntf("%d ", i); printf("\n");
(gdb) l
179 const wchar_t * __restrict__, __gnuc_va_list);
180 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (c
onst wchar_t * __restrict__,
181 const wchar_t * __restrict__, __gnuc_va_list);
182 int main(void)
183 {
184 int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) pri
ntf("%d ", i); printf("\n");
185 return 0;
186 }
(gdb)
As you can see, the macro body is now in the plain view.
One small problem here is that multi-line macros (those continued with \) are expanded into a single line. I haven't found an option to expand them into multiple lines, but you can do that manually.
"One does not simply step into macros."
You still have a few options:
Use the preprocessor, as #WhozCraig recommended.
For a little less code bloat, convert your macros to functions and re-compile.
If you absolutely don't want to recompile and you're comfortable with assembly code you can use stepi to execute your macro one machine instruction at a time.
If all the above does not work, really you should go back to using printf/fprintf within your large macro.
I had to deal with a 300 lines MACRO, burried deep into the library. This was easier than compiling by hand and dealing with post-processed files.
Say in my system in jpeg library:
$ > nm libjpeg.a | grep jpeg_finish_decompress
00000510 T _jpeg_finish_decompress
But in openjpeg library:
$ > nm lib/libopenjpeg.a | grep opj_decode_with_info
00000240 T _opj_decode_with_info#12
The latter has #12 at the end. I guess 12 is the total size of the arguments.
Nevertheless why some symbols have #-ending?
The question arises when I tried to compile mupdf library. It links ok against jpeg
library for example but fails to link agains openjpeg.
The short answer is name mangling. It is used even for plain c code, not only c++.
Next example is from wikipedia. Next function definitions:
int _cdecl f (int x) { return 0; }
int _stdcall g (int y) { return 0; }
int _fastcall h (int z) { return 0; }
give these symbols:
_f
_g#4
#h#4