By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,106 Members | 2,679 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,106 IT Pros & Developers. It's quick & easy.

1)Executing by reading from executable 2)Compileing in a program

P: n/a
Two questions.

1)Is there any way that I can read from an executable and then execute
what I have read.
EXAMPLE:

text
text
this is more
text

:::::START EXE CODE:::
/* executable code in here */
:::::END EXE CODE:::

text text
yep
yeah
text
2)Is there anyway that I can modify the source code of a compiler so
that I can include it in another program to compile other files in that
program and place the output of the compiled files into a large file in
a location specified by an argument to the call of the compiler. Here
is an example.

##MY PSUDO FILE SYSTEM##
$$fl.exe
/* exe code for fl.exe */
&&%

Now I use the compiler that is included within the program. Say at my
programs prompt I enter:(where cc is the compilers name)
:: cc myprog.c -o myprog.exe

This would result in, if all was well:

##MY PSUDO FILE SYSTEM##
$$fl.exe
/* exe code for fl.exe */
&&%
$$myprog.exe
/* exe code for myprog.exe*/
&&%

I'm not sure if this is possible or not but I'm sure some people will
understand what I'm saying, and perhaps some guru will know if it can
be done.
Nori

May 13 '06 #1
Share this Question
Share on Google+
14 Replies


P: n/a
no*********@gmail.com wrote:
Two questions.

1)Is there any way that I can read from an executable and then execute
what I have read.
EXAMPLE:
<snip>

Not in standard C. Your implementation may provide some mechanism for
doing this or may prevent you from doing this.
2)Is there anyway that I can modify the source code of a compiler so
that I can include it in another program to compile other files in that
program and place the output of the compiled files into a large file in
a location specified by an argument to the call of the compiler. Here
is an example.


<snip>

Maybe yes, maybe no. It depends on whether you have the source code for
the compiler and whether you are a good enough programmer. However, it
is probably the wrong solution to whatever problem you are actually
trying to solve.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
May 13 '06 #2

P: n/a
On 2006-05-13, no*********@gmail.com <no*********@gmail.com> wrote:
Two questions.

1)Is there any way that I can read from an executable and then execute
what I have read.
Interesting idea; it is possible on a machine on which code and data are
stored in the same memory (I think this is called a "von Neumann
machine")-- most modern desktop machines are like that. So I gave it a
go.

First I made a file called blah.c with this in it:

int add(a, b)
{
return a + b;
}

and compiled it to blah.o. [this would be called blah.obj on some
systems].

Then I disassembled blah.o and found the actual code of "add" was 11
bytes long and started at offset 0x34L:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 03 45 08 add 0x8(%ebp),%eax
9: 5d pop %ebp
a: c3 ret

So then I just loaded the code directly into an array in another
program, cast the buffer to the proper function type (casting char * to
to a function type I'm pretty sure is "undefined behaviour", but I
thought it might work anyway), and called it:

#include <stdio.h>
#include <stdlib.h>

typedef int (*add_t)(int, int);

add_t load_add(void)
{
FILE *fp = fopen("./blah.o", "rb");
char *code = malloc(11);

fseek(fp, 0x34L, SEEK_SET);
fread(code, 1, 11, fp);

fclose(fp);

return (add_t) code;
}

int main(void)
{
add_t add = load_add();
int result = add(4, 5);

printf("%d\n", result);

return 0;
}

and it printed out 9!

Maybe you can use something like this, depending on what you're trying
to do.
2)Is there anyway that I can modify the source code of a compiler so
that I can include it in another program to compile other files in that
program and place the output of the compiled files into a large file in
a location specified by an argument to the call of the compiler. Here
is an example.

##MY PSUDO FILE SYSTEM##
$$fl.exe
/* exe code for fl.exe */
&&%

Now I use the compiler that is included within the program. Say at my
programs prompt I enter:(where cc is the compilers name)
:: cc myprog.c -o myprog.exe

This would result in, if all was well:

