I wanted to write a brainfuck compiler, but when I went to write one I was stuck at this problem
I want to create an ELF executable (using C/C++) that reads a brainfuck code from a file and generates an executable. Just like GCC/clang
I can read and parse the code, but I don't know how to write an executable that can run on the same system (say x86)?
I want this behavior:
my_bf_compiler ./source.bf -o bin.out
./bin.out
EDIT: I do not want to know how to write a compiler. Read this, compiler part was just for context as to where I will use it
I want to create a binary executable (say maker.out) which when ran creates a executable file (say foo.out). For simplicity let's keep foo.out very simple, when executed it returns 7; So, this is what is expected:
./maker.out # Creates the foo.out executable
./foo.out && echo $ # Runs the executable and prints return value, in this case 7;
So how do I write maker.cpp?
Your initial message was about creating a an executable from a brainfuck code, so this is what this answer focuses on. Your current question is way too broad.
As you have linked in one of your previous posts there is already an implementation that does this here: https://github.com/skeeto/bf-x86/blob/master/bf-x86.c
It basically does 3 steps:
1) Parse the BF code into a intermediate representation (which is here https://github.com/skeeto/bf-x86/blob/master/bf-x86.c#L55)
2) Compile this intermediate representation into machine code (which can be found here https://github.com/skeeto/bf-x86/blob/master/bf-x86.c#L496)
3) Compose the ELF binary according to the specification. The example program does this here. https://github.com/skeeto/bf-x86/blob/master/bf-x86.c#L622 .
Steps 1 and 2 are up to you to find a good implementation, for step 3 the simplest way is to write the ELF header and program header in such a way, that it only has the programs machine code as content and point the entrypoint of the program to the machine code generated in step 2.
The full specification for the ELF format can be found here: https://refspecs.linuxfoundation.org/elf/elf.pdf
#Yanick's answer contains enough information about the ELF format and how to create an elf executable.
However, it seems to me that your question is about how to open/create an executable file. There is a function called chmod/fchmod which might help you.
The following text is taken from the man-page for chmod (run man 2 chmod to see this page):
#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);
The new file mode is specified in mode, which is a bit mask created by ORing together zero or more of the
following:
S_ISUID (04000) set-user-ID (set process effective user ID on execve(2))
S_ISGID (02000) set-group-ID (set process effective group ID on execve(2); mandatory locking, as described
in fcntl(2); take a new file's group from parent directory, as described in chown(2) and
mkdir(2))
S_ISVTX (01000) sticky bit (restricted deletion flag, as described in unlink(2))
S_IRUSR (00400) read by owner
S_IWUSR (00200) write by owner
S_IXUSR (00100) execute/search by owner ("search" applies for directories, and means that entries within
the directory can be accessed)
S_IRGRP (00040) read by group
S_IWGRP (00020) write by group
S_IXGRP (00010) execute/search by group
S_IROTH (00004) read by others
S_IWOTH (00002) write by others
S_IXOTH (00001) execute/search by others
In your case, running chmod("foo.out", S_IRUSR | S_IXUSR) should give you(the owner) the permission to read and execute foo.out. Assuming that you have written foo.out to be a proper elf file, this will make it executable.
Related
I have a large coredumps, say, 120+ Gigabytes.
I need to get program version from it, so I add global constant (pseudo code):
static const char* const = "MAGIC_KEYWORD_FOR_GREPPING_" + MY_PROGRAM_VERSION;
Is it possible to place it to beginning of coredump, so grepping will be faster?
Coredumps are created by the operating system, not by applications that cause them. There is no way for the OS to know the value of some variable in your program. You can adjust the names of your coredumps by setting core_pattern to have the executable name in the coredump's filename included. This man page has the specifiers' description.
It might be that your OS generates coredumps by piping through some application - if cat /proc/sys/kernel/core_pattern returns a string starting with | (for example mine is |/usr/share/apport/apport %p %s %c %P) then you have to adjust the parameters accordingly. See this link for more details
A program generates a text file after every 15 iterations. It overwrites the output.txt (formed at 15th step) with a new output.txt (formed at 30th step), due to using the same name. I can't modify the file name within the program. Can I run some script concurrently with the program on my Ubuntu system that monitors my directory and moves the output.txt file to a desired directory when it is formed or changes the output file name?
I can't modify the file name within the program.
(I take this to mean you are required to not change the file name, not that you don't know how.)
You've marked this posting as C++.
While it is possible to run some script to monitor a directory, coordinating the name change and running a thread or another process (from C++) can be much more challenging than other choices.
How about a simpler approach:
I suggest using std::stringstream to generate a unique pfn (path-file-name) for each time you want to write a file. For instance, an incrementing number can be appended to the unmodifiable-file-name.
Something like:
std::string uniqueFileName(void)
{
std::stringstream ss;
// vvvvvvvvvv -- unmodifiable-file-name is not changed
ss << "output.txt" << ++fileCount;
uniqueFileName = ss.str();
return(uniqueFileName);
}
Good luck.
PS
If you feel you must write the file first in the correct file name, and then change the file name to something unique ... yes, you can rename the file from within this program (i.e. trivial synchronization)
I would use popen() as I feel it provides more feedback, and I've used it before.
Others prefer something like system() (there are about 6 of these).
In either case, use the command to rename the existing file (to each you provide a bash command, like mv fromPfn toPfn, or maybe you'll need cp.
For each, your code must not proceed until the command has completed.
The go test command has support for the -c flag, described as follows:
-c Compile the test binary to pkg.test but do not run it.
(Where pkg is the last element of the package's import path.)
As far as I understand, generating a binary like this is the way to run it interactively using GDB. However, since the test binary is created by combining the source and test files temporarily in some /tmp/ directory, this is what happens when I run list in gdb:
Loading Go Runtime support.
(gdb) list
42 github.com/<username>/<project>/_test/_testmain.go: No such file or directory.
This means I cannot happily inspect the Go source code in GDB like I'm used to. I know it is possible to force the temporary directory to stay by passing the -work flag to the go test command, but then it is still a huge hassle since the binary is not created in that directory and such. I was wondering if anyone found a clean solution to this problem.
Go 1.5 has been released, and there is still no officially sanctioned Go debugger. I haven't had much success using GDB for effectively debugging Go programs or test binaries. However, I have had success using Delve, a non-official debugger that is still undergoing development: https://github.com/derekparker/delve
To run your test code in the debugger, simply install delve:
go get -u github.com/derekparker/delve/cmd/dlv
... and then start the tests in the debugger from within your workspace:
dlv test
From the debugger prompt, you can single-step, set breakpoints, etc.
Give it a whirl!
Unfortunately, this appears to be a known issue that's not going to be fixed. See this discussion:
https://groups.google.com/forum/#!topic/golang-nuts/nIA09gp3eNU
I've seen two solutions to this problem.
1) create a .gdbinit file with a set substitute-path command to
redirect gdb to the actual location of the source. This file could be
generated by the go tool but you'd risk overwriting someone's custom
.gdbinit file and would tie the go tool to gdb which seems like a bad
idea.
2) Replace the source file paths in the executable (which are pointing
to /tmp/...) with the location they reside on disk. This is
straightforward if the real path is shorter then the /tmp/... path.
This would likely require additional support from the compiler /
linker to make this solution more generic.
It spawned this issue on the Go Google Code issue tracker, to which the decision ended up being:
https://code.google.com/p/go/issues/detail?id=2881
This is annoying, but it is the least of many annoying possibilities.
As a rule, the go tool should not be scribbling in the source
directories, which might not even be writable, and it shouldn't be
leaving files elsewhere after it exits. There is next to nothing
interesting in _testmain.go. People testing with gdb can break on
testing.Main instead.
Russ
Status: Unfortunate
So, in short, it sucks, and while you can work around it and GDB a test executable, the development team is unlikely to make it as easy as it could be for you.
I'm still new to the golang game but for what it's worth basic debugging seems to work.
The list command you're trying to work can be used so long as you're already at a breakpoint somewhere in your code. For example:
(gdb) b aws.go:54
Breakpoint 1 at 0x61841: file /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.go, line 54.
(gdb) r
Starting program: /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.test
[snip: some arnings about BinaryCache]
Breakpoint 1, github.com/stellar/deliverator/aws.imageIsNewer (latest=0xc2081fe2d0, ami=0xc2081fe3c0, ~r2=false)
at /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.go:54
54 layout := "2006-01-02T15:04:05.000Z"
(gdb) list
49 func imageIsNewer(latest *ec2.Image, ami *ec2.Image) bool {
50 if latest == nil {
51 return true
52 }
53
54 layout := "2006-01-02T15:04:05.000Z"
55
56 amiCreationTime, amiErr := time.Parse(layout, *ami.CreationDate)
57 if amiErr != nil {
58 panic(amiErr)
This is just after running the following in the aws subdir of my project:
go test -c
gdb aws.test
As an additional caveat, it does seem very selective about where breakpoints can be placed. Seems like it has to be an expression but that conclusion is only via experimentation.
If you're willing to use tools besides GDB, check out godebug. To use it, first install with:
go get github.com/mailgun/godebug
Next, insert a breakpoint somewhere by adding the following statement to your code:
_ = "breakpoint"
Now run your tests with the godebug test command.
godebug test
It supports many of the parameters from the go test command.
-test.bench string
regular expression per path component to select benchmarks to run
-test.benchmem
print memory allocations for benchmarks
-test.benchtime duration
approximate run time for each benchmark (default 1s)
-test.blockprofile string
write a goroutine blocking profile to the named file after execution
-test.blockprofilerate int
if >= 0, calls runtime.SetBlockProfileRate() (default 1)
-test.count n
run tests and benchmarks n times (default 1)
-test.coverprofile string
write a coverage profile to the named file after execution
-test.cpu string
comma-separated list of number of CPUs to use for each test
-test.cpuprofile string
write a cpu profile to the named file during execution
-test.memprofile string
write a memory profile to the named file after execution
-test.memprofilerate int
if >=0, sets runtime.MemProfileRate
-test.outputdir string
directory in which to write profiles
-test.parallel int
maximum test parallelism (default 4)
-test.run string
regular expression to select tests and examples to run
-test.short
run smaller test suite to save time
-test.timeout duration
if positive, sets an aggregate time limit for all tests
-test.trace string
write an execution trace to the named file after execution
-test.v
verbose: print additional output
I've tried to include Kaj de Vos's excellent C library binding available in ANSI.reds, but still cannot find a way to read a directory listing.
I thought that maybe if I could read the . file in binary, I could parse it, but I just get back a NULL pointer:
sizedir: 0
dir: read-file-binary "my-dir/." :sizedir
print-line dir
If I try reading it as a text file, I get a:
*** Runtime Error 1: access violation
*** at: 0040152Eh
Any ideas?
A piece of additional code and definitions needs to be written to read the directory structure and interpret it. It's tricky, because it's partly system dependent, so it goes beyond the ANSI part of my C library binding. Also, to achieve a higher abstraction level on the way to the directory functions in REBOL, you'd have to think about extra data structures that are not native to Red/System.
I've got a series of cpp source file and I want to write another program to JUDGE if they can run correctly (give input and compare their output with standart output) . so how to:
call/spawn another program, and give a file to be its standard input
limit the time and memory of the child process (maybe setrlimit thing? is there any examples?)
donot let the process to read/write any file
use a file to be its standard output
compare the output with the standard output.
I think the 2nd and 3rd are the core part of this prob. Is there any way to do this?
ps. system is Linux
To do this right, you probably want to spawn the child program with fork, not system.
This allows you to do a few things. First of all, you can set up some pipes to the parent process so the parent can supply the input to the child, and capture the output from the child to compare to the expected result.
Second, it will let you call seteuid (or one of its close relatives like setreuid) to set the child process to run under a (very) limited user account, to prevent it from writing to files. When fork returns in the parent, you'll want to call setrlimit to limit the child's CPU usage.
Just to be clear: rather than directing the child's output to a file, then comparing that to the expected output, I'd capture the child's output directly via a pipe to the parent. From there the parent can write the data to a file if desired, but can also compare the output directly to what's expected, without going through a file.
std::string command = "/bin/local/app < my_input.txt > my_output_file.txt 2> my_error_file.txt";
int rv = std::system( command.c_str() );
1) The system function from the STL allows you to execute a program (basically as if invoked from a shell). Note that this approach is inherenly insecure, so only use it in a trusted environment.
2) You will need to use threads to be able to achieve this. There are a number of thread libraries available for C++, but I cannot give you recommendation.
[After edit in OP's post]
3) This one is harder. You either have to write a wrapper that monitors read/write access to files or do some Linux/Unix privilege magic to prevent it from accessing files.
4) You can redirect the output of a program (that it thinks goes to the standard output) by adding > outFile.txt after the way you would normally invoke the program (see 1)) -- e.g. otherapp > out.txt
5) You could run diff on the saved file (from 3)) to the "golden standard"/expected output captured in another file. Or use some other method that better fits your need (for example you don't care about certain formatting as long as the "content" is there). -- This part is really dependent on your needs. diff does a basic comparing job well.