View mode: basic / threaded / horizontal-split · Log in · Help
May 26, 2004
Get memory address of a function?
Hi Everyone, 
How can I access the memory address of a function? I want the
address for 
loading into an Interrupt Descriptor Table. 

example : 

void
enableInterrupts( ... ) { 
... 
tables[14].handler=cast(void*)&_interrupt14;
// This generates an error - e2ir: cannot cast from void delegate() to void*
.. 
} 
void _interrupt14() { 
asm { 
 pusha; push DS; push ES; push FS; push
GS; 
 mov EAX,CR2; 
 push EAX; 
 call interrupt14; 
 pop GS; pop FS; pop ES;
pop DS; popa; 
 iret; 
} 
} 
void interrupt14() {  
// Handler 
} 


Thanks
a lot! 

Braden
May 26, 2004
Re: Get memory address of a function?
What you're doing should work fine. I suspect something else is going on in
the omitted code. Try boiling it down to the minimum.

"Braden MacDonald" <bradenm_k@shaw.ca> wrote in message
news:c91951$i1s$1@digitaldaemon.com...
> Hi Everyone,
>  How can I access the memory address of a function? I want the
> address for
> loading into an Interrupt Descriptor Table.
>
> example :
>
> void
> enableInterrupts( ... ) {
>  ...
>  tables[14].handler=cast(void*)&_interrupt14;
> // This generates an error - e2ir: cannot cast from void delegate() to
void*
> ..
> }
> void _interrupt14() {
>  asm {
>   pusha; push DS; push ES; push FS; push
> GS;
>   mov EAX,CR2;
>   push EAX;
>   call interrupt14;
>   pop GS; pop FS; pop ES;
> pop DS; popa;
>   iret;
>  }
> }
> void interrupt14() {
>  // Handler
> }
>
>
> Thanks
> a lot!
>
>  Braden
>
>
May 26, 2004
Re: Get memory address of a function?
In article <c91cfg$mjj$1@digitaldaemon.com>, Walter says...
>
>What you're doing should work fine. I suspect something else is going on in
>the omitted code. Try boiling it down to the minimum.
>
>"Braden MacDonald" <bradenm_k@shaw.ca> wrote in message
>news:c91951$i1s$1@digitaldaemon.com...
>> Hi Everyone,
>>  How can I access the memory address of a function? I want the
>> address for
>> loading into an Interrupt Descriptor Table.
>>
>> example :
>>
>> void
>> enableInterrupts( ... ) {
>>  ...
>>  tables[14].handler=cast(void*)&_interrupt14;
>> // This generates an error - e2ir: cannot cast from void delegate() to
>void*
>> ..
>> }
>> void _interrupt14() {
>>  asm {
>>   pusha; push DS; push ES; push FS; push
>> GS;
>>   mov EAX,CR2;
>>   push EAX;
>>   call interrupt14;
>>   pop GS; pop FS; pop ES;
>> pop DS; popa;
>>   iret;
>>  }
>> }
>> void interrupt14() {
>>  // Handler
>> }
>>
>>
>> Thanks
>> a lot!
>>
>>  Braden
>>
>>
>
>
Braden, I'm looking at the Intel 386 Asm Manual, and it states, "CR2 is used for
handling page faults when PG (CR0, Paging, bit 31) is set. The processor stores
in CR2 the linear address that triggers the fault." Since I don't see CR0 bit 31
being set in your above code...maybe that's it. ;)
May 26, 2004
Re: Get memory address of a function?
In article <c92s45$2ude$1@digitaldaemon.com>, David L. Davis says...
>
>In article <c91cfg$mjj$1@digitaldaemon.com>, Walter says...
>>
>>What you're doing should work fine. I suspect something else is going on in
>>the omitted code. Try boiling it down to the minimum.
>>
>>"Braden MacDonald" <bradenm_k@shaw.ca> wrote in message
>>news:c91951$i1s$1@digitaldaemon.com...
>>> Hi Everyone,
>>>  How can I access the memory address of a function? I want the
>>> address for
>>> loading into an Interrupt Descriptor Table.
>>>
>>> example :
>>>
>>> void
>>> enableInterrupts( ... ) {
>>>  ...
>>>  tables[14].handler=cast(void*)&_interrupt14;
>>> // This generates an error - e2ir: cannot cast from void delegate() to
>>void*
>>> ..
>>> }
>>> void _interrupt14() {
>>>  asm {
>>>   pusha; push DS; push ES; push FS; push
>>> GS;
>>>   mov EAX,CR2;
>>>   push EAX;
>>>   call interrupt14;
>>>   pop GS; pop FS; pop ES;
>>> pop DS; popa;
>>>   iret;
>>>  }
>>> }
>>> void interrupt14() {
>>>  // Handler
>>> }
>>>
>>>
>>> Thanks
>>> a lot!
>>>
>>>  Braden
>>>
>>>
>>
>>