##MY PSUDO FILE SYSTEM##
$$fl.exe
/* exe code for fl.exe */
&&%
$$myprog.exe
/* exe code for myprog.exe*/
&&%

I'm not sure if this is possible or not but I'm sure some people will
understand what I'm saying, and perhaps some guru will know if it can
be done.


This part I don't really understand I'm afraid. I gather from your other
posts that you're trying to do a kind of hosted OS, one of the features
of which is its own filesystem that appears as a single file to the
hosted OS. The mini-OS itself appears to the host OS as a single running
process, and now it sounds like you want the mini-OS to be able to load
executables from its own filesystem and run them.

The executables it runs are in native compiled code, however.

This makes me think you might be better to work at the level of .o (or
..obj), than .exe. An exe is likely to do all kinds of things required to
start up a real process on the hosted OS, but it sounds like you don't
want that, you just want to run some native code out of the middle of it
somewhere.

If you do use .obj files you will need to do your own "linking", but
that might be part of what the mini-OS does... I don't know.
May 13 '06 #3

P: n/a

Ben C wrote:
On 2006-05-13, no*********@gmail.com <no*********@gmail.com> wrote:
Two questions.

1)Is there any way that I can read from an executable and then execute
what I have read.


Interesting idea; it is possible on a machine on which code and data are
stored in the same memory (I think this is called a "von Neumann
machine")-- most modern desktop machines are like that. So I gave it a
go.

First I made a file called blah.c with this in it:

int add(a, b)
{
return a + b;
}

and compiled it to blah.o. [this would be called blah.obj on some
systems].

Then I disassembled blah.o and found the actual code of "add" was 11
bytes long and started at offset 0x34L:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 03 45 08 add 0x8(%ebp),%eax
9: 5d pop %ebp
a: c3 ret

So then I just loaded the code directly into an array in another
program, cast the buffer to the proper function type (casting char * to
to a function type I'm pretty sure is "undefined behaviour", but I
thought it might work anyway), and called it:

#include <stdio.h>
#include <stdlib.h>

typedef int (*add_t)(int, int);

add_t load_add(void)
{
FILE *fp = fopen("./blah.o", "rb");
char *code = malloc(11);

fseek(fp, 0x34L, SEEK_SET);
fread(code, 1, 11, fp);

fclose(fp);

return (add_t) code;
}

int main(void)
{
add_t add = load_add();
int result = add(4, 5);

printf("%d\n", result);

return 0;
}

and it printed out 9!

Maybe you can use something like this, depending on what you're trying
to do.
2)Is there anyway that I can modify the source code of a compiler so
that I can include it in another program to compile other files in that
program and place the output of the compiled files into a large file in
a location specified by an argument to the call of the compiler. Here
is an example.

##MY PSUDO FILE SYSTEM##
$$fl.exe
/* exe code for fl.exe */
&&%

Now I use the compiler that is included within the program. Say at my
programs prompt I enter:(where cc is the compilers name)
:: cc myprog.c -o myprog.exe

This would result in, if all was well:

##MY PSUDO FILE SYSTEM##
$$fl.exe
/* exe code for fl.exe */
&&%
$$myprog.exe
/* exe code for myprog.exe*/
&&%

I'm not sure if this is possible or not but I'm sure some people will
understand what I'm saying, and perhaps some guru will know if it can
be done.


This part I don't really understand I'm afraid. I gather from your other
posts that you're trying to do a kind of hosted OS, one of the features
of which is its own filesystem that appears as a single file to the
hosted OS. The mini-OS itself appears to the host OS as a single running
process, and now it sounds like you want the mini-OS to be able to load
executables from its own filesystem and run them.

The executables it runs are in native compiled code, however.

This makes me think you might be better to work at the level of .o (or
.obj), than .exe. An exe is likely to do all kinds of things required to
start up a real process on the hosted OS, but it sounds like you don't
want that, you just want to run some native code out of the middle of it
somewhere.

