And kudos to you for following up with your own exploration. It's so often the case that the most interesting stuff is hidden in what other people are wrong about.
A valid point! Clearly the correct solution would be for the kernel module to check if the filename contains the substring "32", and if so it should load it as a 32-bit binary.
So I read the other article, and I saw that bit that disagreed with my essay. My first thought was, "Oh, of course that's how it works. How did I get that so wrong?" My only excuse was that this essay was originally a tech talk and I was under a deadline. (But I really should have caught it when I wrote it up as an essay.)
So I was going to go edit my essay, when I learned that my essay was also posted on Hacker News. And now I discover that someone has already called out my error before I could fix it. Sigh.
Anyway, I just thought I should acknowledge this before I go to fix it.
I couldn't help myself. Despite my better judgement, I wrote an extension to my original essay specifically dissecting this response. (It's now linked at the bottom of the original page.)
I don't think that's a fair characterization of the statement. It's the type of mistakes, not the bare fact of them, that suggests a lack of what we could call "understanding".
If I complain about an answer given to me by one librarian, I'm complaining about that answer and that librarian. If you can find a more knowledgeable librarian somewhere else, that doesn't affect my complaint.
But to be clear, there are no screenshots in the essay. I assimilated the HTML directly into the document.
Look, I understand your point. I really do. But I feel that (perhaps due to one or more of your acknowledged biases) you're applying the wrong context to the situation at hand.
Namely: this is INTERCAL. There is no freaking standard. The "standard" is a 60-page text file written in 1973. The current compiler was written 90% based on this joke-filled document, and 9% new ideas because ESR came up with something even more ridiculous. (The remaining 1% was Don Woods responding to emailed questions by consulting his memory. He still has paper copies of the SPITBOL source code, but the original compiler hasn't been run in over 50 years.) There is no standard because at any given time there are at most three people on the planet who care one iota about INTERCAL standardization, and are only willing to put in any effort if it would be funny. So, for example, the question of what sort of randomness the double-oh-seven operator is contractually required to use is simply not a contextually relevant question.
You seem to be suggesting that it might be possible, even thinly so, that Chat-GPT somehow misapplied a strict standard of randomness in the formation of its response, instead of simply papering over a hole in its knowledge with a bit of improvised plausible-sounding guesswork, a well-documented behavior of both Chat-GPT and thinking entities worldwide. If not, then I humbly apologize for misunderstanding your point. Otherwise, I must politely agree to disagree.
And I'm sorry that my essay rubbed you the wrong way. Perhaps one day you will find it better than you do now, but if not then I hope it passes from your memory quickly.
And again, a heady mix of accurate observations with complete bullshit. Separating out the misinformation is, as always, left as an exercise for the reader.
Nice to see another approach to this subject! Kudos to the author.
I have a couple of responses to specific points brought up in the article.
The author suggests that the original 45-byte executable no longer works on modern systems. If so, this is news to me. Admittedly my current machine is a bit behind the cutting edge (4.15), but what's there should still work. If people are finding the current version to fail for them, I'd appreciate some details on their setup.
* I respectfully disagree that 32-bit executables are "less relevant" today; I suspect they will continue to be supported for many, many years to come. Of course for a new explorer 64-bit executables are far more interesting, but when you're shaving bytes at a time, you can't beat a 32-bit executable.
* Many people are unaware that my original essay is only the first of a series that I wrote. (All of the essays are linked at the bottom of the original.) I note that my smallest 64-bit ELF executable without introducing invalid fields is also 120 bytes, so that's cool.
* However, by taking advantage of unvalidated fields, I was able to produce a working 64-bit ELF executable that is 84 bytes in size. The overlapping is a bit tricky, but I've verified that it continues to work on my box. See http://www.muppetlabs.com/~breadbox/software/tiny/return42.h... -- all variations of my return-42 executables are collected there.
* My smallest 64-bit ELF executable that prints "hello, world\n" (no punctuation: I always use the string from K&R) is 98 bytes. I don't have the assembly for that one posted on my site, but it uses the same layout as the 86-byte executable.
I find I need to quote myself from 2013, as I can't really add anything further to it:
> Wow. I honestly wasn't expecting to ever see this on the front page of HN again, given the current ubiquity of 64-bit Linux. (And yes, before anyone asks, I've played around with minimizing 64-bit executables. Unfortunately they are both larger and less forgiving of tomfoolery. The smallest 64-bit ELF I've created is 84 bytes.)
> Since it is here, though, I want to take the opportunity to say thanks to everyone who's expressed their appreciation of my essay. And I should note here that writing that essay, so many years ago now, is one of the better thing I've done for my career. Share what you have to learn the hard way; the effort won't be wasted.
> Is the author stating that _start is an interface to the OS then? It's interesting I never thought of this as being an interface.
Perhaps it's not the best term, but it's not really incorrect. I probably wouldn't phrase it that way today (20 years later).
> Is this just a long-winded way of saying _start sets up the stack for the new process? WIthout a stack you can't "set up" argc, argv etc.
Well -- to be precise, the stack is created by the kernel during the exec system call. The kernel also copies the argument and environment strings into the process's memory. However, the kernel does not create the argv array of pointers, or the envp array. Building those arrays is the job of _start(), and that is what I meant by "setting up argc and argv".
Please note: That was the case back in 1999. Things are different now -- I think it changed with the 64-bit kernel? In any case, nowadays the ELF loader in the kernel also builds the arrays.
> I would also be curious what "among other things" might include.
As before, it depends on the C runtime. The _start() function might ensure proper initialization of libc, for example. (Again, with current binaries that's usually done via an `.init` section, but in 1999 that was not the norm.)
(Note: I'm assuming from the reference to "map layout" that this comment is directed at the original article, and not the video mentioned in the parent comment.)
Reading the assembly language is what many (perhaps most?) people would do at that point. But not everyone is as comfortable with reading assembly, and I wanted to show that a lot can be done without taking that step.
Also, "easier" is a relative term. It was far, far easier for me to examine the data files sitting comfortably in front of my Linux box, than to try to pull together a decent debugging setup inside of a dosbox before making any headway. There's always more than one way to do it.
I'm afraid that's something I don't have any experience with. However, another commenter mentioned a cool video he did on just this subject, at https://news.ycombinator.com/item?id=21728298 -- so maybe check that out?
Thanks for the kind feedback. Unfortunately I don't know much about communities. Most people who do reverse engineering focus on examining code/assembly, but my limited experience is solely with data files.