16-bit obj files VC++ - visual-c++

How do I compile my VC++ project to a 16-bit flat object file for use in my bootloader I am working on?
To my understanding, an object file is technically already "flat" and the linker turns it into the destination executable format. What I want it to be able to obtain that object file and pass that and my assembly code (in obj format) through the linker to create a flat bootloader.
The [guide][1] is not very specific on where the files are located and just says that you use cl.exe, link.exe, and ml.exe (MASM).
The guide uses MASM, but I know how to output object files with NASM. My main problem is the VC++ thing.

The last 16-bit compiler from Microsoft was VC++ 1.52c. It's ancient, and probably not available any more. Even if it was, chances are pretty good that it wouldn't compile any recent code. Just to name a few of its most obvious shortcomings, it had no support for templates, exception handling, or namespaces at all.
I believe most people working on things like that any more use Open Watcom (which isn't exactly up to date either, but still better than VC++ 1.52c).

Related

How to use assembly code you get online?

I have some C code I would like to optimize. It turns out the Intel C Compiler (ICC) does a much better job at this than GCC but I don't have a copy of that compiler and it is very expensive. However, I can compile it using ICC and get the assembly online at godbolt.org.
If I copy and paste this assembly into a text file, how can I then convert it into a functioning executable?
You will need to begin by making sure that the runtime environment for which godbolt.org compiles is similar enough to your runtime environment, (good luck with that,) because for example you may be using windows, and godbolt.org may be using linux, (or the other way around,) so when you bring the assembly to your system you might be able to convert it to object code, but it will still not link and it will not run.
Then you will need to find an assembler for your platform which is compatible with the syntax of assembly produced by the intel C compiler of godbolt.org so as to produce object files from the assembly files. (Good luck with that.)
Then you will need to find any and all runtime libraries (redistributables) required by code produced by the intel C compiler. (Good luck with that.)
Finally you will need to obtain a linker to link your resulting object files with the runtime libraries to produce an executable. (Good luck with that.)
Sometimes we need honest answers to our questions just so that we can realize how impossible our ideas are.

Why are C/C++ 'obj' files valid only for a specific compiler?

After much struggling with attempting to link a C++ project to a 3rd party static library (.lib), I think I have solved the issue by verifying that I compile my project using the same compiler in which the .lib file was compiled (MSVC11).
Until this point, I assumed all .obj files were equivalent, thus I could take a .lib file (containing various .objs), and use that with any other project I might want to develop in the future. However, this was an incorrect assumption.
So I'm curious as to why (in the context of MSVC) .obj files differ from one version of the compiler to the next. Assuming you're targeting an x86 application, shouldn't the obj files be comprised of the same types of instructions regardless of whether or not you compiled using MSVC11/12/14?
TLDR; Why can't I link a project to an .obj that was created using a different MSVC compiler?
That's because it could be linked to another version of Visual C++ runtime libraries, which is incompatible with the version you are using.
This problem could be even with DLLs if you try to expose C++ objects from it.

AVR Assembler in Linux

I'm trying to learn AVR development in C and Assembly for the Arduino Uno (Atmel 328p microprocessor) in Linux.
I've found many good guides on how to install and setup the AVR plugin for Eclipse, and I've no problem building and uploading C code. However there doesn't seem to be any menu options for creating an assembler project, nor can I seem to find the correct syntax for using the cli avr-as for assembling my programs into a .hex file.
You have a couple choices. I don't know about eclipse, (I just use vim and make directly) but the compilation procedure should be the same.
You can:
Write a mostly C project, in-lining whatever assembly you want. This is usually the easiest method. Check out the AVR-GCC Inline Assembler Cookbook.
Write a purely ASM application that doesn't use the linker at all. e.g. a one-file application (or one file that directly includes the rest of the project explicitly). You'll have to tell your build tool what to do to process the file, but it can be as simple as one invocation of avra or avr-as. You must be sure to carefully do all the low-level initialization and build a complete interrupt vector table for the MCU you're using, or you may get unexpected behavior.
Write a mixed C and ASM application linking between object files from both languages. To do that you do the same thing you would for a pure C project, except some (maybe all) of your source files will need to be assembly. You'll have to tell your build tool how to assemble them in to object files. In a Makefile this would be writing the correct rule (or more likely setting up the ${AS} macro to use the correct assembler). In eclipse there is probably a project setting for it, but with any IDE YMMV. This is probably the hardest option, as you'll have to know the calling convention and ABI of your compiler to successfully execute your pure ASM code.

Finding the shared library name to use with dlload

In my open-source project Artha I use libnotify for showing passive desktop notifications to the user.
Instead of statically linking libnotify, a lookup at runtime is made for the shared object (.so) file via dlload, if available on the target machine, Artha exposes the notification feature in it's GUI. On app. start, a call to dlload with filename param as libnotify.so.1 is made and if it returns a non-null pointer, then the feature is exposed.
A recurring problem with this model is that every time the version number of the library is bumped, Artha's code needs to be updated, currently libnotify.so.4 is the latest to entail such an occurance.
Is there a linux system call (irrespective of the distro the app. is running on), which can tell me if a particular library's shared object is available at runtime? I know that there exists the bruteforce option of enumerating the library by going from 1 to say 10, I find the solution ugly and inelegant.
Also, if this can be addressed via autoconf, then that solution is welcome too I.e. at build time, based on the target machine, the configure.h generated should've the right .so name that can be passed to dlload.
P.S.: I think good distros follow the style of creating links to libnotify.so.x so that a programmer can just do dlload("libnotify.so", RTLD_LAZY) and the right version numbered .so is loaded; unfortunately not all distros follow this, including Ubuntu.
The answer is: you don't.
dlopen() is not designed to deal with things like that, and trying to load whichever soversion you find on the system just because it happens to have the symbols you need is not a good way to do it.
Different sonames have different ABIs, and different ABIs means that you may be calling the same exact symbol name that is expecting a different set (or different size) of parameters, which will cause crashes or misbehaviour that are extremely difficult do debug.
You should have a read on how shared object versions work and what an ABI is.
The libfoo.so link is there for the link editor (ld) and is usually installed with the -devel packages for that reason; it might also very well not be a link but rather a text file with a linker script, often times on purpose to avoid exactly what you're trying to do.

What's the difference between the OMF and COFF format?

Recently I've been maintaining a legacy project written in VC++ 6.0. The code uses so many unique characteristics of this compiler that porting it to a more recent standard compiler has proved to be an herculean task.
Among the thousands lines of code in the project, there are four assembler files. For some reason I don't understand, nor MASM615 nor TASM are able to compile them (they send errors), nevertheless I have the object files. However when I link the library I get a message
warning LNK4033: converting object format from OMF to COFF
The library works as expected, but I've been wondering what's the differences between these binary formats, or if I should expect something ugly from this conversion.
Answer nicked out of "MetaWINDOW FAQ - OMF vs COFF Object File Formats.htm"
Since the dawn of PC civilization up until about the time Microsoft Win32 programming tools came along, almost all PC compilers produced object files using the Intel Object Module Format (OMF) standard. Later, Intel introduced 386 processors and 32-bit protected-mode at which point they also expanded the OMF specification for 32-bits, leading to "OMF-386" which became the standard for most PC protected-mode environments. Around this same time, the original Windows NT development team was also designing code, not only for Intel processors, but also to support processors from other vendors. The Microsoft NT team selected a more portable object module format known as Common Object File Format (COFF) derived from the official object-code format for UNIX System V. COFF object modules later became the defacto standard for all Microsoft Win32 development tools, and gained an advantage in being much closer in format to Portable Executable files - the native executable format for Win32 (a COFF-format linker has much less work to create a 32-bit EXE or DLL from a COFF file than from an OMF format file).
Just as there are OMF- and COFF-format object files (.obj's), there are also OMF and COFF format library files (.lib's). The libraries, fortunately, are basically just a collection of the object files, along with some header information that lets the linker determine which object files to use from the library. To make things difficult however, both OMF and COFF use the same file name extensions, .obj and .lib, to reference the two different types of object and library file formats (because of this you can't just look at the file name extension to tell if the object module or library file is OMF or COFF).
The problem with mixing object files and library files from different compiler vendors is that some vendors support COFF, other vendors use OMF, and a few can handle both. Borland, for example, still uses OMF object files and libraries, while Microsoft's 32-bit compilers produce COFF format files. Watcom C/C++ v11.0 seems to prefer COFF when compiling and linking Windows applications, but generates OMF object files for use with their DOS4GW 32-bit protected-mode DOS-extender. Along with this, Microsoft MASM 6.13 produces OMF files by default, but with the /coff switch can emit COFF object files instead.
When it comes time to link files with different formats, different linkers do differnt things. For example, the Microsoft Visual C/C++ linker is designed for COFF format object files and libraries, but will try to convert OMF object files into COFF files if necessary. This works in some cases, but unfortunately Microsoft LINK does not support all OMF record types, so in many situations the linker may still fail when given OMF format object files. Also while Microsoft LINK attempts some support for OMF object files, it will refuse to process any OMF format libraries. Other linkers, such as Borland's TLINK, are designed for OMF object files and will similarly refuse to work with COFF-format object or library files. Some DOS extender and embedded system vendors, such as Phar Lap, provide their own linkers which support both OMF and COFF, giving you a choice.
The bottom line is that mixing OMF and COFF object and library file types can be a mess (plus the cryptic error messages from the linkers don't help). Unless your linker specifically supports it, you should stick with recommended object and library format for your compiler/linker/platform, and avoid mixing OMF and COFF files.

Resources