If you do use .obj files you will need to do your own "linking", but
that might be part of what the mini-OS does... I don't know.

YES! Finally somebody understands what it is that I'm trying to do.
You have hit the nail right on the head and this has been very helpful.
I had no idea how to go about the execuatble portion of this and I
thank you greatly for your help. This is likely exactly what I will
do.
As for the linking...I'm not exactly sure how to go about that, but it
apears that you have done am I correct? I'm not sure how I could write
a program that would link .o files makeing them executables, however,
scince I don't really care what the operating system that my mini-OS is
running on has to say about much of anything I'm not sure if it would
make much of a differance. Or would it? I'm not intirely sure I know
what I'm getting myself into here :p.
Anyway if you could explain what you ment by the mini-OS linking and
also about if it would be nesisary to have .exe files at all it would
be much apreciated by me.
Nori

P.S. This is the most helpful post I have gotten thus far relating to
my project.

May 13 '06 #4

P: n/a
Ben C wrote:
On 2006-05-13, no*********@gmail.com <no*********@gmail.com> wrote:
Two questions.

1)Is there any way that I can read from an executable and then execute
what I have read.


Interesting idea; it is possible on a machine on which code and data are
stored in the same memory (I think this is called a "von Neumann
machine")-- most modern desktop machines are like that. So I gave it a
go.


<snip>

It's not always possible. The OS might prevent it (mark all pages that
are writeable by the application as not executable). Or you might have
to do relocation which involves understanding the format of the file.

On the other hand, with a few tricks it is possible on some processors
which have separate program and data address spaces.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
May 13 '06 #5

P: n/a
In article <7s************@news.flash-gordon.me.uk>,
Flash Gordon <sp**@flash-gordon.me.uk> wrote:
It's not always possible. The OS might prevent it (mark all pages that
are writeable by the application as not executable).


This is rare in current operating systems, since many programs rely on
being able to do it (in fact, on many versions of unix, all programs
do it). Even if it is disabled by default, there is likely to be a
system call to allow it.

-- Richard
May 13 '06 #6

P: n/a
>1)Is there any way that I can read from an executable and then execute
what I have read.
You can write an emulator for the target CPU and hardware, then
emulate the execution of the program. As long as the specs for the
hardware are available, you should be able to do this, although I
didn't say it would be as fast as the real thing. (For some
processors such as the Z80, there are emulators using today's
hardware that are much faster than the real thing ever got).

You can also provide convenience facilities for dealing with the
emulation, like loading an "emulated ROM" with a just-compiled
program, memory and register dumps and patching, stack traces,
symbolic debugging, breakpoints, emulated I/O devices, etc.

....2)Is there anyway that I can modify the source code of a compiler so
that I can include it in another program to compile other files in that
program and place the output of the compiled files into a large file in
a location specified by an argument to the call of the compiler. Here
is an example.


It would seem simpler to compile the code (if necessary using a
cross-compiler), get an executable, and provide a utility to copy
the executable into your emulated file system, possibly doing format
conversion of the executable if needed. If you must, you can have
a main program that invokes the compiler (the only C way of invoking
another program is system()), then invokes the code that copies it
into the emulated filesystem.

Gordon L. Burditt
May 13 '06 #7

P: n/a
On 2006-05-13, no*********@gmail.com <no*********@gmail.com> wrote:

