Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

app that is able to link .o to itself (win32)

149 views
Skip to first unread message

fir

unread,
Nov 18, 2014, 12:29:37 PM11/18/14
to
I would like to gest such feature in my
program, take given .o (in the format that is output from mingw compiler) load it and link it in my app to call it internally by my
own program

would ut be hard/time consuming to write?
does someone know what efforts it would inwolve? (i would like to have it as a sorta
of plugin/script system) prefer this over dlls or highlevel scripts

could someone maybe wrote such thing and show me some source?

Rick C. Hodgin

unread,
Nov 18, 2014, 12:50:30 PM11/18/14
to
I would advise creating a DLL instead, and then to use LoadLibrary()
to open the DLL and GetProcAddress() to locate each function by name
that you need. You can also link to the .lib generated for the .o
file and have it automatically connect up to the DLL for you at
startup.

Best regards,
Rick C. Hodgin

Jens Thoms Toerring

unread,
Nov 18, 2014, 12:52:54 PM11/18/14
to
fir <profes...@gmail.com> wrote:
> I would like to gest such feature in my
> program, take given .o (in the format that is output from mingw compiler)
> load it and link it in my app to call it internally by my own program

> would ut be hard/time consuming to write?

Yes, because it won't work at all. You'd have to have the com-
plete linker being part of your program and the system would
have to allow self-modifying executables.

> does someone know what efforts it would inwolve? (i would like to have it as
> a sorta of plugin/script system) prefer this over dlls or highlevel scripts

That's exactly where shared libraries are the (only) way to go.
Tey can be loaded on demand by your running program and there
are methods to find the symbols in them, using their names as
strings, which you need for e.g. calling a functions supplied
by the library. Unfortunately, there's no platform-independent
way of doing that.
Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

jacob navia

unread,
Nov 18, 2014, 1:02:38 PM11/18/14
to
I wrote that for my compiler system lcc-win.

It is very easy:

1) Allocate a buffer with enough space for the code and data sections
Note that it must be in a page with the executable bit set.
2) Load the text section from the object file into the buffer.
3) Go through the fixups list and fixup all needed addresses using the
start address of the text section, i e. the start of the buffer.
4) Then load the data sections. Do the same for the data fixups.
5) Then you are done IF the code doesn't have any external references.
If the code has external references you have to resolve them either
using some table of previously computed addresses or some list of DLLs
that you can use to resolve external addresses.

Done.

Do not forget to free the buffer after use.

jacob

P.S. I can sell that code to you. If interested send mail to:

jacob AT jacob DOT remcop DOT fr


Rick C. Hodgin

unread,
Nov 18, 2014, 1:37:24 PM11/18/14
to
On Tuesday, November 18, 2014 1:02:38 PM UTC-5, jacob navia wrote:
> P.S. I can sell that code to you. If interested send mail to:

You could also give that code to fir and the entire world and make it
a better place by your offering. You have these special skills and
talents, have taken the time to debug the functionality, and now it
is a completed thing.

Why hoard it?

Why not remove this burden from every developer who would approach
this need and give unendingly to all of them, and to all of the tools
that could be built atop this offering? They would all come back to
you and your kindness, your love, your free offering unto people for
giving's sake. People's work would then proceed and be built atop
your kindness and generosity, rather than being hindered by these
artificial walls constructed of personal greed.

fir

unread,
Nov 18, 2014, 2:08:19 PM11/18/14
to
sometimes i feel like i would like to pay someone for doing the work i need which i know it would be just easier to me than doing it myself, - but presently i got no money, so this option would be probbaly not the case.. i would like some code for
very simple case at least

like

void foo(void * data)
{
// some function body
//...
}

this i compile to .o with mingw (one function .o)

then in my code i need to link it at runtime in my app and call it

Rick C. Hodgin

unread,
Nov 18, 2014, 2:33:56 PM11/18/14
to
On Tuesday, November 18, 2014 2:08:19 PM UTC-5, fir wrote:
> W dniu wtorek, 18 listopada 2014 19:37:24 UTC+1 użytkownik Rick C. Hodgin napisał:
> > On Tuesday, November 18, 2014 1:02:38 PM UTC-5, jacob navia wrote:
> > > P.S. I can sell that code to you. If interested send mail to:
> >
> > You could also give that code to fir and the entire world and make it
> > a better place by your offering. You have these special skills and
> > talents, have taken the time to debug the functionality, and now it
> > is a completed thing.
> >
> > Why hoard it?
> >
> > Why not remove this burden from every developer who would approach
> > this need and give unendingly to all of them, and to all of the tools
> > that could be built atop this offering? They would all come back to
> > you and your kindness, your love, your free offering unto people for
> > giving's sake. People's work would then proceed and be built atop
> > your kindness and generosity, rather than being hindered by these
> > artificial walls constructed of personal greed.
> >
> > Best regards,
> > Rick C. Hodgin
>
> sometimes i feel like i would like to pay someone for doing the work
> i need which i know it would be just easier to me than doing it myself

Paying for labor is one thing. It's to be expected. But it is another
thing to have already done the work, to possess the digital product in
your hands, and then to be selling copies of it when you've presumably
already eaten up until that point, are still alive, have a place to
stay, etc.

The eternal rewards given to those who share are far greater than those
who get Earthly gain for a season. It's why the enemy tries to get
people to work for Earthly things in exchange for that which they
create or possess.

> but presently i got no money, so this option would be probbaly not
> the case.. i would like some code for
> very simple case at least
>
> like
>
> void foo(void * data)
> {
> // some function body
> //...
> }
>
> this i compile to .o with mingw (one function .o)
>
> then in my code i need to link it at runtime in my app and call it

I have created a program which does this. I needed to have some
declared char* buffers at compile-time exist not in read-only memory,
but rather in read-write memory. The people of this group gave me the
cue to use compound literals. However, Microsoft's compiler did not
support that compound literal syntax, but only GCC. As such, I wrote
a test version which used MinGW and GCC to create an output file which
I then linked together with the MSVC code, and it worked fine.

I'll see if I can find the code. If I remember correctly, GCC had an
option which allowed it to produce an object format that was compatible
with MSVC++ and I was able to include it as an input into the MSVC link
options.

Morris Dovey

unread,
Nov 18, 2014, 2:38:30 PM11/18/14
to
What a magnificent spirit of generosity - this urge to make gift of the
fruit of another’s labors!

The road to hell is paved with good intentions.

--
Morris Dovey
http://www.iedu.com/Solar/

Rick C. Hodgin

unread,
Nov 18, 2014, 2:39:20 PM11/18/14
to
I found the link here:

http://compgroups.net/comp.lang.c++/link-object-files-from-vc++-and-gcc/2080401

The relevant portion is here: "g++ -c -gcoff myfile.cpp -o list.obj"

And then you can include list.obj in your MSVC link input.

-------------------------------------------------------------------
COFF output in GCC was the key. I was able to get it working.

Here's are the steps for a sample build:

(1) Install MinGW on Windows with GCC and bases.
(2) Create the two source files below.
(3) Launch a command prompt that has the path for visual studio tools.
(4) Execute these steps:
(a) C:\>PATH=%PATH%;c:\mingw\bin\
(b) C:\>g++ -c -gcoff list.cpp -o list.obj
(c) C:\>cl /c main.cpp
(d) C:\>link main.obj list.obj /OUT:main.exe
(e) C:\>main
!ne
!wo
!three
(f) C:\>_


=========list.cpp========
#define RW(x) (char []) { x }

extern "C"
{

char* list[] =
{
RW("one"),
RW("two"),
RW("three")
};

}
===========END===========


=========main.cpp========
#include <stdlib.h>
#include <stdio.h>

extern "C"
{
extern char* list[];
}

int main(int argc, char* argv[])
{
for (int i = 0; list[i]; i++)
{
list[i][0] = '!'; // Prove it's read-write
puts(list[i]); // Show it
}
}
===========END===========

G++ and CL working hand-in-hand. :-)

BartC

unread,
Nov 18, 2014, 2:49:23 PM11/18/14
to
"fir" <profes...@gmail.com> wrote in message
news:9eaadbee-9a49-4cc3...@googlegroups.com...


> void foo(void * data)
> {
> // some function body
> //...
> }
>
> this i compile to .o with mingw (one function .o)
>
> then in my code i need to link it at runtime in my app and call it

Why does it have to linked in at runtime; why not linktime?

Is the code created while your application is running? Or does the
application make use of binaries compiled separately? (For example, compiled
by a user who is using your pre-built application.)

Normally DLL files (on Windows) are used for this sort of thing (which is
otherwise very difficult to link to your applications with global functions
and data referenced in both directions, especially if you don't know, at
compile time of your app, the names of the functions). A bit fiddly, but you
can dress it up.

