OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Jun 20, 2019 1:11 pm

All times are UTC - 6 hours




Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 15 posts ] 
Author Message
 Post subject: linux a.out
PostPosted: Mon Feb 11, 2019 2:53 am 
Offline
Member
Member

Joined: Fri Nov 17, 2006 5:26 am
Posts: 34
Hi.

The stack layout for Linux ELF executables is given here:

https://www.win.tue.nl/~aeb/linux/hh/stack-layout.html

I would like to know what the stack layout is for Linux a.out executables.

I'm thinking of getting PDOS/386 to use the Linux layout instead of inventing my own interface.

Thanks. Paul.


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Mon Feb 11, 2019 5:17 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 300
Hi,

As our wiki says, the a.out format is not Linux specific, it's a UNIX format, and at some point it was used by all POSIX compliant OSes. These days it's replaced by ELF in almost every OS (Minix, Linux, most BSDs), but some BSDs still support it as main executable format. More detailed information: NetBSD man page.

Just like ELF, a.out does not specify the stack (ELF has some GNU extensions to tell the stack's minimum size and wether it's executable, but that is not part of the ELF spec, and strongly gcc specific). You can place the stack at the top of the address space or before the text segment, it's up to you. But for your own good, NEVER allow code execution on the stack.

What you put in the stack on program execution should be executable format independent. Whatever the reason for "ELF Auxiliary Table" on the page you linked I'm not sure (and honestly I don't think that clock frequency for example is part of any ELF structure as a matter of fact). Other sources do not mention that either. But other than that, everything is common: environment strings, command line arguments, argc, argv pointer, all needed with a.out as well, because they are specified by the libc (and by the ABI, SysV calling conventions), and not by the executable format.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Mon Feb 11, 2019 8:03 am 
Offline
Member
Member

Joined: Fri Nov 17, 2006 5:26 am
Posts: 34
bzt wrote:
and by the ABI, SysV calling conventions

Thanks for that.

Quote:
What you put in the stack on program execution should be executable format independent.

Surely if PDOS/386 is executing an OS/2 2.0 or Windows 32 binary then it needs to put different things on the stack as to what the executable is expecting?


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Mon Feb 11, 2019 10:10 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1547
kerravon wrote:
Surely if PDOS/386 is executing an OS/2 2.0 or Windows 32 binary then it needs to put different things on the stack as to what the executable is expecting?

Yes, but that's because OS/2 and Windows have different ABIs, and not because the executable format is different. (You may notice that OS/2 1.0 and Win16 both use NE for their executables; same format, different ABI.)


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Mon Feb 11, 2019 2:04 pm 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 582
bzt wrote:
Just like ELF, a.out does not specify the stack (ELF has some GNU extensions to tell the stack's minimum size and wether it's executable, but that is not part of the ELF spec, and strongly gcc specific). You can place the stack at the top of the address space or before the text segment, it's up to you. But for your own good, NEVER allow code execution on the stack.

What you put in the stack on program execution should be executable format independent. Whatever the reason for "ELF Auxiliary Table" on the page you linked I'm not sure (and honestly I don't think that clock frequency for example is part of any ELF structure as a matter of fact). Other sources do not mention that either. But other than that, everything is common: environment strings, command line arguments, argc, argv pointer, all needed with a.out as well, because they are specified by the libc (and by the ABI, SysV calling conventions), and not by the executable format.

Well, ELF and the ABI are defined in the same specification. ELF does in fact specify the layout of the initial stack. The auxvector is required so that the dynamic linker can find the executable it is linking: ld.so is a shared library that is loaded alongside the executable into the process image; however, it does not know where the executable actually is.

_________________
managarm: A microkernel-based OS that is capable of running a Wayland desktop


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Tue Feb 12, 2019 8:58 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 300
Korona wrote:
Well, ELF and the ABI are defined in the same specification.
That usually leads to the confusion you have right now. Just because two things are referenced in the same spec, doesn't mean they are equivalent. The spec just defines how to use that two things together.

Quote:
ELF does in fact specify the layout of the initial stack.
Why are you so surprised? Note that psABI-x86_64.pdf is specifically about how to use ELF format WITH SysV ABI on x86_64. The SCO spec of ELF for example does not talk about registers or stack layouts (because those are processor specific).

Make no mistake, ELF is not limited to SysV ABI at all (take a look at GNU libc's OSABI definitions in elf.h here). On the other hand, noone stops you from using SysV ABI with a PE format (objconv can convert a SysV ABI ELF into a PE without changing the text segment. Objconv won't magically rewrite parts of the code for MS ABI).

