POV-Ray : Newsgroups : povray.off-topic : Linking Server Time
1 Jul 2024 03:15:50 EDT (-0400)
  Linking (Message 11 to 18 of 18)  
<<< Previous 10 Messages Goto Initial 10 Messages
From: clipka
Subject: Re: Linking
Date: 31 May 2016 13:50:34
Message: <574dceea$1@news.povray.org>
Am 29.05.2016 um 09:26 schrieb Orchid Win7 v1:

>> The linker will later use that table to update those memory locations.
> 
> Oh, I see. So, what, the jump op-code says to jump to address zero, and
> the object metadata tells the linker which bytes to change?

Yup.

>> You /could/ look it up... you know, they have this fancy new thing
>> called the Internet, and search engines and things ;)
> 
> Don't you start. I've already spent a day looking at the output of nm,
> objdump and readelf. :-P The manpages tell you what all the switches do,
> but I still have no idea what .text is supposed to mean.

I haven't ever looked at any of those, but when I hear "text" in the
context of linking, I think of the "text segment", which is where all
the instructions will be stored (aka "code segment" as Intel would call it).

>>> For that matter, is it possible to store *data* in an object file? (As
>>> opposed to executable code.)
>>
>> Absolutely. See the `source/base/font/*.cpp` files in the POV-Ray source
>> code for examples.
> 
> Hmm. Interesting.
> 
>   extern const unsigned char font_timrom[36936]={...
> 
> I didn't think you could make an array const. (Wouldn't that just mean
> the array pointer itself is constant? Not the array it points to.) And I
> thought extern means "this is declared somewhere else"?

The "const unsigned char FOO[...]={...}" means that FOO is an array of
constant unsigned chars.

Without the "const", it would mean that the array, although initialized
at startup, could be tampered with later.

As for the "extern" that keyword does /not/ denote that the thing is
defined(!) "somewhere else", but that the thing "has external linkage",
i.e. is shared by multiple translation units (= .c or .cpp files).

Some library authors seem to go to great lengths to declare stuff as
"extern" when their header files are included from code that uses the
library, but leave out that "extern" when included from the library
itself; I currently don't know why they do that -- according to the C
and C++ standards this can only work because most stuff is implicitly
"extern" anyway unless explicitly declared "static".

It so happens that "const" stuff is one of the few things implicitly
"static" unless explicitly declared "extern".


> [Also... Heh, do you know, when you said it, I was thinking I'd be able
> to browse the source online somewhere. Silly me...]

Silly you indeed for not figuring out that you can indeed browse the
source code on GitHub ;)

https://github.com/POV-Ray/povray/tree/master/source/base/font


Post a reply to this message

From: clipka
Subject: Re: Linking
Date: 31 May 2016 14:58:24
Message: <574dded0@news.povray.org>
Am 29.05.2016 um 09:48 schrieb Orchid Win7 v1:

> I was *about* to say that I've only done it with AmigaOS - but that's
> not quite right. What I was *actually* looking it is calling *the OS*,
> which is a bit different.
...
> Presumably any self-respecting protected-mode OS does it differently. In
> particular, calling the kernel presumably implies a transition to
> ring-0, and I don't remember how x86 does that exactly. (From what I
> dimly recall, you purposely trigger a kind of software interrupt, but
> I'm not sure how you designate what function you're trying to call.)

That's pretty simple: You pass a kind of function ID in a particular CPU
register.

For instance, in good old DOS, the sole entry point for all operating
system functions was INT 21h, with the AH register indicating which
function you intended to call.

According to Wikipedia, Linux originally used pretty much the same
principle, except with INT 80h and the AX register.

Windows also uses the AX register to identify the kernel function, but
uses the faster dedicated SYSENTER instruction (introduced with the
Pentium II) instead of a software interrupt. (The drawback is that this
instruction doesn't push a return address onto the stack, so a CALL to a
stub is usually employed.)

Likewise, Linux running on modern machines also uses SYSENTER or the
even newer SYSCALL.


The x86 architecture also provides a mechanism known as a "call gate",
which uses a CALL FAR instruction to a segment specifically set up by
the operating system to redirect the call to an entirely different
address while switching privilege level. This mechanism was used by some
operating systems, but has gone out of style. Not sure whether those
systems used a single call gate and a register to pass a function ID, or
whether they used one call gate per kernel function.


