How to add custom section to ELF file?

All linux binary applications have a common ELF format (Executable and Linking Format). This format consist of header and variouse sections (see ELF Specification). The ELF allows you to attach custom sections with some extra user-data. It means that you can hide some usefull information inside a binary file (like library for example). Why you would want to use such thing? Well, for many reasons. As for an example I will describe my favourite case. I frequently use custom sections to inject some extra information from CI/CD into binary programs for further identification on testbed/production/devices. I usually use custom flags to pass such info in a compile time. Like in a simplified example bellow.

Example Code

This C++ code be easily ported to ANSI C.

#include <iostream>

#define STRINGIZER(arg) #arg
#define STRVAL(v) STRINGIZER(v)

constexpr const char commit_id[] __attribute__((section("mysection"))) = "commit-id=" STRVAL(COMMIT_ID);
constexpr const char build_time[] __attribute__((section("mysection"))) = "build-time=" STRVAL(BUILD_TIME);

int main(int argc, char *argv[])
{
std::cout << "Hello, World!" << std::endl;
return (0);
}

Compile and read extra data

$ g++ --std=c++2a -Werror -pedantic -DCOMMIT_ID=123 -DBUILD_TIME=321 -o main ./main.cpp
$ readelf -p mysection ./main

String dump of section 'mysection':
[ 0] commit-id: 123
[ 10] build-time: 321

Some final words

  1. The important thing is that your user-section with a custom name points to a block of text, so it can be even a json content.
  2. In an ELF specification you can find information that user-section should not start with a dott (it’s reserved for inner use).
  3. It’s not the only way how you can attach custom sections. You can also use objcopy to inject extra user-data.

 

Leave a Comment