(BTW what's wrong with using a high level scripting language? With programs
created and run by users of your application, that's the way to go.)

--
Bartc


BartC

unread,
Nov 18, 2014, 3:11:29 PM11/18/14
to
"Rick C. Hodgin" <rick.c...@gmail.com> wrote in message
news:6c69c5c3-f943-4fe0...@googlegroups.com...
> On Tuesday, November 18, 2014 2:08:19 PM UTC-5, fir wrote:

>> sometimes i feel like i would like to pay someone for doing the work
>> i need which i know it would be just easier to me than doing it myself
>
> Paying for labor is one thing. It's to be expected. But it is another
> thing to have already done the work, to possess the digital product in
> your hands, and then to be selling copies of it when you've presumably
> already eaten up until that point, are still alive, have a place to
> stay, etc.

One application of mine took 2-3 years before I was able to make any money
with it. I'd survived up to that point, yes, by living on savings mostly.

But according to you, I should just have given it away? And presumably
someone who spends years writing a book, or creating or developing any sort
of product should just give it away at the end if they managed to survive
the experience.

--
Bartc

Rick C. Hodgin

unread,
Nov 18, 2014, 3:17:34 PM11/18/14
to
It's okay to sell books because you are making a thing that requires
ongoing repetition to produce each copy, but even the book should not
sell for more than it costs (all long-term expenses considered).

But for digital works, you still possess the thing you spent years
creating, while simultaneously possessing the ability to distribute
it to everyone in the entire world. You can have your digital work
and share it too. You lose nothing by sharing digital works (except
the artificially erected empire walls of self-ownership rather than
shared-giving, which only existed there because (figurative) you
put them there in the first place).

Software, like knowledge, should be disseminated to all for free
because you can share it, give it away to the fullest extent, and
still possess it yourself.

People lose nothing by sharing these things ... except the personal
walls of hoarding/greed/self-seeking-ends that people place around
themselves so as to not have to continue in labor.

Jens Thoms Toerring

unread,
Nov 18, 2014, 3:27:03 PM11/18/14
to
Rick C. Hodgin <rick.c...@gmail.com> wrote:
> I found the link here:

> http://compgroups.net/comp.lang.c++/link-object-files-from-vc++-and-gcc/2080401

> The relevant portion is here: "g++ -c -gcoff myfile.cpp -o list.obj"

> And then you can include list.obj in your MSVC link input.

> -------------------------------------------------------------------
> COFF output in GCC was the key. I was able to get it working.

> Here's are the steps for a sample build:

> (1) Install MinGW on Windows with GCC and bases.
> (2) Create the two source files below.
> (3) Launch a command prompt that has the path for visual studio tools.
> (4) Execute these steps:
> (a) C:\>PATH=%PATH%;c:\mingw\bin\
> (b) C:\>g++ -c -gcoff list.cpp -o list.obj
> (c) C:\>cl /c main.cpp
> (d) C:\>link main.obj list.obj /OUT:main.exe

Fine, now you've got a program linked together from more than
one object file. I'm still a bit doubtful about the necessity
of using the '-gcoff' option, which, as far as I know, just
asks the compiler to produce debugging information in COFF
format, which doesn't seem too relevant for getting the
object files linked together (but I could be wrong, never
having used MinGW). But the OP wrote

> i would like to have it as a sorta of plugin/script system

and in a follow-up post

> then in my code i need to link it at runtime in my app
> and call it

That sounds a lot like loading and using the object file
from within the already running program. That maybe can
done by Jacob Navia, using his own toolchain and intimate
knowledge of the Windows internals, but for us mere mortals
building a shared library and using the the LoadLibrary()
functions and friends (or dlopen() etc. on Unix) seems to
me to be the best way to go.

Rick C. Hodgin

unread,
Nov 18, 2014, 3:44:25 PM11/18/14
to
On Tuesday, November 18, 2014 3:27:03 PM UTC-5, Jens Thoms Toerring wrote:
> That sounds a lot like loading and using the object file
> from within the already running program. That maybe can
> done by Jacob Navia, using his own toolchain and intimate
> knowledge of the Windows internals, but for us mere mortals
> building a shared library and using the the LoadLibrary()
> functions and friends (or dlopen() etc. on Unix) seems to
> me to be the best way to go.

Agree completely. DLLs are the way to go. They exist for this very
purpose.

FWIW, I misunderstood fir's request. I didn't realize he was needing
the runtime linking with the .o output. I have difficulty reading and
at times it's worse than others. It's been bad the past couple days.

Ian Collins

unread,
Nov 18, 2014, 3:59:25 PM11/18/14
to
fir wrote:

Please wrap your lines!
Doesn't windows support a dynamic linking? In the Unix would we would
use the dlopen() and friends for this.

--
Ian Collins

Kaz Kylheku

unread,
Nov 18, 2014, 4:47:54 PM11/18/14
to
It's not different at all. In fact, after developing a product, you might be in
debt, and if enough copies of that digital string of bits does not sell, then
you suffer a loss.

You still have a roof over you head only because other people took the losses
for you on their chins, like investors, and because of mechanisms like
bankruptcy protection, and the protection from your business being
incorporated, so that various creditors don't go after your personal assets.
And also because you had a plan to invest only so much of your personal
portfolio into the project that you could if the project yielded no returns.

People who create a string of bits and sell copies are very much within their
moral right to do so. That string of bits has development costs, and it has to
be priced in an acceptable way so that it sells at all, and so then recovering
the costs means moving N copies at $Y per copy over the window of time
during that window of time in which the program is viable at all.

Some people have historically become very rich from selling large numbers of
copies of technically mediocre software; but they cannot be used as scapegoats.
A lot of software struggles to find customers, even if it is decent and took a
lot of effort to produce.

Kaz Kylheku

unread,
Nov 18, 2014, 4:52:46 PM11/18/14
to
On 2014-11-18, Rick C. Hodgin <rick.c...@gmail.com> wrote:
> On Tuesday, November 18, 2014 3:11:29 PM UTC-5, Bart wrote:
>> "Rick C. Hodgin" <rick.c...@gmail.com> wrote in message
>> news:6c69c5c3-f943-4fe0...@googlegroups.com...
>> > On Tuesday, November 18, 2014 2:08:19 PM UTC-5, fir wrote:
>>
>> >> sometimes i feel like i would like to pay someone for doing the work
>> >> i need which i know it would be just easier to me than doing it myself
>> >
>> > Paying for labor is one thing. It's to be expected. But it is another
>> > thing to have already done the work, to possess the digital product in
>> > your hands, and then to be selling copies of it when you've presumably
>> > already eaten up until that point, are still alive, have a place to
>> > stay, etc.
>>
>> One application of mine took 2-3 years before I was able to make any money
>> with it. I'd survived up to that point, yes, by living on savings mostly.
>>
>> But according to you, I should just have given it away? And presumably
>> someone who spends years writing a book, or creating or developing any sort
>> of product should just give it away at the end if they managed to survive
>> the experience.
>
> It's okay to sell books because you are making a thing that requires
> ongoing repetition to produce each copy, but even the book should not
> sell for more than it costs (all long-term expenses considered).

That is false, because the market *will* in fact pay $50 or $100 for a book, but
will not pay anywhere near that for a book that whose title is A,
and whose pages consist of repetitons of the character 'a' with random
spaces in between. In fact, people will pay slightly more for a completely
blank book, which is cheaper to produce than "A".

You should charge what the market will bear. That reflects the true value
of the product: it means that bids are meeting asks in a fair negotiation.

> Software, like knowledge, should be disseminated to all for free
> because you can share it, give it away to the fullest extent, and
> still possess it yourself.

People can use knowledge to make their lives *materially* better, while the
fool who taught free of charge lives in a ratty apartment and eats Kraft
Dinner.

Gordon Burditt

unread,
Nov 18, 2014, 5:31:08 PM11/18/14
to
> I would like to gest such feature in my
> program, take given .o (in the format that is output from mingw
> compiler) load it and link it in my app to call it internally by my
> own program

What you describe is similar to the implementation of runtime-loaded
libraries in UNIX. This is not just shared libraries, where the
linker determines what to load, but shared objects, where the program
logic determines if/when to load it. The object file has to be
made into a shared object with the linker. The running program
calls dlopen() on the shared object, then calls dlsym() to get the
addresses of functions, which it can then call. When through with
the shared object, call dlclose().

PHP uses these extensively, and whether an extension is loaded
depends on a configuration file.

Yes, you *could* have the program write code, invoke a compiler and
linker, then dlopen() the object and use it. The use of interpreters
can usually make it more platform-independent.

There are all sorts of complicated details about how libraries
needed by the newly-loaded library get referenced, and in case
two different libraries define that symbol, which one is used.

> would ut be hard/time consuming to write?

Porting something like this from Unix to Windows would likely
be time-consuming unless Windows already has something similar.
I don't know much about Windows at this level.

> does someone know what efforts it would inwolve? (i would like
> to have it as a sorta

> of plugin/script system) prefer this over dlls or highlevel scripts
> could someone maybe wrote such thing and show me some source?

If, in Windows, you can have the program ask for a DLL to be loaded
at runtime, this sounds like an implementation of what you're asking
for already exists.

fir

unread,
Nov 18, 2014, 5:45:39 PM11/18/14
to
every person decides for self what he wants - i want the routines to load-in
(link-in) some.o in my own program at any chosen runtime moment and then use (call) it

i know the usability of it in a long run may be limited but i suspect for simple cases (as a given one when whole .o has only one procedure and only one symbol to link) this may be really not to hard
to run (I mean it may be 200 lines of code or so - sadly this need some knowledge of
.o internal format (but maybe not much more as probably when i will load it in
ram i just can call it by pointer as
normal function pointer

yet one thing i do not understand is this fix-up of the symbol? when doing it need i
only adjust the pointer to foo function or
need i fix-up some values in foo procedure body?

Rick C. Hodgin

unread,
Nov 18, 2014, 6:28:20 PM11/18/14
to
Kaz Kylheku writes:
> People can use knowledge to make their lives
> *materially* better, while the fool who taught
> free of charge lives in a ratty apartment and
> eats Kraft Dinner.

Ever read http://biblehub.com/kjv/luke/16.htm
vs 19-31?

"22 And it came to pass, that the beggar died,
and was carried by the angels into Abraham's
bosom: the rich man also died, and was buried;
23 And in hell [the rich man] lift up his eyes,
being in torments, and seeth Abraham afar off,
and Lazarus in his bosom [in Heaven]."

First yields to last, but last never yields.

BartC

unread,
Nov 18, 2014, 6:43:10 PM11/18/14
to
"fir" <profes...@gmail.com> wrote in message
news:ad4e4baa-7861-4816-a768-
> every person decides for self what he wants - i want the routines to
> load-in
> (link-in) some.o in my own program at any chosen runtime moment and then
> use (call) it
>
> i know the usability of it in a long run may be limited but i suspect for
> simple cases (as a given one when whole .o has only one procedure and only
> one symbol to link) this may be really not to hard
> to run (I mean it may be 200 lines of code or so - sadly this need some
> knowledge of
> .o internal format (but maybe not much more as probably when i will load
> it in
> ram i just can call it by pointer as
> normal function pointer
>
> yet one thing i do not understand is this fix-up of the symbol? when doing
> it need i
> only adjust the pointer to foo function or
> need i fix-up some values in foo procedure body?

It can be quite difficult. For one thing, you need to allocate memory that
is executable (that's the easy bit).

You might need to relocate absolute references (to code or static data
addresses). Then the code might itself call other functions, not necessarily
in your application, but in the runtime (maths or other C library functions,
sometimes implicitly). Then you need to determine the entry point for the
function you're interested in.

Another problem before you even do all that is sorting out the .o file
format. (Yet another is ensuring the code is compatible: if your application
is 64-bit, it will have trouble calling a 32-bit function in the object
file. This and other problems are likely if the object file is created on a
different system from the one that generated your application.)

But what you haven't explained is why this code cannot be statically linked
in, or why you can't use conventional means to run a dynamically linked
function.

--
Bartc



Jens Thoms Toerring

unread,
Nov 18, 2014, 6:59:44 PM11/18/14
to
fir <profes...@gmail.com> wrote:

> every person decides for self what he wants - i want the routines to load-in
> (link-in) some.o in my own program at any chosen runtime moment and then use
> (call) it

> i know the usability of it in a long run may be limited but i suspect for
> simple cases (as a given one when whole .o has only one procedure and only
> one symbol to link) this may be really not to hard to run (I mean it may be
> 200 lines of code or so - sadly this need some knowledge of .o internal
> format (but maybe not much more as probably when i will load it in ram i
> just can call it by pointer as normal function pointer

Well, first of all you will need intimate knowledge of the exact
format of such an .o (object) file. Where exactly is the start
of that function?

Then: is it set up as position-independent code, ready to run
in any place you loaded it to? Or do you need to do lots of
transformation on it before it can be ever used? May depend
on the system and/or compiler flags. Object code isn't neces-
sarily just plain, directly usable machine code.

Next: does your system allow you to run code at some arbitrary
position in RAM? It might not for security reasons. You may
need to know the "magic handshake" to get the system to set
an "executable flag" for the pages into which the code has
been loaded. Or to load it at an address that has this flag
set.

What you're up against is basically writing a run-time loader/
linker yourself. That can be far from trivial, even for the most
simple cases. Nothing wrong with trying in order to learn. But
perhaps it might be preferable for a start trying out what
others already have done for you in that respect with the
LoadLibrary() (or dlopen()) stuff. And perhaps there's a reason
why these mechanisms require a DLL/shared library and don't work
with plain .o files? And creating a DLL/shared library is much
less "rocket science" then writing a run-time loader/linker from
scratch. If you attempt to do that this group is not the place
to ask since this is far beyond anything related to C - it's
probably both system- and architecture-dependent.

Robert Wessel

unread,
Nov 19, 2014, 12:40:15 AM11/19/14
to
On Tue, 18 Nov 2014 14:45:31 -0800 (PST), fir <profes...@gmail.com>
wrote:

>W dniu wtorek, 18 listopada 2014 21:27:03 UTC+1 u?ytkownik Jens Thoms Toerring napisa?:
And what exactly is wrong with a DLL (Windows) or shared library
(*nix)? They solve this exact problem, and you won't have to write
thousands of lines of code and muck with the security system in order
to get this to work. And that's assuming it's possible at all - not
all object modules are anywhere near ready to load before a full link
step. Heck, if it was compiled with link time code generation (the
default in VS these days, BTW), the object module won't even contain
any object code, just some intermediate representation the compiler is
using. Even if the object module has traditional object code in it,
it's probably going to need to be linked with some libraries before
it's usable.

And in Windows, you can trivially specify that a DLL is automatically
loaded at load time, although you do need to have a fixed name and
entry point then. Then you can just call it with a "normal" C
function call. And if you have a situation where you might not call
the DLL at all (or can live with it missing), you can use delay loaded
DLLs (you can even hack that to hide the "normal" LoadLibrary and
GetProcAddress, although it's somewhat pointless, IMO). Or just use
LoadLibrary and GetProcAddress, you just end up calling the function
through a function pointer - it's pretty trivial.

And you can do similar things in *nix, although I'm not sure about
delay loads.

Honestly, you had better have some darn good reasons for avoiding DLLs
for this to make even the slightest amount of sense.

Ian Collins

unread,
Nov 19, 2014, 1:42:36 AM11/19/14
to
Robert Wessel wrote:
>
> And in Windows, you can trivially specify that a DLL is automatically
> loaded at load time, although you do need to have a fixed name and
> entry point then. Then you can just call it with a "normal" C
> function call. And if you have a situation where you might not call
> the DLL at all (or can live with it missing), you can use delay loaded
> DLLs (you can even hack that to hide the "normal" LoadLibrary and
> GetProcAddress, although it's somewhat pointless, IMO). Or just use
> LoadLibrary and GetProcAddress, you just end up calling the function
> through a function pointer - it's pretty trivial.
>
> And you can do similar things in *nix, although I'm not sure about
> delay loads.

The dlopen() function can be used to open executables, libraries or
stand alone object files.

--
Ian Collins

fir

unread,
Nov 19, 2014, 3:19:19 AM11/19/14
to
Im using dlls too but i want to du such .o runtime linking for the case of it

It is not hard if you know what to do, i know it partially, dont know some details
lets see how i see it

I want to do some very simple case at first assume that i have mangen.o file
which contains only one procedure and
no static data

mangen.c:
///////////// begin of the file
void mangen(int* data)
{
for(int j=0; j<100; j++)
for(int i=0; i<100; i++)
data[j*100+i] = 111;
}
//////// end of the file

alright, now i compile it with mingw

c:\mingw\bin\gcc -std=c99 -c mangen.c -fno-exceptions -march=core2 -mtune=generic -mfpmath=both -msse2

it yeilds to mangen.o file which is 400 bytes

00000000 4C 01 03 00 00 00 00 00-D8 00 00 00 0A 00 00 00 L...............
00000010 00 00 05 01 2E 74 65 78-74 00 00 00 00 00 00 00 .....text.......
00000020 00 00 00 00 4C 00 00 00-8C 00 00 00 00 00 00 00 ....L...........
00000030 00 00 00 00 00 00 00 00-20 00 30 60 2E 64 61 74 ........ .0`.dat
00000040 61 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 a...............
00000050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000060 40 00 30 C0 2E 62 73 73-00 00 00 00 00 00 00 00 @.0..bss........
00000070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000080 00 00 00 00 00 00 00 00-80 00 30 C0 55 89 E5 83 ..........0.U...
00000090 EC 10 C7 45 FC 00 00 00-00 EB 34 C7 45 F8 00 00 ...E......4.E...
000000A0 00 00 EB 21 8B 45 FC 6B-D0 64 8B 45 F8 01 D0 8D ...!.E.k.d.E....
000000B0 14 85 00 00 00 00 8B 45-08 01 D0 C7 00 6F 00 00 .......E.....o..
000000C0 00 83 45 F8 01 83 7D F8-63 7E D9 83 45 FC 01 83 ..E...}.c~..E...
000000D0 7D FC 63 7E C6 C9 C3 90-2E 66 69 6C 65 00 00 00 }.c~.....file...
000000E0 00 00 00 00 FE FF 00 00-67 01 6D 61 6E 67 65 6E ........g.mangen
000000F0 2E 63 00 00 00 00 00 00-00 00 00 00 5F 6D 61 6E .c.........._man
00000100 67 65 6E 00 00 00 00 00-01 00 20 00 02 01 00 00 gen....... .....
00000110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000120 2E 74 65 78 74 00 00 00-00 00 00 00 01 00 00 00 .text...........
00000130 03 01 4B 00 00 00 00 00-00 00 00 00 00 00 00 00 ..K.............
00000140 00 00 00 00 2E 64 61 74-61 00 00 00 00 00 00 00 .....data.......
00000150 02 00 00 00 03 01 00 00-00 00 00 00 00 00 00 00 ................
00000160 00 00 00 00 00 00 00 00-2E 62 73 73 00 00 00 00 .........bss....
00000170 00 00 00 00 03 00 00 00-03 01 00 00 00 00 00 00 ................
00000180 00 00 00 00 00 00 00 00-00 00 00 00 04 00 00 00 ................

now i need to link it in my program body

lets go to that problem

I.

I suspect that there up in those 400 bytes lies a chunk that i need to load to my previously allocated buffer

could someone maybe provide some simple code that correctly allow me to localise
thic chunk of procedure body?

II.

assume that i did it and now got a body of my procedure in my process space

In such simple procedure case i suspect i
dont need any fixups at all, probably i just can call in my allocated buffer and routine will be correctly executed

Am I right?

but I wonder if in general (assume my linked procedure still not references to any data besides its own local variables and do not calls any other procedures) i would like do some fixups or still no?

tnx for hints

Ian Collins

unread,
Nov 19, 2014, 3:48:52 AM11/19/14
to
fir wrote:
>>
> Im using dlls too but i want to du such .o runtime linking for the case of it
>
> It is not hard if you know what to do, i know it partially, dont know some details
> lets see how i see it

Unless you are tied to the windows platform, you will find doing what
you want to do trivial on Unix/Linux.

--
Ian Collins

Rick C. Hodgin

unread,
Nov 19, 2014, 4:08:02 AM11/19/14
to
Ian Collins wrote:
> Unless you are tied to the windows platform,
> you will find doing what you want to do trivial
> on Unix/Linux.

And to extend Ian's advice:

You can also probably achieve what you want on Windows with CYGWIN using dlopen().

Jens Thoms Toerring

unread,
Nov 19, 2014, 4:28:21 AM11/19/14
to
fir <profes...@gmail.com> wrote:

> Im using dlls too but i want to du such .o runtime linking for the case of
> it
> It is not hard if you know what to do, i know it partially, dont know some
> details lets see how i see it

[hex listing snipped]

> I suspect that there up in those 400 bytes lies a chunk that i need to load
> to my previously allocated buffer

That may even be the case (or completely wrong). But that's
something not at all related to C - if you'd written the code
in a different language and used a compiler for that language
the result might have been the same, or at least very similar.
All this depends on the system you're using, the CPU archi-
tecture and the compiler you've used. But there's not a single
bit specific to C. C does not prescribe what exactly the com-
piler has to output, it just prescribes how the finally pro-
duced program has to behave. How a certain compiler achieves
this is definitely nothing C has anyting to say about.

So you should consider asking in a newsgroup where these details
are the topic. This newsgroup is about C, not the output of the
meat-grinder, called a compiler. In this newsgroup we're talking
about cows, not sausages (Mr Fibble excepted;-)

fir

unread,
Nov 19, 2014, 5:46:11 AM11/19/14
to
W dniu środa, 19 listopada 2014 10:08:02 UTC+1 użytkownik Rick C. Hodgin napisał:
> Ian Collins wrote:
> > Unless you are tied to the windows platform,
> > you will find doing what you want to do trivial
> > on Unix/Linux.
>
> And to extend Ian's advice:
>
> You can also probably achieve what you want on Windows with CYGWIN using dlopen().
>
i need to use pure win32

fir

unread,
Nov 19, 2014, 5:52:54 AM11/19/14
to
i can ask other group - but which one is related and used so i can find answer?

(it is maybe not related to general c but is in the case of specyfic c-linker implementation )

ps i found with objdump that this chunk here is 8c-d7

1. could maybe someone provide hint how to alloc
executable buffer in winapi
2. how in general wrote a proceduure that wil give a body chunk for given symbol name
3. do i need a fixups here?

the procedure is


C:\!CODE\test2>c:\mingw\bin\objdump -fd mangen.o

mangen.o: file format pe-i386
architecture: i386, flags 0x00000038:
HAS_DEBUG, HAS_SYMS, HAS_LOCALS
start address 0x00000000


Disassembly of section .text:

00000000 <_mangen>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 10 sub $0x10,%esp
6: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
d: eb 34 jmp 43 <_mangen+0x43>
f: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp)
16: eb 21 jmp 39 <_mangen+0x39>
18: 8b 45 fc mov -0x4(%ebp),%eax
1b: 6b d0 64 imul $0x64,%eax,%edx
1e: 8b 45 f8 mov -0x8(%ebp),%eax
21: 01 d0 add %edx,%eax
23: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx
2a: 8b 45 08 mov 0x8(%ebp),%eax
2d: 01 d0 add %edx,%eax
2f: c7 00 6f 00 00 00 movl $0x6f,(%eax)
35: 83 45 f8 01 addl $0x1,-0x8(%ebp)
39: 83 7d f8 63 cmpl $0x63,-0x8(%ebp)
3d: 7e d9 jle 18 <_mangen+0x18>
3f: 83 45 fc 01 addl $0x1,-0x4(%ebp)
43: 83 7d fc 63 cmpl $0x63,-0x4(%ebp)
47: 7e c6 jle f <_mangen+0xf>
49: c9 leave
4a: c3 ret
4b: 90 nop

C:\!CODE\test2>pause

does this body need a fixups?

(soory im asking specyfic i need to resolve this)

BartC

unread,
Nov 19, 2014, 7:28:36 AM11/19/14
to
"fir" <profes...@gmail.com> wrote in message
news:5b3d1ce3-1526-407d...@googlegroups.com...
> W dniu środa, 19 listopada 2014 00:43:10 UTC+1 użytkownik Bart napisał:

>> It can be quite difficult. For one thing, you need to allocate memory
>> that
>> is executable (that's the easy bit).
>>
>> You might need to relocate absolute references (to code or static data
>> addresses)....

> I.
>
> I suspect that there up in those 400 bytes lies a chunk that i need to
> load to my previously allocated buffer
>
> could someone maybe provide some simple code that correctly allow me to
> localise
> thic chunk of procedure body?

I haven't looked at object files for many years, but I believe there is a a
block of data in it that tells you which parts of the code block need
relocating. You can't do it easily just by looking at the code, unless you
disassemble the code (if you can even tell which is code and which is data),
and recognise the instructions that will use absolute offsets. But code will
also sometimes use data, and you can't in general tell if a particular word
is user data, or the address of some label (see below).

> II.
>
> assume that i did it and now got a body of my procedure in my process
> space
>
> In such simple procedure case i suspect i
> dont need any fixups at all, probably i just can call in my allocated
> buffer and routine will be correctly executed
>
> Am I right?
>
> but I wonder if in general (assume my linked procedure still not
> references to any data besides its own local variables and do not calls
> any other procedures) i would like do some fixups or still no?

If your code uses, for example, the address of a function, or a switch
statement, then it will be using the absolute address of some label, and
those will need fixups.

In general your scheme will only work in trivial cases, so may not be
worthwhile (and you still need to find where the function starts).

However, if the requirement is simply this:

int (*fn)(int,int); // thanks to Cdecl
void* get_function_address(char*);

fn = get_function_address("int fred(int a,int b) {return a+b;}");

if fn==NULL) exit(0);

a = fn(b, c);

That is, to turn a source file or string containing C code, into the address
of a function, that I think that can be written just by invoking a C
compiler, a linker, and whatever OS functions are used to access the dynamic
library.

A somewhat tedious-to-write function (calling external programs and dealing
with errors), but once written (and all the external support is in place,
but even your method requires a C installation), it can be as simple as
that.

(My interface above assumes a single function is defined. Anything more
complex, you will need the name of the function passed too. If you need
several functions, then a different interface is needed.)

--
Bartc

fir

unread,
Nov 19, 2014, 7:44:08 AM11/19/14
to
>
> (it is maybe not related to general c but is in the case of specyfic c-linker implementation )
>
> ps i found with objdump that this chunk here is 8c-d7
>
PS maybe its a bit curious but i did some test and this hardkoded routine linking works here right away

void test3() //link at runtime external .o routine
{
const int mangen_body_max = 200;
static char mangen_body[mangen_body_max];

//just load chunk

LoadChunkFromFileOnce(mangen_body, mangen_body_max, "mangen2.o", 0x8c, 0xd7 );

//assign pointer

void (*mangen)(int*) = (void (*)(int*)) mangen_body;

// then run
mangen((int*)frame_bitmap);

//it works

}

maybe i have some system setting that do not prevents execution of data arrays

now i need at least two things

1. find a routine that will correctly find appriopriate chunk boundaries
2. resolve some cases with fixups when needed

can someone hint on that?

fir

unread,
Nov 19, 2014, 8:58:45 AM11/19/14
to
>
> //it works

this way i got wery easy plugin/scripting system, probably the biggest downside now is that i cannot call the external functions from the script

if i got such script

extern int randd(void);

void mangen(int* data, int frame_size_x, int frame_size_y)
{
for(int j=0; j<frame_size_y; j++)
for(int i=0; i<frame_size_x; i++)
{
if((i+j)%2==0)
data[j*frame_size_x+i] = randd() ;
}
}
i got such dump


mangen.o: file format pe-i386
architecture: i386, flags 0x00000039:
HAS_RELOC, HAS_DEBUG, HAS_SYMS, HAS_LOCALS
start address 0x00000000


Disassembly of section .text:

00000000 <_mangen>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 53 push %ebx
4: 83 ec 14 sub $0x14,%esp
7: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp)
e: eb 4a jmp 5a <_mangen+0x5a>
10: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp)
17: eb 35 jmp 4e <_mangen+0x4e>
19: 8b 45 f4 mov -0xc(%ebp),%eax
1c: 8b 55 f0 mov -0x10(%ebp),%edx
1f: 01 d0 add %edx,%eax
21: 83 e0 01 and $0x1,%eax
24: 85 c0 test %eax,%eax
26: 75 22 jne 4a <_mangen+0x4a>
28: 8b 45 f4 mov -0xc(%ebp),%eax
2b: 89 c2 mov %eax,%edx
2d: 0f af 55 0c imul 0xc(%ebp),%edx
31: 8b 45 f0 mov -0x10(%ebp),%eax
34: 01 d0 add %edx,%eax
36: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx
3d: 8b 45 08 mov 0x8(%ebp),%eax
40: 8d 1c 02 lea (%edx,%eax,1),%ebx
43: e8 00 00 00 00 call 48 <_mangen+0x48>
48: 89 03 mov %eax,(%ebx)
4a: 83 45 f0 01 addl $0x1,-0x10(%ebp)
4e: 8b 45 f0 mov -0x10(%ebp),%eax
51: 3b 45 0c cmp 0xc(%ebp),%eax
54: 7c c3 jl 19 <_mangen+0x19>
56: 83 45 f4 01 addl $0x1,-0xc(%ebp)
5a: 8b 45 f4 mov -0xc(%ebp),%eax
5d: 3b 45 10 cmp 0x10(%ebp),%eax
60: 7c ae jl 10 <_mangen+0x10>
62: 83 c4 14 add $0x14,%esp
65: 5b pop %ebx
66: 5d pop %ebp
67: c3 ret


this explains a bit call is followed by 000000 (seem to be tha same for rand())

what to do with that?????,

if those called functions are from my own program i probably could read the .o where names list and fixup positions are probably stored and fill it myself

more unclear is what to do if the names are from c-lib - just the same? reckognize them ? take the values from my own program pointers and assign them? think it could work but 'm not sure

(fir)

BartC

unread,
Nov 19, 2014, 10:16:51 AM11/19/14
to
"BartC" <b...@freeuk.com> wrote in message
news:F10bw.711763$9R5.6...@fx29.am4...

> However, if the requirement is simply this:
>
> int (*fn)(int,int); // thanks to Cdecl
> void* get_function_address(char*);
>
> fn = get_function_address("int fred(int a,int b) {return a+b;}");

> A somewhat tedious-to-write function (calling external programs and
> dealing
> with errors), but once written (and all the external support is in place,
> but even your method requires a C installation), it can be as simple as
> that.

Here's a typical implementation. I need to supply the name of the function
(otherwise the string processing involved to extract the name would dominate
the code). Where the source code is already in a file (or you already have
an object file) then it's even simpler. This starts with the source code as
a string:

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

char* gfa_error="";

void* get_function_address(char* fnname, char* program) {
int status;
FILE *f;
#define tempfile "temp.c"
#define objfile "temp.o"
#define dllfile "temp.dll"
HMODULE handle;
void* fnptr;

f=fopen(tempfile,"w");
if (f==NULL) {gfa_error = "Can't create file: " tempfile; return NULL;}

fwrite(program, 1, strlen(program), f);
fclose(f);

status = system("gcc -c " tempfile);
if (status != 0) {gfa_error = "Can't compile: ",tempfile; return NULL;}

status = system("gcc -s -shared " objfile " -o" dllfile);
if (status != 0) {gfa_error = "Can't create DLL: " dllfile; return NULL;}

handle = LoadLibrary(dllfile);
if (handle == 0) {gfa_error = "Can't load DLL " dllfile; return NULL;}

fnptr = GetProcAddress(handle, fnname);
if (fnptr == NULL) {gfa_error = "Can't find function"; return NULL;}

return fnptr;
}

int main(void) {
int (*fn)(int,int);

fn = get_function_address("testfn","int testfn(int a,int b) { return
a+b; }\n");

if (fn==NULL){
printf("Failed: %s\n",gfa_error);
exit(0);
}

printf("It worked: fn(%d,%d) = %d\n",10,20,fn(10,20));

}

One problem is that you don't want to repeat this more than needed, so that
once the dll is created on one run of the program, it will still be there
the next time; you don't need to recompile or relink to dll.

--
Bartc


Rick C. Hodgin

unread,
Nov 19, 2014, 10:32:39 AM11/19/14
to
On Wednesday, November 19, 2014 8:58:45 AM UTC-5, fir wrote:
> >
> > //it works
>
> this way i got wery easy plugin/scripting system, probably the
> biggest downside now is that i cannot call the external functions
> from the script
>
> if i got such script
> [snip of c source code]
> i got such dump
> [snip of at&t (ack!) syntax assembly]

The standard method of doing this is to write your plugins in a DLL.
Use LoadLibrary() to open the DLL and retrieve a handle to it. And
then use GetProcAddress() to retrieve the address to each of the
functions you need.

Here is an example which demonstrates this. I use it for my sound
driver, which is loaded at runtime as an optional plugin:

Specifically lines 144, 148-154, the test if all of the functions
I need are retrieved in line 157, and then their assignment to
the structure in 163-169:
https://github.com/RickCHodgin/libsf/blob/master/vvm/core/oss/oss_plugins.cpp

The structure I use for the sound plugin is here lines 70-108:
https://github.com/RickCHodgin/libsf/blob/master/vvm/core/oss/oss_plugins.h

Using this model where the functions are defined as a structure, multiple
plugins can be loaded if needed, and then each one called appropriately.

What you're trying to do is based on mechanics that are not necessary.
In Win32 alone you can do this through the API and you gain the security
which exists in a constructed DLL that Windows itself will validate upon
the call to LoadLibrary(), and each function being known through
GetProcAddress().

If you need to load other resources from the DLL, you can use code like
in this source file (specifically lines 156, 160 and their related
functions):
https://github.com/RickCHodgin/resourcex/blob/master/resourcex/resourcex/resourcex.cpp

Kenny McCormack

unread,
Nov 19, 2014, 11:08:29 AM11/19/14
to
In article <d577833d-96aa-4ec2...@googlegroups.com>,
Rick C. Hodgin <rick.c...@gmail.com> wrote:
>On Wednesday, November 19, 2014 8:58:45 AM UTC-5, fir wrote:
>> >
>> > //it works
>>
>> this way i got wery easy plugin/scripting system, probably the
>> biggest downside now is that i cannot call the external functions
>> from the script
>>
>> if i got such script
>> [snip of c source code]
>> i got such dump
>> [snip of at&t (ack!) syntax assembly]
>
>The standard method of doing this is to write your plugins in a DLL.
^^^^^????????
>Use LoadLibrary() to open the DLL and retrieve a handle to it. And
>then use GetProcAddress() to retrieve the address to each of the
>functions you need.

This is not a standard method, since none of the following terms appears or
has any traction in the Holy Bible^W^WC standards documents:

LoadLibrary(), DLL, handle, GetProcAddress()

--
Pensacola - the thinking man's drink.

Rick C. Hodgin

unread,
Nov 19, 2014, 11:25:00 AM11/19/14
to
Standard in Win32, which fir has indicated he's pursuing (not using
Cygwin and POSIX, for example).

Kenny McCormack

unread,
Nov 19, 2014, 11:27:20 AM11/19/14
to
In article <94d7c7b9-dce3-4ba5...@googlegroups.com>,
Rick C. Hodgin <rick.c...@gmail.com> wrote:
>On Wednesday, November 19, 2014 11:08:29 AM UTC-5, Kenny McCormack wrote:
>> In article <d577833d-96aa-4ec2...@googlegroups.com>,
>> Rick C. Hodgin <rick.c...@gmail.com> wrote:
>> >The standard method of doing this is to write your plugins in a DLL.
>> ^^^^^????????
>> >Use LoadLibrary() to open the DLL and retrieve a handle to it. And
>> >then use GetProcAddress() to retrieve the address to each of the
>> >functions you need.
>>
>> This is not a standard method, since none of the following terms appears or
>> has any traction in the Holy Bible^W^WC standards documents:
>>
>> LoadLibrary(), DLL, handle, GetProcAddress()
>
>Standard in Win32, which fir has indicated he's pursuing (not using
>Cygwin and POSIX, for example).

Are you really totally unaware of which newsgroup you are posting in?

Maybe using Google or some such rot?

--
"Insisting on perfect safety is for people who don't have the balls to live
in the real world."

- Mary Shafer, NASA Ames Dryden -

Rick C. Hodgin

unread,
Nov 19, 2014, 11:33:35 AM11/19/14
to
On Wednesday, November 19, 2014 11:27:20 AM UTC-5, Kenny McCormack wrote:
> In article <94d7c7b9-dce3-4ba5...@googlegroups.com>,
> Rick C. Hodgin <rick.c...@gmail.com> wrote:
> >Standard in Win32, which fir has indicated he's pursuing (not using
> >Cygwin and POSIX, for example).
>
> Are you really totally unaware of which newsgroup you are posting in?
> Maybe using Google or some such rot?

"Totally unaware"? I don't think so ... but if I were, I ask you: how
would I know?

-----
I don't draw hard-and-fast black-and-white lines across things which
don't require them, such as what's on- and off-topic content in a
newsgroup such as this. In fact, FWIW, people who enforce such things
seem to me to be a little odd in that way...

fir

unread,
Nov 19, 2014, 11:38:38 AM11/19/14
to
interesting but this is not the case i personaly need (want) to do

as i said it partially works - now i can
load .o as plugins but cannot call functions from it

i began to read coff documentation in hoping to resolve this (http://wiki.osdev.org/COFF)

let me state my present problem
i compile such plugin

int tab[1000];

int rand1();
int rand2();
int rand3();



void mangen(int* data, int frame_size_x, int frame_size_y)
{
for(int j=0; j<frame_size_y; j++)
for(int i=0; i<frame_size_x; i++)
{
if(i<100 && j<100)
if((i+j)%2==0)
data[j*frame_size_x+i] = rand1() + rand2() + rand3() ;
}
}

i got such binary from this

00000000 4C 01 04 00 00 00 00 00-6E 01 00 00 10 00 00 00 L.......n.......
00000010 00 00 04 01 2E 74 65 78-74 00 00 00 00 00 00 00 .....text.......
00000020 00 00 00 00 88 00 00 00-B4 00 00 00 50 01 00 00 ............P...
00000030 00 00 00 00 03 00 00 00-20 00 30 60 2E 64 61 74 ........ .0`.dat
00000040 61 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 a...............
00000050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000060 40 00 30 C0 2E 62 73 73-00 00 00 00 00 00 00 00 @.0..bss........
00000070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000080 00 00 00 00 00 00 00 00-80 00 30 C0 2E 64 72 65 ..........0..dre
00000090 63 74 76 65 00 00 00 00-00 00 00 00 14 00 00 00 ctve............
000000A0 3C 01 00 00 00 00 00 00-00 00 00 00 00 00 00 00 <...............
000000B0 40 00 30 C0 55 89 E5 56-53 83 EC 10 C7 45 F4 00 @.0.U..VS....E..
000000C0 00 00 00 EB 66 C7 45 F0-00 00 00 00 EB 51 83 7D ....f.E......Q.}
000000D0 F0 63 7F 47 83 7D F4 63-7F 41 8B 45 F4 8B 55 F0 .c.G.}.c.A.E..U.
000000E0 01 D0 83 E0 01 85 C0 75-32 8B 45 F4 89 C2 0F AF .......u2.E.....
000000F0 55 0C 8B 45 F0 01 D0 8D-14 85 00 00 00 00 8B 45 U..E...........E
00000100 08 8D 34 02 E8 00 00 00-00 89 C3 E8 00 00 00 00 ..4.............
00000110 01 C3 E8 00 00 00 00 01-D8 89 06 83 45 F0 01 8B ............E...
00000120 45 F0 3B 45 0C 7C A7 83-45 F4 01 8B 45 F4 3B 45 E.;E.|..E...E.;E
00000130 10 7C 92 83 C4 10 5B 5E-5D C3 90 90 20 2D 61 6C .|....[^]... -al
00000140 69 67 6E 63 6F 6D 6D 3A-22 5F 74 61 62 22 2C 35 igncomm:"_tab",5
00000150 51 00 00 00 0D 00 00 00-14 00 58 00 00 00 0E 00 Q.........X.....
00000160 00 00 14 00 5F 00 00 00-0F 00 00 00 14 00 2E 66 ...._..........f
00000170 69 6C 65 00 00 00 00 00-00 00 FE FF 00 00 67 01 ile...........g.
00000180 73 6B 72 79 70 74 2E 63-00 00 00 00 00 00 00 00 skrypt.c........
00000190 00 00 5F 6D 61 6E 67 65-6E 00 00 00 00 00 01 00 .._mangen.......
000001A0 20 00 02 01 00 00 00 00-00 00 00 00 00 00 00 00 ...............
000001B0 00 00 00 00 00 00 2E 74-65 78 74 00 00 00 00 00 .......text.....
000001C0 00 00 01 00 00 00 03 01-86 00 00 00 03 00 00 00 ................
000001D0 00 00 00 00 00 00 00 00-00 00 2E 64 61 74 61 00 ...........data.
000001E0 00 00 00 00 00 00 02 00-00 00 03 01 00 00 00 00 ................
000001F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 2E 62 ...............b
00000200 73 73 00 00 00 00 00 00-00 00 03 00 00 00 03 01 ss..............
00000210 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00000220 00 00 2E 64 72 65 63 74-76 65 00 00 00 00 04 00 ...drectve......
00000230 00 00 03 01 14 00 00 00-00 00 00 00 00 00 00 00 ................
00000240 00 00 00 00 00 00 5F 74-61 62 00 00 00 00 A0 0F ......_tab......
00000250 00 00 00 00 00 00 02 00-5F 72 61 6E 64 31 00 00 ........_rand1..
00000260 00 00 00 00 00 00 20 00-02 00 5F 72 61 6E 64 32 ...... ..._rand2
00000270 00 00 00 00 00 00 00 00-20 00 02 00 5F 72 61 6E ........ ..._ran
00000280 64 33 00 00 00 00 00 00-00 00 20 00 02 00 04 00 d3........ .....
00000290 00 00 - ..

the procedure assembly dump is


skrypt.o: file format pe-i386
architecture: i386, flags 0x00000039:
HAS_RELOC, HAS_DEBUG, HAS_SYMS, HAS_LOCALS
start address 0x00000000


Disassembly of section .text:

00000000 <_mangen>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 56 push %esi
4: 53 push %ebx
5: 83 ec 10 sub $0x10,%esp
8: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp)
f: eb 66 jmp 77 <_mangen+0x77>
11: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp)
18: eb 51 jmp 6b <_mangen+0x6b>
1a: 83 7d f0 63 cmpl $0x63,-0x10(%ebp)
1e: 7f 47 jg 67 <_mangen+0x67>
20: 83 7d f4 63 cmpl $0x63,-0xc(%ebp)
24: 7f 41 jg 67 <_mangen+0x67>
26: 8b 45 f4 mov -0xc(%ebp),%eax
29: 8b 55 f0 mov -0x10(%ebp),%edx
2c: 01 d0 add %edx,%eax
2e: 83 e0 01 and $0x1,%eax
31: 85 c0 test %eax,%eax
33: 75 32 jne 67 <_mangen+0x67>
35: 8b 45 f4 mov -0xc(%ebp),%eax
38: 89 c2 mov %eax,%edx
3a: 0f af 55 0c imul 0xc(%ebp),%edx
3e: 8b 45 f0 mov -0x10(%ebp),%eax
41: 01 d0 add %edx,%eax
43: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx
4a: 8b 45 08 mov 0x8(%ebp),%eax
4d: 8d 34 02 lea (%edx,%eax,1),%esi
50: e8 00 00 00 00 call 55 <_mangen+0x55>
55: 89 c3 mov %eax,%ebx
57: e8 00 00 00 00 call 5c <_mangen+0x5c>
5c: 01 c3 add %eax,%ebx
5e: e8 00 00 00 00 call 63 <_mangen+0x63>
63: 01 d8 add %ebx,%eax
65: 89 06 mov %eax,(%esi)
67: 83 45 f0 01 addl $0x1,-0x10(%ebp)
6b: 8b 45 f0 mov -0x10(%ebp),%eax
6e: 3b 45 0c cmp 0xc(%ebp),%eax
71: 7c a7 jl 1a <_mangen+0x1a>
73: 83 45 f4 01 addl $0x1,-0xc(%ebp)
77: 8b 45 f4 mov -0xc(%ebp),%eax
7a: 3b 45 10 cmp 0x10(%ebp),%eax
7d: 7c 92 jl 11 <_mangen+0x11>
7f: 83 c4 10 add $0x10,%esp
82: 5b pop %ebx
83: 5e pop %esi
84: 5d pop %ebp
85: c3 ret
86: 90 nop
87: 90 nop

I need now some simple routine that would
give mi information which function pointer i need to poke in which offset before running the routine

Keith Thompson

unread,
Nov 19, 2014, 11:38:59 AM11/19/14
to
Robert Wessel <robert...@yahoo.com> writes:
[...]
> And what exactly is wrong with a DLL (Windows) or shared library
> (*nix)? They solve this exact problem, and you won't have to write
> thousands of lines of code and muck with the security system in order
> to get this to work. And that's assuming it's possible at all - not
> all object modules are anywhere near ready to load before a full link
> step. Heck, if it was compiled with link time code generation (the
> default in VS these days, BTW), the object module won't even contain
> any object code, just some intermediate representation the compiler is
> using. Even if the object module has traditional object code in it,
> it's probably going to need to be linked with some libraries before
> it's usable.
[...]
> Honestly, you had better have some darn good reasons for avoiding DLLs
> for this to make even the slightest amount of sense.

Why not just invoke the linker to generate a DLL from the object file,
and then load the DLL? (I presume that's easy enough to do, but I don't
know the details.)

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

fir

unread,
Nov 19, 2014, 11:48:47 AM11/19/14
to
yes, pure winapi

Rick C. Hodgin

unread,
Nov 19, 2014, 11:54:05 AM11/19/14
to
I admire what you're doing, fir. I just don't understand why it's
necessary. I think the task you've carved out for yourself is most
admirable even if only for academic ends ... I just cannot help but
wonder why you need such a feature if you're not a linker, but only
loading things at runtime which have previously been compiled. There
are well-proven, well-established facilities to address these needs,
and I'm not able to grasp why you can't use them.

Are you writing a computer virus? :-)

fir

unread,
Nov 19, 2014, 12:20:09 PM11/19/14
to
no, i dislike malware i write 100% peacefull game prototypes

why?
1. becouse it is not so hard (i showed you 5 lines of code and it works! - i got functional (bit limited) runtime plugin at the cost of 5 lines of code)
2. becouse I LOVE LOW LEVEL (main reason)
3. becouse i like different cases, if im trying this option doesnt mean that i will automatically not use dll-s or scripts in other cases, just want to test this, why not
4. i plan to write a c compiler and linker systems , want to know coff and linking stuff anyway

BartC

unread,
Nov 19, 2014, 12:22:12 PM11/19/14
to
"fir" <profes...@gmail.com> wrote in message
news:444f61d9-c83b-4c94...@googlegroups.com...
>> "BartC" <b...@freeuk.com> wrote in message

<snip wasted effort>
(Well, almost; I might use it myself...)

> interesting but this is not the case i personaly need (want) to do

In the OP you said this:

> I would like to gest such feature in my
> program, take given .o (in the format that is output from mingw compiler)
> load it and link it in my app to call it internally by my
> own program

Plenty of advice has been given to do exactly that!

What you haven't said is why you need to deal directly with the object file
and what is wrong with the normal methods.

> void mangen(int* data, int frame_size_x, int frame_size_y)

> I need now some simple routine that would
> give mi information which function pointer i need to poke in which offset
> before running the routine

Look in the symbol table for the name of the function?

--
Bartc

Rick C. Hodgin

unread,
Nov 19, 2014, 12:36:41 PM11/19/14
to
On Wednesday, November 19, 2014 12:20:09 PM UTC-5, fir wrote:
> 4. i plan to write a c compiler and linker systems , want to know coff and linking stuff anyway

There is likely source code for some small *NIX compilers and linkers out
there. You could learn a lot by examining the source code. Don't go for
GCC or some monster like that (I think someone posted recently GCC is so
large it takes hours?? to compile itself -- I could be remembering that
wrong :-)).

fir

unread,
Nov 19, 2014, 12:41:53 PM11/19/14
to
W dniu środa, 19 listopada 2014 18:22:12 UTC+1 użytkownik Bart napisał:
>
> What you haven't said is why you need to deal directly with the object file
> and what is wrong with the normal methods.
>
as i said i like testing different cases,
i i test one it doesnt really mean that i
consider other to be worse (you often need to try some cases only to abandon it, but still its someteimes worth testing)

fir

unread,
Nov 19, 2014, 12:45:56 PM11/19/14
to
> > I need now some simple routine that would
> > give mi information which function pointer i need to poke in which offset
> > before running the routine
>
> Look in the symbol table for the name of the function?
>
probably, but what exactly it will look here? Im inspecting it but i got no much experience in dabbling in coff, so some hints would be helpfull on my way ;o

Robert Wessel

unread,
Nov 19, 2014, 4:17:07 PM11/19/14
to
On Wed, 19 Nov 2014 09:45:47 -0800 (PST), fir <profes...@gmail.com>
wrote:
Most Window object* files use MS's variant of COFF, called PE. The
specification can be found here:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms680547(v=vs.85).aspx

There are several articles about the format as well, but most focus on
image files. A couple for a start:

http://msdn.microsoft.com/en-us/magazine/ms809762.aspx

http://msdn.microsoft.com/en-us/magazine/cc301805.aspx


*Image files are PE as well, although they use a different subset of
features.

Robert Wessel

unread,
Nov 19, 2014, 4:17:40 PM11/19/14
to
On Wed, 19 Nov 2014 08:38:50 -0800, Keith Thompson <ks...@mib.org>
wrote:

>Robert Wessel <robert...@yahoo.com> writes:
>[...]
>> And what exactly is wrong with a DLL (Windows) or shared library
>> (*nix)? They solve this exact problem, and you won't have to write
>> thousands of lines of code and muck with the security system in order
>> to get this to work. And that's assuming it's possible at all - not
>> all object modules are anywhere near ready to load before a full link
>> step. Heck, if it was compiled with link time code generation (the
>> default in VS these days, BTW), the object module won't even contain
>> any object code, just some intermediate representation the compiler is
>> using. Even if the object module has traditional object code in it,
>> it's probably going to need to be linked with some libraries before
>> it's usable.
>[...]
>> Honestly, you had better have some darn good reasons for avoiding DLLs
>> for this to make even the slightest amount of sense.
>
>Why not just invoke the linker to generate a DLL from the object file,
>and then load the DLL? (I presume that's easy enough to do, but I don't
>know the details.)


Assuming the linker is installed, and you know where (and which one,
as there might be several), and you know what parameters and libraries
are needed to link the code (and again, there might be several
versions installed). But why not invoke the linker when you compile
the program in the first place? Presumably if you can run the
compiler, the linker is available as well. And the developer of the
extension should probably know what's needed to link their code.

And if you're going to offer to link the extension for the user, why
not just compile the whole program? Or if you're generating the code
internally, and you're invoking an external compiler to compile it,
just link it there too.

BartC

unread,
Nov 19, 2014, 5:22:50 PM11/19/14
to


"Robert Wessel" <robert...@yahoo.com> wrote in message
news:982q6apjima0et3b4...@4ax.com...
> On Wed, 19 Nov 2014 09:45:47 -0800 (PST), fir <profes...@gmail.com>
> wrote:
>
>>> > I need now some simple routine that would
>>> > give mi information which function pointer i need to poke in which
>>> > offset
>>> > before running the routine
>>>
>>> Look in the symbol table for the name of the function?
>>>
>>probably, but what exactly it will look here? Im inspecting it but i got
>>no much experience in dabbling in coff, so some hints would be helpfull on
>>my way ;o
>
>
> Most Window object* files use MS's variant of COFF, called PE. The
> specification can be found here:

I don't think that's right. Executable files (what I'd call PE files), have
an MSDOS header and stub program, followed by 'PE' and the rest of the file.

Object files don't have the MSDOS header and stub, nor the 'PE' signature.
(I found this out an hour ago.)

> http://msdn.microsoft.com/en-us/library/windows/desktop/ms680547(v=vs.85).aspx

> There are several articles about the format as well, but most focus on
> image files. A couple for a start:

I've never bothered with PE format in the past because I thought it was far
too complex and badly documented. The OP's comments made me think maybe it
wasn't so difficult, and I had another look.

I wasn't wrong! The documentation is all over the place, and I needed to
look in different places to gather those essential details that they don't
bother to mention.

I'm having a look at this, by writing a program to read and display the data
I'm interested in. I suggest the OP does something similar (if he's going on
to write a compiler and linker**). I don't think his ad-hoc approach will
work well.

(** Although I've written compilers without knowing object file formats. I
either used my own which were then combined to form 16-bit NE executables
(much faster than doing it the normal way). Or now, generating assembler
source and letting someone else worry about creating binary code and object
files. If I did have to generate binary code directly, I'd probably find a
way of avoiding using object and PE formats.)

> *Image files are PE as well, although they use a different subset of
> features.

I don't know the difference between image files and PE...

--
Bartc

Rick C. Hodgin

unread,
Nov 19, 2014, 5:36:32 PM11/19/14
to
Bart wrote:
> Or now, generating assembler source and
> letting someone else worry about creating
> binary code and object files.

This is RDC's way of handling it, though I also
have my own assembler and ABI. The x86 output
is largely MASM compatible (a few tweaks).

Robert Wessel

unread,
Nov 19, 2014, 5:50:49 PM11/19/14
to
On Wed, 19 Nov 2014 22:22:20 -0000, "BartC" <b...@freeuk.com> wrote:

>
>
>"Robert Wessel" <robert...@yahoo.com> wrote in message
>news:982q6apjima0et3b4...@4ax.com...
>> On Wed, 19 Nov 2014 09:45:47 -0800 (PST), fir <profes...@gmail.com>
>> wrote:
>>
>>>> > I need now some simple routine that would
>>>> > give mi information which function pointer i need to poke in which
>>>> > offset
>>>> > before running the routine
>>>>
>>>> Look in the symbol table for the name of the function?
>>>>
>>>probably, but what exactly it will look here? Im inspecting it but i got
>>>no much experience in dabbling in coff, so some hints would be helpfull on
>>>my way ;o
>>
>>
>> Most Window object* files use MS's variant of COFF, called PE. The
>> specification can be found here:
>
>I don't think that's right. Executable files (what I'd call PE files), have
>an MSDOS header and stub program, followed by 'PE' and the rest of the file.
>
>Object files don't have the MSDOS header and stub, nor the 'PE' signature.
>(I found this out an hour ago.)
>
>> http://msdn.microsoft.com/en-us/library/windows/desktop/ms680547(v=vs.85).aspx


Neither of which are the important parts of PE. The MZ stub and PE
are there for executables ("image" files in COFF/PE terms) so that the
loader can identify the files. If you check out the doc, you'll see
that the MS-DOS stub and PE signature are there only on image files.

Just run dumpbin on an obj (built without LTCG).


>> There are several articles about the format as well, but most focus on
>> image files. A couple for a start:
>
>I've never bothered with PE format in the past because I thought it was far
>too complex and badly documented. The OP's comments made me think maybe it
>wasn't so difficult, and I had another look.
>
>I wasn't wrong! The documentation is all over the place, and I needed to
>look in different places to gather those essential details that they don't
>bother to mention.
>
>I'm having a look at this, by writing a program to read and display the data
>I'm interested in. I suggest the OP does something similar (if he's going on
>to write a compiler and linker**). I don't think his ad-hoc approach will
>work well.


It's not really that complex, especially if you only consider image
(executable) files, although there are a lot of tedious details to get
right to get all the functionality. The image format has mostly
image-loadable sections with the relocations neatly separated in
another area, although there are some complexities with imports and
exports. The object formats have a number of additional issues to
contend with, sections, grouping, fixups (rather more complex than the
simple relocations in image files), and other tedium.


>(** Although I've written compilers without knowing object file formats. I
>either used my own which were then combined to form 16-bit NE executables
>(much faster than doing it the normal way). Or now, generating assembler
>source and letting someone else worry about creating binary code and object
>files. If I did have to generate binary code directly, I'd probably find a
>way of avoiding using object and PE formats.)
>
>> *Image files are PE as well, although they use a different subset of
>> features.
>
>I don't know the difference between image files and PE...


PEs are either image (executable) or object files (".obj") files.

fir

unread,
Nov 19, 2014, 7:24:49 PM11/19/14
to
W dniu środa, 19 listopada 2014 23:22:50 UTC+1 użytkownik Bart napisał:
> I've never bothered with PE format in the past because I thought it was far
> too complex and badly documented. The OP's comments made me think maybe it
> wasn't so difficult, and I had another look.
>
> I wasn't wrong! The documentation is all over the place, and I needed to
> look in different places to gather those essential details that they don't
> bother to mention.

I was always confused by what exactly this fix-up means, aftet watching this
e8 00 00 00 00 which is call with NULL instead of function adress things turned from unknown to mostly known

I go thru coff specs a bit and probably can draw somewhat simplified wiew of the things




it will go like

if f is begning of the .o file

take int at (f+2c)
it is "reloc table" adres (RTA for short)

tak short at (f+34)
it is reloc table records number (RTAN for short)

for(int i=0; i<RTAN; i++)
{
PA = RTA + 0x0a * i
SN = RTA + 0x0a * i + 4
}

PA is 'poke' adress, where you need insert the pointer value for symbol SN,

SN is a ordinal number of the symbol in symbol table

take (f+8) to get symbol table adres, STA
for short

STA + 18 * SN is the beginning of the symbol name,

there is written "The Symbol name field stores the name of this symbol if it is eight characters or fewer, otherwise this field contains a pointer into the String table." - so it yeilds to another lookup for longer names

takeint at (f+28) to get the text section beginning (assembly code)

that would be all i need to do for short

need to loop through rellocs, wil gain poke adress and corresponding symbol (function) name, if i rekognize function name (as the one i use in my hosc app then i just poke the pointer - if i do not reckognize i will break at error - fixups done, cann call the 'script' then and it should be able to call my functions

dont know if other specyfic things will not work. (i wasnt thinking about fixups
nneded for acces to script static data but it will be probably about the same)

i cannot link to the functions other than i got in host program, like c-lib calls other than i use in my host program - as it would involve the need to reach for its .o images and load it in (and it those reach for other unresolved symbols reach for more .o till all be loaded), but dont matter

(this recipe i wrote above may be a bit
simplified as mentioned adresses f+2c f+28 and f+34 are not fixed probably
text_header+18,text_header+14,text_header+20, ant the text header must be find by by name - but dont matter - the most important is process of fixups which seem to be quite easy just a loop of pokes each pke corresponding to symbol name, not such complex and definitely worth knowing to understand how linking works

tnx for atenntion





fir

unread,
Nov 19, 2014, 7:36:38 PM11/19/14
to
W dniu środa, 19 listopada 2014 23:22:50 UTC+1 użytkownik Bart napisał:
> I've never bothered with PE format in the past because I thought it was far
> too complex and badly documented. The OP's comments made me think maybe it
> wasn't so difficult, and I had another look.
>
> I wasn't wrong! The documentation is all over the place, and I needed to
> look in different places to gather those essential details that they don't
> bother to mention.

I was always confused by what exactly this fix-up means,
aftet watching this e8 00 00 00 00 which is call
with NULL instead of function adress things turned
from unknown to mostly known

I go thru coff specs a bit and probably can draw
somewhat simplified wiew of the things



it will go like


if f is begning of the .o file

take int at (f+2c)
it is "reloc table" adres (RTA for short) (*)

take short at (f+34)
it is reloc table records number (RTAN for short)

loop like this

for(int i=0; i<RTAN; i++)
{
PA = RTA + 0x0a * i
SN = RTA + 0x0a * i + 4
}

PA is 'poke' adress, where you need insert the
pointer value for symbol SN,

SN is a ordinal number of the symbol in symbol table

take (f+8) to get symbol table adres, STA
for short

STA + 18 * SN is the beginning of the symbol name,

there is yet written "The Symbol name field stores
the name of this symbol if it is eight characters
or fewer, otherwise this field contains a pointer
into the String table." - so it may yeild to another
lookup for longer names

take int at (f+28) to get the text section beginning
(assembly code)

that would be all i need to do, for short

need to loop through rellocs, wil gain poke adress
and corresponding symbol (function) name, if i rekognize
function name (as the one i got pointer to, in my hosc
app, then i just poke the pointer - if i do not
reckognize i will break at error - fixups done,
can call the 'script' then, and it should be able
to call linked functions

dont know if other specyfic things will not work.
(i wasnt thinking about fixups nneded for acces to
script static data (probably also need fixups hope
same easy way, but it will be probably like the calls)

i cannot link to the functions other than i got in host
program, like c-lib calls other than that i use in my host
program - as it would involve the need to reach for its .o
images and load it in (and it those reach for other
unresolved symbols reach for more .o till all be loaded -
probably this works this grabby way), but dont matter

(*) (this recipe i wrote above may be a bit
simplified as mentioned adresses f+2c f+28 and f+34
are not fixed probably text_header+18,text_header+14,
text_header+20, and the text header is not neccessary
f+14 and must must be find by by name - but dont matter
- the most important is process of fixups which seem
to be quite easy just a loop of pokes each poke

BartC

unread,
Nov 19, 2014, 8:28:41 PM11/19/14
to
"fir" <profes...@gmail.com> wrote in message
news:82eb5d56-08c1-4e36...@googlegroups.com...
> W dniu środa, 19 listopada 2014 23:22:50 UTC+1 użytkownik Bart napisał:
>> I've never bothered with PE format in the past because I thought it was
>> far
>> too complex and badly documented. The OP's comments made me think maybe
>> it
>> wasn't so difficult, and I had another look.
>>
>> I wasn't wrong! The documentation is all over the place, and I needed to
>> look in different places to gather those essential details that they
>> don't
>> bother to mention.

> if f is begning of the .o file
>
> take int at (f+2c)
> it is "reloc table" adres (RTA for short) (*)
>
> take short at (f+34)
> it is reloc table records number (RTAN for short)

> take (f+8) to get symbol table adres, STA
> for short
>
> STA + 18 * SN is the beginning of the symbol name,

It's remarkable you've got this far apparently by hacking. But have you
thought about doing this properly?

For example, the first 20 bytes of the object file are described by this
struct:

typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

(word is 16 bits, dword is 32-bits).

If you use #include <windows.h>, then this is predefined. Your (f+8) to get
to the symbol table would be hdr.PointerToSymbolTable (after reading the
first 20 bytes into such a struct 'hdr').

Following these 20 bytes are hdr.NumberOfSections sections, each of 40
bytes. If you search around you will find a struct definition for this too
(I don't know if Windows defines it; the documentation is poor). And so on
for the other structs used. (In fact if you read the entire file into
memory, then you can probably set up C arrays to directly point into the
various tables. The executable code will be included.)

(I've been looking at the at the PE format, and the object format is
simpler: it doesn't have the DOS stub, the Image_Optional_Header or Data
Directories; with those in place, all your offsets would be different. But
my interest would be in PE format rather than COFF, with a view to
generating PE directly.)

--
Bartc

David Brown

unread,
Nov 20, 2014, 4:21:46 AM11/20/14
to
On 19/11/14 18:36, Rick C. Hodgin wrote:
> On Wednesday, November 19, 2014 12:20:09 PM UTC-5, fir wrote:
>> 4. i plan to write a c compiler and linker systems , want to know
>> coff and linking stuff anyway

COFF was outdated some 15 years ago by ELF. But maybe it is still in
use on Windows.

>
> There is likely source code for some small *NIX compilers and linkers
> out there. You could learn a lot by examining the source code.
> Don't go for GCC or some monster like that (I think someone posted
> recently GCC is so large it takes hours?? to compile itself -- I
> could be remembering that wrong :-)).
>

gcc doesn't usually take more and about 15 minutes to build, unless you
want to include Go, Fortran and Java as well as C and C++. But it /is/
a monster (both in size and in scariness) - there are few people who
really understand its inner workings. You won't learn much about
compiler design by studying it.

The binutils project might be helpful - it covers the assembler, linker
and librarian used by gcc, and has libraries that deal with formats such
as COFF and ELF.


If you want to look at a serious compiler, go for llvm and clang. The
project is big and complex, but very well structured - it is
specifically made to be modular and to allow people to build up tools
using the libraries and modules. This would let you concentrate on the
parts you are most interested in. So if you want to experiment with a C
language front-end, use llvm for the backend and code generation. If
you want to play with code generation, use clang and make your own
backend for llvm. If you want to learn about optimisation, work with
the modules in the middle. That would let you get a working system step
by step, without having to do /everything/ yourself.


I don't know of any open source linkers other than binutils and the
linker in llvm - there simply hasn't been a need for them. There are a
few other open source C compilers AFAIK, but they are mostly rather
limited and outdated.

fir

unread,
Nov 20, 2014, 4:27:51 AM11/20/14
to
good point, i know its a hck, never do it 'properly',
headers is no problem, you can copy it from webpage, but how exactly would you do that?
load a file to buffer then cast structure pointers to that?

the struct of this file is like that (or about)

file_header //20 bytes
(optional_header) //28 bytes
section_header[N] //40*N bytes
...
section1_chunk; //?? not sure
section2_chunk;
section3_chunk;
....
relocation_pair[N] //10*N bytes
linenumber_pair[N] //6*N
symbol_record[N} //18*N
strng_table //?? not sure, tired of reading spec ;o

how would you use it properrly, casting on struct pointers, mallocking and reading in at runtime or what

(i slightly forget how it would look like when casting on record array, you cast given char* on record* then just add [i] after that to read the data?

BartC

unread,
Nov 20, 2014, 6:43:02 AM11/20/14
to
"fir" <profes...@gmail.com> wrote in message
news:1a0c0f9c-90fa-47af...@googlegroups.com...
> W dniu czwartek, 20 listopada 2014 02:28:41 UTC+1 użytkownik Bart napisał:

>> It's remarkable you've got this far apparently by hacking. But have you
>> thought about doing this properly?
>>
>> For example, the first 20 bytes of the object file are described by this
>> struct:
>>

>> If you use #include <windows.h>, then this is predefined. Your (f+8) to
>> get

> good point, i know its a hck, never do it 'properly',
> headers is no problem, you can copy it from webpage, but how exactly would
> you do that?
> load a file to buffer then cast structure pointers to that?

Here's an example program, based on my idea of reading the entire file into
memory and setting up pointers to it (rather than reading pieces into
separate structs, arrays and buffers). This then displays the symbol table
and the string table (only the names of the symbols, and only the
shortnames; long names use an offset or index into the string table).

But once everything is in those arrays (sectiontable[] etc), then it's far
easier to work with and proceed. (See if it's any better than blindly using
offsets into the file!)

(Change "test.o" to the name of your test object file.)

What you will need are the details of all those structs. MSDN will give you
some. What I had to do was combine all the win*.h files from \MINGW\INCLUDE
into a big file that I could search.

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

#define infile "test.o"

typedef uint32_t u32;
typedef uint8_t byte,u8;

int getfilesize(FILE *handle) {
u32 p,size;

p = ftell(handle);
fseek(handle,0,2);
size = ftell(handle);
fseek(handle,p,0);
return size;
}

char *readfile(char *filename) {
FILE *f;
int size;
byte *m;

f = fopen(filename,"rb");
if (f==0) {
return NULL;
}
size = getfilesize(f);
m = malloc(size);
if (m==NULL) {
return NULL;
}

fseek(f,0,0);
fread(m,1,size,f);

fclose(f);
return m;
}

char** set_stringtable(char* strdata, int *nstrings) {
/* create an indexed symbol table from the string data at given offset */
char *start, *end, *p;
char **table;
int i,n,size;

size = *(int*)strdata; /* total bytes of string data including size */

start = strdata+4;
end = strdata+size;

/* first pass counts strings only */
n = 0;
p = start;
while (p<end) {
if (*p==0) ++n;
++p;
}

table = malloc(n*sizeof(char*));
if (table==NULL) {puts("Can't alloc string table"); exit(0);}

/* Second pass builds the index table*/
p = start;
for (i = 0; i<n; ++i) {
table[i] = p;
while (*p) ++p;
++p;
}

*nstrings = n;
return table;
}

int main(void) {
char* coff;
IMAGE_FILE_HEADER *hdr;
IMAGE_SECTION_HEADER *sectiontable;
IMAGE_SYMBOL *symboltable,*sym;

int nsections, nsymbols, nstrings=0;
char **stringtable;
char *stringdata;
int i;

coff = readfile(infile);

if (coff==NULL) {puts("Can't load " infile); exit(0);}
hdr = (void*)coff;

printf("Object file %s Loaded OK; Machine = %X\n",infile,hdr->Machine);

sectiontable = (void*)(coff+sizeof(*hdr));
nsections = hdr->NumberOfSections;

symboltable = (void*)(coff+hdr->PointerToSymbolTable);
nsymbols = hdr->NumberOfSymbols;

stringdata = (char*)symboltable+nsymbols*sizeof(IMAGE_SYMBOL)+4;
stringtable = set_stringtable(stringdata-4,&nstrings);

printf("Nsections = %d\n",nsections);
printf("Nsymbols = %d\n",nsymbols);
printf("Nstrings = %d\n",nstrings);

for (i = 0; i<nsymbols; ++i) {
sym = &symboltable[i];
printf("Symbol %d: %s\n",i,sym->N.ShortName);
}

for (i = 0; i<nstrings; ++i) {
printf("String %d: %s\n",i,stringtable[i]);
}
}

--
Bartc

fir

unread,
Nov 20, 2014, 12:23:34 PM11/20/14
to
allright i will code this all relocations after some time (felt a bit tired, my heed started tu hurt, - not coding related thing)

one unclear thing releted would be else the topic of linking .o as a .exe, I suspect not very much is needet to do when
converting .o to exe . adding some dos header, and what else? (nothing?)

could maybe someone hint on this?

Nobody

unread,
Nov 21, 2014, 3:19:41 PM11/21/14
to
On Tue, 18 Nov 2014 09:28:31 -0800, fir wrote:

> I would like to gest such feature in my
> program, take given .o (in the format that is output from mingw
> compiler) load it and link it in my app to call it internally by my own
> program
>
> would ut be hard/time consuming to write? does someone know what efforts
> it would inwolve? (i would like to have it as a sorta of plugin/script
> system) prefer this over dlls or highlevel scripts

Why would you prefer a .o file to a .dll file?

They contain almost exactly the same data, but .dll is orders of magnitude
easier to load into a running process (as Windows already provides you
with the LoadLibrary() and GetProcAddress() functions).

glen herrmannsfeldt

unread,
Nov 24, 2014, 5:50:05 PM11/24/14
to
Kenny McCormack <gaz...@shell.xmission.com> wrote:

(snip, someone wrote)

>>The standard method of doing this is to write your plugins in a DLL.
> ^^^^^????????
>>Use LoadLibrary() to open the DLL and retrieve a handle to it. And
>>then use GetProcAddress() to retrieve the address to each of the
>>functions you need.

> This is not a standard method, since none of the following terms appears or
> has any traction in the Holy Bible^W^WC standards documents:

> LoadLibrary(), DLL, handle, GetProcAddress()

It is the method used by the many processors for interpreted
languages that allow one to call C (or other compiled language)
code for speed.

I believe R, Mathematica, and Octave, and probably a few others
that I haven't tried.

-- glen

BartC

unread,
Nov 24, 2014, 6:35:10 PM11/24/14
to
"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
news:m50cmg$3mr$2...@speranza.aioe.org...
> Kenny McCormack <gaz...@shell.xmission.com> wrote:

>> This is not a standard method, since none of the following terms appears
>> or
>> has any traction in the Holy Bible^W^WC standards documents:
>
>> LoadLibrary(), DLL, handle, GetProcAddress()
>
> It is the method used by the many processors for interpreted
> languages that allow one to call C (or other compiled language)
> code for speed.

Not necessarily for speed (when used properly, interpretation speed
shouldn't be a problem).

It might be the only way to make use of an external library. Or to talk to
the OS.

(But it does require that library to have an interface that can defined as
a set of DLL functions. It doesn't really work when one interpreted language
wants to directly talk to a different interpreted language. For a start,
they'd have to fight over which one is in charge and should be executed
first.

I might be wrong but it doesn't seem to me that any interpreted/scripting
language likes to acknowledge the existence of any other
interpreted/scripting language.)

--
Bartc

glen herrmannsfeldt

unread,
Nov 24, 2014, 9:52:36 PM11/24/14
to
BartC <b...@freeuk.com> wrote:

(snip regarding DLLs for dynamically generating and loading programs)

>> It is the method used by the many processors for interpreted
>> languages that allow one to call C (or other compiled language)
>> code for speed.

> Not necessarily for speed (when used properly, interpretation speed
> shouldn't be a problem).

Yes, using the built-in operations of interpreted languages should
be fast. Also, ones that implement JIT compilers.

Often enough, though, one wants to do something else, maybe
interface to existing C code, but use the interpreted language
for graphing.

> It might be the only way to make use of an external library.
> Or to talk to the OS.

> (But it does require that library to have an interface that can
> defined as a set of DLL functions. It doesn't really work when
> one interpreted language wants to directly talk to a different
> interpreted language. For a start, they'd have to fight over
> which one is in charge and should be executed first.

For those cases, I try to write out a file from the first, and
read it into the second. Sometimes works, sometimes doesn't.

> I might be wrong but it doesn't seem to me that any
> interpreted/scripting language likes to acknowledge the
> existence of any other interpreted/scripting language.)

http://www.cs.washington.edu/events/colloquia/details?id=2594

mentioned, as I remember, that some believe that there should
be a universal programming language with enough features for
everyone.

Others, it seems, believe that all software developers need their
own custom language. This latter idea would seem to lead to many
interpreted languages, with features specific to the developer
of that language. If some can convince others to use it, and
enough do such that it gets popular, we might know about it.

It is interesting that Octave did not start out as an attempt
to duplicate Matlab, but eventually moved in that direction.
By now, there are many Octave features not in Matlab that it
can be hard to go in either direction.

-- glen

Malcolm McLean

unread,
Nov 24, 2014, 10:17:57 PM11/24/14
to
On Tuesday, November 18, 2014 9:52:46 PM UTC, Kaz Kylheku wrote:
> On 2014-11-18, Rick C. Hodgin <rick.c...@gmail.com> wrote:
>
> People can use knowledge to make their lives *materially* better,
> while the fool who taught free of charge lives in a ratty apartment
> and eats Kraft Dinner.
>
If you read Enid Blyton's school stories, the mistresses are all
scatty and plain, the girls from wealthy backgrounds with, it's
implied, glamorous lives ahead of them. In one book they all leave
for St Andrew's university, which is about the snobbiest in Britain.

That's how things were run, to an extent still are. School mistresses
were expected to be spinsters, and they lived a fairly austere
existence, in the school itself.

But whilst learning is hard master, money is a much harder one,
more exacting, more demanding of time and attention, more ruthless
in punishing those of its servants who aren't sufficiently diligent
in their duties. I think more people come to regret a life spent
chasing money than a life devoted to teaching.

Malcolm McLean

unread,
Nov 24, 2014, 10:31:29 PM11/24/14
to
On Tuesday, November 18, 2014 9:47:54 PM UTC, Kaz Kylheku wrote:
>
> It's not different at all. In fact, after developing a product,
> you might be in debt, and if enough copies of that digital string
> of bits does not sell, then you suffer a loss.
>
> You still have a roof over you head only because other people took
> the losses for you on their chins,
>
If you don't sell software, then you can't know whether the
time and money invested in writing it was worthwhile, at least
if your goal was economic rather than, say, artistic or
scientific. So if investors only back products they feel will
result in a revenue stream that returns the investment, you don't
get misallocation of resources.
>
> Some people have historically become very rich from selling large
> numbers of copies of technically mediocre software; but they cannot
> be used as scapegoats.
> A lot of software struggles to find customers, even if it is decent
> and took a lot of effort to produce.
>
Software is unusual in that it's very difficult to predict
returns. A good program which performs a basic task will be run
millions of times a day. But only if for some reason it becomes
the accepted standard, which happens for all sorts of reasons.

You've then got a powerful standards effect, because other people
need your program, not because they think it's better than the
competition, but because they need to open files created by
your program. The corollary of that is that a program which doesn't
achieve the status of a standard can sell very few copies indeed.

Malcolm McLean

unread,
Nov 24, 2014, 10:34:04 PM11/24/14
to
tcc (tiny C compiler) is an open source, manageable compiler.

0 new messages