Post1: Braden, I'm looking at the Intel 386 Asm Manual, and it states, "CR2 is
used for handling page faults when PG (CR0, Paging, bit 31) is set. The
processor stores in CR2 the linear address that triggers the fault." Since I
don't see CR0 bit 31 being set in your above code...maybe that's it. ;)

Post2: Braden, it looks like I may have misread your problem...sorry. To set up
a pointer to a function in D:

// Creates a void function pointer with void 
// parameters, this matchs void _interrupt14() 
void function( ) pt2Function;

// Assigns the function's address to the pointer
pt2Function = &_interrupt14; 

// Then can call the function thru the point
pt2Function();

Hope I got it right this time?
May 27, 2004
Re: Get memory address of a function?
You were right. If both functions were members of the same struct, then it
won't compile. If I make _interrupt14 global, then it compiles fine. Is there
any way around this? I'd rather not have a global function if possible.
___________________________________ 
struct Something { 
void f1() { 
 void*
p2 = cast(void*)&_f2; // Error 
 void* p3 = cast(void*)&_f3; // OK 
} 
void
f2() { 
 //Something 
} 
} 

void f3() { 
//Something 
}
___________________________________ 

In article
<c91cfg$mjj$1@digitaldaemon.com>, Walter says... 
> 
>What you're doing should
work fine. I suspect something else is going on in 
>the omitted code. Try
boiling it down to the minimum. 
> 
>"Braden MacDonald" <bradenm_k@shaw.ca>
wrote in message 
>news:c91951$i1s$1@digitaldaemon.com... 
>> Hi Everyone, 
>>
How can I access the memory address of a function? I want the 
>> address for
>> loading into an Interrupt Descriptor Table. 
>> 
>> example : 
>> 
>> void 
>> enableInterrupts( ... ) { 
>>  ... 
>>  tables[14].handler=cast(void*)&_interrupt14; 
>> // This generates an error - e2ir: cannot cast from void delegate() to 
>void* 
>> .. 
>> } 
>> void _interrupt14() { 
>>  asm { 
>>   pusha; push DS; push ES; push FS; push GS; 
>>   mov EAX,CR2; 
>>   push EAX; 
>>   call interrupt14; 
>>   pop GS; pop FS; pop ES; pop DS; popa; 
>>   iret; 
>>  } 
>> } 
>> void interrupt14() { 
>>  // Handler 
>> } 

>> Thanks a lot! 
>> 
>>  Braden
May 27, 2004
Re: Get memory address of a function?
Braden MacDonald wrote:

> You were right. If both functions were members of the same struct, then it
> won't compile. If I make _interrupt14 global, then it compiles fine. Is there
> any way around this? I'd rather not have a global function if possible.
> ___________________________________ 
> struct Something { 
>  void f1() { 
>   void*
> p2 = cast(void*)&_f2; // Error 
>   void* p3 = cast(void*)&_f3; // OK 
>  } 
>  void
> f2() { 
>   //Something 
>  } 
> } 
>  
> void f3() { 
>  //Something 
> }

You'll have to make f2 static.  As it stands, &f2 is 8 bytes long, not 
four. (four for a pointer to the Something instance, four more for the 
address of the method)

 -- andy
