posts: add m32.md
This commit is contained in:
parent
e49b97a80a
commit
aa2b945765
157
content/posts/m32.md
Normal file
157
content/posts/m32.md
Normal 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 - https://git.dotya.ml/wanderer
|
||||
draft: false
|
||||
toc: true
|
||||
enableGitInfo: true
|
||||
images:
|
||||
tags:
|
||||
- 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.
|
||||
|
||||
```c
|
||||
/* 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
|
||||
[64bit-only](https://wiki.archlinux.org/title/Frequently_asked_questions#What_architectures_does_Arch_support?)
|
||||
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](https://musl.libc.org/)
|
||||
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
|
||||
|
||||
```sh
|
||||
~ % 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:
|
||||
|
||||
```sh
|
||||
~ % 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](https://bbs.archlinux.org/viewtopic.php?pid=1136063#p1136063) points to
|
||||
a (spoiler: *partial*) solution: `lib32-glibc` is needed, so let's install it
|
||||
|
||||
```sh
|
||||
~ % sudo pacman -S lib32-glibc
|
||||
```
|
||||
|
||||
and try again:
|
||||
|
||||
```sh
|
||||
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
/usr/sbin/ld: cannot find libgcc_s.so.1: No such file or directory
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
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
|
||||
`lib32-gcc-libs`:
|
||||
|
||||
```sh
|
||||
~ % sudo pacman -S lib32-gcc-libs
|
||||
```
|
||||
|
||||
Now the program can finally be compiled and run and we can see it's a 32bit
|
||||
binary.
|
||||
|
||||
```sh
|
||||
~ % 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/ld-linux.so.2, BuildID[sha1]=2ff0c8dce8f64db4960aa6aef6cd9936326e990d, for GNU/Linux 4.4.0, not stripped
|
||||
~ % ldd ./32ftw
|
||||
linux-gate.so.1 (0xf7f50000)
|
||||
libc.so.6 => /usr/lib32/libc.so.6 (0xf7ce5000)
|
||||
/lib/ld-linux.so.2 => /usr/lib/ld-linux.so.2 (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
|
||||
day](#installing-deps-and-calling-it-a-day).
|
Loading…
Reference in New Issue
Block a user