Ben C wrote:
On 2006-05-13, no*********@gmail.com <no*********@gmail.com> wrote:
> Two questions.
>
> 1)Is there any way that I can read from an executable and then execute
> what I have read.
Interesting idea; it is possible on a machine on which code and data are
stored in the same memory (I think this is called a "von Neumann
machine")-- most modern desktop machines are like that. So I gave it a
go.

First I made a file called blah.c with this in it:

int add(a, b)
{
return a + b;
}

and compiled it to blah.o. [this would be called blah.obj on some
systems].

Then I disassembled blah.o and found the actual code of "add" was 11
bytes long and started at offset 0x34L:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 03 45 08 add 0x8(%ebp),%eax
9: 5d pop %ebp
a: c3 ret

So then I just loaded the code directly into an array in another
program, cast the buffer to the proper function type (casting char * to
to a function type I'm pretty sure is "undefined behaviour", but I
thought it might work anyway), and called it:

#include <stdio.h>
#include <stdlib.h>

typedef int (*add_t)(int, int);

add_t load_add(void)
{
FILE *fp = fopen("./blah.o", "rb");
char *code = malloc(11);

fseek(fp, 0x34L, SEEK_SET);
fread(code, 1, 11, fp);

fclose(fp);

return (add_t) code;
}

int main(void)
{
add_t add = load_add();
int result = add(4, 5);

printf("%d\n", result);

return 0;
}


[snip]
As for the linking...I'm not exactly sure how to go about that, but it
apears that you have done am I correct? I'm not sure how I could write
a program that would link .o files makeing them executables, however,
scince I don't really care what the operating system that my mini-OS is
running on has to say about much of anything I'm not sure if it would
make much of a differance. Or would it?
I'm not intirely sure I know what I'm getting myself into here :p.
No nor am I :)
Anyway if you could explain what you ment by the mini-OS linking and
also about if it would be nesisary to have .exe files at all it would
be much apreciated by me.


To see what I mean by "linking", try the example I posted, but add this
to blah.c:

int muladd(int a, int b, int c)
{
return add(a, b * c);
}

Now try to "call" muladd from the main program by loading it into
memory... You will need to load both add and muladd, and somehow arrange
for the call to add from muladd to jump to the right place. This is
linking, basically-- setting up the path from one function to another.

The thing about exe files is they contain a lot of information specific
to the OS about how to load them into memory and run them. Doing
anything with them except just running them in the way the OS expects is
likely to be more complex than working with .obj files. If your mini-OS
wants to just run them then it's really just a shell rather than a
mini-OS.

The best thing is to try some things out and you will realize what's
needed and work out what's going on. Compile the .obj files you're
loading with minimal compiler optimizations to keep them as simple as
possible, and investigate disassembler programs; I would recommend GNU
objdump.
May 14 '06 #8

P: n/a


Ben C wrote:
On 2006-05-13, no*********@gmail.com <no*********@gmail.com> wrote:

Ben C wrote:
On 2006-05-13, no*********@gmail.com <no*********@gmail.com> wrote:
> Two questions.
>
> 1)Is there any way that I can read from an executable and then execute
> what I have read.

Interesting idea; it is possible on a machine on which code and data are
stored in the same memory (I think this is called a "von Neumann
machine")-- most modern desktop machines are like that. So I gave it a
go.

First I made a file called blah.c with this in it:

int add(a, b)
{
return a + b;
}

and compiled it to blah.o. [this would be called blah.obj on some
systems].

Then I disassembled blah.o and found the actual code of "add" was 11
bytes long and started at offset 0x34L:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 03 45 08 add 0x8(%ebp),%eax
9: 5d pop %ebp
a: c3 ret

So then I just loaded the code directly into an array in another
program, cast the buffer to the proper function type (casting char * to
to a function type I'm pretty sure is "undefined behaviour", but I
thought it might work anyway), and called it:

#include <stdio.h>
#include <stdlib.h>

typedef int (*add_t)(int, int);

add_t load_add(void)
{
FILE *fp = fopen("./blah.o", "rb");
char *code = malloc(11);

fseek(fp, 0x34L, SEEK_SET);
fread(code, 1, 11, fp);

fclose(fp);

return (add_t) code;
}

int main(void)
{
add_t add = load_add();
int result = add(4, 5);

printf("%d\n", result);

return 0;
}


[snip]
As for the linking...I'm not exactly sure how to go about that, but it
apears that you have done am I correct? I'm not sure how I could write
a program that would link .o files makeing them executables, however,
scince I don't really care what the operating system that my mini-OS is
running on has to say about much of anything I'm not sure if it would
make much of a differance. Or would it?
I'm not intirely sure I know what I'm getting myself into here :p.


No nor am I :)
Anyway if you could explain what you ment by the mini-OS linking and
also about if it would be nesisary to have .exe files at all it would
be much apreciated by me.


