
x86: Deprecate a.out support - turrini
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=eac616557050737a8d6ef6fe0322d0980ff0ffde
======
gumby
To fix the nomenclature confusion in this thread:

a.out was the name of the output file from unix linker. Thus the format of
that file was "a.out" format. all the other unix toolchains did the same thing
for compatibility.

a.out is pretty limited, though fine for small PDP-11 binaries: some text
(executable), initialized data, and an amount of RAM to preallocate, plus some
symbols.

Even when I was designing bfd back in 1989 it was clear that a.out, while
pervasive, just wasn't powerful enough, especially when you added C++
constructors, destructors, atexit stuff etc. SVR4 by then had COFF to be more
flexible (Microsoft's PE is a COFF derivative). But COFF was kinda crufty (not
bad for a first effort!) and was clumsy for things like shared libraries.

ELF is a good example of a standards committee designing something to handle
known problems. It's not perfect, but pretty good.

~~~
egorfine
I'm curious to learn: what C++ constructors have to do with the executable
format? I do get that atexit might require a special place in the binary for
the kernel to jump to, but how does a relatively high end language feature
drop down to binary format?

~~~
gumby
> how does a relatively high end language feature drop down to binary format?

All high end language features drop down to binary formats -- that's what ABIs
are.

In the case of things like constructors and destructors you can of course just
stick them all in the text section and have the linker construct call to them
in some fashion. You'd have to use some reserved name mangling to distinguish
them so that the linker can even _find_ them.

If instead you have separate sections the linker can just run through the
symbol table; the dynamic loader can even do so so the compile-time linker can
ignore those sections (just copy them). You can even play tricks like
unloading them after running (or only load exit code upon exit) if memory
games like that matter. etc etc.

It's all about how you communicate semantic issues from compile time to run
time, as with all ABI issues.

------
ihuman
Is this related to the a.out file that gcc outputs if you don't specify a
filename with -o? Also, I thought bit rot was bits in files changing over time
due to the storage medium failing; is this a different use of the term?

~~~
pwg
> Is this related to the a.out file that gcc outputs if you don't specify a
> filename with -o?

It is not directly related to the filename used by gcc. It is related to the
a.out binary executable file format
([https://en.wikipedia.org/wiki/A.out](https://en.wikipedia.org/wiki/A.out)).
It is confusing due to the file format, and the choice of default name by gcc,
having the same name.

> Also, I thought bitrot was bits in files changing over time due to the
> storage medium failing;

That is the usual meaning for "bitrot".

> is this a different use of the term?

To some extent yes. In this context the use of "bitrot" is related to parts of
the source code drifting apart from changes made in other areas of the source.
So in a very broad sense, a similar meaning, but also a very contextual based
meaning.

~~~
SilasX
Am I reading that Wikipedia link right, that the default name of compiled
executables is a.out because they originally _were_ emitted in that format?

~~~
Sniffnoy
No, you've got it backwards. The format is called that because it was the
format of the a.out file.

~~~
SilasX
So they named the standard compiler output "a.out", for independent reasons,
and when it came time to distinguish formats, they called the original
standard format "a.out" just because that's what the file name always was?

~~~
Sniffnoy
Exactly. I mean, I don't know the exact history of when the name "a.out" got
transferred to the format, but I have to assume that it wasn't until there was
something to contrast it with.

------
TorKlingberg
I don't think I have ever encountered an a.out binary in many years of using
Linux. The default compiler output file is named a.out, but it's actually in
ELF format.

I have encountered COFF executables, and been part of a COFF->ELF transition
on a embedded system, but Linux never supported COFF afaik.

~~~
pkaye
In the earlier days the executables were all a.out format. There was a
transition year where all the ELF binaries were slowly being converted over to
ELF format in the Linux distributions. There was a similar transition when
unicode became standard.

~~~
qubex
I remember that. I was running Slackware at the time and I had an eventful
couple of months...

------
girst
the thread about this in the kernel mailing list:
[https://lore.kernel.org/lkml/20190305145717.GD8256@zn.tnic/](https://lore.kernel.org/lkml/20190305145717.GD8256@zn.tnic/)

------
jepler
I thought we didn't break userspace

~~~
Arnt
Sure. But is there an a.out userspace? How do you make a.out binaries on linux
today?

~~~
ktjfi
Isn't a.out the default output format of gcc? I think if you type "gcc
myfile.c" you get an a.out executable.

~~~
benj111
As others have pointed out it's an elf file called a.out.

I would like to ask who's idea it was to name GCCs default output after a
completely different file format ?!

~~~
Arnt
gcc copied most of its command-line arguments from older compilers, including
-o, and the default value if -o isn't set was also copied.

So the command-line arguments and defaults are older than the ELF format. When
ELF support was added, the question was: Should the default value for -o
depend on other arguments? There didn't seem to be good reason to have a
complicated default, and keeping the simple default provided compatibility
with old scripts and makefiles.

cd tests ; for a in *.c ; do gcc $a && ./a.out ; done

------
icedchai
I remember upgrading my Slackware box from a.out to ELF back in 1995 or so.

~~~
ordu
What did it meant? I'm just curious, was it the issue of dynamic library
format, or need to change ld.so, or what?

~~~
icedchai
It's been 20+ years, so I'm a bit fuzzy on the details. I do recall having to
at least build a new kernel with ELF support, then a compile a new libc and
ld.so. My system had a mix of both a.out and ELF binaries for a while. This
was a "heavily customized" Slackware, circa 1994, where I installed the base
system then upgraded things from source...

------
oflebbe
Wow this is 25 years ago? I can vaguely remember when Eric Youngdale
approached libc's HJ Lu to fix shared libs by not reinventing the wheel but
using Sys V ELF. Great article by Eric back than
[https://www.linuxjournal.com/article/1060](https://www.linuxjournal.com/article/1060)
.

------
NelsonMinar
I still have some ancient statically linked a.out Linux binaries lying around
from my old projects where the compile environment was sufficiently
complicated I don't think I could easily recompile the code. I appreciate that
I can still run the binaries. But I think the last time I actually needed to
was ~8 years ago.

~~~
TazeTSchnitzel
I wonder if such files could be converted to elf.

~~~
grawprog
Seems like it should be possible.

[https://stackoverflow.com/questions/15291168/how-to-
convert-...](https://stackoverflow.com/questions/15291168/how-to-convert-
linux-kernel-bin-into-elf-format)

You can do it the other way around.

[https://www.systutorials.com/docs/linux/man/1-elftoaout/](https://www.systutorials.com/docs/linux/man/1-elftoaout/)

------
cracauer
At the time I wasn't happy with that change. All of the BSD's did shared
libraries with a.out just fine. The BSDs used GNU binutils, so the
improvements were there to use for Linux. Linux' change away from a.out meant
that binutils stopped developing a.out support, which then forced an ELF
change on the BSDs.

At the time I could run an entire firewall on a 1.44 MB floppy, kernel, libs
and enough userland for ipfw scripting. With FreeBSD 2.x. FreeBSD 3.x with ELF
put that right out of reach.

Of course now that I spend my days parking silly stuff in random ELF sections
I am pretty happy.

------
avian
Interesting bit from Wikipedia:

“Linux's transition to ELF was more or less forced due to the complex nature
of building a.out shared libraries on that platform, which included the need
to register the virtual address space at which the library was located with a
central authority, as the a.out ld.so in Linux was unable to relocate shared
libraries.”

[https://en.wikipedia.org/wiki/A.out](https://en.wikipedia.org/wiki/A.out)

------
tomc1985
Man, my very first C program was a file called a.out

RIP :/

