Technology1 min read

Paths in Pieces

By · Published by Everything Blog

In short

The issue arises because GCC on x86-64 platforms optimizes operations like `memcpy` and `std::string` by segmenting constants into vector-sized chunks rather than preserving contiguous text. In tests using GCC 12 or newer, the compiler split directory paths into overlapping 16-byte segments, preventing standard utilities like `grep` and GNU binutils's `strings` from matching the full original text. Additionally, GCC deduplicates repeating patterns in padded placeholder strings, compressing an intended 256-byte path down to 176 bytes. This compression disrupts in-place patching workflows relied upon by tools like Spack and Conda to alter binary targets post-compilation.

Key points

  • Strings copied into buffers are fragmented during compiler optimization, whereas strings…: Strings copied into buffers are fragmented during compiler optimization, whereas strings passed strictly as pointers remain intact in the binary.
  • Relocation systems in package managers like Conda and Spack break when padded placeholder…: Relocation systems in package managers like Conda and Spack break when padded placeholder strings are compressed and lose their contiguous sequence.
  • Traditional text-scanning utilities can no longer be solely relied upon to catch unwanted…: Traditional text-scanning utilities can no longer be solely relied upon to catch unwanted absolute paths in modern x86-64 binaries.

Sources checked by our analysis pipeline: 1

Nov 12th, 2026

Many[1][2][3][4][5][6][7][8][9] Linux distributions and package managers audit just-built binaries for non-relocatable absolute paths. If a binary contains a path /path/from/build/machine

, it might not run on the end-user's machine.

Now, a basic grep

on the binary, or a slightly more sophisticated

$ strings bin/app | grep /path/from/build/machine

using GNU binutils's strings

will detect these paths, right?

The answer is no, at least when using GCC and targeting x86-64

: you should not assume that string constants end up literally in the binary.

Basic example

In this C++ source we create a std::string

from a string constant:

#include <iostream>

#include <string>

#define PREFIX "/home/linuxbrew/.linuxbrew"

int main() {

std::string prefix{PREFIX};

std::cout << prefix << '\n';

}

Compile with GCC 12 or later and run, which prints the path:

$ g++ -O2 main.cpp -o main

$ ./main

/home/linuxbrew/.linuxbrew

But the path occurs precisely 0 times in the binary itself:

$ grep -acF /home/linuxbrew/.linuxbrew main

0

$ strings ./main | grep -cF /home/linuxbrew/.linuxbrew

0

Surely these bytes must be part of the binary somewhere? Let's run strings

on it and grep…

Technology