Toolchain Knowledge
Our ARM toolchain:
CC := $(GCC_ARM_BASE)arm-none-eabi-gcc
LD := $(GCC_ARM_BASE)arm-none-eabi-gcc
OBJCPY := $(GCC_ARM_BASE)arm-none-eabi-objcopy
OBJDUMP := $(GCC_ARM_BASE)arm-none-eabi-objdump
SIZE := $(GCC_ARM_BASE)arm-none-eabi-size
AR := $(GCC_ARM_BASE)arm-none-eabi-gcc-ar
GDB := $(GCC_ARM_BASE)arm-none-eabi-gdb
OPENOCD := openocd
Our X86 toolchain:
CC := $(COMPILER)
LD := $(COMPILER)
OBJCPY := objcopy
OBJDUMP := objdump
SIZE := size
AR := ar
GDB := gdb
What's a Toolchain?
In software, a toolchain is a set of programming tools that is used to perform a complex software development task or to create a software product, which is typically another computer program or a set of related programs.
A simple software development toolchain may consist of:
- compiler and
- linker (which transform the source code into an executable program),
- libraries (which provide interfaces to the operating system),
- debugger (which is used to test and debug created programs).
Our Toolchain:
The GNU toolchain is a broad collection of programming tools produced by the GNU Project.
- GNU make: an automation tool for compilation and build
- GNU Compiler Collection (GCC): a suite of compilers for several programming languages
- GNU C Library (glibc): core C library including headers, libraries, and dynamic loader
- GNU Binutils: a suite of tools including linker, assembler and other tools
- GNU Bison: a parser generator, often used with the Flex lexical analyser
- GNU m4: an m4 macro processor
- GNU Debugger (GDB): a code debugging tool
- GNU build system (autotools): Autoconf, Automake and Libtool
Playing Around:
Resources:
Preprocessing:
This is where the macros expand, you can see the output of the preprocessing step, just run gcc with the -E option.
#define hello_val 123 #define RETURN_HELLO_VAL(some_arg) \ do { \ return some_arg; \ } while (0) int main(void) { RETURN_HELLO_VAL(hello_val); }
Running gcc hello.c -E
returns something like:
(base) ➜ temp git:(master) ✗ gcc -E hello.c # 1 "hello.c" # 1 "<built-in>" 1 # 1 "<built-in>" 3 # 362 "<built-in>" 3 # 1 "<command line>" 1 # 1 "<built-in>" 2 # 1 "hello.c" 2 int main(void) { do { return 123; } while (0); }
beautiful. Preprocessing works!
Compilation:
It's really just converting your preprocessed C code to assembly. Running gcc -S hello.c
dumps a file named hello.s
which has the following content:
.section __TEXT,__text,regular,pure_instructions .build_version macos, 10, 15 sdk_version 10, 15 .globl _main ## -- Begin function main .p2align 4, 0x90 _main: ## @main .cfi_startproc ## %bb.0: pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset %rbp, -16 movq %rsp, %rbp .cfi_def_cfa_register %rbp movl $0, -4(%rbp) ## %bb.1: movl $123, -4(%rbp) ## %bb.2: movl -4(%rbp), %eax popq %rbp retq .cfi_endproc ## -- End function .subsections_via_symbols
Here's what they mean:
- LOL u thought I'd actually look all that mumbo jumbo up?
Assembly:
Here, your assembly code → object code! (Those .o files!)
doing gcc -c hello.s
gives you: hello.o
To look at it either do hexdump
hello.o
or od -c hello.o
(base) ➜ temp git:(master) ✗ hexdump hello.o 0000000 cf fa ed fe 07 00 00 01 03 00 00 00 01 00 00 00 0000010 04 00 00 00 08 02 00 00 00 20 00 00 00 00 00 00 0000020 19 00 00 00 88 01 00 00 00 00 00 00 00 00 00 00 0000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000040 f0 00 00 00 00 00 00 00 28 02 00 00 00 00 00 00 0000050 f0 00 00 00 00 00 00 00 07 00 00 00 07 00 00 00 0000060 04 00 00 00 00 00 00 00 5f 5f 74 65 78 74 00 00 0000070 00 00 00 00 00 00 00 00 5f 5f 54 45 58 54 00 00 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000090 33 00 00 00 00 00 00 00 28 02 00 00 04 00 00 00 00000a0 18 03 00 00 02 00 00 00 00 04 00 80 00 00 00 00 00000b0 00 00 00 00 00 00 00 00 5f 5f 63 73 74 72 69 6e 00000c0 67 00 00 00 00 00 00 00 5f 5f 54 45 58 54 00 00 00000d0 00 00 00 00 00 00 00 00 33 00 00 00 00 00 00 00 00000e0 13 00 00 00 00 00 00 00 5b 02 00 00 00 00 00 00 00000f0 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 0000100 00 00 00 00 00 00 00 00 5f 5f 63 6f 6d 70 61 63 0000110 74 5f 75 6e 77 69 6e 64 5f 5f 4c 44 00 00 00 00 0000120 00 00 00 00 00 00 00 00 48 00 00 00 00 00 00 00 0000130 40 00 00 00 00 00 00 00 70 02 00 00 03 00 00 00 0000140 28 03 00 00 02 00 00 00 00 00 00 02 00 00 00 00 0000150 00 00 00 00 00 00 00 00 5f 5f 65 68 5f 66 72 61 0000160 6d 65 00 00 00 00 00 00 5f 5f 54 45 58 54 00 00 0000170 00 00 00 00 00 00 00 00 88 00 00 00 00 00 00 00 0000180 68 00 00 00 00 00 00 00 b0 02 00 00 03 00 00 00 0000190 00 00 00 00 00 00 00 00 0b 00 00 68 00 00 00 00 00001a0 00 00 00 00 00 00 00 00 32 00 00 00 18 00 00 00 00001b0 01 00 00 00 00 0f 0a 00 00 0f 0a 00 00 00 00 00 00001c0 02 00 00 00 18 00 00 00 38 03 00 00 03 00 00 00 00001d0 68 03 00 00 20 00 00 00 0b 00 00 00 50 00 00 00 00001e0 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00001f0 02 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 0000200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000220 00 00 00 00 00 00 00 00 55 48 89 e5 89 7d fc 8b 0000230 45 fc 5d c3 0f 1f 40 00 55 48 89 e5 48 83 ec 10 0000240 48 8d 3d 14 00 00 00 b0 00 e8 00 00 00 00 31 c9 0000250 89 45 fc 89 c8 48 83 c4 10 5d c3 48 65 6c 6c 6f 0000260 20 68 68 72 6c 64 68 65 6c 6c 6f 21 0a 00 00 00 0000270 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 01 0000280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000290 10 00 00 00 00 00 00 00 23 00 00 00 00 00 00 01 00002a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00002b0 14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01 00002c0 10 0c 07 08 90 01 00 00 24 00 00 00 1c 00 00 00 00002d0 58 ff ff ff ff ff ff ff 0c 00 00 00 00 00 00 00 00002e0 00 41 0e 10 86 02 43 0d 06 00 00 00 00 00 00 00 00002f0 24 00 00 00 44 00 00 00 40 ff ff ff ff ff ff ff 0000300 23 00 00 00 00 00 00 00 00 41 0e 10 86 02 43 0d 0000310 06 00 00 00 00 00 00 00 22 00 00 00 02 00 00 2d 0000320 1b 00 00 00 02 00 00 15 20 00 00 00 01 00 00 06 0000330 00 00 00 00 01 00 00 06 07 00 00 00 0f 01 00 00 0000340 00 00 00 00 00 00 00 00 01 00 00 00 0f 01 00 00 0000350 10 00 00 00 00 00 00 00 17 00 00 00 01 00 00 00 0000360 00 00 00 00 00 00 00 00 00 5f 6d 61 69 6e 00 5f 0000370 61 64 64 5f 61 72 73 68 61 6e 5f 6e 75 6d 00 5f 0000380 70 72 69 6e 74 66 00 00 0000388
Well shit this is just a whole bunch of zeros and ones. A better command that ACTUALLY SHOWS U SOMETHING:
(base) ➜ temp git:(master) ✗ od -c hello.o 0000000 317 372 355 376 \a \0 \0 001 003 \0 \0 \0 001 \0 \0 \0 0000020 004 \0 \0 \0 \b 002 \0 \0 \0 \0 \0 \0 \0 \0 \0 0000040 031 \0 \0 \0 210 001 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 0000060 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 0000100 360 \0 \0 \0 \0 \0 \0 \0 ( 002 \0 \0 \0 \0 \0 \0 0000120 360 \0 \0 \0 \0 \0 \0 \0 \a \0 \0 \0 \a \0 \0 \0 0000140 004 \0 \0 \0 \0 \0 \0 \0 _ _ t e x t \0 \0 0000160 \0 \0 \0 \0 \0 \0 \0 \0 _ _ T E X T \0 \0 0000200 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 0000220 3 \0 \0 \0 \0 \0 \0 \0 ( 002 \0 \0 004 \0 \0 \0 0000240 030 003 \0 \0 002 \0 \0 \0 \0 004 \0 200 \0 \0 \0 \0 0000260 \0 \0 \0 \0 \0 \0 \0 \0 _ _ c s t r i n 0000300 g \0 \0 \0 \0 \0 \0 \0 _ _ T E X T \0 \0 0000320 \0 \0 \0 \0 \0 \0 \0 \0 3 \0 \0 \0 \0 \0 \0 \0 0000340 023 \0 \0 \0 \0 \0 \0 \0 [ 002 \0 \0 \0 \0 \0 \0 0000360 \0 \0 \0 \0 \0 \0 \0 \0 002 \0 \0 \0 \0 \0 \0 \0 0000400 \0 \0 \0 \0 \0 \0 \0 \0 _ _ c o m p a c 0000420 t _ u n w i n d _ _ L D \0 \0 \0 \0 0000440 \0 \0 \0 \0 \0 \0 \0 \0 H \0 \0 \0 \0 \0 \0 \0 0000460 @ \0 \0 \0 \0 \0 \0 \0 p 002 \0 \0 003 \0 \0 \0 0000500 ( 003 \0 \0 002 \0 \0 \0 \0 \0 \0 002 \0 \0 \0 \0 0000520 \0 \0 \0 \0 \0 \0 \0 \0 _ _ e h _ f r a 0000540 m e \0 \0 \0 \0 \0 \0 _ _ T E X T \0 \0 0000560 \0 \0 \0 \0 \0 \0 \0 \0 210 \0 \0 \0 \0 \0 \0 \0 0000600 h \0 \0 \0 \0 \0 \0 \0 260 002 \0 \0 003 \0 \0 \0 0000620 \0 \0 \0 \0 \0 \0 \0 \0 \v \0 \0 h \0 \0 \0 \0 0000640 \0 \0 \0 \0 \0 \0 \0 \0 2 \0 \0 \0 030 \0 \0 \0 0000660 001 \0 \0 \0 \0 017 \n \0 \0 017 \n \0 \0 \0 \0 \0 0000700 002 \0 \0 \0 030 \0 \0 \0 8 003 \0 \0 003 \0 \0 \0 0000720 h 003 \0 \0 \0 \0 \0 \v \0 \0 \0 P \0 \0 \0 0000740 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 002 \0 \0 \0 0000760 002 \0 \0 \0 001 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 0001000 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 * 0001040 \0 \0 \0 \0 \0 \0 \0 \0 U H 211 345 211 } 374 213 0001060 E 374 ] 303 017 037 @ \0 U H 211 345 H 203 354 020 0001100 H 215 = 024 \0 \0 \0 260 \0 350 \0 \0 \0 \0 1 ɉ 0001120 ** E 374 211 310 H 203 304 020 ] 303 H e l l o 0001140 h h r l d h e l l o ! \n \0 \0 \0 0001160 \0 \0 \0 \0 \0 \0 \0 \0 \f \0 \0 \0 \0 \0 \0 001 0001200 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 0001220 020 \0 \0 \0 \0 \0 \0 \0 # \0 \0 \0 \0 \0 \0 001 0001240 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 0001260 024 \0 \0 \0 \0 \0 \0 \0 001 z R \0 001 x 020 001 0001300 020 \f \a \b 220 001 \0 \0 $ \0 \0 \0 034 \0 \0 \0 0001320 X 377 377 377 377 377 377 377 \f \0 \0 \0 \0 \0 \0 \0 0001340 \0 A 016 020 206 002 C \r 006 \0 \0 \0 \0 \0 \0 \0 0001360 $ \0 \0 \0 D \0 \0 \0 @ 377 377 377 377 377 377 377 0001400 # \0 \0 \0 \0 \0 \0 \0 \0 A 016 020 206 002 C \r 0001420 006 \0 \0 \0 \0 \0 \0 \0 " \0 \0 \0 002 \0 \0 - 0001440 033 \0 \0 \0 002 \0 \0 025 \0 \0 \0 001 \0 \0 006 0001460 \0 \0 \0 \0 001 \0 \0 006 \a \0 \0 \0 017 001 \0 \0 0001500 \0 \0 \0 \0 \0 \0 \0 \0 001 \0 \0 \0 017 001 \0 \0 0001520 020 \0 \0 \0 \0 \0 \0 \0 027 \0 \0 \0 001 \0 \0 \0 0001540 \0 \0 \0 \0 \0 \0 \0 \0 \0 _ m a i n \0 _ 0001560 a d d _ a r s h a n _ n u m \0 _ 0001600 p r i n t f \0 \0 0001610 (base) ➜ temp g
OMG! look! we have add_arshan_num which was a function I defined. We can also see the Hello hhrld that my program was printing out.
Linker:
You can just link the program using the -compiler: gcc hello.o -o hello
That'll give you a hello
file that you can execute and it'll say "Hello World!".
But that's boring stuff, imma go more in depth: