<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Can Gulmez</title>
    <description>The latest articles on Forem by Can Gulmez (@cangulmez).</description>
    <link>https://forem.com/cangulmez</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3457100%2F58231770-b49c-45be-a12c-22330682820e.png</url>
      <title>Forem: Can Gulmez</title>
      <link>https://forem.com/cangulmez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/cangulmez"/>
    <language>en</language>
    <item>
      <title>POSIX Shared Memory</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Wed, 08 Apr 2026 12:47:19 +0000</pubDate>
      <link>https://forem.com/cangulmez/posix-shared-memory-1l1n</link>
      <guid>https://forem.com/cangulmez/posix-shared-memory-1l1n</guid>
      <description>&lt;p&gt;POSIX shared memory allows to us to share a mapped region between unrelated processes without needing to create a corresponding  file.&lt;/p&gt;

&lt;p&gt;Linux uses a dedicated &lt;code&gt;tmpfs&lt;/code&gt; file system mounted under the directory &lt;code&gt;/dev/shm&lt;/code&gt;. This file system has kernel persistance - the shared memory objects that it contains will persists even if no process currently has them open, but they will be lost if the system is shut down.&lt;/p&gt;

&lt;p&gt;To use a POSIX shared memory object, we perform two steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use the &lt;code&gt;shm_open()&lt;/code&gt; function to open an object with a specified name. The &lt;code&gt;shm_open()&lt;/code&gt; function is analogous to the &lt;code&gt;open()&lt;/code&gt; system call. It either creates a new shared memory object or opens an existing object. As its function result, &lt;code&gt;shm_open()&lt;/code&gt; returns a file descriptor referring to the object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pass the file descriptor obtained in the previous step in a call to &lt;code&gt;mmap()&lt;/code&gt; that specifies &lt;code&gt;MAP_SHARED&lt;/code&gt; in the flags argument. This maps the shared memory object into the process's virtual address space.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/mman.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/stat.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;        /* For mode constants */&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;           /* For O_* constants */&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;shm_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;oflag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode_t&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;shm_unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;name&lt;/code&gt; argument identifies the shared memory object to be created or opened. The &lt;code&gt;oflags&lt;/code&gt; argument is a mask of bits of O_* as being in &lt;code&gt;open()&lt;/code&gt; system call.&lt;/p&gt;

&lt;p&gt;At any point, we can apply &lt;code&gt;fstat()&lt;/code&gt; to the file descriptor returned by &lt;code&gt;shm_open()&lt;/code&gt; in order to obtain a &lt;code&gt;stat&lt;/code&gt; structure whose contain information about the shared memory object.&lt;/p&gt;

&lt;p&gt;Example of creating a POSIX shared memory is &lt;a href="https://github.com/CanGulmez/Linux-Programming-Interface/blob/main/pshm/pshm_create.c" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After created the memory object, we of course want to read and write the data into that. Data reading program is &lt;a href="https://github.com/CanGulmez/Linux-Programming-Interface/blob/main/pshm/pshm_write.c" rel="noopener noreferrer"&gt;here&lt;/a&gt; and writing program is &lt;a href="https://github.com/CanGulmez/Linux-Programming-Interface/blob/main/pshm/pshm_read.c" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;SUSv3 requires that POSIX shared memory objects have at least kernel persistence; that is, they continue to exist until they are explicitly removed or the system is rebooted. When a shared memory object is no longer required, it should be removed using &lt;code&gt;shm_unlink()&lt;/code&gt;. The example program of its usage is &lt;a href="https://github.com/CanGulmez/Linux-Programming-Interface/blob/main/pshm/pshm_unlink.c" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In summary, a POSIX shared memory object is used to share a region of memory between unrelated processes without creating an underlying disk file. To do this, we replace the call to &lt;code&gt;open()&lt;/code&gt; that normally precedes &lt;code&gt;mmap()&lt;/code&gt; with a call to &lt;code&gt;shm_open()&lt;/code&gt;. The &lt;code&gt;shm_open()&lt;/code&gt; call creates a file in a memory-based file system, and we can employ traditional file descriptor system calls to perform various operations on this virtual file. In particular, &lt;code&gt;ftruncate()&lt;/code&gt; must be used to set the size of the shared memory object, since initially it has a length of zero.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>lowcode</category>
      <category>gnu</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Flashing and Debugging A Firmware in Detail</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Tue, 10 Mar 2026 20:38:32 +0000</pubDate>
      <link>https://forem.com/cangulmez/flashing-and-debugging-a-firmware-in-detail-d3f</link>
      <guid>https://forem.com/cangulmez/flashing-and-debugging-a-firmware-in-detail-d3f</guid>
      <description>&lt;p&gt;In this tutorial, I will inspect, flash and debug a firmware written for STM32F446RE microcontroller. To accomplish this, we need some dedicated tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;openocd&lt;/li&gt;
&lt;li&gt;arm-none-eabi-*&lt;/li&gt;
&lt;li&gt;gdb-multiarch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;openocd is the primarily tool that we have to get. It's used as bridge between your host machine and debugger hardware. (I'm using use ST-Link hardware in this time). I will use it to connect to the debugger hardware. arm-none-eabi-* tools are the ARM toolchain   used in development of the firmware. gdb-multiarch is the debugger too.&lt;/p&gt;

&lt;p&gt;You can get these tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;openocd gcc-arm-none-eabi gdb-multiarch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: I'm on Ubuntu 24.04, gcc-arm-none-eabi tools don't include the gdb debugger like arm-none-eabi-gdb. So that gdb-multiarch is being installed externally. On some distribution, the gdb debugger comes with gcc-arm-none-eabi.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Suppose that I have a firmware called "firmware.elf" and wanna inspect it as first step. &lt;/p&gt;

&lt;p&gt;The first thing that you should do probably is to determine the firmware itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;file firmware.elf
&lt;span class="go"&gt;firmware.elf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;file&lt;/em&gt; command simply outputs the firmware properties like the endiannes, architecture, or so on. You can see easily that this firmware was written for 32-bit ARM Cortex.&lt;/p&gt;

&lt;p&gt;We can see also the section sizes (in bytes) of the firmware with &lt;em&gt;arm-none-eabi-size&lt;/em&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;arm-none-eabi-size firmware.elf
&lt;span class="go"&gt;   text    data     bss     dec     hex filename
   5252      20    1732    7004    1b5c firmware.elf
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are not familiar with sections of the executables, I've wrote many tutorials that explains the ELF executable. You can look at there.&lt;/p&gt;

&lt;p&gt;If you exactly wanna see the contents of the firmware, &lt;em&gt;arm-none-eabi-objdump&lt;/em&gt; is the primarily tool for that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight armasm"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="nb"&gt;arm&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;eabi&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;objdump&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;j&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;text&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;d&lt;/span&gt; &lt;span class="nv"&gt;firmware&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;elf&lt;/span&gt;

&lt;span class="nl"&gt;firmware&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nl"&gt;elf&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;     &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="nv"&gt;format&lt;/span&gt; &lt;span class="nv"&gt;elf32&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;littlearm&lt;/span&gt;


&lt;span class="nl"&gt;Disassembly&lt;/span&gt; &lt;span class="nb"&gt;of&lt;/span&gt; &lt;span class="nv"&gt;section&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;

&lt;span class="err"&gt;(...)&lt;/span&gt;

&lt;span class="nl"&gt;0800079c&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;:&lt;/span&gt;
 &lt;span class="err"&gt;800079&lt;/span&gt;&lt;span class="nb"&gt;c&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;b500&lt;/span&gt;        &lt;span class="nv"&gt;push&lt;/span&gt;    &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;lr&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
 &lt;span class="err"&gt;800079&lt;/span&gt;&lt;span class="nb"&gt;e&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;b091&lt;/span&gt;        &lt;span class="nv"&gt;sub&lt;/span&gt; &lt;span class="nv"&gt;sp&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt; &lt;span class="no"&gt;@&lt;/span&gt; &lt;span class="mh"&gt;0x44&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;a0&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f000&lt;/span&gt; &lt;span class="nv"&gt;f8ac&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;80008&lt;/span&gt;&lt;span class="nv"&gt;fc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;HAL_Init&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;a4&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f000&lt;/span&gt; &lt;span class="nv"&gt;f82c&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;8000800&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;configOscClk&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;a8&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f000&lt;/span&gt; &lt;span class="nv"&gt;f844&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;8000834&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;configDebugPort&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;ac&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4911&lt;/span&gt;        &lt;span class="nv"&gt;ldr&lt;/span&gt; &lt;span class="nv"&gt;r1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;   &lt;span class="no"&gt;@&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80007&lt;/span&gt;&lt;span class="nv"&gt;f4&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x58&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;)&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;ae&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="nv"&gt;d12&lt;/span&gt;        &lt;span class="nv"&gt;ldr&lt;/span&gt; &lt;span class="nv"&gt;r5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;   &lt;span class="no"&gt;@&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80007&lt;/span&gt;&lt;span class="nv"&gt;f8&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x5c&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;)&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;b0&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="nv"&gt;c12&lt;/span&gt;        &lt;span class="nv"&gt;ldr&lt;/span&gt; &lt;span class="nv"&gt;r4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;   &lt;span class="no"&gt;@&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80007&lt;/span&gt;&lt;span class="nv"&gt;fc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x60&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;)&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;b2&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4668&lt;/span&gt;        &lt;span class="nv"&gt;mov&lt;/span&gt; &lt;span class="nv"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;sp&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;b4&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f7ff&lt;/span&gt; &lt;span class="nv"&gt;ff08&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;80005&lt;/span&gt;&lt;span class="nv"&gt;c8&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;strcpy&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;b8&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4668&lt;/span&gt;        &lt;span class="nv"&gt;mov&lt;/span&gt; &lt;span class="nv"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;sp&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;ba&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f7ff&lt;/span&gt; &lt;span class="nv"&gt;ff81&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;80006&lt;/span&gt;&lt;span class="nv"&gt;c0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;strlen&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;be&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f04f&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="nv"&gt;ff&lt;/span&gt;   &lt;span class="nv"&gt;mov&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;w&lt;/span&gt;   &lt;span class="nv"&gt;r3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;4294967295&lt;/span&gt; &lt;span class="no"&gt;@&lt;/span&gt; &lt;span class="mh"&gt;0xffffffff&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;c2&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;b282&lt;/span&gt;        &lt;span class="nv"&gt;uxth&lt;/span&gt;    &lt;span class="nv"&gt;r2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;r0&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;c4&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4669&lt;/span&gt;        &lt;span class="nv"&gt;mov&lt;/span&gt; &lt;span class="nv"&gt;r1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;sp&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;c6&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;480&lt;/span&gt;&lt;span class="nv"&gt;d&lt;/span&gt;        &lt;span class="nv"&gt;ldr&lt;/span&gt; &lt;span class="nv"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pc&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;   &lt;span class="no"&gt;@&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80007&lt;/span&gt;&lt;span class="nv"&gt;fc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x60&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;)&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;c8&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f000&lt;/span&gt; &lt;span class="nv"&gt;fdc2&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;8001350&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;cc&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4629&lt;/span&gt;        &lt;span class="nv"&gt;mov&lt;/span&gt; &lt;span class="nv"&gt;r1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;r5&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;ce&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4668&lt;/span&gt;        &lt;span class="nv"&gt;mov&lt;/span&gt; &lt;span class="nv"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;sp&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;d0&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f7ff&lt;/span&gt; &lt;span class="nv"&gt;fefa&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;80005&lt;/span&gt;&lt;span class="nv"&gt;c8&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;strcpy&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;d4&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4668&lt;/span&gt;        &lt;span class="nv"&gt;mov&lt;/span&gt; &lt;span class="nv"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;sp&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;d6&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f7ff&lt;/span&gt; &lt;span class="nv"&gt;ff73&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;80006&lt;/span&gt;&lt;span class="nv"&gt;c0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;strlen&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;da&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f04f&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="nv"&gt;ff&lt;/span&gt;   &lt;span class="nv"&gt;mov&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;w&lt;/span&gt;   &lt;span class="nv"&gt;r3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;4294967295&lt;/span&gt; &lt;span class="no"&gt;@&lt;/span&gt; &lt;span class="mh"&gt;0xffffffff&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;de&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;b282&lt;/span&gt;        &lt;span class="nv"&gt;uxth&lt;/span&gt;    &lt;span class="nv"&gt;r2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;r0&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;e0&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4669&lt;/span&gt;        &lt;span class="nv"&gt;mov&lt;/span&gt; &lt;span class="nv"&gt;r1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;sp&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;e2&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;4620&lt;/span&gt;        &lt;span class="nv"&gt;mov&lt;/span&gt; &lt;span class="nv"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;r4&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;e4&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f000&lt;/span&gt; &lt;span class="nv"&gt;fdb4&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;8001350&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;HAL_UART_Transmit&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;e8&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f44f&lt;/span&gt; &lt;span class="mi"&gt;707&lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;   &lt;span class="nv"&gt;mov&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;w&lt;/span&gt;   &lt;span class="nv"&gt;r0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;   &lt;span class="no"&gt;@&lt;/span&gt; &lt;span class="mh"&gt;0x3e8&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;ec&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;f000&lt;/span&gt; &lt;span class="nv"&gt;f8b2&lt;/span&gt;   &lt;span class="nv"&gt;bl&lt;/span&gt;  &lt;span class="mi"&gt;8000954&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;HAL_Delay&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;f0&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;e7ec&lt;/span&gt;        &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;n&lt;/span&gt; &lt;span class="mi"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;cc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x30&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;f2&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="nv"&gt;bf00&lt;/span&gt;        &lt;span class="nv"&gt;nop&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;f4&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;0800146&lt;/span&gt;&lt;span class="nv"&gt;c&lt;/span&gt;    &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;   &lt;span class="mh"&gt;0x0800146c&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;f8&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;08001489&lt;/span&gt;    &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;   &lt;span class="mh"&gt;0x08001489&lt;/span&gt;
 &lt;span class="err"&gt;80007&lt;/span&gt;&lt;span class="nb"&gt;fc&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;   &lt;span class="mi"&gt;20000084&lt;/span&gt;    &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;   &lt;span class="mh"&gt;0x20000084&lt;/span&gt;

&lt;span class="err"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, you see the &lt;em&gt;main()&lt;/em&gt; function in &lt;em&gt;.text&lt;/em&gt; section of the firmware. At left, the address of the machine code were being displayed. At center, you see the machine code corresponding to assembly instructions that is at right side.&lt;/p&gt;

&lt;p&gt;Inspecting the contents of ELF executable is huge topic. It has many variants and view-of-points in there.&lt;/p&gt;

&lt;p&gt;"Flashing" term means writing the dedicated sections of the firmware into the flash memory area of the microcontroller. It's done with many different ways. But I will show you openocd tool.&lt;/p&gt;

&lt;p&gt;In here, I have to define that how exactly does openocd work. It actually creates a server into the host machine with given configuration files. After starting the server session, you need to connect to that server over telnet or gdb. &lt;/p&gt;

&lt;p&gt;Let's do it. Firstly, connect the microcontroller to the host machine. Then open a terminal session and type this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;openocd &lt;span class="nt"&gt;-f&lt;/span&gt; interface/stlink.cfg &lt;span class="nt"&gt;-f&lt;/span&gt; target/stm32f4x.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, I gave the two configuration files. First is the interface. As I said, I use the ST-Link connection. Second is the target file. It defines the target architecture. The openocd comes a bunch of configuration files. So search it and find the appropriate configuration files.&lt;/p&gt;

&lt;p&gt;You will see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
&lt;/span&gt;&lt;span class="gp"&gt;Info : auto-selecting first available session transport "hla_swd". To override use 'transport select &amp;lt;transport&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'.
&lt;/span&gt;&lt;span class="go"&gt;Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 2000 kHz
Info : STLINK V2J33M25 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.224656
Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The openocd attached the 4444 port to telnet and 3333 port to gdb. So that I will bind the 3333 port in the gdb session.&lt;/p&gt;

&lt;p&gt;Secondly, open the second terminal and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gdb-multiarch firmware.elf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the moment, you are in the gdb session. In here, bind to the 3333 port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;(gdb) target remote localhost:3333
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For now, you are in the control and responsible for the all flashing and debugging operations.&lt;/p&gt;

&lt;p&gt;To flash the firmware, use these commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;(gdb) monitor reset halt
(gdb) load
(gdb) monitor reset halt
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are tons of commands you can type in the gdb session. We can split these commands in two categories. &lt;em&gt;monitor &lt;/em&gt; commands directly are run by the openocd command. Other commands are run by the gdb itself.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;load&lt;/em&gt; is the main command to flash the firmware. Before and after that command, resetting and halting the CPU execution is good practice. Output will be like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Loading section .isr_vector, size 0x1c4 lma 0x8000000
Loading section .text, size 0x126c lma 0x8000200
Loading section .rodata, size 0x4c lma 0x800146c
Loading section .ARM, size 0x8 lma 0x80014b8
Loading section .init_array, size 0x4 lma 0x80014c0
Loading section .fini_array, size 0x4 lma 0x80014c4
Loading section .data, size 0xc lma 0x80014c8
Start address 0x08001400, load size 5272
Transfer rate: 9 KB/sec, 753 bytes/write.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means that the firmware successfully was flashed 🥳.&lt;/p&gt;

&lt;p&gt;If you just wanna flash the firmware and not debugging, this following command is enough:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;openocd &lt;span class="nt"&gt;-f&lt;/span&gt; interface/stlink.cfg &lt;span class="nt"&gt;-f&lt;/span&gt; target/stm32f4x.cfg &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"program firmware.elf verify reset exit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of dealing with two terminal sessions, above command is just the one-step operation.&lt;/p&gt;

&lt;p&gt;The main reason opening the second gdb session is to make the debugging. If you did the debugging previously, you will be familiar with these commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;(gdb) break main
(gdb) continue
(gdb) next
(gdb) finish
(gdb) print var
(gdb) x/16wx *ptr
(gdb) set var
(gdb) list
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The debugging operations are huge and will not fit into a single tutorial as you guest. So that I don't wanna dive into the these and other operations. But I wanna give you a good reference: &lt;em&gt;The Art of Debugging with GDB, DDD, and Eclipse&lt;/em&gt; written by Norman Matloff and Peter Jay Salzman.&lt;/p&gt;

&lt;p&gt;Until here, I gave a overall explanation the end-to-end pipeline. I'll explain the other stuffs in further. &lt;/p&gt;

</description>
      <category>lowcode</category>
      <category>c</category>
      <category>linux</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Simple Code Injection into ELF Executable</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Tue, 03 Mar 2026 12:44:18 +0000</pubDate>
      <link>https://forem.com/cangulmez/simple-code-injection-into-elf-executable-2i2o</link>
      <guid>https://forem.com/cangulmez/simple-code-injection-into-elf-executable-2i2o</guid>
      <description>&lt;p&gt;In this tutorial, I will explain an code injection technique into ELF executable.&lt;/p&gt;

&lt;p&gt;Firstly, you need to understand the ELF executable, its contents, sections, symbol table or so on. I've written a dedicated article previously. So if you don't have any information about ELF, please read it firstly and then come here again.&lt;/p&gt;

&lt;p&gt;Let's say we have the following source file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Simple Code Injection
 */&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"#%d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compile this source file and then run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gcc main.c &lt;span class="nt"&gt;-o&lt;/span&gt; main &lt;span class="p"&gt;;&lt;/span&gt; ./main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you will see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#0
#1
#2
#3
#4
#5
#6
#7
#8
#9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, I will change the &lt;em&gt;num = 10&lt;/em&gt; to &lt;em&gt;num = 5&lt;/em&gt; so that the output will be #0 to #4. &lt;/p&gt;

&lt;p&gt;To accomplish this, I need to find the corresponding machine instruction/s. According to your background, you need to know that &lt;em&gt;num&lt;/em&gt; variable will be in the &lt;em&gt;.text&lt;/em&gt; section of ELF executable. Because it is the local variable. To display the .text section of the program, &lt;em&gt;objdump&lt;/em&gt; is the primarily tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;objdump &lt;span class="nt"&gt;-j&lt;/span&gt; .text &lt;span class="nt"&gt;-d&lt;/span&gt; main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be as following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nasm"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="err"&gt;0000000000001149&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="err"&gt;1149&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="nf"&gt;f3&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nv"&gt;e&lt;/span&gt; &lt;span class="nv"&gt;fa&lt;/span&gt;             &lt;span class="nv"&gt;endbr64&lt;/span&gt;
    &lt;span class="err"&gt;114&lt;/span&gt;&lt;span class="nl"&gt;d:&lt;/span&gt;   &lt;span class="err"&gt;55&lt;/span&gt;                      &lt;span class="nf"&gt;push&lt;/span&gt;   &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;
    &lt;span class="err"&gt;114&lt;/span&gt;&lt;span class="nl"&gt;e:&lt;/span&gt;   &lt;span class="err"&gt;48&lt;/span&gt; &lt;span class="err"&gt;89&lt;/span&gt; &lt;span class="nf"&gt;e5&lt;/span&gt;                &lt;span class="nv"&gt;mov&lt;/span&gt;    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;
    &lt;span class="err"&gt;1151&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="err"&gt;48&lt;/span&gt; &lt;span class="err"&gt;83&lt;/span&gt; &lt;span class="nf"&gt;ec&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;             &lt;span class="nv"&gt;sub&lt;/span&gt;    &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rsp&lt;/span&gt;
    &lt;span class="err"&gt;1155&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="err"&gt;89&lt;/span&gt; &lt;span class="err"&gt;7&lt;/span&gt;&lt;span class="nf"&gt;d&lt;/span&gt; &lt;span class="nv"&gt;ec&lt;/span&gt;                &lt;span class="nv"&gt;mov&lt;/span&gt;    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;edi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x14&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;1158&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="err"&gt;48&lt;/span&gt; &lt;span class="err"&gt;89&lt;/span&gt; &lt;span class="err"&gt;75&lt;/span&gt; &lt;span class="nf"&gt;e0&lt;/span&gt;             &lt;span class="nv"&gt;mov&lt;/span&gt;    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x20&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;115&lt;/span&gt;&lt;span class="nl"&gt;c:&lt;/span&gt;   &lt;span class="nf"&gt;c7&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="nv"&gt;fc&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt;    &lt;span class="nv"&gt;movl&lt;/span&gt;   &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;1163&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="nf"&gt;c7&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="nv"&gt;f8&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt;    &lt;span class="nv"&gt;movl&lt;/span&gt;   &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;116&lt;/span&gt;&lt;span class="nl"&gt;a:&lt;/span&gt;   &lt;span class="nf"&gt;eb&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nv"&gt;d&lt;/span&gt;                   &lt;span class="nv"&gt;jmp&lt;/span&gt;    &lt;span class="mi"&gt;1189&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="err"&gt;116&lt;/span&gt;&lt;span class="nl"&gt;c:&lt;/span&gt;   &lt;span class="err"&gt;8&lt;/span&gt;&lt;span class="nf"&gt;b&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="nv"&gt;f8&lt;/span&gt;                &lt;span class="nv"&gt;mov&lt;/span&gt;    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
    &lt;span class="err"&gt;116&lt;/span&gt;&lt;span class="nl"&gt;f:&lt;/span&gt;   &lt;span class="err"&gt;89&lt;/span&gt; &lt;span class="nf"&gt;c6&lt;/span&gt;                   &lt;span class="nv"&gt;mov&lt;/span&gt;    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;esi&lt;/span&gt;
    &lt;span class="err"&gt;1171&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="err"&gt;48&lt;/span&gt; &lt;span class="err"&gt;8&lt;/span&gt;&lt;span class="nf"&gt;d&lt;/span&gt; &lt;span class="mi"&gt;05&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nv"&gt;c&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nv"&gt;e&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt;    &lt;span class="nv"&gt;lea&lt;/span&gt;    &lt;span class="mh"&gt;0xe8c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nv"&gt;rip&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="mi"&gt;2004&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;_IO_stdin_used&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="err"&gt;1178&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="err"&gt;48&lt;/span&gt; &lt;span class="err"&gt;89&lt;/span&gt; &lt;span class="nf"&gt;c7&lt;/span&gt;                &lt;span class="nv"&gt;mov&lt;/span&gt;    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
    &lt;span class="err"&gt;117&lt;/span&gt;&lt;span class="nl"&gt;b:&lt;/span&gt;   &lt;span class="nf"&gt;b8&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt;          &lt;span class="nv"&gt;mov&lt;/span&gt;    &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
    &lt;span class="err"&gt;1180&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="nf"&gt;e8&lt;/span&gt; &lt;span class="nv"&gt;cb&lt;/span&gt; &lt;span class="nv"&gt;fe&lt;/span&gt; &lt;span class="nv"&gt;ff&lt;/span&gt; &lt;span class="nv"&gt;ff&lt;/span&gt;          &lt;span class="nv"&gt;call&lt;/span&gt;   &lt;span class="mi"&gt;1050&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;printf@plt&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="err"&gt;1185&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="err"&gt;83&lt;/span&gt; &lt;span class="err"&gt;45&lt;/span&gt; &lt;span class="nf"&gt;f8&lt;/span&gt; &lt;span class="mi"&gt;01&lt;/span&gt;             &lt;span class="nv"&gt;addl&lt;/span&gt;   &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;1189&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="err"&gt;8&lt;/span&gt;&lt;span class="nf"&gt;b&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="nv"&gt;f8&lt;/span&gt;                &lt;span class="nv"&gt;mov&lt;/span&gt;    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
    &lt;span class="err"&gt;118&lt;/span&gt;&lt;span class="nl"&gt;c:&lt;/span&gt;   &lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="nf"&gt;b&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="nv"&gt;fc&lt;/span&gt;                &lt;span class="nv"&gt;cmp&lt;/span&gt;    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;0x4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
    &lt;span class="err"&gt;118&lt;/span&gt;&lt;span class="nl"&gt;f:&lt;/span&gt;   &lt;span class="err"&gt;7&lt;/span&gt;&lt;span class="nf"&gt;c&lt;/span&gt; &lt;span class="nv"&gt;db&lt;/span&gt;                   &lt;span class="nv"&gt;jl&lt;/span&gt;     &lt;span class="mi"&gt;116&lt;/span&gt;&lt;span class="nv"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x23&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="err"&gt;1191&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="nf"&gt;b8&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="mi"&gt;00&lt;/span&gt;          &lt;span class="nv"&gt;mov&lt;/span&gt;    &lt;span class="kc"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;eax&lt;/span&gt;
    &lt;span class="err"&gt;1196&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="nf"&gt;c9&lt;/span&gt;                      &lt;span class="nv"&gt;leave&lt;/span&gt;
    &lt;span class="err"&gt;1197&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="nf"&gt;c3&lt;/span&gt;                      &lt;span class="nv"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which machine instruction/s corresponds to &lt;em&gt;num = 10&lt;/em&gt;? You need to know reading the assembly instructions in here. The answer is the &lt;strong&gt;movl   $0xa,-0x4(%rbp)&lt;/strong&gt; assembly instruction. Because the stack pointer of the program was enlarged by 4 bytes (&lt;em&gt;int&lt;/em&gt; holds 4 bytes of memory) to lower address and put the immediate 0xA value. So that I need to change the 0xA value to 0x5. &lt;/p&gt;

&lt;p&gt;After the found required assembly instruction, I need to determine the memory address of it. If you look at center column, the machine instruction is &lt;strong&gt;c7 45 fc 0a 00 00 00&lt;/strong&gt;. In here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;c7: the opcode of &lt;em&gt;movl&lt;/em&gt; register&lt;/li&gt;
&lt;li&gt;45 fc: the displacement of -0x4(%rbp)&lt;/li&gt;
&lt;li&gt;0a 00 00 00: the immediate value, 0xA (little-endian)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;c7 byte resides at 0x115c address so that 0a byte at 0x115f.&lt;/p&gt;

&lt;p&gt;To change that byte, I'm gonna use &lt;em&gt;hexedit&lt;/em&gt; program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;hexedit ./main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xykdj3162c4xy1fq0pv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xykdj3162c4xy1fq0pv.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, you move to 0x115F address and change the 0x0A value to 0x05. Save the changes and then run the program again. You will see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#0
#1
#2
#3
#4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. You injected the new code in the ELF executable 🥳. &lt;/p&gt;

&lt;p&gt;This technique is simple and powerful. But there are some limitations. The most important one is that you should not shift the byte addresses, just replace it. If you wanna change the entire ELF executable addresses, you need the other techniques. That's the next article's topic.&lt;/p&gt;

</description>
      <category>c</category>
      <category>lowcode</category>
      <category>computerscience</category>
      <category>linux</category>
    </item>
    <item>
      <title>ELF Executable Analysis in Detail</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Tue, 24 Feb 2026 20:03:28 +0000</pubDate>
      <link>https://forem.com/cangulmez/elf-executable-analysis-in-detail-3p5i</link>
      <guid>https://forem.com/cangulmez/elf-executable-analysis-in-detail-3p5i</guid>
      <description>&lt;p&gt;In everyday, we run some kind of programs to handle our works. There are many type of programs, GUIs, CLIs, TUIs or so on. But at low level, there are two kind of program formats: PE (Portable Executable) for Windows and ELF (Executable and Linkable Format) for Linux. &lt;/p&gt;

&lt;p&gt;In this tutorial, I will explain the ELF executables in detail.&lt;/p&gt;

&lt;p&gt;Firstly, let's start with the overall layout:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcpujvtc64w38ocjvh6zc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcpujvtc64w38ocjvh6zc.png" alt=" " width="387" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you see, an ELF executable consists of four layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Executable Header&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Program Headers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sections&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Section Headers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Executable Header
&lt;/h3&gt;

&lt;p&gt;Every ELF file starts with an &lt;em&gt;executable header&lt;/em&gt;, which is just a structured series of bytes telling you that it's an ELF file, what kind of ELF file it is, and where in the file to find all the other contents. It's defined as follow in /usr/include/elf.h:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdurlu5pmfkinz7utvied.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdurlu5pmfkinz7utvied.png" alt=" " width="589" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;e_ident&lt;/em&gt;: The executable header starts with a 16-byte array. First 4-byte, magic value, identifying the file as an ELF binary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;e_type&lt;/em&gt;: The type of the executable. For example REL means relocatable object file, EXEC means executable binary and DYN means dynamic libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;e_machine&lt;/em&gt;: The architecture that the executable is intended to run on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;e_version&lt;/em&gt;: The version of the ELF specification (always 1, I really don't know why it exists 😂).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;e_entry&lt;/em&gt;: The virtual address at which execution should start.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;e_phoff&lt;/em&gt;, &lt;em&gt;e_shoff&lt;/em&gt;: The file offsets to the beginning of the program header table and the section header table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;e_flags&lt;/em&gt;: The flags specific to the architecture for which the binary is compiled (typically 0 for x86_64).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;e_ehsize&lt;/em&gt;: The size of the executable header, in bytes (for 64-bit systems, it's always 64).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see the executable header with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ readelf -h ./prog
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1400
  Start of program headers:          64 (bytes into file)
  Start of section headers:          135496 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         29
  Section header string table index: 28
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Section Headers
&lt;/h3&gt;

&lt;p&gt;The code and data in an ELF binary are logically divided into continuous nonoverlapping chunks called &lt;strong&gt;section&lt;/strong&gt;s. Sections don't have any predetermined structure; instead, the structure of each section varies depending on the contents. So every section is described in &lt;em&gt;section header table&lt;/em&gt;. It's defined as follow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrorlbmbp2grio4ulyfa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrorlbmbp2grio4ulyfa.png" alt=" " width="582" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;sh_name&lt;/em&gt;: The index of the sections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;sh_type&lt;/em&gt;: Every section has a type, indicated by an integer field. Common types: PROBITS for machine instructions, SYMTAB for static symbol table, DYNSYM for dynamic symbol table, STRTAB for string tables, REL(A) for relocation entries used by the linker, DYNAMIC for information needed for dynamic linking or so on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;sh_flags&lt;/em&gt;: The section flags. Common flags: W means the section is writable, A means the content of the section are to be loaded into memory when executing the executable, X means the section is executable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;sh_addr, sh_offset, sh_size&lt;/em&gt;: The virtual address, file offset (in bytes from the start&lt;br&gt;
of the file), and size (in bytes) of the sections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;sh_link&lt;/em&gt;: Sometimes, there are relationships between sections. This field keeps the index count of the related sections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;sh_info&lt;/em&gt;: Additional information about sections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;sh_addralign&lt;/em&gt;: Some sections may need to be aligned in memory in a particular way for efficiency of memory accesses. The values 0 and 1 are reserved to indicate no special alignment needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;sh_entsize&lt;/em&gt;: Some sections contain a table of well-defined data structures. For such sections, this field indicates the size in bytes of each entry in the table. When the field is unused, it is set to zero.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see the section headers with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ readelf --sections --wide ./prog
There are 29 section headers, starting at offset 0x21148:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000000318 000318 00001c 00   A  0   0  1
  [ 2] .note.gnu.property NOTE            0000000000000338 000338 000030 00   A  0   0  8
  [ 3] .note.gnu.build-id NOTE            0000000000000368 000368 000024 00   A  0   0  4
  [ 4] .note.ABI-tag     NOTE            000000000000038c 00038c 000020 00   A  0   0  4
  [ 5] .gnu.hash         GNU_HASH        00000000000003b0 0003b0 000028 00   A  6   0  8
  [ 6] .dynsym           DYNSYM          00000000000003d8 0003d8 000378 18   A  7   1  8
  [ 7] .dynstr           STRTAB          0000000000000750 000750 00016d 00   A  0   0  1
  [ 8] .gnu.version      VERSYM          00000000000008be 0008be 00004a 02   A  6   0  2
  [ 9] .gnu.version_r    VERNEED         0000000000000908 000908 000080 00   A  7   2  8
  [10] .rela.dyn         RELA            0000000000000988 000988 0000d8 18   A  6   0  8
  [11] .rela.plt         RELA            0000000000000a60 000a60 0002d0 18  AI  6  24  8
  [12] .init             PROGBITS        0000000000001000 001000 00001b 00  AX  0   0  4
  [13] .plt              PROGBITS        0000000000001020 001020 0001f0 10  AX  0   0 16
  [14] .plt.got          PROGBITS        0000000000001210 001210 000010 10  AX  0   0 16
  [15] .plt.sec          PROGBITS        0000000000001220 001220 0001e0 10  AX  0   0 16
  [16] .text             PROGBITS        0000000000001400 001400 018c54 00  AX  0   0 16
  [17] .fini             PROGBITS        000000000001a054 01a054 00000d 00  AX  0   0  4
  [18] .rodata           PROGBITS        000000000001b000 01b000 002ee8 00   A  0   0 16
  [19] .eh_frame_hdr     PROGBITS        000000000001dee8 01dee8 0005fc 00   A  0   0  4
  [20] .eh_frame         PROGBITS        000000000001e4e8 01e4e8 001914 00   A  0   0  8
  [21] .init_array       INIT_ARRAY      0000000000020cc0 020cc0 000008 08  WA  0   0  8
  [22] .fini_array       FINI_ARRAY      0000000000020cc8 020cc8 000008 08  WA  0   0  8
  [23] .dynamic          DYNAMIC         0000000000020cd0 020cd0 000200 10  WA  7   0  8
  [24] .got              PROGBITS        0000000000020ed0 020ed0 000130 08  WA  0   0  8
  [25] .data             PROGBITS        0000000000021000 021000 000010 00  WA  0   0  8
  [26] .bss              NOBITS          0000000000021020 021010 000010 00  WA  0   0 32
  [27] .comment          PROGBITS        0000000000000000 021010 00002b 01  MS  0   0  1
  [28] .shstrtab         STRTAB          0000000000000000 02103b 00010a 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), l (large), p (processor specific)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sections
&lt;/h3&gt;

&lt;p&gt;In previous chapter, you see that the ELF executable has a set of sections at which each section has a special meaning. For now, let me explain these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;.init and .fini&lt;/em&gt;: The &lt;em&gt;.init&lt;/em&gt; section contains machine code that performs initialization before the &lt;em&gt;main()&lt;/em&gt; function and &lt;em&gt;.fini&lt;/em&gt; runs after it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;.text&lt;/em&gt;: This section is where the main code of the executable resides that we've wrote. It's the main concern for binary analysis or reverse engineering efforts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;.bss, .data, .rodata&lt;/em&gt;: There sections are where the program variables live. According to the declaration style, the variable goes into one of the three sections. For example, &lt;em&gt;initialized&lt;/em&gt; global variables live in &lt;em&gt;.data&lt;/em&gt;, &lt;em&gt;uninitialized&lt;/em&gt; global variables live in &lt;em&gt;.bss&lt;/em&gt; and &lt;em&gt;constant&lt;/em&gt; variables live in &lt;em&gt;.rodata&lt;/em&gt;. Don't forget that the local variables go in the stack, so &lt;em&gt;.text&lt;/em&gt;, not into one of these sections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;.rel.* and .rela.*&lt;/em&gt;: These sections contain the information used by the linker for performing relocations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;.dynamic&lt;/em&gt;: It contains the "road map" for dynamic linker when loading and setting up the ELF executable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As an example, you can inspect a specific section with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ objdump -j .text -d ./prog

./prog:     file format elf64-x86-64

Disassembly of section .text:

0000000000001400 &amp;lt;.text&amp;gt;:
    1400:       f3 0f 1e fa             endbr64
    1404:       31 ed                   xor    %ebp,%ebp
    1406:       49 89 d1                mov    %rdx,%r9
    1409:       5e                      pop    %rsi
    140a:       48 89 e2                mov    %rsp,%rdx
    140d:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
    1411:       50                      push   %rax
    1412:       54                      push   %rsp
    1413:       45 31 c0                xor    %r8d,%r8d
    1416:       31 c9                   xor    %ecx,%ecx
    1418:       48 8d 3d 48 15 00 00    lea    0x1548(%rip),%rdi        # 2967 &amp;lt;rand@plt+0x1577&amp;gt;
    141f:       ff 15 b3 fb 01 00       call   *0x1fbb3(%rip)        # 20fd8 &amp;lt;rand@plt+0x1fbe8&amp;gt;
    1425:       f4                      hlt
    1426:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1)
    142d:       00 00 00 
    1430:       48 8d 3d d9 fb 01 00    lea    0x1fbd9(%rip),%rdi        # 21010 &amp;lt;rand@plt+0x1fc20&amp;gt;
    1437:       48 8d 05 d2 fb 01 00    lea    0x1fbd2(%rip),%rax        # 21010 &amp;lt;rand@plt+0x1fc20&amp;gt;
    143e:       48 39 f8                cmp    %rdi,%rax
    1441:       74 15                   je     1458 &amp;lt;rand@plt+0x68&amp;gt;
    1443:       48 8b 05 96 fb 01 00    mov    0x1fb96(%rip),%rax        # 20fe0 &amp;lt;rand@plt+0x1fbf0&amp;gt;
    144a:       48 85 c0                test   %rax,%rax
    144d:       74 09                   je     1458 &amp;lt;rand@plt+0x68&amp;gt;
    144f:       ff e0                   jmp    *%rax
    1451:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

(...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Program Headers
&lt;/h3&gt;

&lt;p&gt;The program header table provides a &lt;em&gt;segment view&lt;/em&gt; of the binary, as opposed to the &lt;em&gt;section view&lt;/em&gt; provided by the section header table. It's defined as follow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8ju6auuns4gk64up863.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8ju6auuns4gk64up863.png" alt=" " width="453" height="118"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4azsq1vx1s8vi1bos53x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4azsq1vx1s8vi1bos53x.png" alt=" " width="453" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;p_type&lt;/em&gt;: The type of segments. Common types: LOAD means the segment are intended to be loaded into memory, INTERP means the segment contains &lt;em&gt;.interp&lt;/em&gt; section providing name of the interpreter that is to be used to load the executable, DYNAMIC means the segment contains the &lt;em&gt;.dynamic&lt;/em&gt; section, which tells the interpreter how to parse and prepare the binary for execution, PHDR means the segment encompasses the program header table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;p_flags&lt;/em&gt;: The runtime access permissions for the segments. Common flags: X means executable, R means readable, W means writable or so on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;p_offset, p_vaddr, p_paddr, p_filesz, p_memsz&lt;/em&gt;: These equals to &lt;em&gt;sh_offset&lt;/em&gt;, &lt;em&gt;sh_addr&lt;/em&gt;, &lt;em&gt;sh_size&lt;/em&gt; fields in the section headers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;p_align&lt;/em&gt;: It's equal to &lt;em&gt;sh_addralign&lt;/em&gt; field.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see the program headers with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ readelf --segments --wide ./prog

Elf file type is DYN (Position-Independent Executable file)
Entry point 0x1400
There are 13 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000000040 0x0000000000000040 0x0002d8 0x0002d8 R   0x8
  INTERP         0x000318 0x0000000000000318 0x0000000000000318 0x00001c 0x00001c R   0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x000d30 0x000d30 R   0x1000
  LOAD           0x001000 0x0000000000001000 0x0000000000001000 0x019061 0x019061 R E 0x1000
  LOAD           0x01b000 0x000000000001b000 0x000000000001b000 0x004dfc 0x004dfc R   0x1000
  LOAD           0x020cc0 0x0000000000020cc0 0x0000000000020cc0 0x000350 0x000370 RW  0x1000
  DYNAMIC        0x020cd0 0x0000000000020cd0 0x0000000000020cd0 0x000200 0x000200 RW  0x8
  NOTE           0x000338 0x0000000000000338 0x0000000000000338 0x000030 0x000030 R   0x8
  NOTE           0x000368 0x0000000000000368 0x0000000000000368 0x000044 0x000044 R   0x4
  GNU_PROPERTY   0x000338 0x0000000000000338 0x0000000000000338 0x000030 0x000030 R   0x8
  GNU_EH_FRAME   0x01dee8 0x000000000001dee8 0x000000000001dee8 0x0005fc 0x0005fc R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
  GNU_RELRO      0x020cc0 0x0000000000020cc0 0x0000000000020cc0 0x000340 0x000340 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt 
   03     .init .plt .plt.got .plt.sec .text .fini 
   04     .rodata .eh_frame_hdr .eh_frame 
   05     .init_array .fini_array .dynamic .got .data .bss 
   06     .dynamic 
   07     .note.gnu.property 
   08     .note.gnu.build-id .note.ABI-tag 
   09     .note.gnu.property 
   10     .eh_frame_hdr 
   11     
   12     .init_array .fini_array .dynamic .got 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Until here, I gave you the overall, a bit detailed, presentation about the ELF executable. For next articles, I will dive into the binary analysis techniques in deeply for Linux.&lt;/p&gt;

&lt;p&gt;Resource:&lt;/p&gt;

&lt;p&gt;Andriesse D., Practical Binary Analysis, no starch press, San Francisco.&lt;/p&gt;

</description>
      <category>c</category>
      <category>gcc</category>
      <category>lowcode</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>How to build a firmware using Makefile?</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Sun, 21 Dec 2025 12:46:38 +0000</pubDate>
      <link>https://forem.com/cangulmez/how-to-build-a-firmware-using-makefile-3flm</link>
      <guid>https://forem.com/cangulmez/how-to-build-a-firmware-using-makefile-3flm</guid>
      <description>&lt;p&gt;In embedded programming, we trust IDEs like STM32CubeIDE, Keil or so on. These IDEs give us just some buttons and UIs to build, flash, and debug the source code that we've written for a MCU. But, I think that every engineer that works on this field have to know that how these steps are made by hand.&lt;/p&gt;

&lt;p&gt;In this tutorial, I will show building a firmware written for STM32F446RE MCU with just using a single Makefile.&lt;/p&gt;

&lt;p&gt;Below is the project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree
.
├── bin/
├── drivers/
│   ├── CMSIS/
│   ├── STM32F446RETX_FLASH.ld
│   └── STM32F4xx_HAL_Driver/
├── lib/
├── Makefile
└── src/
    ├── it.c
    ├── main.c
    ├── main.h
    └── peripheral.c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firstly, which libraries do we need to have?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;HAL library&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CMSIS library&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linker script&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Startup/system code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;arm-none-eabi-* tools&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've put the all required libraries/scripts into &lt;strong&gt;/drivers&lt;/strong&gt; directory. Please download these using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git clone &lt;span class="nt"&gt;--recurse-submodules&lt;/span&gt; https://github.com/STMicroelectronics/STM32CubeF4.git
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;gcc-arm-none-eabi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, HAL library is used to program the peripherals and CMSIS for ARM-Cortex itself. These are the most important libraries that we have to get. &lt;/p&gt;

&lt;p&gt;Apart from that, we also need some special files. First is the &lt;strong&gt;linker script&lt;/strong&gt;. It includes the memory layout of microcontroller. Sometimes, it comes from above command. But if you cannot find it there, please install it externally. Another file is the &lt;strong&gt;startup code&lt;/strong&gt;. It's written in Assembly language. As its name suggests, it's the first code that runs in microcontroller. Basically, it includes the &lt;strong&gt;Reset_Handler&lt;/strong&gt; and a branch that jumps into &lt;strong&gt;main()&lt;/strong&gt; function in your source code. Also &lt;strong&gt;system code&lt;/strong&gt; includes the some generic and general definitions.&lt;/p&gt;

&lt;p&gt;After downloaded and explained the required ones, Let's write the &lt;strong&gt;Makefile&lt;/strong&gt; step by step:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Toolchain definitions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;CC&lt;/span&gt;              &lt;span class="o"&gt;:=&lt;/span&gt; arm-none-eabi-gcc
&lt;span class="nv"&gt;OBJCOPY&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; arm-none-eabi-objcopy
&lt;span class="nv"&gt;SIZE&lt;/span&gt;            &lt;span class="o"&gt;:=&lt;/span&gt; arm-none-eabi-size
&lt;span class="nv"&gt;RM&lt;/span&gt;              &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;span class="nv"&gt;FILE&lt;/span&gt;            &lt;span class="o"&gt;:=&lt;/span&gt; file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. MCU-specific definitions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;DEVICE_FAMILY&lt;/span&gt;        &lt;span class="o"&gt;:=&lt;/span&gt; STM32F4xx
&lt;span class="nv"&gt;DEVICE_MODEL&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; STM32F446xx
&lt;span class="nv"&gt;DEVICE_VARIANT&lt;/span&gt;       &lt;span class="o"&gt;:=&lt;/span&gt; STM32F446RETx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Compiler and linker flags&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;CORTEX_FLAGS&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nt"&gt;-mthumb&lt;/span&gt; &lt;span class="nt"&gt;-mcpu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;cortex-m4 &lt;span class="nt"&gt;-mfpu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;fpv4-sp-d16 &lt;span class="nt"&gt;-mfloat-abi&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hard
&lt;span class="nv"&gt;COMMON_FLAGS&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nt"&gt;-g3&lt;/span&gt; &lt;span class="nt"&gt;-Os&lt;/span&gt; &lt;span class="nt"&gt;-ffunction-sections&lt;/span&gt; &lt;span class="nt"&gt;-fdata-sections&lt;/span&gt; &lt;span class="nt"&gt;-Wall&lt;/span&gt;
&lt;span class="nv"&gt;AS_FLAGS&lt;/span&gt;             &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nt"&gt;-x&lt;/span&gt; assembler-with-cpp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, we've defined some flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-mthumb&lt;/strong&gt; means that the firmware uses thumb (16-bit) instruction set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-mcpu=cortex-m4&lt;/strong&gt; means the ARM-Cortex series itself.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-mfpu=fpv4-sp-d16&lt;/strong&gt; and &lt;strong&gt;-mfloat-abi=hard&lt;/strong&gt; means that floating-point operations can be done in the firmware.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Include paths&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;MAIN_INC&lt;/span&gt;        &lt;span class="o"&gt;:=&lt;/span&gt; ./src
&lt;span class="nv"&gt;CMSIS_INC&lt;/span&gt;       &lt;span class="o"&gt;:=&lt;/span&gt; ./drivers/CMSIS/Include
&lt;span class="nv"&gt;CMSIS_DEV_INC&lt;/span&gt;   &lt;span class="o"&gt;:=&lt;/span&gt; ./drivers/CMSIS/Device/ST/STM32F4xx/Include
&lt;span class="nv"&gt;HAL_INC&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; ./drivers/STM32F4xx_HAL_Driver/Inc
&lt;span class="nv"&gt;CMSIS_DSP_INC&lt;/span&gt;   &lt;span class="o"&gt;:=&lt;/span&gt; ./drivers/CMSIS/DSP/Include
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, we specified the header files that are used in the source code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Source and special files&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;MAIN_SRC&lt;/span&gt;        &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;wildcard ./src/&lt;span class="k"&gt;*&lt;/span&gt;.c&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;HAL_SRC&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;wildcard ./drivers/STM32F4xx_HAL_Driver/Src/&lt;span class="k"&gt;*&lt;/span&gt;.c&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;SYSTEM_SRC&lt;/span&gt;      &lt;span class="o"&gt;:=&lt;/span&gt; ./drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c
&lt;span class="nv"&gt;STARTUP_CODE&lt;/span&gt;    &lt;span class="o"&gt;:=&lt;/span&gt; ./drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f446xx.S
&lt;span class="nv"&gt;LINKER_SCRIPT&lt;/span&gt;   &lt;span class="o"&gt;:=&lt;/span&gt; ./drivers/STM32F446RETX_FLASH.ld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6. Sorthands and build definitions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;DEFINES&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;DEVICE_FAMILY&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;DEVICE_MODEL&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;DEVICE_VARIANT&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                        &lt;span class="nt"&gt;-DUSE_HAL_DRIVER&lt;/span&gt;

&lt;span class="nv"&gt;SOURCES&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;MAIN_SRC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;HAL_SRC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;SYSTEM_SRC&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;OBJECTS&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;notdir &lt;span class="p"&gt;$(&lt;/span&gt;patsubst %.c,%.o,&lt;span class="p"&gt;$(&lt;/span&gt;SOURCES&lt;span class="p"&gt;)))&lt;/span&gt; startup_stm32f446xx.o
&lt;span class="nv"&gt;INCLUDES&lt;/span&gt;            &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;MAIN_INC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;CMSIS_DEV_INC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;CMSIS_INC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;HAL_INC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                        &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;CMSIS_DSP_INC&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;CFLAGS&lt;/span&gt;          &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;CORTEX_FLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;COMMON_FLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;DEFINES&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;INCLUDES&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;AFLAGS&lt;/span&gt;          &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;CORTEX_FLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;AS_FLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;DEFINES&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;INCLUDES&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;LDFLAGS&lt;/span&gt;         &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;CORTEX_FLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-T&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;LINKER_SCRIPT&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                        &lt;span class="nt"&gt;-Wl&lt;/span&gt;,--gc-sections,--relax &lt;span class="nt"&gt;--specs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nano.specs &lt;span class="nt"&gt;--specs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nosys.specs &lt;span class="se"&gt;\&lt;/span&gt;
                    &lt;span class="nt"&gt;-Wl&lt;/span&gt;,--start-group &lt;span class="nt"&gt;-lc&lt;/span&gt; &lt;span class="nt"&gt;-lm&lt;/span&gt; &lt;span class="nt"&gt;-lnosys&lt;/span&gt; &lt;span class="nt"&gt;-Wl&lt;/span&gt;,--end-group
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, I mostly did the string operations and manipulations. But some points are interesting and need some explanations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Firstly, I've grouped the sources and libraries and converted the source file suffixes into object file formats.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also, I've created three total flags that will be used for compiling, assembling, and linking phases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In linker flags, I put the linker script. As you noticed, this step will be done after the compiling the source files. I also linked the some libraries. &lt;strong&gt;-lc&lt;/strong&gt; is the standard C library. In firmware, we use often string manipulation functions (&lt;strong&gt;strlen()&lt;/strong&gt;, &lt;strong&gt;strcat()&lt;/strong&gt;, &lt;strong&gt;strcpy()&lt;/strong&gt; or so on), &lt;strong&gt;snprint()&lt;/strong&gt;, &lt;strong&gt;memset()&lt;/strong&gt;, or similar ones. &lt;strong&gt;-lm&lt;/strong&gt; is the math library as you know. &lt;strong&gt;-lnosys&lt;/strong&gt; means that I'm just implementing the bare-metal firmware, there is no such as kernel or fully OS.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;7. Output files&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;FIRMWARE_ELF&lt;/span&gt;    &lt;span class="o"&gt;:=&lt;/span&gt; firmware.elf
&lt;span class="nv"&gt;FIRMWARE_BIN&lt;/span&gt;    &lt;span class="o"&gt;:=&lt;/span&gt; firmware.bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generally, we use the ELF file when flashing and debugging. ELF executable includes the both machine code, metadata, debug information, symbol table or similar stuffs. In contrast, BIN executable just includes the machine code. If you look at the size of both, you will use the ELF executable is much bigger! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. The recipe&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;