To see what I mean by "linking", try the example I posted, but add this
to blah.c:

int muladd(int a, int b, int c)
{
return add(a, b * c);
}

Now try to "call" muladd from the main program by loading it into
memory... You will need to load both add and muladd, and somehow arrange
for the call to add from muladd to jump to the right place. This is
linking, basically-- setting up the path from one function to another.

The thing about exe files is they contain a lot of information specific
to the OS about how to load them into memory and run them. Doing
anything with them except just running them in the way the OS expects is
likely to be more complex than working with .obj files. If your mini-OS
wants to just run them then it's really just a shell rather than a
mini-OS.

The best thing is to try some things out and you will realize what's
needed and work out what's going on. Compile the .obj files you're
loading with minimal compiler optimizations to keep them as simple as
possible, and investigate disassembler programs; I would recommend GNU
objdump.


And I really thought that I was getting somewere too. Okay one
question and it sounds simple enough but here goes: How in the world do
I set it up to that muladd would jump to the right place? Also, would
doing things in this mannor require things that could not be automated?
I was really hoping that there would be some way to execute things
that were in the psudo-filesystem without actually doing manual work.
Thanks.
Nori

May 14 '06 #9

P: n/a
>> 1)Is there any way that I can read from an executable and then execute
what I have read.
Interesting idea; it is possible on a machine on which code and data are
stored in the same memory (I think this is called a "von Neumann
machine")-- most modern desktop machines are like that. So I gave it a
go.


It's not necessary for code and data to be in the same memory, or for
the target machine and the host machine to have instruction sets anything
like each other. All you need is a program running on the host that
emulates the target machine. All of the state of the target machine
(RAM, ROM, registers, etc.) is in the data space of the host machine.
There are lots of emulators for various machines, especially those for
CPUs often used in embedded controllers.
Then I disassembled blah.o and found the actual code of "add" was 11
bytes long and started at offset 0x34L:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 03 45 08 add 0x8(%ebp),%eax
9: 5d pop %ebp
a: c3 ret


Note that if you move code from one address to another, the code
might change (particularly for (conditional) branch instructions
that aren't PC-relative, or if the code uses local data). This is
often called "relocation". An object (as opposed to executable)
file has information needed to locate code anywhere. Executable
files might not (particularly if the OS uses virtual memory and
always loads executables at a fixed address).

Gordon L. Burditt
May 14 '06 #10

P: n/a
Allow me to slightly rephrase my origional post based on information
that I have now:
Is there any way that I could execute say

#include <stdio.h>
main() {
printf("hello world\n");
}

Within another program. Where hello.c or .o or .exe or .whatever is
stored

place one::
yep
place two::
whatever
place three::
code for hello.o .exe or .whatever

Thanks
Nori

no*********@gmail.com wrote:
Two questions.

1)Is there any way that I can read from an executable and then execute
what I have read.
EXAMPLE:

text
text
this is more
text

:::::START EXE CODE:::
/* executable code in here */
:::::END EXE CODE:::

text text
yep
yeah
text
2)Is there anyway that I can modify the source code of a compiler so
that I can include it in another program to compile other files in that
program and place the output of the compiled files into a large file in
a location specified by an argument to the call of the compiler. Here
is an example.

##MY PSUDO FILE SYSTEM##
$$fl.exe
/* exe code for fl.exe */
&&%

Now I use the compiler that is included within the program. Say at my
programs prompt I enter:(where cc is the compilers name)
:: cc myprog.c -o myprog.exe

This would result in, if all was well:

##MY PSUDO FILE SYSTEM##
$$fl.exe
/* exe code for fl.exe */
&&%
$$myprog.exe
/* exe code for myprog.exe*/
&&%