Post a reply to this message

From: scott
Subject: Re: Linking
Date: 1 Jun 2016 03:22:28
Message: <574e8d34@news.povray.org>
> The way AmigaOS does it, memory address 0x00000004 holds a pointer to
> the function table for exec.library. Every function in the library has a
> known index in that table, so by adding your index to the address
> pointed to, you get a function pointer to the actual library function
> that you want. Now since exec.library is the one that contains the
> functions to load *other* libraries, from here you can open any other
> library you want. This similarly returns a function table base pointer,
> which you can use in the same way.
>
> Of course, exec.library is in ROM, as are most of the low-level system
> libraries [including the entire GUI]. But you don't need to care about
> that. Just call OpenLibrary(), and it'll load from disk if required, and
> ultimately give you back a base pointer.
>
> Presumably any self-respecting protected-mode OS does it differently. In
> particular, calling the kernel presumably implies a transition to
> ring-0, and I don't remember how x86 does that exactly. (From what I
> dimly recall, you purposely trigger a kind of software interrupt, but
> I'm not sure how you designate what function you're trying to call.)

Not a protected-mode OS, but in RISCOS on ARM there is an instruction 
"SWI" that triggers a software interrupt. There are 24 bits spare in 
that instruction to specify the routine number (the other 8 to identify 
the instruction itself and conditional execution flags etc). Routines 
have a name and a number, the OS maintains a list if you can only 
remember the name (in fact most compilers/interpreters will allow you to 
write the name, and automatically substitute the number to the 
instruction). The processor registers r0 up to r8 (IIRC) were passed on 
to the SWI handler code and returned, so these were used for parameters 
and return values.

It was possible to add your own routines to this system, in fact this is 
how almost all 3rd party libraries (eg music players, image converters, 
compression software,...) were written. The equivalent of how DLLs are 
used today I guess.


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Linking
Date: 1 Jun 2016 12:59:28
Message: <574f1470$1@news.povray.org>
On 31/05/2016 07:57 PM, clipka wrote:
> Am 29.05.2016 um 09:48 schrieb Orchid Win7 v1:
>
>> I was *about* to say that I've only done it with AmigaOS - but that's
>> not quite right. What I was *actually* looking it is calling *the OS*,
>> which is a bit different.
> ...
>> Presumably any self-respecting protected-mode OS does it differently. In
>> particular, calling the kernel presumably implies a transition to
>> ring-0, and I don't remember how x86 does that exactly. (From what I
>> dimly recall, you purposely trigger a kind of software interrupt, but
>> I'm not sure how you designate what function you're trying to call.)
>
> That's pretty simple: You pass a kind of function ID in a particular CPU
> register.
>
> For instance, in good old DOS, the sole entry point for all operating
> system functions was INT 21h, with the AH register indicating which
> function you intended to call.

That's essentially a direct call to the BIOS itself, isn't it? Or does 
MS-DOS actually interact with this somehow? (I realise that MS-DOS is a 
very thin "OS", if you can even call it that.)

> According to Wikipedia, Linux originally used pretty much the same
> principle, except with INT 80h and the AX register.

OK...

> Windows also uses the AX register to identify the kernel function, but
> uses the faster dedicated SYSENTER instruction (introduced with the
> Pentium II) instead of a software interrupt. (The drawback is that this
> instruction doesn't push a return address onto the stack, so a CALL to a
> stub is usually employed.)
>
> Likewise, Linux running on modern machines also uses SYSENTER or the
> even newer SYSCALL.

OK, fair enough.

Both IA32 (and later AMD64) are quite short on registers, which is 
presumably why the default C calling convention is seemingly via the 
stack. In AmigaOS, running on a Motorola 68000 with a dozen registers, 
most of this stuff is via register...

> The x86 architecture also provides a mechanism known as a "call gate",

Yeah, I remember reading about that in the IA32 reference manual. I 
can't recall the details of how it works though.

> This mechanism was used by some
> operating systems, but has gone out of style.

OK. Sounds like there's not much point remembering then.


Post a reply to this message

From: clipka
Subject: Re: Linking
Date: 2 Jun 2016 01:23:06
Message: <574fc2ba$1@news.povray.org>
Am 01.06.2016 um 18:59 schrieb Orchid Win7 v1:

>> For instance, in good old DOS, the sole entry point for all operating
>> system functions was INT 21h, with the AH register indicating which
>> function you intended to call.
> 
> That's essentially a direct call to the BIOS itself, isn't it? Or does
> MS-DOS actually interact with this somehow? (I realise that MS-DOS is a
> very thin "OS", if you can even call it that.)

No; the BIOS uses the same principle, but different interrupts.

BIOS-level disk I/O, for instance, uses INT 13h.


>> The x86 architecture also provides a mechanism known as a "call gate",
> 
> Yeah, I remember reading about that in the IA32 reference manual. I
> can't recall the details of how it works though.

Don't worry, the IA32 reference manuals recall the details pretty well ;)


Post a reply to this message

From: dick balaska
Subject: Re: Linking
Date: 2 Jun 2016 04:49:05
Message: <574ff301$1@news.povray.org>
Am 2016-06-02 01:22, also sprach clipka:

> No; the BIOS uses the same principle, but different interrupts.
>
> BIOS-level disk I/O, for instance, uses INT 13h.

I haven't been inside of Windows since ... XP.  Do they *still* use 
that?  I recall an early Linux decision was to get the hell away from 
the BIOS asap and stay away.  -- Device drivers uber alles.

(I kept waiting for M$ to invent the swap partition, to speed things up 
a little.)

I was always annoyed that when M$ bought Seattle Computer Products' DOS, 
they didn't rearrange the function numbers before releasing it.  It 
would have been nice if the disk functions were grouped together for 
when referring to The Green Book.  Instead, it was obvious that as each 
function was added, it just went to the end of the list. So, 
open/read/write/close were like 5/6/7/8. Then delete was 23, rename was 
54. A real pita for book referring.

-- 
dik


Post a reply to this message

From: clipka
Subject: Re: Linking
Date: 2 Jun 2016 05:49:39
Message: <57500133$1@news.povray.org>
Am 02.06.2016 um 10:49 schrieb dick balaska:
> Am 2016-06-02 01:22, also sprach clipka:
> 
>> No; the BIOS uses the same principle, but different interrupts.
>>
>> BIOS-level disk I/O, for instance, uses INT 13h.
> 
> I haven't been inside of Windows since ... XP.  Do they *still* use
> that?  I recall an early Linux decision was to get the hell away from
> the BIOS asap and stay away.  -- Device drivers uber alles.

On machines without UEFI support, both Windows AND Linux still use the
BIOS... for the very first phase of the boot procedure.

From then on, Windows doesn't look back at the BIOS either. It may keep
the BIOS' assignments of resources (I/O addresses, interrupts and DMA
channels) to hardware components, but that's about as far as the BIOS'
influence on the running system goes.

The decision is actually a very pragmatic one: The BIOS has always been
designed to run in 16-bit Real Mode, and invoking it from 32-bit
protected mode (not to mention 64-bit long mode) would add a shitload of
overhead. The 16-bit mode also limits the efficiency of the driver code
itself.


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Linking
Date: 2 Jun 2016 13:43:07
Message: <5750702b$1@news.povray.org>
On 02/06/2016 09:49 AM, dick balaska wrote:
> Am 2016-06-02 01:22, also sprach clipka:
>
>> No; the BIOS uses the same principle, but different interrupts.
>>
>> BIOS-level disk I/O, for instance, uses INT 13h.
>
> I haven't been inside of Windows since ... XP. Do they *still* use that?
> I recall an early Linux decision was to get the hell away from the BIOS
> asap and stay away. -- Device drivers uber alles.

AFAIK, both Windows and Linux use the BIOS to figure out your hardware 
layout early in the boot sequence... and then never touch it ever again.

Basically, once the OS kernel has figured out your memory map and which 
regions to not clobber, it switches to its own native device drivers, 
exits real mode and enters protected mode, and never looks back.

[U]EFI changes this, in that it allows a protected-mode OS to directly 
request services from it. Even so, nobody really uses this except for 
boot configuration tasks. (If only because your OS still needs to work 
on old BIOS systems as well...)


Post a reply to this message

<<< Previous 10 Messages Goto Initial 10 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.