&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------"&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"----- Building the source files -----"&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------"&lt;/span&gt;
    &lt;span class="p"&gt;@$(&lt;/span&gt;CC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;AFLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;STARTUP_CODE&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;@$(&lt;/span&gt;CC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;CFLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;SOURCES&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"\n------------------------------------"&lt;/span&gt;
    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"----- Linking the object files -----"&lt;/span&gt;
    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"------------------------------------"&lt;/span&gt;
    &lt;span class="err"&gt;@$(CC)&lt;/span&gt; &lt;span class="err"&gt;$(LDFLAGS)&lt;/span&gt; &lt;span class="err"&gt;$(OBJECTS)&lt;/span&gt; &lt;span class="err"&gt;-o&lt;/span&gt; &lt;span class="err"&gt;$(FIRMWARE_ELF)&lt;/span&gt;
    &lt;span class="err"&gt;@$(OBJCOPY)&lt;/span&gt; &lt;span class="err"&gt;-O&lt;/span&gt; &lt;span class="err"&gt;binary&lt;/span&gt; &lt;span class="err"&gt;$(FIRMWARE_ELF)&lt;/span&gt; &lt;span class="err"&gt;$(FIRMWARE_BIN)&lt;/span&gt;
    &lt;span class="err"&gt;@$(RM)&lt;/span&gt; &lt;span class="err"&gt;$(OBJECTS)&lt;/span&gt;

    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"\n-------------------------------------"&lt;/span&gt;
    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"----- The firmware memory usage -----"&lt;/span&gt;
    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------"&lt;/span&gt;
    &lt;span class="err"&gt;@$(SIZE)&lt;/span&gt; &lt;span class="err"&gt;$(FIRMWARE_ELF)&lt;/span&gt;

    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"\n-------------------------------------"&lt;/span&gt;
    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"----- The firmware binary format ----"&lt;/span&gt;
    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------"&lt;/span&gt;
    &lt;span class="err"&gt;@$(FILE)&lt;/span&gt; &lt;span class="err"&gt;$(FIRMWARE_ELF)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, run the Makefile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it 🥳🥳🥳. You've built the both &lt;strong&gt;firmware.elf&lt;/strong&gt; and &lt;strong&gt;firmware.bin&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You are ready to flash the built firmware into microcontroller with this or similar command (over ST-Link connection):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;openocd &lt;span class="nt"&gt;-f&lt;/span&gt; interface/stlink.cfg &lt;span class="nt"&gt;-f&lt;/span&gt; target/stm32f4x.cfg &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"program firmware.elf verify reset exit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>c</category>
      <category>programming</category>
      <category>computerscience</category>
      <category>lowcode</category>
    </item>
    <item>
      <title>What exactly is "program" and what does it include?</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Mon, 08 Dec 2025 14:05:17 +0000</pubDate>
      <link>https://forem.com/cangulmez/what-exactly-is-a-program-and-what-does-it-include-53j3</link>
      <guid>https://forem.com/cangulmez/what-exactly-is-a-program-and-what-does-it-include-53j3</guid>
      <description>&lt;p&gt;In this article, I wanna talk about &lt;strong&gt;program&lt;/strong&gt; and &lt;strong&gt;process&lt;/strong&gt; terms that are fundamental elements in computer-science. This two terms generally are used exchangeably. But in technically, both are so different. Let's begin with explaining these terms and then deeply see the what it includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;program&lt;/strong&gt; is a file containing a range of information that describes how to construct a "process" at run time [1].&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;process&lt;/strong&gt; is an instance of an executing program [1].&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the formal definations. If I try to express with my words:&lt;/p&gt;

&lt;p&gt;A program (or binary) is a file that includes the machine code + metadata + debug information (if the program compiled with -g flag) and process is a abstraction point that kernel creates and then allocates hardware resources like CPU, RAM, memory or similar ones.&lt;/p&gt;

&lt;p&gt;First thing that you should know is the program format. In recently, there are two type of program formats that the compilers generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ELF (Executable and Linkable Format)&lt;/li&gt;
&lt;li&gt;PE (Portable Executable)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Executable and Linkable Format
&lt;/h2&gt;

&lt;p&gt;ELF is the standard format for UNIX/Linux systems and PE for Windows. I'm currently on Ubuntu 24.10 (x86_64) so that I will explain and use ELF format. As you guest, I don't know really PE format. But there is a good reference handbook that you can look at. It's "Practical Binary Analysis" written by Dennis Andriesse.&lt;/p&gt;

&lt;p&gt;After explained the program formats, right now, let's look at the inside of the program:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2ozvdt4ayf1grr4fgmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2ozvdt4ayf1grr4fgmw.png" alt=" " width="395" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In general, any program includes these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Executable header&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Program headers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sections&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Section headers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every ELF file starts with an &lt;strong&gt;executable header&lt;/strong&gt;, which is just a structured series of bytes telling you that it's and ELF file, what kind of ELF file it is, and where in the files to find all the other contents [2].&lt;/p&gt;

&lt;p&gt;You can exactly see the content of this header with &lt;strong&gt;readelf&lt;/strong&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ readelf -h ./copy
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1160
  Start of program headers:          64 (bytes into file)
  Start of section headers:          17496 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         37
  Section header string table index: 36
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In there, first four digits (7f 45) of &lt;em&gt;Magic&lt;/em&gt; series define the program format. You will see the probably different series if you are on Windows. Other properties is the self-explaining.&lt;/p&gt;

&lt;p&gt;The code and data in an ELF program are logically divided into &lt;strong&gt;sections&lt;/strong&gt;. Each section includes a specific part of your source code. And the sections in the binary are contained in the &lt;strong&gt;section header table&lt;/strong&gt;. Some sections are used to execute the machine instructions and some for other information (like symbol table used by debugger). Let's look at the section headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ readelf --sections --wide ./copy
There are 37 section headers, starting at offset 0x4458:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        0000000000000318 000318 00001c 00   A  0   0  1
  [ 2] .note.gnu.property NOTE            0000000000000338 000338 000030 00   A  0   0  8
  [ 3] .note.gnu.build-id NOTE            0000000000000368 000368 000024 00   A  0   0  4
  [ 4] .note.ABI-tag     NOTE            000000000000038c 00038c 000020 00   A  0   0  4
  [ 5] .gnu.hash         GNU_HASH        00000000000003b0 0003b0 000028 00   A  6   0  8
  [ 6] .dynsym           DYNSYM          00000000000003d8 0003d8 000180 18   A  7   1  8
  [ 7] .dynstr           STRTAB          0000000000000558 000558 0000d3 00   A  0   0  1
  [ 8] .gnu.version      VERSYM          000000000000062c 00062c 000020 02   A  6   0  2
  [ 9] .gnu.version_r    VERNEED         0000000000000650 000650 000030 00   A  7   1  8
  [10] .rela.dyn         RELA            0000000000000680 000680 0000d8 18   A  6   0  8
  [11] .rela.plt         RELA            0000000000000758 000758 0000d8 18  AI  6  24  8
  [12] .init             PROGBITS        0000000000001000 001000 00001b 00  AX  0   0  4
  [13] .plt              PROGBITS        0000000000001020 001020 0000a0 10  AX  0   0 16
  [14] .plt.got          PROGBITS        00000000000010c0 0010c0 000010 10  AX  0   0 16
  [15] .plt.sec          PROGBITS        00000000000010d0 0010d0 000090 10  AX  0   0 16
  [16] .text             PROGBITS        0000000000001160 001160 00043a 00  AX  0   0 16
  [17] .fini             PROGBITS        000000000000159c 00159c 00000d 00  AX  0   0  4
  [18] .rodata           PROGBITS        0000000000002000 002000 000040 00   A  0   0  4
  [19] .eh_frame_hdr     PROGBITS        0000000000002040 002040 000034 00   A  0   0  4
  [20] .eh_frame         PROGBITS        0000000000002078 002078 0000a8 00   A  0   0  8
  [21] .init_array       INIT_ARRAY      0000000000003d78 002d78 000008 08  WA  0   0  8
  [22] .fini_array       FINI_ARRAY      0000000000003d80 002d80 000008 08  WA  0   0  8
  [23] .dynamic          DYNAMIC         0000000000003d88 002d88 0001f0 10  WA  7   0  8
  [24] .got              PROGBITS        0000000000003f78 002f78 000088 08  WA  0   0  8
  [25] .data             PROGBITS        0000000000004000 003000 000010 00  WA  0   0  8
  [26] .bss              NOBITS          0000000000004020 003010 000010 00  WA  0   0 32
  [27] .comment          PROGBITS        0000000000000000 003010 00002b 01  MS  0   0  1
  [28] .debug_aranges    PROGBITS        0000000000000000 00303b 000030 00      0   0  1
  [29] .debug_info       PROGBITS        0000000000000000 00306b 000472 00      0   0  1
  [30] .debug_abbrev     PROGBITS        0000000000000000 0034dd 000184 00      0   0  1
  [31] .debug_line       PROGBITS        0000000000000000 003661 00017e 00      0   0  1
  [32] .debug_str        PROGBITS        0000000000000000 0037df 00031a 01  MS  0   0  1
  [33] .debug_line_str   PROGBITS        0000000000000000 003af9 00012f 01  MS  0   0  1
  [34] .symtab           SYMTAB          0000000000000000 003c28 000438 18     35  18  8
  [35] .strtab           STRTAB          0000000000000000 004060 00028c 00      0   0  1
  [36] .shstrtab         STRTAB          0000000000000000 0042ec 00016a 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), l (large), p (processor specific)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main topic of this tutorial is the sections. So I wanna explain in deeply each one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.init&lt;/strong&gt; and &lt;strong&gt;.fini&lt;/strong&gt;: The machine code in these sections are used before/after the &lt;em&gt;main()&lt;/em&gt; function in program. Don't forget that we're not writing this sections. Compiler itself creates these to handle low-level (or hardware-specific) works. I don't know actually what both of them do!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.text&lt;/strong&gt;: It is the main area where we focus on binary analysis and reverse-engineering stuffs and includes the your code in machine instruction representation. If you look at there, you see that it has voluminous area and thousands of lines of machine code even if it is small program.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.bss&lt;/strong&gt;, &lt;strong&gt;.data&lt;/strong&gt; and &lt;strong&gt;.rodata&lt;/strong&gt;: These sections are writable and used to hold various variable in source code. &lt;strong&gt;.bss&lt;/strong&gt; includes the &lt;em&gt;static&lt;/em&gt; and &lt;em&gt;global uninitialized&lt;/em&gt; and &lt;strong&gt;.data&lt;/strong&gt; includes the &lt;em&gt;static&lt;/em&gt; and &lt;em&gt;global initialized&lt;/em&gt; variables. Also &lt;strong&gt;.rodata&lt;/strong&gt; consists of variables defined with &lt;em&gt;const&lt;/em&gt; keyword in code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.dynamic&lt;/strong&gt;: This is the "road map" for the kernel and dynamic linker when loading and setting up an ELF binary for executions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.init_array&lt;/strong&gt; and &lt;strong&gt;.fini_array&lt;/strong&gt;: These contains an array of pointers to functions to use as constructors/destructors. You maybe know that how to create constructor and destructor using compiler specific-tool, line one &lt;em&gt;__attribute__((constructor)) void run_before_main(void);&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.shstrtab&lt;/strong&gt;, &lt;strong&gt;.symtab&lt;/strong&gt;, &lt;strong&gt;.strtab&lt;/strong&gt;, &lt;strong&gt;.dynsym&lt;/strong&gt; and &lt;strong&gt;.dynstr&lt;/strong&gt;: The &lt;strong&gt;.shstrtab&lt;/strong&gt; section is simply an array of NULL-terminated strings that contain the names of all the sections in binary. The &lt;strong&gt;.symtab&lt;/strong&gt; contains a symbol table and &lt;strong&gt;.strtab&lt;/strong&gt; contains the symbolic names. The &lt;strong&gt;.dynsym&lt;/strong&gt; and &lt;strong&gt;.dynstr&lt;/strong&gt; are analogous to &lt;strong&gt;.symtab&lt;/strong&gt; and &lt;strong&gt;.strtab&lt;/strong&gt;, except that they contain symbols and strings needed for dynamic linking rather than static linking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.debug_&lt;/strong&gt;: These sections are used primarily by debugger (GDB) so that it has not include and machine code but just metadata about program that debugger can use later. If you don't compile the program with &lt;em&gt;-g&lt;/em&gt; option, these sections will not there.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is a part of &lt;strong&gt;.text&lt;/strong&gt; section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ objdump -j .text -d ./copy

./copy:     file format elf64-x86-64

(...)

Disassembly of section .text:

0000000000001249 &amp;lt;main&amp;gt;:
    1249:f3 0f 1e fa          endbr64
    124d:55                   push   %rbp
    124e:48 89 e5             mov    %rsp,%rbp
    1251:48 81 ec 40 04 00 00 sub    $0x440,%rsp
    1258:89 bd cc fb ff ff    mov    %edi,-0x434(%rbp)
    125e:48 89 b5 c0 fb ff ff mov    %rsi,-0x440(%rbp)
    1265:64 48 8b 04 25 28 00 mov    %fs:0x28,%rax
    126c:00 00 
    126e:48 89 45 f8          mov    %rax,-0x8(%rbp)
    1272:31 c0                xor    %eax,%eax
    1274:83 bd cc fb ff ff 03 cmpl   $0x3,-0x434(%rbp)
    127b:75 24                jne    12a1 &amp;lt;main+0x58&amp;gt;
    127d:48 8b 85 c0 fb ff ff mov    -0x440(%rbp),%rax
    1284:48 83 c0 08          add    $0x8,%rax
    1288:48 8b 00             mov    (%rax),%rax
    128b:48 8d 15 72 0d 00 00 lea    0xd72(%rip),%rdx        # 2004 &amp;lt;_IO_stdin_used+0x4&amp;gt;

(...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, we see the three columns that show the machine instructions of your program. At left side, you see the addresses of machine instructions. When running the program, stack pointer tracks these addresses. At center, you see the actual machine instructions corresponding to your code. Program counter register tracks this machine instructions. At right side, you see the assembly-level representations. When dealing with reverse-engineering, we inspect these to understand what program does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual Memory Layout
&lt;/h2&gt;

&lt;p&gt;After discussed the ELF program format, right now, I will explain the virtual memory layout of a process (running program instance). When you run the program, kernel creates a memory layout as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftw61ve9j3jviy2l7jhcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftw61ve9j3jviy2l7jhcn.png" alt=" " width="552" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've explained the &lt;strong&gt;.text, .data, .bss,&lt;/strong&gt; and &lt;strong&gt;.rodata&lt;/strong&gt; sections previously. Apart from these, you see the &lt;strong&gt;stack&lt;/strong&gt; and &lt;strong&gt;heap&lt;/strong&gt; areas.&lt;/p&gt;

&lt;p&gt;Both are the memory areas that kernel uses to execute the machine instructions. Stack area has LIFO (Last-In First-Out) model. When executing the program, kernel &lt;em&gt;pushes/pops&lt;/em&gt; the instructions in here. So it grows up to lower address space. Heap area is completely different! It has FIFO (First-In First-Out) model. Kernel uses this memory space for dynamic allocation with &lt;strong&gt;malloc()/free()&lt;/strong&gt; function family. And it grows up to upper address space. The heap address border is claimed by &lt;strong&gt;brk()&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;Until here, I wanna give you a general overview about programs and processes. If you want to dive in more, you can check and look at the below references.&lt;/p&gt;

&lt;p&gt;[1]. Kerrisk M., The Linux Programming Interface, no starch press, San Francisco, page 113.&lt;br&gt;
[2]. Andriesse D., Practical Binary Analysis, no starch press, San Francisco, page 33.&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>lowcode</category>
      <category>linux</category>
      <category>c</category>
    </item>
    <item>
      <title>Safe and Secure Software - MISRA C:2012</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Tue, 11 Nov 2025 14:51:31 +0000</pubDate>
      <link>https://forem.com/cangulmez/safe-and-secure-software-misra-c2012-32c1</link>
      <guid>https://forem.com/cangulmez/safe-and-secure-software-misra-c2012-32c1</guid>
      <description>&lt;p&gt;We say that programming languages like C, C++, Rust as "general-purpose". That means that we can do everything (theoretically) with these. But in critical system development (let's say military or aerospace), we need some rules to use the languages safely and securely.&lt;/p&gt;

&lt;p&gt;In this article, I'm gonna explain the MISRA C:2012 rules and example code blocks. Let's start!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: I'm gonna dive into the important rules in later posts.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A standard C environment
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 1.1&lt;/strong&gt;: The program shall contain no violations of the standard C syntax and constraints, and shall not exceed the implementation's translation limits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule 1.2&lt;/strong&gt;: Language extensions should not be used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void outer(void)
{
    printf("Outer function!\n");

    __extension__ void inner(void)  /* VIOLATION */
    {
        printf("Inner function!\n");
    }
    inner();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 1.3&lt;/strong&gt;: There shall be no occurrence of undefined or critical unspecified behaviour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unused code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 2.1&lt;/strong&gt;: A project shall not contain &lt;em&gt;unreachable code&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void main(int argc, char *argv[])
{
    int res;

    exit(EXIT_SUCCESS);

    res = 1;        /* VIOLATION */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 2.2&lt;/strong&gt;: There shall be no &lt;em&gt;dead code&lt;/em&gt;.&lt;br&gt;
&lt;strong&gt;Rule 2.3/4/5&lt;/strong&gt;: A project should not contain unused type/tag/macro declarations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int func(void)
{
#define DATA    5
#define SIZE    10      /* VIOLATION */

    return DATA;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 2.6&lt;/strong&gt;: A function should not contain unused label declarations.&lt;br&gt;
&lt;strong&gt;Rule 2.7&lt;/strong&gt;: There should be no unused parameters in functions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Comments
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 3.1&lt;/strong&gt;: The character sequences /* and // shall not be used within a comment.&lt;br&gt;
&lt;strong&gt;Rule 3.2&lt;/strong&gt;: Line-splicing shall not be used in // comments.&lt;/p&gt;
&lt;h2&gt;
  
  
  Character sets and lexical conventions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 4.1&lt;/strong&gt;: Octal and hexadecimal escape sequences shall not be terminated.&lt;br&gt;
&lt;strong&gt;Rule 4.2&lt;/strong&gt;: Trigraphs should not be used.&lt;/p&gt;
&lt;h2&gt;
  
  
  Identifiers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 5.1&lt;/strong&gt;: &lt;em&gt;External identifiers&lt;/em&gt; shall be distinct.&lt;br&gt;
&lt;strong&gt;Rule 5.2&lt;/strong&gt;: Identifiers declared in the same &lt;em&gt;scope&lt;/em&gt; and name space shall be distinct.&lt;br&gt;
&lt;strong&gt;Rule 5.3&lt;/strong&gt;: An identifier in an inner scope shall not hide an identifier declared in an outer scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int func(void)
{
    int i;
    {
        int i;  /* VIOLATION */

        i = 4;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 5.4&lt;/strong&gt;: &lt;em&gt;Macro identifiers&lt;/em&gt; shall be distinct.&lt;br&gt;
&lt;strong&gt;Rule 5.5&lt;/strong&gt;: Identifiers shall be distinct from macro names.&lt;br&gt;
&lt;strong&gt;Rule 5.6/7&lt;/strong&gt;: A &lt;em&gt;typedef&lt;/em&gt;/tag name shall be a unique identifier.&lt;br&gt;
&lt;strong&gt;Rule 5.8/9&lt;/strong&gt;: Identifiers that define objects or functions with external/internal linkage shall be unique.&lt;/p&gt;
&lt;h2&gt;
  
  
  Types
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 6.1&lt;/strong&gt;: Bit-fields shall only be declared with an appropriate type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct s {
    unsigned int a:2;   
    int          b:2; /* VIOLATION (plain int not permitted) */
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 6.2&lt;/strong&gt;: Single-bit named bit fields shall not be of a signed type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Literals and constants
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 7.1&lt;/strong&gt;: Octal constants shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 7.2&lt;/strong&gt;: A "u" or "U" suffix shall be applied to all integer constants that are represented in an unsigned type.&lt;br&gt;
&lt;strong&gt;Rule 7.3&lt;/strong&gt;: The lowercase character "l" shall not be used in a literal suffix.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const int64_t   a = 0L;
const int64_t   b = 0l;     /* VIOLATION */
const uint64_t c = 0Lu; 
const uint64_t d = 0lU;     /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 7.4&lt;/strong&gt;: A string literal shall not be assigned to an object unless the object's type is "pointer to &lt;em&gt;const&lt;/em&gt;-qualified &lt;em&gt;char&lt;/em&gt;".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const volatile char *s1 = "string";
char *s2 = "string";                            /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Declarations and definations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 8.1&lt;/strong&gt;: Types shall be explicitly specified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extern          x;      /* VIOLATION (implicit int type) */
extern int16_t y;
const           z;      /* VIOLATION (implicit int type) */
extern int32_t q;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 8.2&lt;/strong&gt;: Function types shall be in &lt;em&gt;prototype form&lt;/em&gt; with named parameters.&lt;br&gt;
&lt;strong&gt;Rule 8.3&lt;/strong&gt;: All declarations of an object or function shall use the same names and type qualifiers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extern f(signed int param);
         f(int param);              /* Okey */
extern g(int * const param);
         g(int * p);                /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 8.4&lt;/strong&gt;: A compatible declaration shall be visible when an object or function with external linkage is defined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extern int x;
         int x = 5;     /* OK */

int y = 3;              /* VIOLATION - no prior declaration */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 8.5&lt;/strong&gt;: An external object or function shall be declared once in one or only one file.&lt;br&gt;
&lt;strong&gt;Rule 8.6&lt;/strong&gt;: An identifier with external linkage shall have exactly one external definition.&lt;br&gt;
&lt;strong&gt;Rule 8.7&lt;/strong&gt;: Functions and objects should not be defined with external linkage if they are referenced in only one translation unit.&lt;br&gt;
&lt;strong&gt;Rule 8.8&lt;/strong&gt;: The &lt;em&gt;static&lt;/em&gt; storage class specifier shall be used in all declarations of objects and functions that have internal linkage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static int32_t x = 0;
extern int32_t x;     /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 8.9&lt;/strong&gt;: An object should be defined at block scope if its identifier only appears in a single function.&lt;br&gt;
&lt;strong&gt;Rule 8.10&lt;/strong&gt;: An &lt;em&gt;inline function&lt;/em&gt; shall be declared with the static storage class.&lt;br&gt;
&lt;strong&gt;Rule 8.11&lt;/strong&gt;: When an array with external linkage is declared, its size should be explicitly specified.&lt;br&gt;
&lt;strong&gt;Rule 8.12&lt;/strong&gt;: Within an enumerator list, the value of an implicitly-specified enumeration constant shall be unique.&lt;br&gt;
&lt;strong&gt;Rule 8.13&lt;/strong&gt;: A pointer should point to a &lt;em&gt;const&lt;/em&gt;-qualified type whether possible.&lt;br&gt;
&lt;strong&gt;Rule 8.14&lt;/strong&gt;: The &lt;em&gt;restrict&lt;/em&gt; type qualifier shall not be used.&lt;/p&gt;
&lt;h2&gt;
  
  
  Initialization
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 9.1&lt;/strong&gt;: The value of an object with automatic storage duration shall not be read before it has been set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void f(bool_t b, uint16_t *p)
{
    if (b) {
        *p = 3U;
    }
}

void g(void)
{
    uint16_t u;

    f(false, &amp;amp;u);

    if (u == 3U) {
        /* VIOLATION - u has not be assigned a value */
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 9.2&lt;/strong&gt;: The initializer for an aggregate or union shall be enclosed in braces.&lt;br&gt;
&lt;strong&gt;Rule 9.3&lt;/strong&gt;: Arrays shall not be partially initialized.&lt;br&gt;
&lt;strong&gt;Rule 9.4&lt;/strong&gt;: An element of an object shall not be initialized more than once.&lt;br&gt;
&lt;strong&gt;Rule 9.5&lt;/strong&gt;: Where designated initializers are used to initialize an array object, the size of the array shall be specified explicitly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int a1[5] = {0};            /* OK */
int a2[] = {4, 7, 1};   /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The essential type model
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 10.1&lt;/strong&gt;: Operands shall not be of an inappropriate &lt;em&gt;essential type&lt;/em&gt;. (I did not understand that yet 😂, look at page 82-84 at MISRA C:2012 Guidelines).&lt;br&gt;
&lt;strong&gt;Rule 10.2&lt;/strong&gt;: Expressions of &lt;em&gt;essential character type&lt;/em&gt; shall not be used inappropriately in addition and subtraction operations.&lt;br&gt;
&lt;strong&gt;Rule 10.3&lt;/strong&gt;: The value of an expression shall not be assigned to an object with a narrower &lt;em&gt;essential type&lt;/em&gt; or of a different &lt;em&gt;essential type category&lt;/em&gt;.&lt;br&gt;
&lt;strong&gt;Rule 10.4&lt;/strong&gt;: Both operands of an operator in which the &lt;em&gt;usual arithmetic&lt;/em&gt; conversions, are performed shall have the same &lt;em&gt;essential type category&lt;/em&gt;.&lt;br&gt;
&lt;strong&gt;Rule 10.5&lt;/strong&gt;: The value of an expression should not be cast to an inappropriate &lt;em&gt;essential type&lt;/em&gt;.&lt;br&gt;
&lt;strong&gt;Rule 10.6&lt;/strong&gt;: The value of a &lt;em&gt;composite expression&lt;/em&gt; shall not be assigned to an object with wider &lt;em&gt;essential type&lt;/em&gt;.&lt;br&gt;
&lt;strong&gt;Rule 10.7&lt;/strong&gt;: If a &lt;em&gt;composite expression&lt;/em&gt; is used as one operand of an operator in which the &lt;em&gt;usual arithmetic conversions&lt;/em&gt; are performed then the other operand shall not have wider &lt;em&gt;essential type&lt;/em&gt;.&lt;br&gt;
&lt;strong&gt;Rule 10.8&lt;/strong&gt;: The value of a &lt;em&gt;composite expression&lt;/em&gt; shall not be cast to a different &lt;em&gt;essential type category&lt;/em&gt; or a wider &lt;em&gt;essential type&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pointer type conversions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 11.1&lt;/strong&gt;: Conversions shall not be performed between a pointer to function and any other type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef void (*fp16) (int16_t n);
typedef void (*fp32) (int32_t n);

fp16 fp1 = NULL;                /* OK */
fp32 fp2 = (fp32) fp1;      /* VIOLATION - a function pointer to different one */

if (fp2 != NULL) {          /* OK */

}

fp16 fp3 = (fp16) 0x8000;   /* VIOLATION - integer into function pointer */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 11.2&lt;/strong&gt;: Conversions shall not be performed between a pointer to an incomplete type and any other type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct s;
struct t;
struct s *sp;
struct t *tp;
int16_t *ip;

sp = NULL;                      /* OK */
ip = (int16_t *) sp;            /* VIOLATION */
sp = (struct s *) 1234;     /* VIOLATION */
tp = (struct t *) sp;       /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 11.3&lt;/strong&gt;: A cast shall not be performed between a pointer to object type and a pointer to a different object type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint8_t *p1;
uint32_t *p2;

p2 = (uint32_t *) p1;           /* VIOLATION */

const short *p;
const volatile short *q;

q = (const volatile short *) p; /* OK */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 11.4&lt;/strong&gt;: A conversion should not be performed between a pointer to object and an integer type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint16_t *p;

int32_t addr = (int32_t) &amp;amp;p;        /* VOILATION */
uint8_t *q = (uint_t *) addr;       /* VIOLATION */
bool_t b = (bool_t) p;              /* VIOLATION */

enum tag {A, B, C};

enum tag e = (enum tag) p;          /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 11.5&lt;/strong&gt;: A conversion should not be performed from pointer to &lt;em&gt;void&lt;/em&gt; into pointer to object (except &lt;em&gt;NULL&lt;/em&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint32_t *p32;
void *p;
uint16_t *p16;

p = p32;                    /* OK */
p16 = p;                    /* VIOLATION */
p = (void*) p16;        /* OK */
p32 = (uint32_t *);     /* VIOLATION */ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 11.6&lt;/strong&gt;: A cast shall not be performed between pointer to &lt;em&gt;void&lt;/em&gt; and an arithmetic type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void *p;
uint32_t u;

p = (void *) 0x1234u;   /* VIOLATION */
u = (uint32_t) p;           /* VIOLATION */ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 11.7&lt;/strong&gt;: A cast shall be performed between pointer to object and a non-integer arithmetic type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int16_t *p;
float32_t f;

f = (float32_t) p;  /* VIOLATION */
p = (int16_t *) f;  /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 11.8&lt;/strong&gt;: A cast shall not remove &lt;em&gt;const&lt;/em&gt; or &lt;em&gt;volatile&lt;/em&gt; qualification from the type pointed to by a pointer.&lt;br&gt;
&lt;strong&gt;Rule 11.9&lt;/strong&gt;: The macro &lt;em&gt;NULL&lt;/em&gt; shall be the only permitted form of integer &lt;em&gt;null pointer constant&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int32_t *p1 = 0;                /* VIOLATION */
int32_t *p2 = (void *) 0;   /* OK */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Expressions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 12.1&lt;/strong&gt;: The precedence of operators within expressions should be made explicit.&lt;br&gt;
&lt;strong&gt;Rule 12.2&lt;/strong&gt;: The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the &lt;em&gt;essential type&lt;/em&gt; of the left hand operand.&lt;br&gt;
&lt;strong&gt;Rule 12.3&lt;/strong&gt;: The comma operator should not be used.&lt;br&gt;
&lt;strong&gt;Rule 12.4&lt;/strong&gt;: Evaluation of &lt;em&gt;constant expressions&lt;/em&gt; should not lead to unsigned integer wrap-around.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#define DELAY       10000u
#define WIDTH       60000u

void fixed_pulse(void)
{
    uint16_t off_time16 = DELAY + WIDTH;    /* VIOLATION */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Side effects
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 13.1&lt;/strong&gt;: &lt;em&gt;Initializer lists&lt;/em&gt; shall not contain &lt;em&gt;persistent side effects&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;volatile uint16_t v1;

void f(void)
{
    uint16_t a[2] = {v1, 0};    /* VIOLATION - volatile is side effect */
}

void g(uint16_t x, uint16_t y)
{
    uint16_t a[2] = {x + y, x - y}; /* OK */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 13.2&lt;/strong&gt;: The value of an expression and its &lt;em&gt;persistent side effects&lt;/em&gt; shall be the same under all permitted evaluation orders.&lt;br&gt;
&lt;strong&gt;Rule 13.3&lt;/strong&gt;: A full expression containing an increment (++) or decrement (--) operator should have no other potential &lt;em&gt;side effects&lt;/em&gt; other than that caused by the increment or decrement operator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;u8a = u8b++;                /* VIOLATION */
u8a = ++u8b + u8c--;        /* VIOLATION */
x++;                            /* OKEY */
a[i]++;                     /* OK */
c-&amp;gt;x++;                     /* OK */
*p++;                           /* OKEY */
(*p)++;                     /* OK */
++(*p);                     /* OK */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 13.4&lt;/strong&gt;: The result of an assignment operator should not be &lt;em&gt;used&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = y;              /* OK */
a[x] = a[x = y];    /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 13.5&lt;/strong&gt;: The right hand operand of a logical &amp;amp;&amp;amp; or || operator shall not contain &lt;em&gt;persistent side effects&lt;/em&gt;.&lt;br&gt;
&lt;strong&gt;Rule 13.6&lt;/strong&gt;: The operand of the &lt;em&gt;sizeof&lt;/em&gt; operand shall not contain any expression which has potential &lt;em&gt;side effects&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Control statement expressions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 14.1&lt;/strong&gt;: A &lt;em&gt;loop counter&lt;/em&gt; shall not have &lt;em&gt;essential floating&lt;/em&gt; type.&lt;br&gt;
&lt;strong&gt;Rule 14.2&lt;/strong&gt;: A &lt;em&gt;for&lt;/em&gt; loop shall be well-formed.&lt;br&gt;
&lt;strong&gt;Rule 14.3&lt;/strong&gt;: Controlling expressions shall not be invariant.&lt;br&gt;
&lt;strong&gt;Rule 14.4&lt;/strong&gt;: The controlling expression of an &lt;em&gt;if&lt;/em&gt; statement and the controlling expression of an &lt;em&gt;iteration-statement&lt;/em&gt; shall have &lt;em&gt;essential Boolean&lt;/em&gt; type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int32_t *p, *q;

while (p)               /* VIOLATION */
{
}

while (q != NULL)       /* OK */
{
}

while (true)            /* OK */
{
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Control flow
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 15.1&lt;/strong&gt;: The &lt;em&gt;goto&lt;/em&gt; statement should not be used.&lt;br&gt;
&lt;strong&gt;Rule 15.2&lt;/strong&gt;: The &lt;em&gt;goto&lt;/em&gt; statement shall jump to a label declared later in the same function.&lt;br&gt;
&lt;strong&gt;Rule 15.3&lt;/strong&gt;: Any label referenced by a &lt;em&gt;goto&lt;/em&gt; statement shall be declared in the same block, or in any block enclosing the &lt;em&gt;goto&lt;/em&gt; statement.&lt;br&gt;
&lt;strong&gt;Rule 15.4&lt;/strong&gt;: There should be no more than one &lt;em&gt;break&lt;/em&gt; or &lt;em&gt;goto&lt;/em&gt; statement used to terminate any iteration statement.&lt;br&gt;
&lt;strong&gt;Rule 15.5&lt;/strong&gt;: A function should have a single point of exit at the end.&lt;br&gt;
&lt;strong&gt;Rule 15.6&lt;/strong&gt;: The body of an &lt;em&gt;iteration-statement&lt;/em&gt; or a &lt;em&gt;selection-statement&lt;/em&gt; shall be a &lt;em&gt;compound-statement&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while (true)            /* VIOLATION */
    process_data();

while (true)            /* OK */
{
    process_data();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 15.7&lt;/strong&gt;: All &lt;em&gt;if ... else if&lt;/em&gt; constructs shall be terminated with an &lt;em&gt;else&lt;/em&gt; statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch statements
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 16.1&lt;/strong&gt;: All &lt;em&gt;switch&lt;/em&gt; statements shall be well-formed.&lt;br&gt;
&lt;strong&gt;Rule 16.2&lt;/strong&gt;: A &lt;em&gt;switch label&lt;/em&gt; shall only be used when the most closely-enclosing compound statement is the body of a &lt;em&gt;switch&lt;/em&gt; statement.&lt;br&gt;
&lt;strong&gt;Rule 16.3&lt;/strong&gt;: An unconditional &lt;em&gt;break&lt;/em&gt; statement shall terminate every &lt;em&gt;switch-clause&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (x)
{
    case 0:         /* OK */
        break;  
    case 1:         /* OK */
    case 2:         /* OK */
        break;
    case 4:         /* VIOLATION */
        a = b;
    default:            /* VIOLATION - 'default' even should have 'break' */
        ;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 16.4&lt;/strong&gt;: Every &lt;em&gt;switch&lt;/em&gt; statement shall have a &lt;em&gt;default&lt;/em&gt; label.&lt;br&gt;
&lt;strong&gt;Rule 16.5&lt;/strong&gt;: A &lt;em&gt;default&lt;/em&gt; label shall appear as either the first or the last &lt;em&gt;switch label&lt;/em&gt; of a &lt;em&gt;switch&lt;/em&gt; statement.&lt;br&gt;
&lt;strong&gt;Rule 16.6&lt;/strong&gt;: Every &lt;em&gt;switch&lt;/em&gt; statement shall have at least two &lt;em&gt;switch-clauses&lt;/em&gt;.&lt;br&gt;
&lt;strong&gt;Rule 16.7&lt;/strong&gt;: A &lt;em&gt;switch-expression&lt;/em&gt; shall not have &lt;em&gt;essential Boolean&lt;/em&gt; type.&lt;/p&gt;
&lt;h2&gt;
  
  
  Functions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 17.1&lt;/strong&gt;: The features of &amp;lt;stdarg.h&amp;gt; shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 17.2&lt;/strong&gt;: Functions shall not call themselves, either directly or indirectly.&lt;br&gt;
&lt;strong&gt;Rule 17.3&lt;/strong&gt;: A function shall not be declared implicitly.&lt;br&gt;
&lt;strong&gt;Rule 17.4&lt;/strong&gt;: All exit paths from a function with non-&lt;em&gt;void&lt;/em&gt; return type shall have an explicit &lt;em&gt;return&lt;/em&gt; statement with an expression.&lt;br&gt;
&lt;strong&gt;Rule 17.5&lt;/strong&gt;: The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements.&lt;br&gt;
&lt;strong&gt;Rule 17.6&lt;/strong&gt;: The declaration of an array parameter shall not contain &lt;em&gt;static&lt;/em&gt; keyword between the [].&lt;br&gt;
&lt;strong&gt;Rule 17.7&lt;/strong&gt;: The value returned by a function having non-&lt;em&gt;void&lt;/em&gt; return type shall be &lt;em&gt;used&lt;/em&gt;.&lt;br&gt;
&lt;strong&gt;Rule 17.8&lt;/strong&gt;: A function parameter should not be modified.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pointers and arrays
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 18.1&lt;/strong&gt;: A pointer resulting from arithmetic on a pointer operand shall address an element of the same array as that pointer operand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void f(void)
{
    int32_t data = 0;
    int32_t b = 0;
    int32_t c[10] = {0};
    int32_t d[5][2] = {0};

    int32_t *p1 = &amp;amp;c[0];        /* OK */
    int32_t *p2 = &amp;amp;c[10];   /* OK (even) */
    int32_t *p3 = &amp;amp;c[11];   /* VIOLATION */

    data = *p2;                 /* VIOLATION */

    p1++;                           /*  OK */
    c[-1] = 0;                  /* VIOLATION */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 18.2&lt;/strong&gt;: Subtraction between pointers shall only be applied to pointers that address elements of the same array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void f(void)
{
    int32_t a1[10];
    int32_t a2[10];
    int32_t *p1 = &amp;amp;a1[1];
    int32_t *p2 = &amp;amp;a2[10];
    ptrdiff_t diff;

    diff = p1 - a1;     /* OK */
    diff = p2 - a2;     /* OK */
    diff = p1 - p2;     /* VIOLATION */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 18.3&lt;/strong&gt;: The relational operators &amp;gt;, &amp;gt;=, &amp;lt; and &amp;lt;= shall not be applied to objects of pointer type except where they point into the same object.&lt;br&gt;
&lt;strong&gt;Rule 18.4&lt;/strong&gt;: The +, -, +=, -= operators should not be applied to an expression of pointer type.&lt;br&gt;
&lt;strong&gt;Rule 18.5&lt;/strong&gt;: Declarations should contain no more than two levels of pointer nesting.&lt;br&gt;
&lt;strong&gt;Rule 18.6&lt;/strong&gt;: The address of an object with automatic storage shall not be copied to another object that persists after the first object has ceased to exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int8_t *f(void)
{
    int8_t local;

    return &amp;amp;local;      /* VIOLATION */
}

uint16_t *sp;

void g(uint16_t *p)
{
    sp = p;             /* VIOLATION */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 18.7&lt;/strong&gt;: Flexible array members shall not be declared.&lt;br&gt;
&lt;strong&gt;Rule 18.8&lt;/strong&gt;: Variable-length array types shall not be used.&lt;/p&gt;
&lt;h2&gt;
  
  
  Overlapping storage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 19.1&lt;/strong&gt;: An object shall not be assigned or copied to an overlapping object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void f(void)
{
    union {
        int16_t i;
        int16_t j;
    } a = {0}, b = {1};

    a.j = a.i;      /* VIOLATION */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 19.2&lt;/strong&gt;: The &lt;em&gt;union&lt;/em&gt; keyword should not be used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preprocessing directives
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 20.1&lt;/strong&gt;: &lt;em&gt;#include&lt;/em&gt; directives should only be preceded by preprocessor directives or comments.&lt;br&gt;
&lt;strong&gt;Rule 20.2&lt;/strong&gt;: The ', " or \ characters and the /* or // character sequences shall not occur in a &lt;em&gt;header file&lt;/em&gt; name.&lt;br&gt;
&lt;strong&gt;Rule 20.3&lt;/strong&gt;: The &lt;em&gt;#include&lt;/em&gt; directive shall be followed by either a &amp;lt;filename&amp;gt; or "filename" sequence.&lt;br&gt;
&lt;strong&gt;Rule 20.4&lt;/strong&gt;: A macro shall not be defined with the same name as a keyword.&lt;br&gt;
&lt;strong&gt;Rule 20.5&lt;/strong&gt;: &lt;em&gt;#undef&lt;/em&gt; should not be used.&lt;br&gt;
&lt;strong&gt;Rule 20.6&lt;/strong&gt;: Tokens that look like a preprocessing directive shall not occur with a macro argument.&lt;br&gt;
&lt;strong&gt;Rule 20.7&lt;/strong&gt;: Expressions resulting from the expansion of macro parameters shall be enclosed in parentheses.&lt;br&gt;
&lt;strong&gt;Rule 20.8&lt;/strong&gt;: The controlling expression of a &lt;em&gt;#if&lt;/em&gt; or &lt;em&gt;#elif&lt;/em&gt; preprocessing directive shall evaluate to 0 or 1.&lt;br&gt;
&lt;strong&gt;Rule 20.9&lt;/strong&gt;: All identifiers used in the controlling expression of &lt;em&gt;#if&lt;/em&gt; or &lt;em&gt;#elif&lt;/em&gt; preprocessing directives shall be &lt;em&gt;#define&lt;/em&gt;'d before evaluation.&lt;br&gt;
&lt;strong&gt;Rule 20.10&lt;/strong&gt;: The # and ## preprocessor operators should not be used.&lt;br&gt;
&lt;strong&gt;Rule 20.11&lt;/strong&gt;: A macro parameter immediately following a # operator shall not immediately be followed by a ## operator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#define A(x)        #x      /* OK */
#define B(x, y) x ## y  /* OK */
#define C(x, y)   #x ## y   /* VIOLATION */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 20.12&lt;/strong&gt;: A macro parameter used as an operand to the # or ## operators, which is itself subject to further macro replacement, shall only be used as an operand to these operators.&lt;br&gt;
&lt;strong&gt;Rule 20.13&lt;/strong&gt;: A line whose first token is # shall be a valid preprocessing directive.&lt;br&gt;
&lt;strong&gt;Rule 20.14&lt;/strong&gt;: All &lt;em&gt;#else&lt;/em&gt;, &lt;em&gt;#elif&lt;/em&gt; and &lt;em&gt;#endif&lt;/em&gt; preprocessor directives shall reside in the same file as the &lt;em&gt;#if&lt;/em&gt;, &lt;em&gt;#ifdef&lt;/em&gt; or &lt;em&gt;#ifndef&lt;/em&gt; directive to which they are related.&lt;/p&gt;
&lt;h2&gt;
  
  
  Standard libraries
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 21.1&lt;/strong&gt;: &lt;em&gt;#define&lt;/em&gt; and &lt;em&gt;#undef&lt;/em&gt; shall not be used on a reserved identifier or reserved macro name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#undef __LINE__                 /* VIOLATION (begins with _) */
#define _GUARD_H    1               /* VIOLATION (begins with _) */

#define defined                 /* VIOLATION (reserved identifier) */
#define errno my errno          /* VIOLATION (library identifier) */
#define isneg(x)    ((x) &amp;lt; 0)   /* OKEY */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 21.2&lt;/strong&gt;: A reserved identifier or macro name shall not be declared.&lt;br&gt;
&lt;strong&gt;Rule 21.3&lt;/strong&gt;: The memory allocation and deallocation functions of &amp;lt;stdlib.h&amp;gt; shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 21.4&lt;/strong&gt;: The standard &lt;em&gt;header file&lt;/em&gt; &amp;lt;setjmp.h&amp;gt; shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 21.5&lt;/strong&gt;: The standard &lt;em&gt;header file&lt;/em&gt; &amp;lt;signal.h&amp;gt; shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 21.6&lt;/strong&gt;: The standard library input/output functions shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 21.7&lt;/strong&gt;: The &lt;em&gt;atof&lt;/em&gt;, &lt;em&gt;atol&lt;/em&gt;, &lt;em&gt;atoll&lt;/em&gt; functions of &amp;lt;stdlib.h&amp;gt; shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 21.8&lt;/strong&gt;: The library functions &lt;em&gt;abort&lt;/em&gt;, &lt;em&gt;exit&lt;/em&gt;, &lt;em&gt;getenv&lt;/em&gt; and &lt;em&gt;system&lt;/em&gt; of &amp;lt;stdlib.h&amp;gt; shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 21.9&lt;/strong&gt;: The library functions &lt;em&gt;bsearch&lt;/em&gt; and &lt;em&gt;qsort&lt;/em&gt; of &amp;lt;stdlib.h&amp;gt; shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 21.10&lt;/strong&gt;: The standard library time and date functions shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 21.11&lt;/strong&gt;: The standard &lt;em&gt;header file&lt;/em&gt; &amp;lt;tgmath.h&amp;gt; shall not be used.&lt;br&gt;
&lt;strong&gt;Rule 21.12&lt;/strong&gt;: The exception handling features of &amp;lt;fenv.h&amp;gt; should not be used.&lt;/p&gt;
&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Rule 22.1&lt;/strong&gt;: All resources obtained dynamically by means of standard library functions shall be explicitly released.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int f(void)
{
    void *a = malloc(40);

    /* VIOLATION - not released */
    return 1;
}

int g(void)
{
    FILE *fp = fopen("file", "r");

    /* VIOLATION - not closed */
    return 1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule 22.2&lt;/strong&gt;: A block of memory shall only be freed if it was allocated by means of a standard library function.&lt;br&gt;
&lt;strong&gt;Rule 22.3&lt;/strong&gt;: The same file shall not be open for read and write access at the same time on different streams.&lt;br&gt;
&lt;strong&gt;Rule 22.4&lt;/strong&gt;: There shall no attempt to write to a stream which has been opened as read-only.&lt;br&gt;
&lt;strong&gt;Rule 22.5&lt;/strong&gt;: A pointer to a &lt;em&gt;FILE&lt;/em&gt; object shall not be dereferenced.&lt;br&gt;
&lt;strong&gt;Rule 22.6&lt;/strong&gt;: The value of a pointer to a &lt;em&gt;FILE&lt;/em&gt; shall not be used after the associated stream has been closed.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>lowcode</category>
      <category>c</category>
      <category>security</category>
    </item>
    <item>
      <title>Interrupt Management in ARM Cortex-M</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Sat, 18 Oct 2025 17:46:52 +0000</pubDate>
      <link>https://forem.com/cangulmez/interrupt-management-in-arm-cortex-m-5g1g</link>
      <guid>https://forem.com/cangulmez/interrupt-management-in-arm-cortex-m-5g1g</guid>
      <description>&lt;p&gt;Interrupts is the must-known concept in embedded programming. So I wanna explain the interrupt management in ARM Cortex-M.&lt;/p&gt;

&lt;p&gt;ARM architecture distinguishes between the two types: &lt;em&gt;interrupt&lt;/em&gt; and &lt;em&gt;system exception&lt;/em&gt;. Interrupts are primarily sourced by external hardware like UART that warns about arrival of data. System exceptions are more software-related and caused by ARM Cortex internal.&lt;/p&gt;

&lt;p&gt;Interrupts and system exceptions are exchangeably used. But even if both of these do same thing (especially in programming), the differences are important for us, engineers!&lt;/p&gt;

&lt;p&gt;I'll use "interrupt" word for both terms further, if otherwise declared.&lt;/p&gt;

&lt;p&gt;Before diving into interrupts, you need to understand the general execution workflow of ARM Cortex. There are two types of &lt;em&gt;execution&lt;/em&gt; modes: &lt;em&gt;thread&lt;/em&gt; and &lt;em&gt;interrupt&lt;/em&gt;. After resetting the microcontroller, execution flow starts in thread mode so that if you want to use interrupts, you need to enter the interrupt mode. But how?&lt;/p&gt;

&lt;p&gt;When you flash your firmware into microcontroller (base address of 0x08000000, in case), ARM Cortex starts to execute the firmware's machine instructions in thread mode. If you want to use any interrupt, you have to explicitly say it to ARM Cortex by using &lt;em&gt;Interrupt Service Routines (ISRs)&lt;/em&gt;. ISRs are actually standard C functions, but have the special signatures. I'm gonna explain it later.&lt;/p&gt;

&lt;p&gt;The most important question about interrupts is that why do we need interrupts?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The answer: Interrupts are the source of multiprogramming!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Interrupts give us &lt;em&gt;second&lt;/em&gt; execution flow besides the main flow (executed in thread mode by default). It also gives the &lt;em&gt;context switch&lt;/em&gt; mechanism for RTOS. I will explain it lastly. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dvmqafsj7ilkcameuq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dvmqafsj7ilkcameuq1.png" alt=" " width="800" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ARM Cortex has a special hardware called &lt;em&gt;Nested Vectored Interrupt Controller (NVIC)&lt;/em&gt;. It handles and manages the all interrupt usage. Below is the its simple schematic:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifm0nlj1u3zt5ujigevn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifm0nlj1u3zt5ujigevn.png" alt=" " width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another important dedicated hardware is the &lt;em&gt;EXTI Controller&lt;/em&gt;. The peripheral interrupts in the microcontroller directly are connected to NVIC. But If you want to use interrupts over microcontroller pins (like detecting rising or falling edge of a button), you have to use EXTI lines. Microcontroller pins are grouped and tied to specific EXTI lines. Please look at the reference manual to find it.&lt;/p&gt;

&lt;p&gt;We have many different types of interrupts. For now, let's look at these:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxuqk3xcz9kjg3zxrjgh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxuqk3xcz9kjg3zxrjgh.png" alt=" " width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ARM Cortex has defined 15 fixed system exceptions (coming from internal of Cortex). But microcontroller vendors specify also variable-length interrupts (coming from external of Cortex). For example, STM32 series microcontrollers allow up to 256 interrupts.&lt;/p&gt;

&lt;p&gt;But where are located these interrupts? The answer is the &lt;em&gt;at vector table&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The vector table is an array of word data inside the system&lt;br&gt;
memory, each representing the starting address of one exception type [1].&lt;/p&gt;

&lt;p&gt;If you've flashed any firmware into microcontroller over OpenOCD + GDB, you've seen probably the this vector table. If you've not, let's see it exactly. &lt;/p&gt;

&lt;p&gt;I have STM32F446RE microcontroller and ST-LINK connection. I've compiled a firmware (&lt;em&gt;firmware.elf&lt;/em&gt;) to flash it. Open a terminal and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ openocd -f interface/stlink.cfg -f target/stm32f4x.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And open the second terminal and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ arm-none-eabi-gdb firmware.elf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, type these into GDB session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) target remote localhost:3333
(gdb) monitor reset halt
(gdb) load
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After flashed the firmware into microcontroller, you will see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Loading section .isr_vector, size 0x1c4 lma 0x8000000
Loading section .text, size 0x1080 lma 0x80001d0
Loading section .rodata, size 0x10 lma 0x8001250
Loading section .init_array, size 0x4 lma 0x8001260
Loading section .fini_array, size 0x4 lma 0x8001264
Loading section .data, size 0x10 lma 0x8001268
Start address 0x80011d0, load size 4716
Transfer rate: 9 KB/sec, 786 bytes/write.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeah! You see the interrupt vector table (&lt;em&gt;.isr_vector&lt;/em&gt;) section was flashed at the base address of flash memory and other sections after the vector table. If you use any type of interrupt, the ARM Cortex gets the corresponding ISR handler from there so that ARM Cortex exactly knows the ISR handler addresses. You just need to select the required ISR handler function!&lt;/p&gt;

&lt;p&gt;As I said before, ISR handlers are special type of C functions. But why? Because the handlers have predefined function prototypes. You have to use these function prototypes. Otherwise, ARM Cortex cannot find it and treated as normal C functions, not the ISR handlers. &lt;/p&gt;

&lt;p&gt;These predefined handler prototypes are stored in the &lt;em&gt;startup code&lt;/em&gt;. For STM32F446RE, it is &lt;em&gt;startup_stm32f446xx.S&lt;/em&gt; file. Below is a part of this startup code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(...)

  .word  Reset_Handler
  .word  NMI_Handler
  .word  HardFault_Handler
  .word  MemManage_Handler
  .word  BusFault_Handler

(...)

  .word     CAN1_TX_IRQHandler                /* CAN1 TX                      */                         
  .word     CAN1_RX0_IRQHandler               /* CAN1 RX0                     */                          
  .word     CAN1_RX1_IRQHandler               /* CAN1 RX1                     */                          
  .word     CAN1_SCE_IRQHandler               /* CAN1 SCE                     */                          
  .word     EXTI9_5_IRQHandler                /* External Line[9:5]s          */                          
  .word     TIM1_BRK_TIM9_IRQHandler          /* TIM1 Break and TIM9          */         
  .word     TIM1_UP_TIM10_IRQHandler          /* TIM1 Update and TIM10        */         
  .word     TIM1_TRG_COM_TIM11_IRQHandler     /* TIM1 Trigger and Commutation and TIM11 */
  .word     TIM1_CC_IRQHandler                /* TIM1 Capture Compare         */                          
  .word     TIM2_IRQHandler                   /* TIM2                         */                   
  .word     TIM3_IRQHandler                   /* TIM3                         */                   
  .word     TIM4_IRQHandler                   /* TIM4                         */                   
  .word     I2C1_EV_IRQHandler                /* I2C1 Event                   */                          
  .word     I2C1_ER_IRQHandler                /* I2C1 Error                   */                          
  .word     I2C2_EV_IRQHandler                /* I2C2 Event                   */                          
  .word     I2C2_ER_IRQHandler                /* I2C2 Error                   */          

(...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the beginning, I've stated that interrupts are the source of multiprogramming. This is core logic behind the RTOS!&lt;/p&gt;

&lt;p&gt;RTOSes use the interrupts to create many &lt;em&gt;tasks&lt;/em&gt;. In classic firmware written with RTOS, there are many tasks that the RTOS kernel have to handle and manage. You can think that task in the firmware corresponds to process in the computers. &lt;/p&gt;

&lt;p&gt;The RTOS kernel needs to execute these tasks in order and with same time-slice so that the kernel cuts the one task execution and passes to the next task execution using &lt;em&gt;context switches&lt;/em&gt;. This is done by using interrupts. For example, FreeRTOS kernel uses &lt;em&gt;SVC&lt;/em&gt; and &lt;em&gt;PendSV&lt;/em&gt; interrupts specificly to make the contex switch. Apart from that, the RTOS kernel uses also the &lt;em&gt;SysTick&lt;/em&gt; interrupt to give the equal execution time to each task. &lt;/p&gt;

&lt;p&gt;Got it. I've explain the interrupt management in ARM Cortex-M in general. I put the some references below. You can look at the interrupts and similar topics in there.&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;p&gt;[1]. Yiu J., The Definitive Guide to The ARM Cortex-M3, Second Edition, Newnes, page 36.&lt;/p&gt;

&lt;p&gt;Noviello C., Mastering STM32, 0.26 Release, Leanpub&lt;/p&gt;

</description>
      <category>lowcode</category>
      <category>arm</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to write HAL (Hardware Abstraction Layer) Library for MCUs?</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Thu, 16 Oct 2025 10:44:38 +0000</pubDate>
      <link>https://forem.com/cangulmez/how-to-write-hal-hardware-abstraction-layer-library-for-mcus-843</link>
      <guid>https://forem.com/cangulmez/how-to-write-hal-hardware-abstraction-layer-library-for-mcus-843</guid>
      <description>&lt;p&gt;In embedded programming, we use mostly libraries, IDEs, extensions or so on. I'm on that way also. This gives us the simplicity and consistency. But even we should do that at projects, I think that every embedded programmer should now what is going on under the hood!&lt;/p&gt;

&lt;p&gt;In this post, I wanna share how to write a minimal HAL library (just for LED blinking) for STM32F446RE microcontroller. I just will do simple memory mappings and register operations so that it will be simple, but you will learn the most important stuffs about embedded programming.&lt;/p&gt;

&lt;p&gt;Firstly, you have to know exactly two terms: &lt;strong&gt;memory mapping&lt;/strong&gt; and &lt;strong&gt;register operations&lt;/strong&gt;. So embedded programming (nearly) is all about these.&lt;/p&gt;

&lt;p&gt;Every microcontroller has a memory layout and this layout is separated into different groups. We know that which address owns what. For example, if I wanna use GPIO peripheral, I should look at memory address of that GPIO from the microcontroller's &lt;em&gt;reference manual&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In STM32F4 series microcontrollers, 0x40000000 is the base address for all peripherals. Below is a part of peripherals' memory layout:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fttmmv8dlxebhuprfysjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fttmmv8dlxebhuprfysjl.png" alt=" " width="578" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We see the what type of peripheral lays out at which addresses and busses. So we use these addresses when programming embedded device.&lt;/p&gt;

&lt;p&gt;Don't forget that I will just write a minimal library that just can blink the LED. But the logic behind it is persistent for other applications.&lt;/p&gt;

&lt;p&gt;What exactly is there at the peripheral addresses? The question is &lt;strong&gt;registers&lt;/strong&gt;. Every peripheral has a set of registers that make the peripheral usable. Registers are the main topic in embedded world so that you have to know what is exactly it and how works?&lt;/p&gt;

&lt;p&gt;A register is a 32-bit addressed data holder at all and used to do a "work". Every register in a peripheral has a special work and all registers make the peripheral active. We set the bits of these registers so that it is programmed!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Embedded programming is all about the setting up the bits of registers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So that beside the memory mapping, registers must also be defined in the source code. Below is RCC AHB1 peripheral clock enable register as an example (we'll use this to enable the clock of GPIOA port further):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9f744fhdw51gjiu7aqyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9f744fhdw51gjiu7aqyj.png" alt=" " width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After giving the core logic behind the embedded programming, let's start writing library. You can use any IDE/extension for compiling, flashing and debugging. I'm gonna use PlatformIO extension within VS Code. I've created &lt;em&gt;main.h&lt;/em&gt; and &lt;em&gt;main.c&lt;/em&gt; source files. In main.h, I'm gonna define the memory mappings and registers and, in main.c, I will blink the LED. Let's start!&lt;/p&gt;

&lt;p&gt;According to reference manual (look at "2.2. Memory organization"):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#define APB1_BASEADDR               0x40000000UL
#define APB2_BASEADDR               0x40010000UL
#define AHB1_BASEADDR               0x40020000UL
#define AHB2_BASEADDR               0x50000000UL
#define AHB3_BASEADDR               0xA0001000UL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#define GPIOA_BASEADDR              (AHB1_BASEADDR + 0x0UL)
#define RCC_BASEADDR                (AHB1_BASEADDR + 0x00003800UL)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've defined the bus and GPIO port addresses. As I said before, I just write for LED blinking (connected to PA0 pin of microcontroller) so that we just need the GPIO and RCC peripherals.&lt;/p&gt;

&lt;p&gt;By the way, RCC (Reset and Clock Control) is peripheral that is used to reset/clock the microcontroller peripherals. I need to enable the clock of GPIOA port firstly.&lt;/p&gt;

&lt;p&gt;After the defined memory mappings, let's define the peripheral registers. As I said before, we have many registers that belong to its peripheral. It is good practice to use &lt;em&gt;struct&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef unsigned int uint32_t;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef struct {
    volatile uint32_t CR;           /* RCC clock control */
    volatile uint32_t PLLCFGR;      /* RCC PLL configuration */
    volatile uint32_t CFGR;         /* RCC clock configuration */
    volatile uint32_t CIR;          /* RCC clock interrupt */
    volatile uint32_t AHB1RSTR; /* RCC AHB1 peripheral reset */
    volatile uint32_t AHB2RSTR; /* RCC AHB2 peripheral reset */
    volatile uint32_t AHB3RSTR; /* RCC AHB3 peripheral reset */
    volatile uint32_t NA1;          /* Reversed */
    volatile uint32_t APB1RSTR; /* RCC APB1 peripheral reset */
    volatile uint32_t APB2RSTR; /* RCC APB2 peripheral reset */
    volatile uint32_t NA2;          /* Reversed */
    volatile uint32_t NA3;          /* Reversed */
    volatile uint32_t AHB1ENR;      /* RCC AHB1 peripheral clock enable */
    volatile uint32_t AHB2ENR;      /* RCC AHB2 peripheral clock enable */
    volatile uint32_t AHB3ENR;      /* RCC AHB3 peripheral clock enable */
    volatile uint32_t NA4;          /* Reversed */
    volatile uint32_t APB1ENR;      /* RCC APB1 peripheral clock enable */
    volatile uint32_t APB2ENR;      /* RCC APB2 peripheral clock enable */
    volatile uint32_t NA5;          /* Reversed */
    volatile uint32_t NA6;          /* Reversed */
    volatile uint32_t AHB1LPENR;    /* RCC AHB1 peripheral clock enable in low power mode */
    volatile uint32_t AHB2LPENR;    /* RCC AHB2 peripheral clock enable in low power mode */
    volatile uint32_t AHB3LPENR;    /* RCC AHB3 peripheral clock enable in low power mode */
    volatile uint32_t NA7;          /* Reversed */
    volatile uint32_t APB1LPENR;    /* RCC APB1 peripheral clock enable in low power mode */
    volatile uint32_t APB2LPENR;    /* RCC APB2 peripheral clock enable in low power mode */
    volatile uint32_t NA8;          /* Reserved */
    volatile uint32_t NA9;          /* Reserved */
    volatile uint32_t BDCR;         /* RCC backup domain control */
    volatile uint32_t CSR;          /* RCC clock control &amp;amp; status */
    volatile uint32_t NA10;         /* Reserved */
    volatile uint32_t NA11;         /* Reserved */
    volatile uint32_t SSCGR;        /* RCC spread spectrum clock generation */
    volatile uint32_t PLLI2SCFGR;   /* RCC PLLI2S configuration */
    volatile uint32_t PLLSAICFGR;   /* RCC PLL configuration */
    volatile uint32_t DCKCFGR;      /* RCC dedicated clock configuration */
    volatile uint32_t CKGATENR; /* RCC clocks gated enable */
    volatile uint32_t DCKCFGR2; /* RCC dedicated clocks configuration 2 */
} RCC_Handler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef struct {
    volatile uint32_t MODER;        /* GPIO port mode */
    volatile uint32_t OTYPER;       /* GPIO port output type */
    volatile uint32_t OSPEEDR;      /* GPIO port output speed */
    volatile uint32_t PUPDR;        /* GPIO port pull-up/pull-down */
    volatile uint32_t IDR;          /* GPIO port input data */
    volatile uint32_t ODR;          /* GPIO port output data */
    volatile uint32_t BSRR;         /* GPIO port bit set/reset */
    volatile uint32_t LCKR;         /* GPIO port configuration lock */
    volatile uint32_t AFRL;         /* GPIO alternate function low */
    volatile uint32_t AFRH;         /* GPIO alternate function high */
} GPIO_Handler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#define RCC                          ((RCC_Handler *) RCC_BASEADDR)
#define GPIOA                           ((GPIO_Handler *) GPIOA_BASEADDR)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please recheck your reference manual and define the correct registers (look at "6.3. RCC Registers" and "7.4. GPIO Registers").&lt;/p&gt;

&lt;p&gt;Don't forget that each peripheral register has 32-bit length. Also  defining the registers with &lt;strong&gt;volatile&lt;/strong&gt; keyword is good practice. This tells to compiler: "Hey compiler, you don't have to optimize register variables because they will probably be changed quickly".&lt;/p&gt;

&lt;p&gt;Another point is that you have to follow the register offsets. For example, MODER register of GPIOA port is at 0x40020000 so the next register, OTYPER, address should be at 0x40020004 (32-bit offset). Generally, registers are queued so that you just put these in &lt;em&gt;struct&lt;/em&gt; in order. But sometimes, there can be offset gaps, as being in RCC registers. If you look at carefully at &lt;em&gt;RCC_Handler&lt;/em&gt;, there are &lt;em&gt;NAx&lt;/em&gt; (Not Applicable) variables. These are not registers. It's the placeholders. Because of at that offset, any register is not defined.&lt;/p&gt;

&lt;p&gt;Right now, let's define the &lt;em&gt;main()&lt;/em&gt; (entry-point) like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void main(void)
{
    RCC-&amp;gt;AHB1ENR |= (1 &amp;lt;&amp;lt; 0);       /* Enable GPIOA clock */

    GPIOA-&amp;gt;MODER |= (1 &amp;lt;&amp;lt; 0);       /* General purpose output mode */
    GPIOA-&amp;gt;OTYPER &amp;amp;= ~(1 &amp;lt;&amp;lt; 0); /* Output push-pull */
    GPIOA-&amp;gt;OSPEEDR &amp;amp;= ~(3 &amp;lt;&amp;lt; 0);    /* Low speed */
    GPIOA-&amp;gt;PUPDR &amp;amp;= ~(3 &amp;lt;&amp;lt; 0);; /* No pull-up, pull-down */
    GPIOA-&amp;gt;BSRR = (1 &amp;lt;&amp;lt; 0);         /* Set (1 &amp;lt;&amp;lt; 16 for reset) */

    while (1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, we used the &lt;em&gt;bitwise&lt;/em&gt; operations to manipulate the register bits. I assume that you already know it from your programming background.&lt;/p&gt;

&lt;p&gt;What exactly bits are manipulated?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;bit of RCC AHB1 register &lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;and 2. bits of GPIO MODER register&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;bit of GPIO OTYPER register&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;and 2. bits of GPIO OSPEEDR register&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;and 2. bits of GPIO PUPDR register&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;ol&gt;
&lt;li&gt;bit of GPIO BSRR register&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, you can compile and then flash this program to the microcontroller. That's it 🥳🥳🥳.&lt;/p&gt;

</description>
      <category>lowcode</category>
      <category>c</category>
      <category>mcu</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Linux Programming Interface - Time</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Wed, 15 Oct 2025 13:02:40 +0000</pubDate>
      <link>https://forem.com/cangulmez/the-linux-programming-interface-time-2hbk</link>
      <guid>https://forem.com/cangulmez/the-linux-programming-interface-time-2hbk</guid>
      <description>&lt;p&gt;In any type of program, we mostly are interested in two different time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Real (Calendar) time&lt;/em&gt;: This time is measured from a standard point (generally, UTC, 1 January 1970). Obtaining the calendar time is primarily source of what you see at screen of your computer. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Process time&lt;/em&gt;: This is the amount of CPU time used by a process. Measuring process time is useful for checking or optimizing the performance of a program or algorithm.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every computer has a dedicated built-in hardware clock that enables the kernel to measure real and process time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calendar Time and Time Conversion
&lt;/h2&gt;

&lt;p&gt;To handle real time, the GNU libraries give us many functions as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuz9b8cmsnoijig1yfp2w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuz9b8cmsnoijig1yfp2w.png" alt=" " width="579" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are also function signatures that we use when handling time in the program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;time_t time(time_t *tloc);
char *asctime(const struct tm *tm);
char *ctime(const time_t *timep);
struct tm *gmtime(const time_t *timep);
struct tm *localtime(const time_t *timep);
time_t mktime(struct tm *tm);
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;time()&lt;/em&gt; system call returns the number of seconds since the Epoch (1 January 1970) and then this number of seconds are stored in &lt;em&gt;time_t&lt;/em&gt; (&lt;code&gt;typedef long time_t&lt;/code&gt;) data type.&lt;/p&gt;

&lt;p&gt;To convert this number of seconds in printable format, we use the &lt;em&gt;ctime()&lt;/em&gt; function.&lt;/p&gt;

&lt;p&gt;We can also convert this number of seconds into a so-called &lt;em&gt;broken-down time&lt;/em&gt; (&lt;code&gt;struct tm&lt;/code&gt;) by using &lt;em&gt;gmtime()&lt;/em&gt; and &lt;em&gt;localtime()&lt;/em&gt; functions. After that, we see the year, month, week, hours and so on. &lt;/p&gt;

&lt;p&gt;The &lt;em&gt;mktime()&lt;/em&gt; function does vise-verse, translates a broken-down time into number of seconds.&lt;/p&gt;

&lt;p&gt;We also use &lt;em&gt;asctime()&lt;/em&gt; to convert broken-down time to printable format.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgcxbadf92n1v4e4sf0fr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgcxbadf92n1v4e4sf0fr.png" alt=" " width="556" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I put here a simple program that shows the how to use these functions I've described:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Retrieving and converting calendar times */

#include "../linux.h"

#define SECONDS_IN_TROPICAL_YEAR    (365.24219 * 24 * 60 * 60)

void main(int argc, char *argv[])
{
   time_t t;
   struct tm *gmp, *locp;
   struct tm gm, loc;
   struct timeval tv;

   t = time(NULL);
   printf("Seconds since the Epoch: %ld", (long) t);
   printf(" (about %6.3f years)\n", t / SECONDS_IN_TROPICAL_YEAR);

   if (gettimeofday(&amp;amp;tv, NULL) == -1)
      syscall_error();
   printf(" gettimeofday() returned %ld secs, %ld microsecs\n",
      (long) tv.tv_sec, (long) tv.tv_usec);

   gmp = gmtime(&amp;amp;t);
   if (gmp == NULL)
      syscall_error();

   gm = *gmp;  /* Save local copy */

   printf("Broken down by gmtime():\n");
   printf(" year=%d, mon=%d, mday=%d, hour=%d, min=%d, sec=%d ", 
      gm.tm_year, gm.tm_mon, gm.tm_mday, gm.tm_hour, gm.tm_min, gm.tm_sec);
   printf(" wday=%d, yday=%d, isdst=%d\n", gm.tm_wday, gm.tm_yday, gm.tm_isdst);

   locp = localtime(&amp;amp;t);
   if (locp == NULL)
      syscall_error();

   loc = *locp;   /* Save local copy */

   printf("Broken down by localtime():\n");
   printf(" year=%d, mon=%d, mday=%d, hour=%d, min=%d, sec=%d ", 
      loc.tm_year, loc.tm_mon, loc.tm_mday, loc.tm_hour, loc.tm_min, loc.tm_sec);
   printf(" wday=%d, yday=%d, isdst=%d\n", loc.tm_wday, loc.tm_yday, loc.tm_isdst);

   printf("asctime() formats the gmtime() value as: %s\n", asctime(&amp;amp;gm));
   printf("ctime() formats the time() value as: %s\n", ctime(&amp;amp;t));

   printf("mktime() of gmtime() value: %ld secs\n", (long) mktime(&amp;amp;gm));
   printf("mktime() of localtime() value: %ld secs\n", (long) mktime(&amp;amp;loc));

   exit(EXIT_SUCCESS);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;strftime()&lt;/em&gt; function provides us with more precise control when converting a broken-down into printable form. We just put pre-defined specifiers into third argument of &lt;em&gt;strftime()&lt;/em&gt; function. These specifiers:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fioxot3d49kl9b2wat9qh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fioxot3d49kl9b2wat9qh.png" alt=" " width="589" height="712"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below is the another program that shows the function usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* A function that returns a string containing the current time */

#include "../linux.h"

#define BUF_SIZE  1000

/* Return a string containing the current time formatted according to
   the specification in 'format' (see strftime(3) for specifiers).
   If 'format' is NULL, we use "%c" as a specifier (which gives the
   date and time as for ctime(3), but without the trailing newline).
   Returns NULL on error. */

char *currTime(const char *format)
{
   static char buffer[BUF_SIZE];
   time_t t;
   size_t s;
   struct tm *tm;

   t = time(NULL);
   tm = localtime(&amp;amp;t); 
   if (tm == NULL)
      return NULL;

   s = strftime(buffer, BUF_SIZE, (format != NULL) ? format : "%c", tm);

   return (s == 0) ? NULL : buffer;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Timezones
&lt;/h2&gt;

&lt;p&gt;Different countries operate on different timezones and DST regimes. Programs that input and output times must take care of this.&lt;/p&gt;

&lt;p&gt;Timezone information tends to be both voluminous and volatile. So rather than encoding it directly into libraries, the system maintains this information in files under &lt;em&gt;/usr/share/zoneinfo&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To specify a timezone when running a program, we set the &lt;code&gt;TZ&lt;/code&gt; environment variable to a string consisting of a colon followed by one of the timezone names (like TZ=":Pacific/Auckland").&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;tzset()&lt;/em&gt; function is used to obtain the current timezone setting. This function initializes three global variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;char *tzname[2];
int daylight;
long timezone;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function first checks the &lt;code&gt;TZ&lt;/code&gt; environment variable. If this variable is not set, then the timezone is initialized to the default defined in the timezone file &lt;em&gt;/etc/localtime&lt;/em&gt;. If the &lt;code&gt;TZ&lt;/code&gt; environment variable is defined with a value that can't be matched to a timezone file, or it is an empty string, then UTC is used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Locales
&lt;/h2&gt;

&lt;p&gt;Different countries use different conventions for displaying information such as numbers, currency amounts, dates, and times.&lt;/p&gt;

&lt;p&gt;Ideally, all programs designed to run in more than one location should deal with locales in order to display and input information in the user's preferred language and format. This constitutes the complex subject of &lt;em&gt;internationalization (I18N)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Like timezone information, locales are maintained under &lt;em&gt;/usr/share/locale&lt;/em&gt;. Under each locale subdirectory is a standard set of files that specify the conventions for this locale:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfysdu255ptyie3luirz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfysdu255ptyie3luirz.png" alt=" " width="672" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;setlocale()&lt;/em&gt; function is used to both set and query program's current locale. Below is the its function signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;char *setlocale(int category, const char *locale);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two different methods of setting the locale. The &lt;em&gt;locale&lt;/em&gt; argument may be a string specifying one of the locales defined under &lt;em&gt;/usr/lib/locale&lt;/em&gt; or more conveniently &lt;code&gt;selocale(LC_ALL, "")&lt;/code&gt; meaning that locale settings should be taken from environment variables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Process Time
&lt;/h2&gt;

&lt;p&gt;Process time is the amount of CPU time used by a process since it was created. For recording purposes, the kernel separates CPU time into the following two components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;User CPU time&lt;/em&gt; (amount of time spent executing in user mode)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;System CPU time&lt;/em&gt; (amount of time spent executing in kernel mode)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes, we refer to process time as the &lt;em&gt;total CPU time&lt;/em&gt; consumed by the process.&lt;/p&gt;

&lt;p&gt;When dealing with process time, &lt;em&gt;times()&lt;/em&gt; and &lt;em&gt;clock()&lt;/em&gt; functions are used. Signatures are below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;clock_t times(struct tms *buf);
clock_t clock(void);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;times()&lt;/em&gt; system call retrieves process time information (both user and system time separately) and store it into &lt;code&gt;struct tms&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Otherwise, &lt;em&gt;clock()&lt;/em&gt; function is simpler and returns the total amount of CPU time. Below is the basic program that shows both of these functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Retrieving process CPU times */

#include "../linux.h"

void displayProcessTimes(const char *msg)
{
   struct tms t;
   clock_t clockTime;
   static long clockTicks = 0;

   if (msg != NULL)
      printf("%s", msg);

   if (clockTicks == 0) {  /* Fetch clock ticks on first call */
      clockTicks = sysconf(_SC_CLK_TCK);
      if (clockTicks == -1)
         syscall_error();
   }

   clockTime = clock();
   if (clockTime == -1)
      syscall_error();

   printf("clock() returns: %ld clocks-per-sec (%.2f secs)\n",
      (long) clockTime, (double) clockTime / CLOCKS_PER_SEC);

   if (times(&amp;amp;t) == -1)
      syscall_error();

   printf("times() yields: user CPU: %.2f; system CPU: %.2f\n", 
      (double) t.tms_utime / clockTicks, 
      (double) t.tms_stime / clockTicks);
}

void main(int argc, char *argv[])
{
   int numCalls, i;

   printf("CLOCKS_PER_SEC: %ld  sysconf(_SC_CLK_TCK): %ld\n\n",
      (long) CLOCKS_PER_SEC, sysconf(_SC_CLK_TCK));

   displayProcessTimes("At program start:\n");

   numCalls = (argc &amp;gt; 1) ? atoi(argv[1]) : 100000000;
   for (i = 0; i &amp;lt; numCalls; i++)
      (void) getppid();

   displayProcessTimes("After getppid() loop:\n");

   exit(EXIT_SUCCESS);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>lowcode</category>
      <category>c</category>
      <category>linux</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Linux Programming Interface - Memory Mappings</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Thu, 09 Oct 2025 09:25:35 +0000</pubDate>
      <link>https://forem.com/cangulmez/the-linux-programming-interface-memory-mappings-5f4h</link>
      <guid>https://forem.com/cangulmez/the-linux-programming-interface-memory-mappings-5f4h</guid>
      <description>&lt;p&gt;Let's continue discussing the Linux programming with &lt;em&gt;mmap()&lt;/em&gt; system call.&lt;/p&gt;

&lt;p&gt;The mmap() system call creates a new &lt;em&gt;memory mapping&lt;/em&gt; in the calling process's virtual address space. There are two types of mapping:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;File mapping&lt;/em&gt;: A file mapping maps a region of a file directly into the calling process's virtual memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Anonymous mapping&lt;/em&gt;: An anonymous mapping doesn't have a corresponding file. Instead, the pages of the mapping are initialized to 0.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The memory in one process's mapping may be shared with mappings in other processes (MAP_SHARED). This can occur in two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When two processes map the same region of a file, they share the same pages of physical memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A child process created by &lt;em&gt;fork()&lt;/em&gt; inherits copies of its parent's mappings, and these mappings refer to the same pages of physical memory as the corresponding mappings in the parent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also set the memory mapping as private (MAP_PRIVATE) so that other processes cannot see the content of the memory mapping.&lt;/p&gt;

&lt;p&gt;In total, we can use mmap() in four situations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Private file mapping&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Private anonymous mapping&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Shared file mapping&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Shared anonymous mapping&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And don't forget &lt;em&gt;exec()&lt;/em&gt; family erase and rebuild the process virtual memory so that memory mapping is lost.&lt;/p&gt;

&lt;p&gt;If you type the &lt;code&gt;man 2 mmap&lt;/code&gt; and see the its signatures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;mmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;prot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;off_t&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;munmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;msync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mremap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;oldaddr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;oldsize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;newsize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="cm"&gt;/* void *newaddr */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;addr&lt;/em&gt; argument indicates the virtual address at which the mapping is to be located. You should put the &lt;em&gt;NULL&lt;/em&gt; so that kernel selects the proper address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;length&lt;/em&gt; argument specifies the size of the mapping in bytes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;prot&lt;/em&gt; argument is a bit mask specifying the protection to be placed on the mapping and can take PROT_NONE, PROT_READ, PROT_WRITE, PROT_EXEC. For example, PROT_READ | PROT_WRITE means that mapping can be read and written but not executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;flags&lt;/em&gt; argument is a bit mask of options controlling various aspects and can be MAP_PRIVATE and MAP_SHARED.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;fd&lt;/em&gt; and &lt;em&gt;offset&lt;/em&gt; arguments are just for file mapping. But, in case of anonymous mapping, it is good practice to set &lt;em&gt;fd&lt;/em&gt; as -1.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is the simple anonymous file mapping program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"../linux.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;stat&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;strcmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"--help"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;usage_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Wrong command-line usage"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;O_RDONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fstat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;st_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROT_READ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAP_PRIVATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;MAP_FAILED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STDOUT_FILENO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;st_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As can be seen above, for file mapping (private or shared), the following steps are applied:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Obtain the file descriptor that is mapped, typically via a call to &lt;em&gt;open()&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;em&gt;stat()&lt;/em&gt; system call to get the file length in bytes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pass these variables to mmap() system call call with NULL as start address of mapping.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is the another example about shared file mapping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"../linux.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define MEM_SIZE 10
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;strcmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"--help"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;usage_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Wrong command-line usage"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;O_RDWR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MEM_SIZE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROT_READ&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PROT_WRITE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAP_SHARED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;MAP_FAILED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="cm"&gt;/* No longer need 'fd' */&lt;/span&gt;
      &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Current string=%.*s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MEM_SIZE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;            &lt;span class="cm"&gt;/* Update contents of region */&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;MEM_SIZE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="n"&gt;usage_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"String too long"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="n"&gt;memset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MEM_SIZE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="cm"&gt;/* Zero out region */&lt;/span&gt;
      &lt;span class="n"&gt;strncpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;MEM_SIZE&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MEM_SIZE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MS_SYNC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Copied &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt; to shared memory&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we see the writing 10 bytes to shared memory mapping after the zeroing a partition of file mapping. In addition, we see the &lt;em&gt;msync()&lt;/em&gt; system call. It is actually optional but good practice when writing to disk. It ensures that the 10 bytes are written to disk. &lt;/p&gt;

&lt;p&gt;In addition to MAP_PRIVATE and MAP_SHARED, Linux allows a number of other values to be included in the mmap() flags argument:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MAP_ANONYMOUS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAP_FIXED&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAP_LOCKED&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAP_HUGETLB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAP_NORESERVE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAP_PRIVATE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAP_POPULATE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAP_SHARED&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MAP_UNINITIALIZED&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please read the manual page (&lt;code&gt;man 2 mmap&lt;/code&gt;) to learn these flags.&lt;/p&gt;

&lt;p&gt;When talking about memory mapping and virtual memory layout, I wanna give you some virtual memory operations. There are four main system call:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;mprotect()&lt;/em&gt; system call changes the protection on a region of virtual memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;mlock()&lt;/em&gt; and &lt;em&gt;mlockall()&lt;/em&gt; system calls lock a region of virtual memory into physical memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;mincore()&lt;/em&gt; system call allows a process to determine whether the pages in a region of virtual memory are resident in physical memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;madvise()&lt;/em&gt; system call allows a process to advise the kernel about its future patterns of usage of a virtual memory region.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Signatures of these system calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;mprotect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;prot&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;mlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;mlockall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;munlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;munlockall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;mincore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;madvise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;advice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is the simple program about changing the memory protection mapped by mmap() system call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"../linux.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define LEN          (1024 * 1024)
#define SHELL_FMT    "cat /proc/%ld/maps | grep zero"
#define CMD_SIZE     (sizeof(SHELL_FMT) + 20)
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CMD_SIZE&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
   &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROT_NONE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAP_SHARED&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; 
               &lt;span class="n"&gt;MAP_ANONYMOUS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;MAP_FAILED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="cm"&gt;/* Display line from /proc/self/maps corresponding to mapping */&lt;/span&gt;

   &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Before mprotect()&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;snprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CMD_SIZE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SHELL_FMT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;getpid&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
   &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="cm"&gt;/* Change protection on memory to allow read and write access */&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mprotect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROT_READ&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PROT_WRITE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;syscall_error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"After mprotect()&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, firstly I've mapped a shared anonymous memory. mprotect() changes the memory mapping's from none to read and write protections. To see the this change, we can inspect the &lt;em&gt;/proc/PID/maps&lt;/em&gt; file.&lt;/p&gt;

</description>
      <category>c</category>
      <category>linux</category>
      <category>lowcode</category>
      <category>gcc</category>
    </item>
    <item>
      <title>Programming and Flashing MCU without any IDE</title>
      <dc:creator>Can Gulmez</dc:creator>
      <pubDate>Fri, 03 Oct 2025 09:31:41 +0000</pubDate>
      <link>https://forem.com/cangulmez/programming-and-flashing-mcu-without-any-ide-2ho7</link>
      <guid>https://forem.com/cangulmez/programming-and-flashing-mcu-without-any-ide-2ho7</guid>
      <description>&lt;p&gt;Let's dive into embedded world!&lt;/p&gt;

&lt;p&gt;In this post, I will explain the STM32F4 microcontroller programming and flashing without any IDE like STM32Cube IDE.&lt;/p&gt;

&lt;p&gt;Let's start with the programming side. The main interface that we use for programming STM32-based microcontroller is the STM32 Cube HAL (Hardware Abstraction Layer) library. It is implemented by vendor, STMicroelectronics. Also we need the CMSIS (Common Microcontroller Software Interface Standard) library developed by ARM. Additionally, linker script, startup code, and similar files are needed.&lt;/p&gt;

&lt;p&gt;I'm using the PlatformIO extension in VS Code. It handles the all library dependencies, just install that extension and create a new project. The libraries and binaries will be installed and can be used directly. Don't forget that &lt;em&gt;platformio.ini&lt;/em&gt; is the configuration file, edit it according to your microcontroller.&lt;/p&gt;

&lt;p&gt;I've written a example program in &lt;em&gt;/src/main.c&lt;/em&gt; in the PlatformIO project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * Demo Project
 */

#include &amp;lt;stm32f4xx_hal.h&amp;gt;

/**
 * Oscillator and Clock Configuration
 */
void OscClockConfig(void)
{
    /* ... */
}

void main(int argc, char *argv[])
{
        HAL_Init();

    OscClockConfig();

    /* Enable some peripheral clocks over RCC registers */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    /* Configure the PA0 pin just as push-pull output */
    GPIO_InitTypeDef initPA0;
    initPA0.Pin = GPIO_PIN_0;
    initPA0.Mode = GPIO_MODE_OUTPUT_PP;
    initPA0.Pull = GPIO_NOPULL;
    initPA0.Speed = GPIO_SPEED_FREQ_LOW;    /* doesn't matter */
    HAL_GPIO_Init(GPIOA, &amp;amp;initPA0);

    /* Set the PA0 pin to logic 1 (+3.3V) */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, SET);

    while (1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create the proper binary (ELF for GNU/Linux and PE for Windows) that will be flashed into microcontroller, we need to compile it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pio run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget that run this command where platformio.ini is. The output of this command will be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Processing genericSTM32F446RE (platform: ststm32; board: genericSTM32F446RE; framework: stm32cube)
---------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/genericSTM32F446RE.html
PLATFORM: ST STM32 (19.2.0) &amp;gt; STM32F446RE (128k RAM. 512k Flash)
HARDWARE: STM32F446RET6 180MHz, 128KB RAM, 512KB Flash
DEBUG: Current (blackmagic) External (blackmagic, jlink, stlink)
PACKAGES: 
 - framework-stm32cubef4 @ 1.28.1 
 - tool-ldscripts-ststm32 @ 0.2.0 
 - toolchain-gccarmnoneeabi @ 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -&amp;gt; https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 59 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio/build/genericSTM32F446RE/FrameworkHALDriver/Src/stm32f4xx_hal.o
Compiling .pio/build/genericSTM32F446RE/FrameworkHALDriver/Src/stm32f4xx_hal_adc.o

...

Compiling .pio/build/genericSTM32F446RE/FrameworkHALDriver/Src/stm32f4xx_ll_utils.o
Compiling .pio/build/genericSTM32F446RE/src/main.o
src/main.c:15:6: warning: return type of 'main' is not 'int' [-Wmain]
 void main(int argc, char *argv[])
      ^~~~
Compiling .pio/build/genericSTM32F446RE/FrameworkCMSISDevice/gcc/startup_stm32f446xx.o
Compiling .pio/build/genericSTM32F446RE/FrameworkCMSISDevice/system_stm32f4xx.o
Archiving .pio/build/genericSTM32F446RE/libFrameworkCMSISDevice.a
Indexing .pio/build/genericSTM32F446RE/libFrameworkCMSISDevice.a
Linking .pio/build/genericSTM32F446RE/firmware.elf
Checking size .pio/build/genericSTM32F446RE/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home &amp;gt; Project Inspect"
RAM:   [          ]   0.0% (used 40 bytes from 131072 bytes)
Flash: [          ]   0.2% (used 1148 bytes from 524288 bytes)
Building .pio/build/genericSTM32F446RE/firmware.bin
============================================== [SUCCESS] Took 20.12 seconds ==============================================
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this command finished, there will be two files named &lt;em&gt;firmware.bin&lt;/em&gt; and &lt;em&gt;firmware.elf&lt;/em&gt; under &lt;em&gt;./pio/build&lt;/em&gt; directory. &lt;/p&gt;

&lt;p&gt;firmware.bin includes the pure raw machine code that will be written to microcontroller. To flash this, you have to declare the base address of flash memory (0x08000000 in case). firmware.elf includes the pure the machine code plus debug info, sections or so on. This is primarily used for debugger, &lt;em&gt;GDB&lt;/em&gt;. So if you look at the sizes, firmware.elf will be much bigger.&lt;/p&gt;

&lt;p&gt;After producing the binaries and before flashing it, we want sometimes to inspect binary contents. For example, let's look at the section headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ arm-none-eabi-objdump -h firmware.elf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firmware.elf:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .isr_vector   000001c4  08000000  08000000  00010000  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .text         00000470  080001c4  080001c4  000101c4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .rodata       00000000  08000634  08000634  0002000c  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  3 .ARM.extab    00000000  08000634  08000634  0002000c  2**0
                  CONTENTS
  4 .ARM          00000000  08000634  08000634  0002000c  2**0
                  CONTENTS
  5 .preinit_array 00000000  08000634  08000634  0002000c  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  6 .init_array   00000004  08000634  08000634  00010634  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  7 .fini_array   00000004  08000638  08000638  00010638  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  8 .data         0000000c  20000000  0800063c  00020000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  9 .bss          0000001c  2000000c  08000648  0002000c  2**2
                  ALLOC
 10 ._user_heap_stack 00000600  20000028  08000648  00020028  2**0
                  ALLOC
 11 .ARM.attributes 0000002a  00000000  00000000  0002000c  2**0
                  CONTENTS, READONLY
 12 .comment      0000007e  00000000  00000000  00020036  2**0
                  CONTENTS, READONLY
 13 .debug_frame  0000002c  00000000  00000000  000200b4  2**2
                  CONTENTS, READONLY, DEBUGGING, OCTETS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here, we see the many sections. Each section include different stuffs. The machine code will be in &lt;em&gt;.text&lt;/em&gt; section. So it is the main target for reverse-engineering works. Apart from that &lt;em&gt;.data&lt;/em&gt;, &lt;em&gt;.bss&lt;/em&gt; and &lt;em&gt;.rodata&lt;/em&gt; sections will contain the various variable declarations. &lt;em&gt;.isr_vector&lt;/em&gt; is the ARM-specific section that includes the ISRs (Interrupt Service Routines). It is related to the interrupt mechanism in ARM Cortex. &lt;em&gt;.init_array&lt;/em&gt; and &lt;em&gt;.fini_array&lt;/em&gt; sections include the constructor/destructor machine code. These run before/after the &lt;em&gt;main()&lt;/em&gt; (entry-point) function. &lt;em&gt;.debug_frame&lt;/em&gt; is primarily used by GDB debugger. There are also ARM-specific sections that I don't know actually.&lt;/p&gt;

&lt;p&gt;To display the machine code and its corresponding assembly commands, run this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ arm-none-eabi-objdump -s .text -d firmware.elf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or we can see the HAL functions used in the program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ arm-none-eabi-strings firmware.elf | grep HAL_*

HAL_NVIC_SetPriority
HAL_GPIO_WritePin
HAL_MspInit
HAL_GPIO_Init
HAL_SYSTICK_Config
HAL_Init
HAL_NVIC_SetPriorityGrouping
HAL_InitTick
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actually debugging a firmware is the huge topic and deserves a alone post so that I will go with the flashing phase.&lt;/p&gt;

&lt;p&gt;To flash a STM32 microcontroller, we have a few options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;openocd&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;st-flash&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;dfu-util&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before the selecting right tool, we need to determine the programming interface that we're current using. Two interfaces shines in embedded world: &lt;em&gt;SWD (Serial Wire Debug)&lt;/em&gt; and &lt;em&gt;USB&lt;/em&gt;. For ARM-based microcontrollers, SWD is the standard programming/debugging interface. Most modern microcontrollers, additionally, support DFU (Device Firmware Update) interface to program microcontroller over USB. If you plan to use SWD interface, you need a hardware called &lt;em&gt;ST-LINK&lt;/em&gt;. In USB interface, you just need USB cable. But to put the microcontroller in DFU mode, you put the &lt;em&gt;BOOT0&lt;/em&gt; pin to logic 1 (+3.3V). Both interfaces have advantages/disadvantages. You need to select the right tool for your case.&lt;/p&gt;

&lt;p&gt;For this post, I have SWD interface and ST-LINK device. To list and check ST-LINK connection, &lt;em&gt;lsusb&lt;/em&gt; can be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ lsusb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0438:7900 Advanced Micro Devices, Inc. Root Hub
Bus 001 Device 003: ID 0bda:c024 Realtek Semiconductor Corp. Bluetooth Radio 
Bus 001 Device 004: ID 174f:116a Syntek EasyCamera
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0483:374b STMicroelectronics ST-LINK/V2.1
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start with OpenOCD (Open On-Chip Debugger), if you have SWD interface and ST-LINK, the mostly reliable way is to use OpenOCD. It's open source project that supports multiple interfaces and microcontrollers. You can think it as a bridge between ST-LINK and microcontroller. We can use OpenOCD in two different ways. If you just want flashing firmware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program firmware.elf verify reset exit"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select &amp;lt;transport&amp;gt;'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 2000 kHz
Info : STLINK V2J33M25 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.223622
Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
[stm32f4x.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x0800308c msp: 0x20020000
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
** Programming Started **
Info : device id = 0x10006421
Info : flash size = 512 KiB
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
shutdown command invoked
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget that if you want to flash firmware.bin, explicitly, declare the flash address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program firmware.bin 0x08000000 verify reset exit"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also want to debug the firmware beside the flashing it. Firstly, open a OpenOCD session in a terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ openocd -f interface/stlink.cfg -f target/stm32f4x.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select &amp;lt;transport&amp;gt;'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 2000 kHz
Info : STLINK V2J33M25 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.229921
Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that in another terminal, with GDB:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ arm-none-eabi-gdb firmware.elf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be in GDB session. In here, you have to bind 3333 port and then load the firmware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) target remote localhost:3333
(gdb) monitor reset halt
(gdb) load
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the end, you will see the flashed sections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Loading section .isr_vector, size 0x1c4 lma 0x8000000
Loading section .text, size 0x470 lma 0x80001c4
Loading section .init_array, size 0x4 lma 0x8000634
Loading section .fini_array, size 0x4 lma 0x8000638
Loading section .data, size 0xc lma 0x800063c
Start address 0x80005c8, load size 1608
Transfer rate: 3 KB/sec, 321 bytes/write.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firmware is loaded successfully 🥳.&lt;/p&gt;

&lt;p&gt;After this phase, we can start debugging. I will show some commonly used commands but as I said before, this post focus on programming and flashing so that debugging is another post's topic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) info registers        // show register information
(gdb) break main            // put a breakpoint at main()
(gdb) continue              
(gdb) next                  
(gdb) step
(gdb) x/1wx 0x40023830      // examine the RCC register
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another tool is st-flash. You can think that it's STM32-version of OpenOCD. It uses SWD interface and it is used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ st-flash write firmware.bin 0x8000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;st-flash 1.8.0
2025-10-03T12:27:22 INFO common.c: STM32F446: 128 KiB SRAM, 512 KiB flash in at least 128 KiB pages.
file firmware.bin md5 checksum: 19739c7292a119ff141424e01acdf2e8, stlink checksum: 0x0001c4f0
2025-10-03T12:27:22 INFO common_flash.c: Attempting to write 1608 (0x648) bytes to stm32 address: 134217728 (0x8000000)
EraseFlash - Sector:0x0 Size:0x4000 -&amp;gt; Flash page at 0x8000000 erased (size: 0x4000)
2025-10-03T12:27:22 INFO flash_loader.c: Starting Flash write for F2/F4/F7/L4
2025-10-03T12:27:22 INFO flash_loader.c: Successfully loaded flash loader in sram
2025-10-03T12:27:22 INFO flash_loader.c: Clear DFSR
2025-10-03T12:27:22 INFO flash_loader.c: enabling 32-bit flash writes
2025-10-03T12:27:22 INFO common_flash.c: Starting verification of write complete
2025-10-03T12:27:22 INFO common_flash.c: Flash written and verified! jolly good!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;dfu-util is a bit different. Despite openocd and st-flash use SWD interface, dfu-util is used with USB connection. Don't forget that you have to put the microcontroller in DFU mode by setting the BOOT0 pin to logic 1 (+3.3V). After that reset the microcontroller and then flash the firmware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dfu-util -a 0 -s 0x08000000:leave -D firmware.bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>lowcode</category>
      <category>c</category>
      <category>gcc</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
