Topic: dynamic code


Author: wizofaus@hotmail.com (Dylan Nicholson)
Date: Mon, 16 Feb 2004 04:32:09 +0000 (UTC)
Raw View
david@tribble.com (David R Tribble) wrote in message news:<f4002eab.0401260911.603b611d@posting.google.com>...
>
> So rather than extend the standard C *language* to add this feature, you
> really would be better off trying to extend the standard C *library* to add
> support for dynamic shared libraries.
>
> Perhaps using some overlapping combination of Unix and Win32 as a starting
> point, perhaps something along the lines of:
>
>   // Added to <stdlib.h> perhaps
>
>   #define __STDC_LOADLIB__  <expr>  // YYYYMM, or -1 if not supported
>
>   // Loaded shared library address (descriptor) in memory
>   typedef void *  libaddr_t;
>
>   // Load a shared library file at a recommended address,
>   //  if 'loadaddr' is null, the system decides where to load it
>   libaddr_t _loadlib(const char *libname, void *loadaddr);
>
>   // Find a loaded shared library by name
>   libaddr_t _findlib(const char *libname);
>
>   // Find a function within a loaded shared library,
>   //  'funcname' may require prototype ornamentation
>   void (*)() _findlibfunc(const char *funcname, libaddr_t loadaddr);
>
>   // Unload a library that's no longer needed
>   int _unloadlib(libaddr_t loadaddr);
>

While I don't disagree that support for dynamic library loading is
justifiable at a standards level (*), I would hope no C++ interface
would look like the above (I understand your proposal was mainly meant
for C).

The wrapper I use for it looks roughly like:

struct shared_object
{
 explicit shared_object(const char* name);
 explicit shared_object(const std::string& name);
 ~shared_object();

 template <class T>
 bool lookup(const char* name, T& addr)
 {
  void* raw = lookup(name);
  addr = *reinterpret_cast<T*>(&raw);
  return addr != 0;
 }
private:
 void* lookup(const char* name);
};

Note that you can typically lookup more than just functions from a
shared object/library - any symbol with size void* or less is usually
supported.

Dylan



(*) At about the same level as thread-support, and perhaps directory
support.  Even some embedded systems support these, and I would hazard
a guess that over 90% of C/C++ code would run on systems with these
features.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: brok@rubikon.pl (Bronek Kozicki)
Date: Thu, 5 Feb 2004 18:30:18 +0000 (UTC)
Raw View
On Sat, 24 Jan 2004 22:10:59 +0000 (UTC), Bronek Kozicki wrote:
> You may better spend your time looking for better support for dynamic
> libaries in C++. It's not there, but if someone can prepare reasonable
> proposal, who knows ...

Apologies to Pete Becker and Matt Austern. There is reasonable proposal
already:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1428.html
there are also some notes from Santa Cruz meeting:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1418.html
and discussion of the subject:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1400.html

I'm sorry I overlooked it :(


B.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jackklein@spamcop.net (Jack Klein)
Date: Mon, 26 Jan 2004 09:22:45 +0000 (UTC)
Raw View
On Sat, 24 Jan 2004 02:00:37 +0000 (UTC), danielgutson@hotmail.com
(danielgutson@hotmail.com) wrote in comp.std.c:

> Hi.
>
> Please take a look to the following piece of code:
>
> -----------------------------
> typedef int Funtype(void);
>
> int func(void)
> {
>  return 1+1;
> }
>
> int main(void)
> {
>  Funtype* f = (Funtype*) malloc(sizeof(*func));
>  memcpy(f, func, sizeof(*func));
>
>  return (*f)();
> }
> ------------------------------
>
> Suppose that we
>   - exacly know the physical start address of a function, and may cast
> it to (let's say void*)
>   - exactly know the size that the bytecode takes
>
> Then, we would be able to:
>
>   - save (file) the function's bytecode
>   - retrieve it dynamically and execute it (in runtime), by loading a
> stream of bytes into a buffer, cast its start to the appropiate
> prototype, and invoke the () operators with the complete signature.
>   - copy a function located 'somewhere' to a faster ram and execute it
> there (don't focus too much in this one)
>
> ---
> Right now, there's no standard way of
>  - obtaining the physical size of a function definition
>  - obtaining the 'real' physical position of a function (for example,
> in VC++ when casting a function pointer to 'int', or
> re-interpreting_cast it to <char*>, the returned address is an
> indirection that only contains a 'jmp' instruction to the real
> position)
>
> What I'm proposing is to standarize this capabilities in order to be
> able to do some of the things I mention above, such as dynamic loading
> functions (as 'plugins').
> I'm just inviting a discussion, and for global functions only. Class'
> methods are a bit more complex, and would require additional
> considerations (v-tables).
> I'd like to know your comments about this idea.
>
> Some considerations:
>   - function size should be solved at linking time, since someone may
> refer to a function in another compilation unit. Do you compiler
> writers, see too many difficulties?
>   - obtaining the size of a function, syntactically, could be by
> adding the * prefix operator to the function name (as in the example
> above), or by defining a new operator: 'fsizeof()'.
>
> Waiting for your comments!
>
>    Daniel.

This is another fallacy of the viewpoint that desktop computing is the
only kind of computing that there is.  A great deal of C code, and a
growing amount of C++ code, goes into embedded systems.  In some of
these architectures, code can only be executed from read-only memory
blocks.  You might be able to copy the binary code of a function from
its original location to some location in faster RAM, but then you
would not be able to execute it from there.

There are really only two types of situations where this feature would
be useful.

One is the so/DLL/plug-in type of use on large systems, and those that
can make use of it already provide it, including very high level and
even remote mechanisms like COM and CORBA.

The other is in embedded systems like DSPs and high-speed RISC
processors that have a certain amount of internal maximum speed RAM
that may be used for code execution.  In this case there is no real
need for the code to be relocatable, or even executable at the address
where it resides in code space (flash/EPROM/EEPROM/ROM).  There is
only one place it can ever be moved to for execution.  And this case
is generally handled by linker options in the tool set, e.g. ARM's
"scatter loading".

I can't see any good reasons to add this to the language, and several
good reasons not to.  Where you need this mechanism it already exists.
In many cases where it doesn't, it can't, so you would be adding a
superset to the language(s) that some otherwise conforming
implementations would not be able to supply.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: david@tribble.com (David R Tribble)
Date: Mon, 26 Jan 2004 23:16:02 +0000 (UTC)
Raw View
danielgutson@hotmail.com wrote:
>> What I'm proposing is to standarize this capabilities in order to be
>> able to do some of the things I mention above, such as dynamic loading
>> functions (as 'plugins').

>> I also expected the comment about operating system    DLL-like
>> mechanisms. I answer:    this is a simple, standard way of doing it   ,
>> and there   s more to say about, but that would be mentioning advantages
>> that I will mention in a later message.

>> My immediate answer falls in some syntactic help to tell the compiler
>>    fileable function   : generate it contiguosly beacause I will save it
>> somewhere, I   ll use    memcpy    :)
>> This could be a keyword or some lexical symbol.

Bronek Kozicki wrote:
> You may better spend your time looking for better support for dynamic
> libaries in C++. It's not there, but if someone can prepare reasonable
> proposal, who knows ...

I agree.  I know of no architecture where you can simply copy the contents
(code) of a function to an arbitrary address and then call it like a real
function and expect it to work.  All sorts of issues have to be addressed:

  - relocating jump and subroutine references
  - relocating data symbol references
  - loading code into a code segment (instead of a data/heap segment)
  - loading both code and data segments of a function
  - forcing the loading of other dependent functions/libraries
  - update the internal load-map (if any) used by the loader/debugger

What you are doing is not unreasonable, i.e., synthesizing a function at
runtime by loading code dynamically and then invoking it.  But this problem
has already been tackled since the days of OS/360, and then later in the
80's with Unix, and then later on PC's with DLLs - in other words, this
problem has already been solved using dynamic shared libraries.  All of the
issues above have been addressed by each OS's support of such libraries.


So rather than extend the standard C *language* to add this feature, you
really would be better off trying to extend the standard C *library* to add
support for dynamic shared libraries.

Perhaps using some overlapping combination of Unix and Win32 as a starting
point, perhaps something along the lines of:

  // Added to <stdlib.h> perhaps

  #define __STDC_LOADLIB__  <expr>  // YYYYMM, or -1 if not supported

  // Loaded shared library address (descriptor) in memory
  typedef void *  libaddr_t;

  // Load a shared library file at a recommended address,
  //  if 'loadaddr' is null, the system decides where to load it
  libaddr_t _loadlib(const char *libname, void *loadaddr);

  // Find a loaded shared library by name
  libaddr_t _findlib(const char *libname);

  // Find a function within a loaded shared library,
  //  'funcname' may require prototype ornamentation
  void (*)() _findlibfunc(const char *funcname, libaddr_t loadaddr);

  // Unload a library that's no longer needed
  int _unloadlib(libaddr_t loadaddr);

You need to make the proposal minimal and generic enough to cover all
implementations that provide shared libraries, while also providing enough
functionality to be useful.  You also have to address implementations that
don't support shared libraries (essentially making these functions optional).

(BTW, "byte code" is somewhat Java-centric and implies interpreted code;
a better term to use is "object code".)

-drt

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Tue, 27 Jan 2004 04:15:55 +0000 (UTC)
Raw View
danielgutson@hotmail.com (danielgutson@hotmail.com) wrote in message news:<23478c42.0401250758.627b1ccf@posting.google.com>...
> kuyper@wizard.net (James Kuyper) wrote in message
> [...]
> > I think that you're assuming (or wish to implicitly require) that each
> > function occupies a single distinct continuous relocateable block of
> [...]
..
> But, the main thing I want to highlight here, is the issue that the
> last poster mentioned: my implicit assumption that code is contiguous:
> I forgot this.
> I think this is a real issue, since others are easy to solve and just
> rely on who (and how) would use this mechanism. I mean, user
> responsibility.
>
> About continuity, it may perfectly occur that the compiler generates
> separated blocks for the same function.
>
> My immediate answer falls in some syntactic help to tell the compiler
>    fileable function   : generate it contiguosly beacause I will save it
> somewhere, I   ll use    memcpy    :)
> This could be a keyword or some lexical symbol.

