Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > alt.os.development > #8241

Re: How to bind HLLs to OS calls

From "James Harris" <james.harris.1@gmail.com>
Newsgroups alt.os.development
Subject Re: How to bind HLLs to OS calls
Date 2015-06-24 07:55 +0100
Organization A noiseless patient Spider
Message-ID <mmdk74$l9o$1@dont-email.me> (permalink)
References <mls29c$b0q$1@dont-email.me> <op.x0ewr50gyfako5@localhost> <mluuql$4cc$1@dont-email.me> <op.x0g2zlo8yfako5@localhost>

Show all headers | View raw


"Rod Pemberton" <boo@fasdfrewar.cdm> wrote in message 
news:op.x0g2zlo8yfako5@localhost...
> On Thu, 18 Jun 2015 13:24:52 -0400, James Harris 
> <james.harris.1@gmail.com> wrote:
>> "Rod Pemberton" <boo@fasdfrewar.cdm> wrote in message 
>> news:op.x0ewr50gyfako5@localhost...
>>> On Wed, 17 Jun 2015 11:05:30 -0400, James Harris 
>>> <james.harris.1@gmail.com> wrote:

...

>>>> Implementing all OS services as functions allows some to be handled 
>>>> in  user mode without forcing all to transition to privileged 
>>>> mode.)
>>>
>>> Yes, but I think you would need a library of each language, except
>>> the primary language used for the OS API, e.g., except assembly.
>>
>> Sorry, I don't understand that sentence.
>
> s/of/for
>
> Essentially, I was saying you need to do what you responded to above 
> as:
> JH> "That seems like a lot of work and a lot of duplication of 
> effort."
> Every compiler would "need to have subroutines for each OS call" in 
> order
> "to provide OS access."

If I understand, you are saying that I might need a library for each 
language. I don't think so for two reasons:

1. There are only so many calling conventions. There is a good list of 
x86 ones at

https://en.wikipedia.org/wiki/X86_calling_conventions#List_of_x86_calling_conventions

and a wider picture at

https://en.wikipedia.org/wiki/Calling_convention

I think that rather than a library for each language it would be more 
accurate to say that there would need to be a library (or at least a set 
of entry points) for each calling convention. That is still quite a lot 
but the idea is that the OS developer would provide such 'libraries' to 
go with each new release of the OS.

2. Using the naming of components

  app --> interface code --> kernel

rather than link the interface code (i.e. the OS code that the app calls 
directly) in with the app I would rather find a way of providing that 
code at load time. To explain why:

If an app goes through the traditional process of being compiled and 
linked to form a load module then the interface code (supplied by the OS 
developer) would have to be available when linking happens and would end 
up being part of the load module. That's fine in a sense but it is 
inflexible for at least two reasons.

i) If it turns out there is a bug in the interface code then that bug 
would end up being built in to the load module.

ii) Most interface code functions would include an instruction to enter 
into the kernel. There are multiple ways of getting to kernel mode and 
some ways are faster than others. The way that is best will depend on 
the CPU the OS is running on. For example, on a 486 the best way to 
enter the kernel may be via a software interrupt or a far call whereas 
on a Core 2 the best way may be via SYSENTER or SYSCALL. Application 
programmers shouldn't have to concern themselves with which one to use. 
IMO the OS should choose that for them.

For both those reasons it would be better for the interface code to be 
made available by the running OS, rather than built into apps 
statically.

The upshot of the above, I think, is that app calls to the OS should be 
resolved when the app is loaded. That suggests that there needs to be 
some form of dynamic linking. The specific interface code used should be 
made available and linked when the app is loaded (or even lazy linked 
when it is running). Such code can avoid the above two problems: it can 
have had any known bugs corrected and can use the best method of getting 
to kernel mode, all without the app having to be recompiled.

Coming back to the point you made about interface code being available 
at compile time, for the above reasons I would rather make it available 
at load time. Although the compiler *would* need to know the interface 
to OS calls (such as would be supplied in a C header) it would *not* 
need to have the real interface code available. (However, the linker 
might need some dummy code or stub code so that the link process could 
happen. That code would get replaced at load time or run time.)

If this sounds like I am making life hard for myself that is probably 
true. But it just seems the right thing to do for the reasons mentioned 
above.

I am currently playing with ideas on *how* to dynamically link the 
interface code with the app but don't have a good answer yet.

>>> So, functions overloaded with multi-language support? ...
>>
>> Yes. One interface per calling convention rather than one per 
>> language.
>
> How do you unify that across multiple languages which have different
> methods for calling a function and different calling conventions?

Wouldn't having a separate entry point or separate function for each 
calling convention be enough?

For example, say there was an OS function which took an integer and a 
string and returned a character. Pascal pushes parameters in the 
opposite order to C. That could be dealt with easily enough. One entry 
point could expect parms left-to-right and the other could expect them 
right-to-left. Pascal strings have a different form. That could be more 
of a problem. Perhaps there could be two subroutines, one of which 
handled C strings and the other of which handled Pascal strings. Where 
appropriate they could call common functions but otherwise could remain 
separate pieces of code. The return value would also be returned in a 
form suitable to the calling convention.