Quote:
The auxvector is required so that the dynamic linker can find the executable it is linking
Which you may or may not need, depending on YOUR dynamic linker implementation. You don't have to copy Linux's ld.so. My dynamic linker for example does not need it, as it knows where the binaries are loaded in memory. From the SCO spec: "PT_NOTE The array element specifies the location and size of auxiliary information. See ‘‘Note Section’’ below for details." and "Note information is optional. The presence of note information does not affect a program’s ABI conformance". Read Section 5-13 (Dynamic linker).

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Tue Feb 12, 2019 11:08 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 582
bzt wrote:
Quote:
The auxvector is required so that the dynamic linker can find the executable it is linking
Which you may or may not need, depending on YOUR dynamic linker implementation. You don't have to copy Linux's ld.so. My dynamic linker for example does not need it, as it knows where the binaries are loaded in memory. From the SCO spec: "PT_NOTE The array element specifies the location and size of auxiliary information. See ‘‘Note Section’’ below for details." and "Note information is optional. The presence of note information does not affect a program’s ABI conformance". Read Section 5-13 (Dynamic linker).

Yes. I assumed that it was clear from context that I am only talking about the SysV ABI. Seems that it was not; I should have cleared that up. However, the SysV ABI is not Linux specific. It is the x86_64 specialization of the more general ABI that you linked; those two do not contradict but augment each other.

Furthermore, you cannot use the SysV ABI with PE, that just does not make sense. Parts of the functionality (e.g. dl_iterate_phdrs, dlopen) cannot be implemented on top of other executable formats (unless you just make them fail or jump through hoops to emulate parts of the format).

DT_NOTE is unrelated to the auxvector (even on the SysV ABI).

_________________
managarm: A microkernel-based OS that is capable of running a Wayland desktop


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Tue Feb 12, 2019 12:14 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 300
Hi Korona,

Please do not confuse beginners with half-thruths and misinformation. Thanks.

Korona wrote:
Yes. I assumed that it was clear from context that I am only talking about the SysV ABI.
The OP was asking about ELF and stacks, and ELF is not SysV ABI only. And SysV ABI does not mandate ELF auxvector on stack either.

Korona wrote:
The auxvector is required so that the dynamic linker can find the executable it is linking
Again, why? The OP's page lists all (id,value) pairs in it. What do you think, which one of these makes the table absolutely necessary and indispendable for the dynamic linker?
Quote:
The ELF Auxiliary Table is a list of (id,value) pairs.
AT_SYSINFO=32 VSYSCALL_ENTRY: 0xffffe400
AT_SYSINFO_EHDR=33 VSYSCALL_BASE: 0xffffe000
AT_HWCAP=16 hardware capabilities: 0x0183f9ff
AT_PAGESZ=6 page size: 4096
AT_CLKTCK=17 clock frequency for times(): 100 Hz
AT_PHDR=3 address program headers: 0x08048034
AT_PHENT=4 size of program header: 32
AT_PHNUM=5 number of program headers: 8
AT_BASE=7 base address of interpreter: 0x40000000
AT_FLAGS=8 flags: 0
AT_ENTRY=9 program entry point: 0x08048360
AT_UID=11 uid: 500
AT_EUID=12 effective uid: 500
AT_GID=13 gid: 100
AT_EGID=14 effective gid: 100
AT_SECURE=23 secure mode boolean: 0
AT_PLATFORM=15 address of platform string: 0xbffff6cb
AT_NULL=0 end of table
All those values are just informational, copies of values which could be accessed otherwise. In short, auxvector is not mandatory, nor does it have any exclusive information, not even on x86_64.

Korona wrote:
Furthermore, you cannot use the SysV ABI with PE, that just does not make sense. Parts of the functionality (e.g. dl_iterate_phdrs, dlopen) cannot be implemented on top of other executable formats
Why not? What stops you from implementing dlopen() for PE? Nothing. You can compile MINGW to dynamically open PE DLLs with dlopen() for example...

Just for the records, dynamic linker has nothing to do with dlopen(). Let me save you the time of opening the pdf, and quote briefly the section I referenced:
SCO spec Section 5-13 wrote:
When building an executable file that uses dynamic linking, the link editor adds a program header element of type PT_INTERP to an executable file, telling the system to invoke the dynamic linker as the program interpreter.