That's all very nice, but continuity is only part of what's needed.
Relocateability is a much trickier problem. On the architectures I'm
most familiar with, machine code can be written to be relocateable,
but only at significant cost in speed or memory use. I don't know if
there are any architectures where it's impossible to make code
relocateable, but I wouldn't be surprised if someone told me that
there were.

To move code around, you should really require the use of an
OS-specific function which can fix up relocation problems. memcpy()
just isn't that function. I doubt that it's feasible to make a
portable version of such a routine; it depends too much on OS-specific
details.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jackklein@spamcop.net (Jack Klein)
Date: Tue, 27 Jan 2004 17:35:11 +0000 (UTC)
Raw View
On Tue, 27 Jan 2004 04:15:55 +0000 (UTC), kuyper@wizard.net (James
Kuyper) wrote in comp.std.c:

> danielgutson@hotmail.com (danielgutson@hotmail.com) wrote in message ne=
ws:<23478c42.0401250758.627b1ccf@posting.google.com>...
> > kuyper@wizard.net (James Kuyper) wrote in message=20
> > [...]
> > > I think that you're assuming (or wish to implicitly require) that e=
ach
> > > function occupies a single distinct continuous relocateable block o=
f
> > [...]
> ..
> > But, the main thing I want to highlight here, is the issue that the
> > last poster mentioned: my implicit assumption that code is contiguous=
:
> > I forgot this.
> > I think this is a real issue, since others are easy to solve and just
> > rely on who (and how) would use this mechanism. I mean, user
> > responsibility.
> >=20
> > About continuity, it may perfectly occur that the compiler generates
> > separated blocks for the same function.
> >=20
> > My immediate answer falls in some syntactic help to tell the compiler
> > =B4fileable function=B4: generate it contiguosly beacause I will save=
 it