If another language or compiler used the exact same calling convention 
as C or Pascal then it too could call the same library routine. Thus 
there would not be one entry point per language but one per calling 
convention (taking data types as part of the convention).

One problem is getting the calls from C and Pascal etc to the 
appropriate entry points. If the called OS routine was named M then apps 
should be able to just call M by name and leave the computer to convert 
M into M_cdecl or M_stdcall or whatever, according to the convention the 
compiler uses. I haven't yet worked out a way to do this.

> To sufficiently abstract this in the way you're wanting it to be,
> I'd think it'd have to be via a common feature of all OSes.  Perhaps,
> such as file I/O for platforms where "everything is a file" philosphy
> is implemented.  E.g., you write out a text file the parameters, or
> a IPC message as text, a function is called without parameters for
> the host language, the function being called reads the text file and
> parses it.  IIRC, you were discussing something like this in the past,
> e.g., text formatted data, such as XML, and binary endian conversions
> between modules, or across the network, etc.

That is flexible but unfortunately would probably be unnecessarily slow 
for most OS calls.

>>> I guess that depends on the similarity of the implementation of the
>>> underlying languages.  Similar would mean that it's possible. 
>>> Different
>>> would mean that it's not, or not easily.
>>
>
> Also, see above.  Text files might be a round-about solution.
>
>>> I guess that depends on the similarity of the implementation of the
>>> underlying languages.  Similar would mean that it's possible. 
>>> Different
>>> would mean that it's not, or not easily.
>>
>> The benefit would be to have the library of OS-interface functions 
>> provided with the OS, regardless of how many languages call that OS, 
>> rather than one library per language per OS.
>
> IIUC, you can have a common "library of OS-interface functions," but 
> each
> language would need to have a wrap/shim etc to call the OS.  E.g., if 
> the
> OS API is in assembly, say like Int 0x80 for Linux, C functions must 
> wrap
> or shim Int 0x80 to call the OS, Pascal too, Fortran too.  If the OS 
> API
> is in C, then assembly, Pascal, Fortran would need to wrap or shim the 
> C
> function.  It's easier to wrap/shim etc than it is to support more 
> than
> one interface language for the OS, especially if you have a large 
> number
> of functions to support.  If the set of OS functions is small, then 
> the
> OS could support each set in a multitude of languages directly, but 
> then
> you've just shifted the shim/wrap issue from the C, Pascal, Fortran
> library domain to the OS API domain.

By API I am not sure if you are thinking about how to get to kernel mode 
(int 0x80 or far call etc), or are thinking of the defined set of OS 
syscalls. In either case I agree that the calls to interface code (i.e. 
before any transtion to kernel mode) could be wrapped/shimmed. The 
interface code fragments - which are to be supplied by the OS - could 
invoke the kernel so the app wouldn't have to worry about how that was 
done.)

>> I am thinking that the library would be provided by the OS developer
>> and all languages could use its subroutines.
>>
>> Is that feasible?
>
> I'm not real sure what you're asking here ...
>
> If you're specifying the OS API for your OS, then all languages 
> implemented
> on your platform have to use it.

In the sequence

  app --> interface code --> kernel

I was saying that the library of interface code would be provided by the 
OS developer and asking if it was feasible for different languages to 
use the functions within it. Same issue as above, and one I don't have 
the answer to yet.

>> I know that there would need to be some interface info for each 
>> language  (for C that would be header files) but the interface info 
>> for all  languages could be generated from a single source so would 
>> only have to  be defined once, and the implementing code itself (that 
>> applications  call) would only have to be written once.
>
> Ok.  That usually requires some sort of automatic tool to build such 
> files.
> E.g., M4, Gnu Make or Auto-conf, perhaps Grep or AWK or C 
> preprocessor,  etc.
> The C preprocessor has been used to preprocess or create code for 
> other
> situations.  Personally, I'd probably avoid that.

The tool used to build such files may be easiest to write in Python 
which is great for text processing. Or it could be written in C but 
speed would not be important as it would only be run rarely, i.e. when 
there was a new OS interface definition.

James

Back to alt.os.development | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Re: How to bind HLLs to OS calls "Rod Pemberton" <boo@fasdfrewar.cdm> - 2015-06-18 02:10 -0400
  Re: How to bind HLLs to OS calls "Rod Pemberton" <boo@fasdfrewar.cdm> - 2015-06-19 06:19 -0400
    Re: How to bind HLLs to OS calls "James Harris" <james.harris.1@gmail.com> - 2015-06-22 21:22 +0100
      Re: How to bind HLLs to OS calls "Rod Pemberton" <boo@fasdfrewar.cdm> - 2015-06-23 19:24 -0400
        Re: How to bind HLLs to OS calls "Rod Pemberton" <boo@fasdfrewar.cdm> - 2015-06-24 22:15 -0400
    Re: How to bind HLLs to OS calls "James Harris" <james.harris.1@gmail.com> - 2015-06-24 07:55 +0100
      Re: How to bind HLLs to OS calls "Rod Pemberton" <boo@fasdfrewar.cdm> - 2015-06-24 21:00 -0400

csiph-web