I'm not sure if this is possible or not but I'm sure some people will
understand what I'm saying, and perhaps some guru will know if it can
be done.
Nori


May 14 '06 #11

P: n/a
"no*********@gmail.com" <no*********@gmail.com> wrote:
# Two questions.
#
# 1)Is there any way that I can read from an executable and then execute
# what I have read.

Many systems provide for things like dynamic loading or to store
new instructions in memory and make those instructions executable,
but the methods tend to be specific to each system.

# 2)Is there anyway that I can modify the source code of a compiler so
# that I can include it in another program to compile other files in that

Not all installed systems have a c compiler anywhere on the machine.

The usual way to do this is to use a portable interpretter such as
Perl, Tcl, Forth, etc.These languages let you load source code
and then run it, or a partially compiled form of the source. I wouldn't
try to compile and load C fragments within a program: too complicated
and not very portable.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
GERBILS
GERBILS
GERBILS
May 14 '06 #12

P: n/a
Perl...Why didn't I think of that. Seeing as I know some perl it was
kindof stupid of me not to think of that. And if I'm correct there is
some method of embeding perl into C code am I right? I'm not intirely
sure how to do that in perl, however, it seems like it would be far
easier to do in some sort of scripting language. I think that it is
time to re ask my question in a Perl newsgroup. Thanks everyone.
Nori

SM Ryan wrote:
"no*********@gmail.com" <no*********@gmail.com> wrote:
# Two questions.
#
# 1)Is there any way that I can read from an executable and then execute
# what I have read.

Many systems provide for things like dynamic loading or to store
new instructions in memory and make those instructions executable,
but the methods tend to be specific to each system.

# 2)Is there anyway that I can modify the source code of a compiler so
# that I can include it in another program to compile other files in that

Not all installed systems have a c compiler anywhere on the machine.

The usual way to do this is to use a portable interpretter such as
Perl, Tcl, Forth, etc.These languages let you load source code
and then run it, or a partially compiled form of the source. I wouldn't
try to compile and load C fragments within a program: too complicated
and not very portable.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
GERBILS
GERBILS
GERBILS


May 14 '06 #13

P: n/a
On 2006-05-14, no*********@gmail.com <no*********@gmail.com> wrote:


Ben C wrote:
On 2006-05-13, no*********@gmail.com <no*********@gmail.com> wrote:
>
> Ben C wrote:
>> On 2006-05-13, no*********@gmail.com <no*********@gmail.com> wrote:
>> > Two questions.
>> >
>> > 1)Is there any way that I can read from an executable and then execute
>> > what I have read.

[snip]
The best thing is to try some things out and you will realize what's
needed and work out what's going on. Compile the .obj files you're
loading with minimal compiler optimizations to keep them as simple as
possible, and investigate disassembler programs; I would recommend GNU
objdump.


And I really thought that I was getting somewere too. Okay one
question and it sounds simple enough but here goes: How in the world do
I set it up to that muladd would jump to the right place? Also, would
doing things in this mannor require things that could not be automated?
I was really hoping that there would be some way to execute things
that were in the psudo-filesystem without actually doing manual work.


Of course, everything can be automated.

Besides the compiled code for all the functions, the .o file also
contains tables telling you where each function starts and how long the
code for each function is, and also which bits of the compiled code need
to be "patched" after the code for each function has been loaded into
memory.

Here's the source of an extended blah.c:

int add(a, b)
{
return a + b;
}

int muladd(a, b, c)
{
return add(a, b * c);
}

int muladd2(a, b, c)
{
return muladd(a, b, c);
}

Now I compile it and look at the object file with objdump:

$ objdump -r blah.o

RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000001a R_386_PC32 add
00000030 R_386_PC32 muladd

What this tells me is that at offset 0x1a into the text section (which
is offset 0x4e in the file, since the text section starts at 0x34), I
need to insert the offset to the start of the function <add>. And at
offset 0x30 in the text section (0x64 in the file), I need to insert the
offset to the start of the function <muladd>.