> > somewhere, I=B4ll use =B4memcpy=B4 :)
> > This could be a keyword or some lexical symbol.
>=20
> That's all very nice, but continuity is only part of what's needed.
> Relocateability is a much trickier problem. On the architectures I'm
> most familiar with, machine code can be written to be relocateable,
> but only at significant cost in speed or memory use. I don't know if
> there are any architectures where it's impossible to make code
> relocateable, but I wouldn't be surprised if someone told me that
> there were.

There are architectures that have relative jump instructions, such as
X86 and ARM, and it is quite possible that the machine code generated
for functions, particularly small ones, could be internally completely
independent of the absolute address of the code.  On the other hand
there are architectures that do not have relative jump instructions,
where jump destinations are hard coded, although perhaps not many
anymore that are relevant to most C and C++ programmers.  The Intel
8080 was one such.

--=20
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: llewelly.at@xmission.dot.com (llewelly)
Date: Sun, 1 Feb 2004 23:08:50 +0000 (UTC)
Raw View
danielgutson@hotmail.com (danielgutson@hotmail.com) writes:

> kuyper@wizard.net (James Kuyper) wrote in message=20
> [...]
> > I think that you're assuming (or wish to implicitly require) that eac=
h
> > function occupies a single distinct continuous relocateable block of
> [...]
>=20
> An excellent comment-feedback indeed.
>=20
> I was expecting the answer about =B4reference to external symbols=B4.
> Everybody that pointed out about such issue, yes, you are right. And
> my simplest answer is: just file =B4closed=B4 functions (i.e. functions
> that perform some calculus isolatedly, and you want to do different
> implementations).
> I also expected the comment about operating system =B4DLL-like=B4
> mechanisms. I answer: =B4this is a simple, standard way of doing it=B4,
> and there=B4s more to say about, but that would be mentioning advantage=
s
> that I will mention in a later message.
>=20
> But, the main thing I want to highlight here, is the issue that the
> last poster mentioned: my implicit assumption that code is contiguous:
> I forgot this.
> I think this is a real issue, since others are easy to solve and just
> rely on who (and how) would use this mechanism. I mean, user
> responsibility.
>=20
> About continuity, it may perfectly occur that the compiler generates
> separated blocks for the same function.

This concern is not limited to continuity; imagine a platform where
    an absolute jmp (with the target address encoded into the
    instruction) is the fastest kind (or perhaps even the only kind)
    of jmp. Suppose the compiler generated code using such jmps for
    the function being copied. Once such a function is copied, you
    have a very odd function, such that calling the new copy will
    result in jmping back to the old copy at some point. If the
    procedure needs to be sent across the network to a different
    machine, or even merely made availible to another process,
    problems may ensue.

But I think we have the implementation discussion and the usage
    discussion all mixed together here, and I don't think that is
    helpful; if we spend all this time arguing about what memcpy can
    and cannot do, there may never be enough discussion about whether
    your suggestion is any good.

>=20
> My immediate answer falls in some syntactic help to tell the compiler
> =B4fileable function=B4: generate it contiguosly beacause I will save i=
t
> somewhere, I=B4ll use =B4memcpy=B4 :)
> This could be a keyword or some lexical symbol.
[snip]