Exec(BA_OS) and the dynamic linker cooperate to create the process image for the program, which entails the following actions:
- Adding the executable file’s memory segments to the process image;
- Adding shared object memory segments to the process image;
- Performing relocations for the executable file and its shared objects;
- Closing the file descriptor that was used to read the executable file, if one was given to the dynamic linker;
- Transferring control to the program, making it look as if the program had received control directly from exec(BA_OS).
As a matter of fact, dlopen() is so not part of the dynamic linker that it's implemented in a totally different library (libdl.so), and not in the interpreter, ld.so.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Tue Feb 12, 2019 12:45 pm 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 582
bzt wrote:
Hi Korona,

Please do not confuse beginners with half-thruths and misinformation. Thanks.

I am taking that as an offense - I am certainly not spreading half-truth and misinformation. As you may know or may not know, I have written an ELF dynamic linker in mlibc (conforming to the SysV ABI). I have also written a compiler backend that can emit ELF shared libraries and several loaders / linkers. You on the other hand, keep twisting my statements around (like pretending that I ever claimed to speak about something other than the SysV ABI), keep removing context and then claim that my comments are half-truths.

bzt wrote:
The OP was asking about ELF and stacks, and ELF is not SysV ABI only. And SysV ABI does not mandate ELF auxvector on stack either.

ELF is almost only about the SysV ABI. All other ABIs are variations of the SysV one (i.e. the SysV ABI has index zero for a reason). Which OS uses a fundamentally different ELF ABI? If there is one, I do indeed not know about it. Can you link to an ABI supplement for a non-SysV ABI?

And yes, the ABI supplement demands that the auxv is stored on the stay. Specifically in section 3.4.1 with the fitting caption "Initial Stack and Register State".

bzt wrote:
Korona wrote:
The auxvector is required so that the dynamic linker can find the executable it is linking
Again, why? The OP's page lists all (id,value) pairs in it. What do you think, which one of these makes the table absolutely necessary and indispendable for the dynamic linker?
Quote:
The ELF Auxiliary Table is a list of (id,value) pairs.
[...]
All those values are just informational, copies of values which could be accessed otherwise. In short, auxvector is not mandatory, nor does it have any exclusive information, not even on x86_64.

That's just wrong. AT_ENTRY is used to find the entry point of the executable. AT_PHDR is required to find the ELF PHDR of the executable. AT_PHNUM and AT_PHENT are required to parse said PHDR. AT_SECURE is required to determine the execution mode of ld.so. AT_BASE is indeed redundant as the dynamic linker can also relate its _DYNAMIC to the first entry of its own GOT. Most of the rest is informational, true.

bzt wrote:
What stops you from implementing dlopen() for PE? Nothing. You can compile MINGW to dynamically open PE DLLs with dlopen() for example...

Nothing stops you from jumping through hoops but PE is fundamentally incompatible with ELF: it just cannot follow the symbol resolution rules of ELF. For example, PE has import and export tables, while ELF has symbol versioning - it's just not compatible.

bzt wrote:
Just for the records, dynamic linker has nothing to do with dlopen(). Let me save you the time of opening the pdf, and quote briefly the section I referenced:
[...]
As a matter of fact, dlopen() is so not part of the dynamic linker that it's implemented in a totally different library (libdl.so), and not in the interpreter, ld.so.

Thank you, I do know how PT_INTERP works.

Again, your statement about dlopen() is just wrong. The dynamic linker needs to implement dlopen() to make symbol resolution work as expected (granted, libc might implement dlopen() as a stub that calls into ld.so - a fact that is irrelevant here). Please read the relevant documentation, specifically how the symbol resolution order is defined and how local vs. global scopes work.

_________________
managarm: A microkernel-based OS that is capable of running a Wayland desktop


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Tue Feb 12, 2019 2:37 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 300
Korona wrote:
I am taking that as an offense - I am certainly not spreading half-truth and misinformation.
Your choice, it wasn't meant like that. You said dlopen() can't load PE, I gave you a clear counter example with MINGW. If you can't see that you were mistaken, and you think that's an offense, that's your problem.

Korona wrote:
As you may know or may not know, I have written an ELF dynamic linker in mlibc (conforming to the SysV ABI).
Good for you. My OS is compiled with SysV ABI, yet my dynamic linker does not need or use ELF aux, and nothing changes that fact.