May 27, 2004
Re: Get memory address of a function?
>Post2: Braden, it looks like I may have misread your problem...sorry. To set
up 
>a pointer to a function in D: 
> 
>// Creates a void function pointer with void  
>// parameters, this matchs void _interrupt14()  
>void function( ) pt2Function; 
> 
>// Assigns the function's address to the pointer 
>pt2Function = &_interrupt14;  
> 
>// Then can call the function thru the point 
>pt2Function(); 
> 
>Hope I got it right this time? 

Thanks, I have it working now (see my reply to Walter). 

As you may have guessed, I'm writing an operating system in D. I already have 
paging set up and working, and I have a kmalloc/free working as well. What I'm 
trying to do now is set up interrupt handling (especially Page Fault) - which 
has proved more difficult than it first appeared.  

Do you happen to know how to use the "lidt" assembler instruction from D? I 
thought that it took a pointer to a 6-byte structure, but my code will only 
compile if I pass it a 64-bit paramater:


/* Pointer to IDT table: */ 
struct idtPtr { 
ushort length=256*8-1; //Size of table 
uint addr; // Actual pointer to first entry 
} 

void enableInterrupts() { 
IDTEntry[256]* base = cast(IDTEntry[256]*)kmalloc(IDTEntry.size*256); 
idtPtr p; 
p.addr = cast(uint)&((*base)[0]); 
for (int i=0;i<256;i++) { 
..  // fill IDT table pointed to by "base" 
} 
/* Now, load the table into the CPU register: */ 
asm { lidt p; } 
/* Now our interrupt handler should be working. (but it isn't) */ 
} 

/* One Interrupt Descriptor Entry: */ 
struct IDTEntry { 
ushort _handlerH;//High 16 bits of handler address 
ushort _flags=0; 
ushort _segment; 
ushort _handlerL; 
void handler(void* addy) { 
_handlerH = cast(uint)addy>>16; 
_handlerL = cast(uint)addy & 0x0000FFFF; 
} 
void* handler() { return cast(void*)((_handlerH<<16) | (_handlerL)); } 
void segment(ushort s) { _segment=s; } 
void present(bit p) { if (p) {_flags |= 1<<15;} else { _flags &= 0xFFFF 
^(1<<15); } } 
bit present() { return (_flags & (1<<15)) != 0; } 
void kernel(bit kernel) { 
if (!kernel) { 
_flags = _flags | 3<<13; 
} else { 
_flags &= 0xFFFF ^ (3<<13); 
} 
} 
bit kernel() { return (_flags & (3<<13)) != 0; } 
void type(bit interrupt/* opposed to trap*/) { 
_flags &= (0xFFFF) ^ (15<<8); 
if (interrupt) { _flags |= 14<<8; } 
else           { _flags |= 15<<8; } 
} 
} 

___
This code (extracted from my kernel) doesn't work - because any (or all) of
several things could be wrong, I'm not sure which to change. Any ideas?

Thanks a lot!
May 27, 2004
Re: Get memory address of a function?
Make it a static member function, and you can take the address of it just
like a global function.

"Braden MacDonald" <bradenm_k@shaw.ca> wrote in message
news:c93fh9$pme$1@digitaldaemon.com...
> You were right. If both functions were members of the same struct, then it
> won't compile. If I make _interrupt14 global, then it compiles fine. Is
there
> any way around this? I'd rather not have a global function if possible.
> ___________________________________
> struct Something {
>  void f1() {
>   void*
> p2 = cast(void*)&_f2; // Error
>   void* p3 = cast(void*)&_f3; // OK
>  }
>  void
> f2() {
>   //Something
>  }
> }
>
> void f3() {
>  //Something
> }
May 27, 2004
Re: Get memory address of a function?
In article <c93gig$qv9$1@digitaldaemon.com>, Andy Friesen says... 
>You'll have
to make f2 static.  As it stands, &f2 is 8 bytes long, not  
>four. (four for a
pointer to the Something instance, four more for the  
>address of the method)
Right. Thanks for for the explanation, that part compiles fine now. (My IDT
still isn't working, though - see my other email)
Top | Discussion index | About this forum | D home