The .o file also contains a table of where the start of each function
is:

$ objdump -t blah.o

00000000 g F .text 0000000b add
0000000b g F .text 00000018 muladd
00000023 g F .text 00000016 muladd2

This tells me the code for add is at the beginning, muladd starts at 0xb
and muladd2 starts at 0x23. It also tells me how long each function is
(0xb, 0x18 and 0x16 bytes respectively).

So I have all the information I need here to load all the functions into
memory and patch things up.

Here's one way to do it for example:

1. Load the whole .text section (from 0x34 to 0x34 + 0x23 + 0x16 in
blah.o) into a char * buffer allocated with malloc.
2. Patch the relocations. Code to do this at the end of this post.

I have done this "manually" in the sense that I used objdump to examine
blah.o and then hardcoded the numbers into the program. but the
information is all there in blah.o (that's where objdump got it from
after all).

So to automate the process properly you need to parse the .o file.

This is a helpful guide I found to loading and linking generally:

http://www.linuxjournal.com/node/6463/print

There is also a library called libelf you could consider using to parse
the .o file:

http://directory.fsf.org/libs/misc/libelf.html

Note that all this applies to ELF files. If you're using .obj files on
Windows, I don't think they're exactly the same, but the general
principle is similar. You'd have to find some docs for that, which may
be harder as Windows is not free software. Or, alternatively, just
specify that the "executable format" your miniOS uses is based on ELF.

Or you could write a script that actually invokes objdump to get the
information you need and generates a much simpler ".xex" file for your
miniOS in a format you define yourself.

Here's the code then that does some minimal "linking":

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

char *load_text(void)
{
FILE *fp = fopen("./blah.o", "rb");
char *buf = malloc(0x57);
int32_t *p;

/* Read the whole of the .text section into the buffer */
fseek(fp, 0x34L, SEEK_SET);
fread(buf, 1, 0x57, fp);

/* Fix up the "relocations". */
p = (int32_t *) (buf + 0x1a);

/*
* This is the call from muladd to add. add starts at 0, muladd starts at
* 0x1a. Offset is from instruction after muladd. So go back 0x1a + 4 bytes
*/
*p = -(0x1a + 4 - 0);

/*
* This is the call from muladd2 to muladd. muladd2 starts at 0x30, muladd
* starts at 0xb.
*/
p = (int32_t *) (buf + 0x30);
*p = -(0x30 + 4 - 0xb);

return buf;
}

typedef int (*add_t)(int, int);
typedef int (*muladd_t)(int, int, int);

int main(int argc, char **argv)
{
char *code = load_text();
add_t add = (add_t) code;
muladd_t muladd = (muladd_t) (code + 0xb);

int result = muladd(2, 3, 4);

printf("%d\n", result);

free(code);
return 0;
}
May 14 '06 #14

P: n/a
On Sun, 14 May 2006 08:44:23 UTC, SM Ryan
<wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
"no*********@gmail.com" <no*********@gmail.com> wrote:
# Two questions.
#
# 1)Is there any way that I can read from an executable and then execute
# what I have read.
No, not in a portable way.
# 2)Is there anyway that I can modify the source code of a compiler so
# that I can include it in another program to compile other files in that
No, not in a portable way.
Not all installed systems have a c compiler anywhere on the machine.

The usual way to do this is to use a portable interpretter such as
Perl, Tcl, Forth, etc.These languages let you load source code
and then run it, or a partially compiled form of the source. I wouldn't
try to compile and load C fragments within a program: too complicated
and not very portable.

There are some C interpreters around. You may even write such a kind
by yourself.

There is nothing in the standard that requires that a C program has to
run natively. Simply write an interpreter that understunds C or a
compiler that delivers not a binary but byte code or something else
that can been interpreted easy by a program and an interpreter that
interprets that byte code.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
May 15 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.