Korona wrote:
AT_ENTRY is used to find the entry point of the executable. AT_PHDR is required to find the ELF PHDR of the executable. AT_PHNUM and AT_PHENT are required to parse said PHDR.
Considering that the default Linux linker script (for example) puts the elf headers (both ehdr and phdr) in the text segment (+SIZEOF_HEADERS), and also that the executable is loaded at a fixed address (SEGMENT_START("text-segment", 0x400000))) in the address space, all those information can be accessed at a fixed location in the memory using standard ELF structs (that's how my dynamic linker does it, for example).

Korona wrote:
AT_SECURE is required to determine the execution mode of ld.so.
How does that flag modify the actions of the dynamic linker? There are other, more reliable ways to get "SECURE" mode flag. Not to mention that using such a flag in a user writable memory is not really secure at all.

Korona wrote:
Thank you, I do know how PT_INTERP works.

Again, your statement about dlopen() is just wrong. The dynamic linker needs to implement dlopen()
Then how do you explain that dlopen() is NOT part of the interpreter (the dynamic linker) on Linux? This is what I see under Linux (ld.so and libdl.so clearly separated files):
Code:
$ ldd /bin/bash
   linux-vdso.so.1 (0x00007ffd2eeef000)
   libreadline.so.7 => /usr/lib/libreadline.so.7 (0x00007f3dbf5e0000)
   libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f3dbf8dc000)                                     <--- dlopen() implementation
   libc.so.6 => /usr/lib/libc.so.6 (0x00007f3dbf520000)
   libncursesw.so.6 => /usr/lib/libncursesw.so.6 (0x00007f3dbc4b3000)
   /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f3da020d000)        <--- dynamic linker


Please note that I don't really expect answers. I asked them just for your benefit, to make you think. It seems you can't accept the facts from me, that's ok I can relate. Maybe if you ask those questions to yourself, you'll find the correct answers on your own. And no, constructive critisism is not an offense.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Tue Feb 12, 2019 11:15 pm 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 582
Good thing is, I can answer all your questions! :D

I never said dlopen() cannot load PE, I said it cannot load PE according to spec. The symbol resolution order of dlopen() is defined in terms of ELF's local and global scope. The local and global scopes of the DSO are searched in a specific order that is constructed from a topological sort of the DSOs providing the symbols and it takes the exact load order into account. PE does not have those concepts. Furthermore, this information is not available without communicating with the ld.so that linked the initial process image.

