posts: add
continuous-integration/drone/push Build is passing Details
continuous-integration/drone Build is passing Details

This commit is contained in:
leo 2023-06-14 14:14:25 +02:00
parent e49b97a80a
commit aa2b945765
Signed by: wanderer
SSH Key Fingerprint: SHA256:Dp8+iwKHSlrMEHzE3bJnPng70I7LEsa3IJXRH/U+idQ
1 changed files with 157 additions and 0 deletions

content/posts/ Normal file
View File

@ -0,0 +1,157 @@
title: "Compiling C programs using -m32 on Arch in 2023"
description: "Compiling C programs for 32bit on Arch in 2023"
date: 2023-06-14T12:32:52+02:00
author: wanderer -
draft: false
toc: true
enableGitInfo: true
- archlinux
- compilation
- 32bit
## Intro
> **Preliminary:** To be clear, this short post is not primarily concerned with
> *running* the 32bit programs, instead specifically *compiling C programs for
> 32bit (x86)*.
Compiling a `C` program for a 32bit architecture in 2023?
Well, one might still want to poke at reversing smaller address-space programs,
*even in 2023*, and contrary to the popular belief, there still exist pieces of
software not ported to 64bit and architectures in use that are 32bit. Whatever
the motivation, the *compilation* process might not be as straight-forward on
Arch as one would maybe expect, so this post shows how it can be done. Unless
specified otherwise, the `x86` architecture is assumed.
### Example program
> Just show the example program already!
Nothing fancy, just saying hi and printing the value of `esp`. All that is
needed is to compile this into a 32bit binary.
/* 32ftw.c */
#include <stdio.h>
int main() {
printf("hey 32!\n");
register int e asm("esp");
printf("esp: 0x%08x\n", e);
return 0;
For reference, the`GCC` version used was `gcc (GCC) 13.1.1 20230429`.
## TL;DR
To compile a 32bit `C` program on
Arch, additional packages (on top of compilers/linkers) are required. As of
2023-06-14 these are:
* `core/lib32-glibc`
* `core/libr32-gcc-libs`,
which are the GNU C library (could also use [musl libc](
but that would probably necessitate compiler wrapping as GCC seems to prefer
the GNU versions), and the 32bit version of the GCC libraries, respectively.
### Installing deps and calling it a day
~ % sudo pacman -S lib32-glibc lib32-gcc-libs
resolving dependencies...
looking for conflicting packages...
Package (2) New Version Net Change
core/lib32-gcc-libs 13.1.1-1 113.12 MiB
core/lib32-glibc 2.37-3 18.06 MiB
Total Installed Size: 131.18 MiB
:: Proceed with installation? [Y/n]
## The longer version
If you ever needed to compile some `C` sources (such as the example listed
[here](#example-program)) on Arch into a 32 bit binary? You might have
encountered the following:
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
In file included from /usr/include/features.h:515,
from /usr/include/bits/libc-header-start.h:33,
from /usr/include/stdio.h:27,
from 32ftw.c:2:
/usr/include/gnu/stubs.h:7:11: fatal error: gnu/stubs-32.h: No such file or directory
7 | # include <gnu/stubs-32.h>
| ^~~~~~~~~~~~~~~~
compilation terminated.
Alright, a quick search and [an answer on Arch
forums]( points to
a (spoiler: *partial*) solution: `lib32-glibc` is needed, so let's install it
~ % sudo pacman -S lib32-glibc
and try again:
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../ when searching for
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../ when searching for
/usr/sbin/ld: skipping incompatible /usr/lib/ when searching for
/usr/sbin/ld: cannot find No such file or directory
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../ when searching for
/usr/sbin/ld: skipping incompatible /usr/lib/ when searching for
collect2: error: ld returned 1 exit status
> Oh no, it still refuses to work.
As is *somewhat* hinted in the linker's error message depicted above, the
problem can be rectified by installing the GCC libraries (the 32bit version, of
course), which in Arch's `core` repository lives under the name
~ % sudo pacman -S lib32-gcc-libs
Now the program can finally be compiled and run and we can see it's a 32bit
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
hey 32!
esp: 0xff8d27f0
~ % file ./32ftw
32ftw: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/, BuildID[sha1]=2ff0c8dce8f64db4960aa6aef6cd9936326e990d, for GNU/Linux 4.4.0, not stripped
~ % ldd ./32ftw (0xf7f50000) => /usr/lib32/ (0xf7ce5000)
/lib/ => /usr/lib/ (0xf7f52000)
## Closing words
To sum up, compiling a `C` program for 32bit on contemporary Arch works fine
with just a handful of dependencies. In author's opinion, this could be
highlighted better in the Archwiki, but perhaps the target audience is so small
that it hasn't even been considered.
For a not-much-talking summary, check out [TL;DR's calling it a