Specifying that a function is to be contiguos is IMO useless; I think
    you want 'relocatable', 'storable', 'shareable', or some
    such. You definitely don't want to use 'auto'; half the feature
    suggestions that pop up here try to abduct that keyword (as does
    more than one paper availible at the WG21 site)- if 10%
    of them make it into C++200x, auto will be as bad static, or
    maybe worse. In any case - this is just leading us into
    implementation arguments, when, IMO, we still lack a
    sufficiently rigorous description of *what* is to be implemented;
    we have all this discussion about copying, but in fact that may
    be irrelevant; there are plenty of dynamic library
    implementations which do not copy the machine code about (instead,
    they provide per-process copies of any global state a function
    modifies, and use vm hardware to map the same physical memory into
    the virtual addresses spaces of each process).

I think this is nothing more than confusion resulting from your
    attempt to express a feature in a langauge that doesn't support
    it.=20

Describe your desired feature in clear and careful english; any code
    you write without such a description is IMO likely to be hampered
    by the very limitations you wish to eliminate.

For example, if you wish to relocate a function, save its
    implementaiton to disk, or deliever it to another process, say so
    - don't say 'memcpy'; memcpy is the wrong thing for the user to
    see because memcpy is for low-level copying of data, not for
    relocating procedures, and not for symbolic copies, and it's the
    wrong thing for the implementor to see, because an implementor
    knows memcpy will break non-relocatable code.

   =20