Indeed, glibc (that you're talking about when you post the ldd trace) implements dlopen() as a call to _dlfcn_hook->dlopen, where _dlfcn_hook is a vtable provdied by ld.so. This can be seen here. (As I said earlier, the fact that there is a stub in libc does not change the fact that the actual implementation is in ld.so.)

Note that for those aspects of dlopen(), there is a good explanation from Ulrich Drepper, then maintainer of glibc, that explains how the scopes work.

Yes, the default linker script has a fixed base address. However, did you try changing it? If you change it, ld.so still works! If you compile as PIE to take advantage of ASLR, the ld.so still works! Why is that? Because it considers AT_ENTRY for the entry point. If your dynamic linker assumes that PHDRs are loaded to 0x200040, that's fine but it is a violation of the x86_64 ABI supplement. Does your linker work on SysV compatible OSes like Linux or FreeBSD? Or does it only work on your OS? mlibc's dynamic linker does work on all OSes implementing the ABI!

What AT_SECURE does is well-documented. I refer to the man page of glibc's ld.so. It makes sure that ld.so does not load library from LD_LIBRARY_PATH among other effects. Thus, you cannot intercept libraries for executables with AT_SECURE set (e.g. setuid binaries). This is useful, as you could otherwise force the setuid program to do arbitrary stuff. The flag is secure even though it is stored in userspace, as ld.so is the first userspace program that runs (in each process), so it can be sure that the auxv has not been tempered with. Of course, it should not been trusted after ld.so has run (in particular, it could have been set by a library initializing function even before main() runs).

_________________
managarm: A microkernel-based OS that is capable of running a Wayland desktop


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Wed Feb 13, 2019 7:13 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 300
Hi,

Oh you poor lad. If there's something you can't image, then that's impossible? Your way is the only way?
I feel sorry for you, so I try to explain this one last time. What ELFs are capable of, and what and how one particular dynamic linker for SysV ABI has implemented are two totally different things. Do not confuse those.

Korona wrote:
I never said dlopen() cannot load PE, I said it cannot load PE according to spec.
You refuse to see that you're stuck with one spec, the SysV ABI psABI-x86_64. That's not the only way to do things, MINGW developers have done it differently, they can load PE with dlopen() for example.

ELF != SysV ABI, but even with SysV ABI, you have several ways how to do things, and it doesn't matter as long as the interface you show towards the executables meets their expectations, the executable wouldn't know. As a matter of fact, according to the spec, dynamic linker must be TRANSPARENT ("Transferring control to the program, making it look as if the program had received control directly from exec(BA_OS)."), meaning there's no required interface at all. An executable wouldn't call the dynamic linker directly ever. And if you dig deeper, you'll find that late-binding must be also transparent to the application. (And no, dlopen() doesn't count because it's entry point is in a shared library, and not in ld.so).

Korona wrote:
Indeed, glibc (that you're talking about when you post the ldd trace) implements dlopen() as a call to _dlfcn_hook->dlopen, where _dlfcn_hook is a vtable provdied by ld.so.
Can you use dlopen() without libdl.so on Linux? No. Can you implement dlopen() without _dlfcn_hook? Yes. Please note the "should", "must" and "how one particular implementation does" are different things.

Korona wrote:
Yes, the default linker script has a fixed base address. However, did you try changing it? If you change it, ld.so still works!
So does my dynamic linker. And? This does not prove that there are no alternatives to auxvector!

Korona wrote:
What AT_SECURE does is well-documented. I refer to the man page of glibc's ld.so.
Interesting, that man page does not say ELF auxvector must be placed on the stack. It only mentions that on Linux, secure-execution mode is queried with getauxval, which in turn does not say nothing about stacks either, but it clearly states that "This function is a nonstandard glibc extension.". The emphasis is on the word "nonstandard" here.

Korona wrote:
ELF is almost only about the SysV ABI. All other ABIs are variations of the SysV one (i.e. the SysV ABI has index zero for a reason). Which OS uses a fundamentally different ELF ABI?
One last time, ELF != SysV ABI. Think about GNUEFI. Their build system does not link PEs. Instead, they create an ELF with UEFI ABI, and they convert that into a PE as a last step. They can do that despite there's no ELF_OSABI_UEFIABI specified in the ELF spec. Yet it is possible, and GNUEFI works remarkably well.

Please think about what I've said. There are plenty of evidence that your way is not the only way. Try to accept that.
I'd like to encourage hobby OS developers not to follow the half-century old path. The whole reason for hobby OS developement is education and to go boldly where no OSdev has gone before.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Wed Feb 13, 2019 10:12 am 
Offline
Member
Member

Joined: Fri Nov 17, 2006 5:26 am
Posts: 34
I have a follow-on question if I may.

If Windows, OS/2 and Linux had all used ELF32, but with their different ABIs, is there something inside the ELF format that lets you know what ABI is being used?

Because if I wanted PDOS/386 to run all of Windows/OS2/Linux binaries, and they all happened to be ELF, how would I be able to tailor the passed parameters to the executable?

Thanks.


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Wed Feb 13, 2019 10:30 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 582
Yes, the is a field in the header.

@bzt
Let me repeat the facts one more time: No, it is not possible to implement dlopen() in the SysV ABI without communicating with the dynamic linker. And yes, if your linker uses anything other than the stack-stored auxv, it does not conform to the ABI. I will not repeat the arguments; they have been posted and stem from the spec (a section number has been cited). Claiming anything else is a blatant lie and denialism.

And no, we're not talking about if there "is another way". We are talking about what the spec prescribes. There is no room for interpretation here.

As for the rest, I will call our your ad-hominems for what they are: flaming and trolling. I will report them accordingly to moderation. You are trying to belittle both my intelligence and my capability as an OS developer. I will not play into, but let my accomplishments, both as an OS developer and as a CS researcher, speak for themselves.

bzt wrote:
Please do not confuse beginners with half-thruths and misinformation. Thanks.

bzt wrote:
Please note that I don't really expect answers. I asked them just for your benefit, to make you think. It seems you can't accept the facts from me, that's ok I can relate. Maybe if you ask those questions to yourself, you'll find the correct answers on your own.

bzt wrote:
Oh you poor lad. If there's something you can't image, then that's impossible? Your way is the only way?
I feel sorry for you, so I try to explain this one last time.

_________________
managarm: A microkernel-based OS that is capable of running a Wayland desktop


Top
 Profile  
 
 Post subject: Re: linux a.out
PostPosted: Fri Feb 15, 2019 7:56 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9284
Location: On the balcony, watching the Swedish Chef
I've had a look at the chain of custody: The 'proof' linked claims to be the "C ABI", or rather a C ABI since this definitely isn't Microsof's C ABI. It also references being an extension to the 32-bit version, which explicitly mentions the Linux ABI. While these are a de-facto standard, these remain the Linux extensions of the System V ABI. Treat them as such.

dlopen is not in the original SysV abi. The auxiliary vector is part of the standard but simply chucking enough NULLs on the top of the stack already makes you compliant.

And of course, feel free to use the file format in different ways. Linux is not considered to be a particularly good example.

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 15 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group