diff --git a/2001/anonymous/Makefile b/2001/anonymous/Makefile index 31eb5540d..8c3e82fa9 100644 --- a/2001/anonymous/Makefile +++ b/2001/anonymous/Makefile @@ -190,12 +190,12 @@ all: data ${TARGET} supernova deep_magic magic charon pluto ${PROG}: ${PROG}.c + @echo "NOTE: this entry seems to no longer work." magic='${CC} ${CFLAGS}'; \ X='-DA(X)=#X'; \ warning='-Dprocessor'; \ $$magic $$warning -Dmagic= $$X "-DX=A($$magic \"$$X\")" \ $< -o $@ ${LIBS} - anonymous.c # alternative executable # diff --git a/2001/anonymous/README.md b/2001/anonymous/README.md index 1ea456b36..3e4f1ea24 100644 --- a/2001/anonymous/README.md +++ b/2001/anonymous/README.md @@ -9,136 +9,151 @@ make ``` -### To run: +## To run: ```sh -./anonymous file +./anonymous program ``` -### Try: +NOTE: this entry seems to no longer work. [Cody Boone +Ferguson](/winners.html#Cody_Boone_Ferguson) has offered some tips in the +[bugs.md](/bugs.md) file for anyone who mights want to try and fix this but it +seems to require a lot of parsing, debugging, an x86 system and possibly knowing +the internals of the ELF format (x86 specific). You need to run the program on a +binary to test. See the try section below for a program that, if you get the +entry to work, would be okay to test it on. Thank you and we will happily credit +you if you fix this. + +WARNING: if you do get this to work it will destroy files that it is used on. +See the author's warning on this. + + +## Try: ```sh -./anonymous anonymous.ten.c +make anonymous.ten +./anonymous anonymous.ten ``` + ## Judges' comments: - Is emulation the sincerest form of flattery? This small program does - quite a lot of bit twiddling. +Is emulation the sincerest form of flattery? This small program does +quite a lot of bit twiddling. ## Author's comments: - This program is an optimizing dynamic binary translator, allowing you to - run x86 programs on any machine (x86 or otherwise). +This program is an optimizing dynamic binary translator, allowing you to +run x86 programs on any machine (x86 or otherwise). - I have included a simple "10 green bottles" program, already compiled - for the x86. The program 'ten', and its source (dull) are given as info - files. Warning: note that the translator screws around with the binary - you run on it, *will* corrupt the binary to some extent, and may leave - any program you run on it unusable. +I have included a simple "10 green bottles" program, already compiled +for the x86. The program 'ten', and its source (dull) are given as info +files. Warning: note that the translator screws around with the binary +you run on it, *will* corrupt the binary to some extent, and may leave +any program you run on it unusable. - The build script should give an example command to run. +The build script should give an example command to run. - Features +### Features - Basic Block Cache: Rather than translating each instruction individually - the dynamic binary translator generates a translation for an entire - basic block of subject code. Having translated a block once, the target - code generated will be stored for the duration that the program is - running, so as a program runs its performance will improve, as it hits - cached blocks. This can be clearly observed in the example program, - 'ten'. +Basic Block Cache: Rather than translating each instruction individually +the dynamic binary translator generates a translation for an entire +basic block of subject code. Having translated a block once, the target +code generated will be stored for the duration that the program is +running, so as a program runs its performance will improve, as it hits +cached blocks. This can be clearly observed in the example program, +'ten'. - Target Library Linking: +### Target Library Linking: - The program runs dynamically linked elf binaries, and when the subject - program attempts to make a call to a standard library, the translator - attempts to make an appropriate call to the native system libraries on - the target machine. This involves mangling between different calling - conventions, etc. +The program runs dynamically linked elf binaries, and when the subject +program attempts to make a call to a standard library, the translator +attempts to make an appropriate call to the native system libraries on +the target machine. This involves mangling between different calling +conventions, etc. - Automatic Endian Detection/Reversal: +### Automatic Endian Detection/Reversal: - There are various problems raised when attempting to run little endian - x86 code on a big endian chip, such as a PPC. These problems are dealt - with in a manner that is entirely transparent to the user. +There are various problems raised when attempting to run little endian +x86 code on a big endian chip, such as a PPC. These problems are dealt +with in a manner that is entirely transparent to the user. - Configuration +### Configuration: - Warnings: +#### Warnings: - By default the build script should compile the program with a set of - switches such that while compiling the program it generates one error - (which I feel is useful advice). The program should generate no further - compiler errors while it is running (yes, the program can generate - compiler errors while it is running). If you do not wish to see this - error, or if the program generates any further error when compiled using - your C compiler please remove the "warning=..." line from the build - script. +By default the build script should compile the program with a set of +switches such that while compiling the program it generates one error +(which I feel is useful advice). The program should generate no further +compiler errors while it is running (yes, the program can generate +compiler errors while it is running). If you do not wish to see this +error, or if the program generates any further error when compiled using +your C compiler please remove the "warning=..." line from the build +script. - Optimization: +### Optimization: - The build script contains a "-O1" switch for the compiler. Increasing - the optimization level will make the program run *slower*, while - compiling the program without any optimization will allow it to run - *faster*. +The build script contains a "-O1" switch for the compiler. Increasing +the optimization level will make the program run *slower*, while +compiling the program without any optimization will allow it to run +*faster*. - Obfuscation +### Obfuscation: - The most obvious part of the obfuscation is probably the mess of defines - at the top. This may seem a somewhat tired old obfuscation - however - since many of these macros are (sometimes only) used by the program once - it has dynamically recompiled itself, they are only referenced within - the source code from within strings - and therefore the macros cannot be - expanded. Furthermore, some of these strings of code are not given as - strings, but instead are wrapped up in macros that use the "#" - preprocessor operator to turn them into strings. In the hope throwing a - few C beautifiers the macro to generate the strings is not contained - within the source code but instead is passed in on the command line. +The most obvious part of the obfuscation is probably the mess of defines +at the top. This may seem a somewhat tired old obfuscation - however +since many of these macros are (sometimes only) used by the program once +it has dynamically recompiled itself, they are only referenced within +the source code from within strings - and therefore the macros cannot be +expanded. Furthermore, some of these strings of code are not given as +strings, but instead are wrapped up in macros that use the "#" +preprocessor operator to turn them into strings. In the hope throwing a +few C beautifiers the macro to generate the strings is not contained +within the source code but instead is passed in on the command line. - Buried under all this, and the fact that the entire program is just a - call to exit, there are some nice subtle little obfuscations. For - example, you may notice that there are a couple of macros that use the - "##" preprocessor operator to build pairs of functions. One of these - macros is used to build to pairs of functions of which only one has - local variables which shadow global variables; so one modifies the - global state, and the other doesn't. +Buried under all this, and the fact that the entire program is just a +call to exit, there are some nice subtle little obfuscations. For +example, you may notice that there are a couple of macros that use the +"##" preprocessor operator to build pairs of functions. One of these +macros is used to build to pairs of functions of which only one has +local variables which shadow global variables; so one modifies the +global state, and the other doesn't. - There is also quite a nice trick where I wave a magic wand, and a chunk - of code which should only be run when the program is run for the first - time (setting the PC to point at main, etc) gets turned into a - frog^M^M^M^Mstring. The C compiler sees a string by itself in the code, - thinks "yup, thats a valid C expression", and quietly moves on to the - next line of code. +There is also quite a nice trick where I wave a magic wand, and a chunk +of code which should only be run when the program is run for the first +time (setting the PC to point at main, etc) gets turned into a +frog^M^M^M^Mstring. The C compiler sees a string by itself in the code, +thinks "yup, that's a valid C expression", and quietly moves on to the +next line of code. - Limitations +### Limitations: - Due to space limitations only a handful of instructions are supported, - those instructions which are supported may supported in somewhat - non-conventional ways, chunks of the architecture (e.g. flags) are just - ignored, the elf loader does not really load the elf binary, the target - library linking can only pass up to 3 parameters to the target library - function, etc, etc, etc. +Due to space limitations only a handful of instructions are supported, +those instructions which are supported may supported in somewhat +non-conventional ways, chunks of the architecture (e.g. flags) are just +ignored, the elf loader does not really load the elf binary, the target +library linking can only pass up to 3 parameters to the target library +function, etc, etc, etc. - In short, please consider this a full disclaimer for any bug that may - turn up - yes the program is unsafe, but it's pretty cool anyway. +In short, please consider this a full disclaimer for any bug that may +turn up - yes the program is unsafe, but it's pretty cool anyway. - Despite all this, the translator is not exclusively limited to running - the 'ten' program. Other trivial x86 programs may run on the translator - - and I have successfully run a wide range of HelloWorld programs, - including one of last years IOCCC winners, 'tomx'. +Despite all this, the translator is not exclusively limited to running +the 'ten' program. Other trivial x86 programs may run on the translator +\- and I have successfully run a wide range of HelloWorld programs, +including one of last years IOCCC winners, 'tomx'. - Complete Program +### Complete Program: - The fact that the program makes calls to system and execv may imply that - it is not a complete program in its own right, as it relies on other - programs. The call to system is a call to ask gcc to recompile the - translator with a new set of switches, and the call to execv asks for - the newly compiled program to be executed. I would point out that - almost every other entry to this competition also require a C compiler - (well, the published winners at any rate, and I recognize that a few - don't). There is little real difference between this program and one - like last years entry 'dhyang'; both are just C programs that generate C - code as their output. +The fact that the program makes calls to system and execv may imply that +it is not a complete program in its own right, as it relies on other +programs. The call to system is a call to ask gcc to recompile the +translator with a new set of switches, and the call to execv asks for +the newly compiled program to be executed. I would point out that +almost every other entry to this competition also require a C compiler +(well, the published winners at any rate, and I recognize that a few +don't). There is little real difference between this program and one +like last years entry 'dhyang'; both are just C programs that generate C +code as their output. - Enjoy, thanks! +Enjoy, thanks! diff --git a/2001/anonymous/anonymous.c b/2001/anonymous/anonymous.c index ccb9851ef..7572a0776 100644 --- a/2001/anonymous/anonymous.c +++ b/2001/anonymous/anonymous.c @@ -2,6 +2,8 @@ #include #include +#include +#include #define l int* #define F char diff --git a/2001/anonymous/anonymous.ten.c b/2001/anonymous/anonymous.ten.c index 9118a79ea..e80570852 100644 --- a/2001/anonymous/anonymous.ten.c +++ b/2001/anonymous/anonymous.ten.c @@ -10,7 +10,7 @@ int main() { while(bottles) { sing(bottles); sing(bottles); - printf("And if one green bottle should accidently fall,\nThere'd be "); + printf("And if one green bottle should accidentally fall,\nThere'd be "); sing(--bottles); printf("\n"); } diff --git a/bugs.md b/bugs.md index 1528649fa..ce1788975 100644 --- a/bugs.md +++ b/bugs.md @@ -33,6 +33,46 @@ related to making it work under macOS as all that did was removing some invalid prototypes and use `printf()` instead of the invalid pointer to it (incompatible type). +### [2001/anonymous](2001/anonymous/anonymous.c) ([README.md](2001/anonymous/README.md)) + +This entry seems to no longer work and we would appreciate any help from anyone +who can fix this. [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) has +the following hints that might help but he has no system where he could test +it. [Yusuke Endoh](/winners.html#Yusuke_Endoh) [wrote a little bit about +it](https://mame-github-io.translate.goog/ioccc-ja-spoilers/2001/anonymous.html?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en-US&_x_tr_pto=wapp) that +might or might not help but he too could not get it to work. + +Tips from Cody: + +- Try a beautifier on the original C code. +- Use cpp to make the functions easier to parse. For instance if you're in the +directory try `cpp -E anonymous.cp > anonymous.cpp` and look at that file to see +the functions. It might or might not be helpful to use cpp on the beautified +source. +- After beautifying it try changing references of the macros (where not too +complicated) to their definitions. For instance in vim you might do: +`:%s/\/int */g` and then delete the line that was changed to `#define int * +int*` (or else do a range substitute so it's not changed). You might not need +this if you use the cpp. This might be useful anyway to more easily test things. +- If your system has a `setarch` tool that might or might not be of help (I'm +not too familiar with its internals). +- The code appears to do everything from one call to `exit(3)` but it makes use +of the ternary operator and possibly the comma operator. +- Check the Makefile for the defines but also observe that those are in the +source file. It appears that the entry might try compiling as well but that's +from a quick glance. +- The original main() started like: `main (char *ck, char **k)` but we made it +compilable for clang by changing it to be: `main (int cka, char **k) { char *ck += (char *)cka;` which might or might not be good. +- The author warns that only simple source (once compiled) would work so make +use of the provided source file +[2001/anonymous/anonymous.ten.c](2001/anonymous/anonymous.ten.c). To compile try +`make anonymous.ten` from the entry directory which you can then run the entry +on. Note that it needs to be compiled as a x86 program. +- The program will to an extent destroy files it is used on. See the author's +warning in their comments on that. + + ### [2004/burley](2004/burley/burley.c) ([README.md](2004/burley/README.md)) This entry did not compile with clang but [Cody Boone @@ -52,11 +92,12 @@ experience with `longjmp`). In particular: > The longjmp() routines may not be called after the routine which called the > setjmp() routines returns. 3. The main() originally returned a call to main() which appeared to be an -infinite recursion at least as it was; now it returns a call to poke() which has the same number -and type of args (1, `char *`) that main() had. This appears to not be an -infinite recursion but I might be reading it wrong. Perhaps that is the problem? -4. As well main() had only one arg, a `char *`, and there were (seemingly) -needless casts to `char *` from gets(). +infinite recursion at least as it was; now it returns a call to poke() which has +the same number and type of args (1, `char *`) that main() had. This appears to +not be an infinite recursion but I might be reading it wrong. Changing it to not +return itself and the same problem occurs so perhaps this is not the problem. +4. As well main() had only one arg, a `char *`, and there was a (seemingly) +needless cast to `char *` from gets(). This cast remains in the code however. 5. The code no longer uses `gets()` but `fgets()`; this is not the problem however.