---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: llewelly.at@xmission.dot.com (llewelly)
Date: Mon, 2 Feb 2004 00:39:55 +0000 (UTC)
Raw View
danielgutson@hotmail.com (danielgutson@hotmail.com) writes:
[snip]
> Suppose that we
>   - exacly know the physical start address of a function, and may cast
> it to (let's say void*)
>   - exactly know the size that the bytecode takes
>
> Then, we would be able to:
>
>   - save (file) the function's bytecode
>   - retrieve it dynamically and execute it (in runtime), by loading a
> stream of bytes into a buffer, cast its start to the appropiate
> prototype, and invoke the () operators with the complete signature.
>   - copy a function located 'somewhere' to a faster ram and execute it
> there (don't focus too much in this one)
[snip]

Objective-C, smalltalk, perl, Java, and several (all?) lisp variants
    all have loadable functions and/or loadable modules. (There are
    other languages that support loadable functions of one kind or
    another, but I can't recall them.)

Typical unix and windows shared library facilities provide grossly
    equivalent (though IMO much less user-friendly) functionality for
    C and C++ programs, though without the ability to save procedures
    to disk (not all the langauges I listed above provide the ability
    to save to disk either).

These kinds of features can be wonderful for extensibility of
    programs and so forth, but they also greatly reduce (sometimes
    wholly eliminate) one's knowledge about what sort of code gets
    run at run time - IMO, a potentially serious issue for code
    review, testing, debugging, and so forth, which may be too often
    ignored.

Most importantly, there is existing experience to draw upon when
    deciding if/when/how featurs of this sort should be made part of
    ISO C++, and there is existing practice / expectations ISO C++
    should probably aim to be compatible with. (For that matter, if
    the C community wishes for standardization of similar features
    the same applies.)

In general I wish that when features were suggested for integreation
    into ISO C++, there was more discussion of the features and
    experience of other langauges; if their mistakes can be
    understood, then, inasmuch as said experience is applicable to
    C++, ISO C++ needn't repeat their mistakes.

(Possibly it is only this forum which has a deficit in discussion of
    how features of other languages relate to suggested C++ features;
    I don't track the WG21 reflector, and I do know of several members
    who have fair enthusiasm for at least one langauge other than C++.)

Pete Becker wrote a draft proposal for adding dynamic libraries to
    ISO C++ :
    http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1496.html

    (again, no mention of stored procedures.)

I googled the anubis.dkuug.dk site (because most (all?) of the C and
    C++ standarization work is recoreded there), but I didn't find
    any similar suggestions for extending C in that manner. It seems
    to me there is much overlap between the platforms where C is
    considered more appropriate than C++, and the platforms which
    support only static libraries, so I don't consider that a
    surprise.

Note that both C and C++ have sizeable sub-communities for whom
    niether shared libraries, nor stored procedures make sense; IMO
    any such new features should take care to ensure such people are
    not adversely impacted.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Mon, 2 Feb 2004 02:19:07 +0000 (UTC)
Raw View
In message <86d68yjyfv.fsf@xmission.dot.com>, llewelly
<llewelly.at@xmission.dot.com> writes
>For example, if you wish to relocate a function, save its
>    implementaiton to disk, or deliever it to another process, say so
>    - don't say 'memcpy'; memcpy is the wrong thing for the user to
>    see because memcpy is for low-level copying of data, not for
>    relocating procedures, and not for symbolic copies, and it's the
>    wrong thing for the implementor to see, because an implementor
>    knows memcpy will break non-relocatable code.

Anyway I do not think that memcpy could be written to do what the OP
wants on a Harvard Architecture machine. To get such a thing it is
necessary to demonstrate utility and implementability on all platforms.
I do not think that either has been demonstrated by the OP.

--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: david@tribble.com (David R Tribble)
Date: Tue, 3 Feb 2004 21:25:12 +0000 (UTC)
Raw View
llewelly wrote
> Objective-C, smalltalk, perl, Java, and several (all?) lisp variants
>     all have loadable functions and/or loadable modules.
> Typical unix and windows shared library facilities provide grossly
>     equivalent (though IMO much less user-friendly) functionality for
>     C and C++ programs, though without the ability to save procedures
>     to disk (not all the langauges I listed above provide the ability
>     to save to disk either).
>
> Pete Becker wrote a draft proposal for adding dynamic libraries to
>     ISO C++ :
>     http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1496.html

I am working on a short proposal for dynamic (shared) libraries.  It is a
set of low-level functions similar to the dlopen() and dlsym() functions
of many Unix variants.  It is a different approach that Pete's, relying
entirely on library functions, with no additions to the syntax of the
language.


  __STDC_LOADLIB__

    A preprocessor macro that evaluates to a nonzero value if the
    implementation supports dynamic libraries.

  typedef opaque-type  libaddr_t;

    An implementation-defined type that holds information about a dynamic
    library that has been loaded into memory.

  libaddr_t  _loadlib(const char *name, void *addr);

    Loads a dynamic library into memory.  'name' specifies the library by
    name in an implementation-defined fashion.

  int  _unloadlib(libaddr_t addr);

    Unloads a dynamic library from memory.

  libaddr_t  _findlib(const char *name);

    Locates a previously loaded dymanic library in memory.

  void (*)()  _findlibfunc(libaddr_t addr, const char *sym);

    Locates an extern function within a previously loaded dynamic library.

  void *  _findlibvar(libaddr_t addr, const char *sym);

    Locates an extern variable within a previously loaded dynamic library.


> Note that both C and C++ have sizeable sub-communities for whom
>     niether shared libraries, nor stored procedures make sense; IMO
>     any such new features should take care to ensure such people are
>     not adversely impacted.

I've made allowances in the proposal for systems that don't support dynamic
libraries.  Essentially, the library functions are optional.

I'll post a draft of the proposal soon.

-drt
http://david.tribble.com/text/c0xdynlib.html

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: danielgutson@hotmail.com (danielgutson@hotmail.com)
Date: Sat, 24 Jan 2004 02:00:37 +0000 (UTC)
Raw View
Hi.

Please take a look to the following piece of code:

-----------------------------
typedef int Funtype(void);

int func(void)
{
 return 1+1;
}

int main(void)
{
 Funtype* f = (Funtype*) malloc(sizeof(*func));
 memcpy(f, func, sizeof(*func));

 return (*f)();
}
------------------------------

Suppose that we
  - exacly know the physical start address of a function, and may cast
it to (let's say void*)
  - exactly know the size that the bytecode takes

Then, we would be able to:

  - save (file) the function's bytecode
  - retrieve it dynamically and execute it (in runtime), by loading a
stream of bytes into a buffer, cast its start to the appropiate
prototype, and invoke the () operators with the complete signature.
  - copy a function located 'somewhere' to a faster ram and execute it
there (don't focus too much in this one)

---
Right now, there's no standard way of
 - obtaining the physical size of a function definition
 - obtaining the 'real' physical position of a function (for example,
in VC++ when casting a function pointer to 'int', or
re-interpreting_cast it to <char*>, the returned address is an
indirection that only contains a 'jmp' instruction to the real
position)

What I'm proposing is to standarize this capabilities in order to be
able to do some of the things I mention above, such as dynamic loading
functions (as 'plugins').
I'm just inviting a discussion, and for global functions only. Class'
methods are a bit more complex, and would require additional
considerations (v-tables).
I'd like to know your comments about this idea.

Some considerations:
  - function size should be solved at linking time, since someone may
refer to a function in another compilation unit. Do you compiler
writers, see too many difficulties?
  - obtaining the size of a function, syntactically, could be by
adding the * prefix operator to the function name (as in the example
above), or by defining a new operator: 'fsizeof()'.

Waiting for your comments!

   Daniel.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk")
Date: Sat, 24 Jan 2004 18:55:56 +0000 (UTC)
Raw View
On Sat, 24 Jan 2004 02:00:37 +0000, danielgutson@hotmail.com wrote:

> Then, we would be able to:
>
>   - save (file) the function's bytecode
>   - retrieve it dynamically and execute it (in runtime), by loading a
> stream of bytes into a buffer, cast its start to the appropiate
> prototype, and invoke the () operators with the complete signature.

This is not true. The code may be position-dependent by referring to other
code or data by absolute addresses, which may be different in the process
doing the retrieval.

The code can also refer to other functions and data that you didn't
serialize, or didn't unserialize yet. You would want to load larger units,
not functions one by one.

> Right now, there's no standard way of
>  - obtaining the physical size of a function definition
>  - obtaining the 'real' physical position of a function

They would not suffice anyway for dynamic loading of code, which is not as
simple as loading an array of bytes into memory and treating it as code.

--
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: DAGwyn@null.net ("Douglas A. Gwyn")
Date: Sat, 24 Jan 2004 19:09:44 +0000 (UTC)
Raw View
danielgutson@hotmail.com wrote:
> Waiting for your comments!

(1) Functions live in a different address space from data objects.
(2) Functions are not relocatable.
(3) Dynamic loading is not supported.
(4) Fuhgeddaboudit.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: brok@rubikon.pl (Bronek Kozicki)
Date: Sat, 24 Jan 2004 22:10:59 +0000 (UTC)
Raw View
On Sat, 24 Jan 2004 02:00:37 +0000 (UTC), danielgutson@hotmail.com
wrote:

> What I'm proposing is to standarize this capabilities in order to be
> able to do some of the things I mention above, such as dynamic loading
> functions (as 'plugins').

You may better spend your time looking for better support for dynamic
libaries in C++. It's not there, but if someone can prepare reasonable
proposal, who knows ...


B.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: barmar@alum.mit.edu (Barry Margolin)
Date: Sun, 25 Jan 2004 01:14:25 +0000 (UTC)
Raw View
In article <23478c42.0401231503.352220d4@posting.google.com>,
 danielgutson@hotmail.com (danielgutson@hotmail.com) wrote:

> Suppose that we
>   - exacly know the physical start address of a function, and may cast
> it to (let's say void*)
>   - exactly know the size that the bytecode takes
>
> Then, we would be able to:
>
>   - save (file) the function's bytecode
>   - retrieve it dynamically and execute it (in runtime), by loading a
> stream of bytes into a buffer, cast its start to the appropiate
> prototype, and invoke the () operators with the complete signature.
>   - copy a function located 'somewhere' to a faster ram and execute it
> there (don't focus too much in this one)

There's lots more to a function than just its byte code.  If it calls
other functions, you need to ensure that they're also loaded.  If it
accesses global variables, they may not exist in the new process.  The
code would have to be position-independent, so that it can be loaded
into a different location in memory than the place it was saved from.
I'm sure there are other issues.

These are the kinds of problems that a dynamic linker needs to solve.
If your OS supports this, there's often an API like dlopen() and dlsym()
to invoke it.  They don't work for copying arbitrary functions into a
file as you're attempting, they depend on files that have been created
by the linker in a format ready to be loaded at runtime.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Sun, 25 Jan 2004 01:14:28 +0000 (UTC)
Raw View
danielgutson@hotmail.com (danielgutson@hotmail.com) wrote in message news:<23478c42.0401231503.352220d4@posting.google.com>...
..
> Suppose that we
>   - exacly know the physical start address of a function, and may cast
> it to (let's say void*)
>   - exactly know the size that the bytecode takes
>
> Then, we would be able to:
>
>   - save (file) the function's bytecode
>   - retrieve it dynamically and execute it (in runtime), by loading a
> stream of bytes into a buffer, cast its start to the appropiate
> prototype, and invoke the () operators with the complete signature.
>   - copy a function located 'somewhere' to a faster ram and execute it
> there (don't focus too much in this one)
>
> ---
> Right now, there's no standard way of
>  - obtaining the physical size of a function definition
>  - obtaining the 'real' physical position of a function (for example,
> in VC++ when casting a function pointer to 'int', or
> re-interpreting_cast it to <char*>, the returned address is an
> indirection that only contains a 'jmp' instruction to the real
> position)

I think that you're assuming (or wish to implicitly require) that each
function occupies a single distinct continuous relocateable block of
memory. I have no idea whether "single", "distinct", and "continuous"
are typically true, but I'd be very surprised if they were universally
true. I'm positive, however, that "relocateable" is often (usually?)
false.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: danielgutson@hotmail.com (danielgutson@hotmail.com)
Date: Sun, 25 Jan 2004 20:02:20 +0000 (UTC)
Raw View
kuyper@wizard.net (James Kuyper) wrote in message
[...]
> I think that you're assuming (or wish to implicitly require) that each
> function occupies a single distinct continuous relocateable block of
[...]

An excellent comment-feedback indeed.

I was expecting the answer about    reference to external symbols   .
Everybody that pointed out about such issue, yes, you are right. And
my simplest answer is: just file    closed    functions (i.e. functions
that perform some calculus isolatedly, and you want to do different
implementations).
I also expected the comment about operating system    DLL-like
mechanisms. I answer:    this is a simple, standard way of doing it   ,
and there   s more to say about, but that would be mentioning advantages
that I will mention in a later message.

But, the main thing I want to highlight here, is the issue that the
last poster mentioned: my implicit assumption that code is contiguous:
I forgot this.
I think this is a real issue, since others are easy to solve and just
rely on who (and how) would use this mechanism. I mean, user
responsibility.

About continuity, it may perfectly occur that the compiler generates
separated blocks for the same function.

My immediate answer falls in some syntactic help to tell the compiler
   fileable function   : generate it contiguosly beacause I will save it
somewhere, I   ll use    memcpy    :)
This could be a keyword or some lexical symbol.

Would someone get brain panic if I recommend to recycle    auto    word as
a keyword for this purpose?
Example:

auto int f(void)
{
   ...
   return ...
}

(I   m abusing the fact that other kwds. where used for completely
different semantics depending on context, such as    static   ).

Including the usage of a syntactic help (as this    auto    or similar)
would also solve the problem about casting pointer_to_functions to
[let   s say] void*, in which case the exact physical start address of
the function will be returned. (filer side).

Prototype of the pointer to function definition would include this
syntax as well:  (caller side)

typedef auto int Funtype(void);
..
Funtype* f = ...;
..

Any other suggestion?

  Daniel.

pd: thanks.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]