PE/COFF for MIPS

Hi. Is it possible to have a clang/llvm build that both would support
MIPS architecture and PE/COFF format for object files and executables?
without the need to change the code base, of course. just with proper
configuration. So that one can use PE DLL import/export for modules
instead of ELF shared objects. Initially I have been thinking on
creating an ELF->PE translator, but it quickly became obvious, that
it's not practical - because it's the compiler, that needs to
understand declspec(dllimport/dllexport).
I am not a compiler guy, so making changes in such huge projects as
gcc or clang are out of my scope. I am working on firmware/osdev hobby
projects for a mips32r2 board (among ARM ones) and would be very happy
to use such a familiar, useful and handy PE/COFF format for
executables.

Hi,

I think it's a rather difficult task. We need to create COFF object
file writer for MIPS backend and support linking of COFF files in LLD
linker. Now MIPS backend expects ELF output format only. For COFF we
also have to change a code generator because some features cannot be
implemented in COFF.

I think there's also a broader question of 'which COFF'. A lot of the LLVM code assumes that COFF approximates to Windows. If the goal is to target NT 4 or WinCE, which both had MIPS ports, then it's some work but it's largely a matter of adapting the code in the x86 and ARM back ends. There are (were?) also a number of *NIX MIPS systems that used COFF as their binary format and these have very little in common with the Windows format (other than the container structure). Relocation types are different, the C++ ABI is different and there are probably some other differences. If this is for a hobby OS, what are the requirements?

As I recall, Sony has some changes to clang/llvm/FreeBSD-rtld to support dllimport / dllexport in ELF binaries. If this is the requirement, then perhaps asking them to upstream them would be a simpler solution? As I recall, they were private because they didn't think anyone else wanted them, rather than because they involved any competitive advantage.

David

If you have a choice in the matter, just use ELF. It’s the most well-trod path.

Up to this point in your message, I thought you might be trying to target Windows NT for MIPS with a modern compiler. I suspect in that case what you’d want to do is look at how the PE/COFF support is implemented for Windows 32- and 64-bit x86, and see how much of that could be generalized to “any Windows platform.”

  -- Chris

Thank you all for your replies.

To David.

If this is for a hobby OS, what are the requirements?

The requirement would be "pretty much the same as Windows NT for MIPS has".

To Chris.

If you have a choice in the matter, just use ELF. It’s the most well-trod path.

Let's take shared objects. I want to make the kernel modular - not
with just object files delay-linked, but as real modules which can
import/export and be easily loaded, unloaded. they would be loaded
into "the same" kernel part of any process address space, why do I
need PIC? it's just a waste of CPU in this situation. there no
advantage of having them PIC. but can I make shared objects non PIC?
still capable of importing from and exporting to other modules - not
just kernel, with interdepencies, is it possible with such imaginable
ELF non-PIC shared objects? If I will use ELF "executable" for them, I
frankly have no idea of how then make them import/export without ugly
trickery. Of course, I lack skilled knowledge of all the nuances of
ELF, maybe it's doable and I hope so, as a temporary solution, it
still looks much optimistic than modifying clang/llvm, which I'd
happily do if it weren't a gigantic thing one needs to spend a lot of
time staring at just to have a slight idea of its nature.

My OS is going to be NT-like and have WinAPI-like environment. So,
it's like Windows appeared again on MIPS, right. :smiley: would it be too
hard for one to "look how it's done for the x86 and generilze
farther"? Actually, it was my initial question, I just forgot to say
that the platform is "like Windows".

And yet. Say, I reached the stage, where I want to bring a compiler
for my OS. Is clang/llvm friendlier to WinAPI platforms, than gcc for
porting to a WinAPI-like environment? meaning does this port relies on
WinAPI in as much respects as any native program would have, written
for that API or does it demand that the environment looked like POSIX?
I mean, why gcc needs those MinGW/Cygwin stuff instead of just using
what is on the platform - after all a compiler requires not much from
the host system.

My OS is going to be NT-like and have WinAPI-like environment. So,
it's like Windows appeared again on MIPS, right. :smiley: would it be too
hard for one to "look how it's done for the x86 and generilze
farther"?

It's not very hard but requires some work. The same has been done for AArch64 in the last few years - see e.g. 0c72172e320f77380ad2562d2dfe1abb14a25e1c for the initial commit for that effort.

And yet. Say, I reached the stage, where I want to bring a compiler
for my OS. Is clang/llvm friendlier to WinAPI platforms, than gcc for
porting to a WinAPI-like environment? meaning does this port relies on
WinAPI in as much respects as any native program would have, written
for that API or does it demand that the environment looked like POSIX?
I mean, why gcc needs those MinGW/Cygwin stuff instead of just using
what is on the platform - after all a compiler requires not much from
the host system.

If we first put Cygwin aside - gcc doesn't need cygwin for targeting windows - Cygwin is there for being able to port apps that use a lot of POSIX specific APIs to run on top of Windows.

GCC doesn't really need MinGW because of a need to generate calls to POSIX like APIs; after all, the compiler generally generates very few calls to system functions automatically.

In that respect, GCC primarily needs MinGW for two or three reasons: First, because the official Windows SDK isn't redistributable and free software - so MinGW fills the role as a freely redistributable reimplementation of a Windows SDK. And secondly, the Windows SDK headers use a number of MSVC specific language extensions which GCC doesn't support, so in that respect, MinGW is an SDK with GCC friendly headers.

On top of that, MinGW provides just a couple extra POSIX-derived APIs (usleep, getopt and a couple ones - that don't require a runtime but that just are statically linked) for easing porting of some apps, not strictly necessary for GCC for generating code for it (but maybe useful for building GCC itself for that target).

Clang and LLVM can emulate both GCC and MSVC personalities in this aspect, so I'd say it's a good place to start off, so you have all options available. And speaking from experience, I'd say it's fairly straightforward to add support for windows style COFF on a new architecture in the LLVM libaries and tools. Although I haven't really made an equally big effort in GCC/binutils so I don't know for sure, but initial peeks into it made it look like a much more complex task there.

// Martin