The Dwarfs Mac OS
(From Jason Molenda -jmolenda at apple.com)
Until 2005 (or was it 2005?) we only used stabs for debug info on our platform. We use gcc and gdb as our main system's compiler and debugger -- those were ready to support DWARF already, with small tweaks to work with the Mach-O file format, but our linker (the assembler based on a very old GNU as, the linker homegrown) wasn't even close. The linker work needed to do a standard DWARF process was going to be very hard for us to schedule so we looked at other possible solutions.
38 Games Like The Dwarves for Mac OS X Game Cupid 38 Games Like The Dwarves for Mac The Dwarves is a fantasy role-playing game with a strong story and tactically challenging real-time battles. 15 playable heroes, each with individual skills, are to be deployed cleverly. Download Fable of Dwarfs 2.0 for Mac from our software library for free. The application lies within Games, more precisely Strategy. The latest installer takes up 284 KB on disk. Can you mow? mac os. The most popular version among the program users is 2.0.
Our final solution was to segregate executable linking and debug info linking into two separate actions. We have already seen examples of binaries that have nearly a gigabyte of debug information -- and at the same time, we're very focused on the compile-link-debug turnaround time for our development environment. And we very much wanted to take advantage of the vendor extensibility of DWARF to add more information in the future. Forcing all of this data through the linker -- when the linker was the least parallelizable step of the compile-link-debug cycle -- was destined to be a losing proposition.
The first half of our solution is to leave the DWARF debug information in the .o files, much like Michael implemented at Sun many years ago. The addresses in the .o files bear no resemblance to the final executable of course -- we have the linker synthesize some 'debug map' entries (really just nlist stabs records - the toolchain knows how to handle stabs very well already so there wasn't any compelling reason to come up with a new format). For those familiar with stabs, there's no surprises - here's what a source file called 'a.c' with one function, main(), defined looks like in the final executable binary:
The 'OSO' stabs (like the SO stab but for a .o file, hence OSO) provides a pointer to where the object file is located. The SO stabs tell us what source file this corresponds to so we can read just the a.o debug info when the user asks to put a breakpoint on file a.c line 10. The FUN stabs tell us the start address and length of the main() function.
The second half of our solution is to create a dedicated DWARF linker. This is critical to being a fully fledged solution -- the program 'dsymutil' on our platform uses the executable, its debug map entries, and the .o files listed therein, to create a single DWARF debug info file with all fo the addresses mapped to their final addresses. This debug file is separate from the executable binary itself. On Mac OS X we have the concept of a 'bundle' which is a directory containing multiple files related to a single entity. For instance, an application on our platform is in an 'app bundle' -- in the app bundle you'll find the executable, the localization strings, help text, etc, all in a single directory that can be moved around the filesystem. We put the debug info file in one of these bundles, we call it a dSYM bundle.
As I mentioned earlier, the creation of the dSYM bundle was critical to make this a usable solution. Without a way to collect all of the debug info into a single binary, you have no way to save a binary & its debug info in a release without tarring up all the .o files or something similar. If you want to copy a debuggable copy of a program to another system you'd need to drag the binary and all its .o files along with it -- and keep them in the same file path or have a way to override that in the debugger.
Developers aren't used to keeping a binary and its debug info in step so we added some safeguards to catch mistakes. In the debug map entries, we include the modification time of the object file in the stab entry. If someone has rebuilt a .o file but not the executable, we ignore that debug information - it's a better failure mode than assuming the debug info is usable and getting subtly wrong debugger behavior.
The second safeguard we added was to stamp every binary we create with a 128-bit unique identifier (the LC_UUID load command). When a dSYM is created by dsymutil, this uuid from the executable is copied into the DWARF binary. This give us a reliable way to tell if a given binary and given DWARF info are correct for one another. As useful as it is to protect our users from adding the wrong debug info, it has proven to be a great help for FINDING the debug info for a binary. We include many different ways to find the debug info for a binary. The simplest is to look for the dSYM bundle next to the binary. The next is to use a system-wide service on Mac OS X called 'Spotlight' which indexes all the files on the computer and can do very quick lookups; we have an importer for Spotlight which records the uuids of any dSYM bundles on the system. The user can also define their own lookups: A list of directories to look in for dSYMs, or an external program to locate a dSYM, for instance.
In any of these examples the names of the executable and the dSYM are irrelevant -- the only thing used is the uuid in the executable binary. The debugger asks for a dSYM for a uuid and one of these methods returns a path to the matched dSYM.
The result of this is that users are often unburdened of keeping their executable and dSYMs together, or in The Right Place -- if the dSYM is sitting somewhere on their computer, we discover it without their intervention. The ability to call out to a program to find the dSYM allows us internally to do something really cool: We have the dSYMs for every binary in our OS, of course, maintained by our OS build organization. We have a program that puts all the uuids of those dSYMs in a little SQL database and another program that gdb can call to find. When you have this program registered in gdb's lookup scheme, and you launch a random process, you find that you have debug info for every frame in the stack, regardless of what library it came from. We wrote all of this intending that other organizations would want to do the same - it's a pretty simple interface.
Our debugger has two ways of processing DWARF: One for DWARF in .o files and one for DWARF in a dSYM bundle. For dSYMs, there are only a handful of changes from normal gdb's behavior - all of the addresses have been remapped to their final locations by dsymutil so it's just a matter of reading the DWARF out of a separate file. In the .o file location, gdb needs to do the address translation on its own. When we start gdb on such an executable, we read the debug map (the stabs entries) out of the executable and create an address translation map for each .o file specifying what address the symbols landed at. We read the pubtypes sections from the .o files so we have a global view of types, and that's it. We don't read any of the debug info in the .o files until individually needed. We found the time to ingest the pubtypes sections from the .o files to be very fast so we didn't try to come up with a way for the linker to include type information in the executable.
The translation of addresses in the debugger is generally straightforward -- some functions in the .o file may not make it to the final executable, of course. We process the DWARF in the .o file as you normally would but all addresses go through the translation table so they're changed to their final values. 'common' symbols (global data not initialized to a value which all have an address of 0 in the .o file) need a little bit of extra care; in gdb I use the names of the symbols to process them. Greg Clayton wrote dsymutil and he uses some additional relocation information from the binary to do them; both approaches work fine. I only had easy access to the nlist records in gdb so the approach I used made more sense there.
The Dwarfs Mac Os Catalina
In a nutshell, that's everything that comes to mind about our approach. We implemented the basic scheme a few years back and have switched over all our tools to using it for a while now -- the most recent Mac OS X OS release (10.5, 'Leopard') was all using DWARF with this setup. The only unfinished bit I can think of is that I haven't gotten CFI for DWARF in .o files to work yet -- but we don't use CFI to do our backtraces by default on our platform yet because there are a couple of shortcomings in gcc's output so it hasn't been a priority by any means. I've put a good amount of effort into overhauling gdb's backtrace scheme for our i386/x86_64 back-ends so we usually OK without CFI/EH frame info.
There are some wrinkles with kernel extensions ('kexts') on our system that took some effort to handle correctly with our DWARF scheme. I won't go into it, kexts are very unusual.
One benefit to having our DWARF debug info in a dSYM bundle (a directory) instead of just a plain file is that we have the option of including additional data in there as well. You could envision putting a copy of the source code in the dSYM bundle too, maybe xar'ed and compressed, and having the debugger expand it as-needed when debugging.
The uuids in the binaries has proven to be a real boon across the organization. It doesn't provide the features that crypto signing binaries does (we do that on our platform as well) but it does disambiguate binaries very nicely. On our platform when we generate a crash report we include the name of each binary/library, its load location, and its UUID. We include the overall system version # but if the user has installed some binaries on their own, or an update did not complete successfully, we've got everything we need to detect what happened. Define royal flush. It also aids in automated symbolication of such crash reports; no one has to figure out what debug info the crash report should be symbolicated against, it's declared right in the text via the uuids.
Anyway, I think that's it. While I'm impressed with the work Cary has been doing these past few months, we decided that getting the linker out of the DWARF business altogether was the way to go -- we get dramatically faster turnaround on incremental builds when the developer is waiting for the computer, and although the separate debug info file seems like a drawback at first, we've been able to use the uuids to solve lots of long-standing problems and I suspect we'll be using the dSYM bundle scheme to interesting effect in the future; putting the DWARF in there was just our first step.
If anything isn't clear just give me a shout and I'll try to be clearer. I kind of threw this together at the end of a long day and I've got an early morning tomorrow. :)
Welcome to the FreePascal on the Macintosh page. Here is information especially for you who want to write a program for the Macintosh.
News:
2009-02-09:The download statistics indicate that the snapshots below are still downloaded a lot. Note that all fixes from those snapshots are also in the official release of FPC 2.2.2 (and will be also in later versions, when they become available), which was released in August 2008. Since FPC 2.2.2 also contains many additional fixes, we recommend you to use that version. It is available from the regular download pages.
2007-11-14:There are some errors in the new linker shipped with Xcode 3.0/Mac OS X 10.5. A detailed overview was posted to the fpc-pascal mailing list. We have worked around most of those issues and created (stable) development snapshots for both PowerPC and Intel. These are intended to be installed on top of the 2.2.0 release version. Future releases will have these fixes incorporated.
One linker bug cannot be completely worked around in the compiler, which is related to the Stabs debugging format. For this reason, we recommend to switch to the Dwarf debugging format on Mac OS X 10.5. On the command line, you can do this by using -gw instead of -g to generate debugging information. In the Xcode projects, add -gw at the end of the FPC_SPECIFIC_OPTIONS project setting for the Debug configuration.
2006-08-27:Regular snapshots of FPC 2.1.1 (both for PowerPC and for Intel - the latterdenoted as i386) are now generated by and available from the Lazarus team.
If you only need the compiler (to either use it from the command line or from Xcode),you only have to download and install the 'fpc' package.
2005-12-18:
Version 2.0.2 that was released a few weeks ago has all fixes and improvements of the 2.1.1 snapshot that was here (like Mac Pascal style objects and creationof dynamic libraries). Additionally, it doesn't suffer from the installationproblems the 2.1.1 snapshot installer had. Get the release here.
2005-07-23:
The 2.1.1 snapshot that was here is no longer available.
If you really need to be up to date with FPC,please consider using Subversion, and build the compiler by your self.
Some changes:
- No more '_main' symbol in the system unit (so can link with C main programs)
- Shared library creation support under Mac OS X
- Several bugfixes related to overflow checking on PPC
There is now a wiki page covering porting issues, from traditional mac pascals to FPC.
2005-06-21:
A FPC 2.1.1 snapshot is available here (10.8 MB, does not include the PDF documentation). It includes:
- Support for Macintosh Object Pascal in Macpas mode (includes support for mixing in Delphi-style OOP programming in Macpas mode, except that you have to use 'object' instead of 'class' everywhere -- all occurrences of 'class' are simply internally replaced by the _OBJECT compiler token)
- Fixed bug which caused stack corruption in procedures receiving floating point parameters and parameters on the stack (only if the caller side was compiled by FPC)
- Fixed bug in overflow checking of integer operations (some calculations were buggy if overflow checking is turned on, which is the case in the default development building style of Xcode if you use the integration kit)
- Fixed bug in division of unsigned numbers > $7fffffff by a power of 2
2005-05-15:
At last !!!!! Free Pascal 2.0 is released for Mac OS X and classic Mac OS,as well as for other targets.
This means Free Pascal for the mac is not considered beta anymore.Get it on one of the mirror download sites.
Targets on the Macintosh:
Target / Processor | Status | Remark | Contact |
---|---|---|---|
final | For Mac OS X | ||
final | Target Mac OS means classic Mac OS, up to System 9.x. Although it of course also work in the classic environment in Mac OS X | ||
Mac OS on M68K | not planned | If someone is interrested to contribute, there is a possiblity to implement this target. There is support for MC68000 in the FPC source code, although not updated for a while. |
Mac Pascal dialect
The dialect of Pascal supported by popular Pascals on Macintosh is supported in part. Read more here.Free Pascal 2.0 for Mac OS X is the current release. It should at least work on Mac OS X 10.1 and higher. It requires that you have installed XCode from Apple, to have assembler, linker and make tools available to fpc. For older versions of Mac OS X you should install Apple Development Tools instead. Both can be downloaded for free from Apple, but requires that you register yourself as a member of Apple Developer Connection. Both are also included in the Mac OS X bundle.
To download, go to the Download page, and choose a mirror site near you (to limit net traffic). The documentation is included, but can also be downloaded separatelly. If you want the source code, it has to be downloaded separatelly.
There most recent FPC 2.1.1 snapshot is available here (10.4 MB)with, among others, support for mac style object pascal. See above under NEWS.Mac Os Versions
Note that the compiler is a unix style program and is run from the Terminal on Mac OS X.
Please report any bugs encountered.
Using FPC from XCode
It is possible to use Free Pascal from within XCode (Mac OS X 10.3 is required).Look at the step-by-step instruction of how to download and install the XCode Integration Kit. Thanks to Rolf Jansen for this contribution.Free Pascal 2.0 for Mac OS is the current release. It will work on latest classic Mac OS (that is 9.2.2) and below, probably down to 7.1.2 (the first Mac OS for PowerPC), and also in the classic compatibility environment on Mac OS X. However it has only been tested on Mac OS 9 and Mac OS X classic environment.
It requires that you have installed Macinstosh Programmers Workshop (MPW) which can be downloaded for free from Apple.
To download, go to the Download page, and choose a mirror site near you (to limit net traffic). The documentation, as well as the source code (if you need it), has to be downloaded separatelly.
Note that the compiler is an MPW tool. Ice cream parkour mac os.
Please report any bugs encountered.
Current status of classic Mac OS
Native FPC compiler (as an MPW tool) | Almost complete | |
Unit System.pp | Complete | The system unit is implicitly used by every program. Contains basic file and memory handling among others. |
Unit Dos.pp | Complete | Contrary to what its name suggests, the DOS unit is cross plattfrom and contains utility routines for file and date handling, beyond that in System.pp. It is reminiscent from Turbo Pascal. |
Unit Sysutils.pp | Planned | A moderner alternative to unit DOS, compatible with Delphi. |
Unit MacOS | Complete | API to the Macintosh Toolbox |
Units strings objpas heaptrc getopts etc | Implemented. | They are target independent. |
Other units | Non-existent. Some will be implemented. | Implementation will depend on how important the unit is and if difficulties arise. |
Debugging
There is some limited possibilities to debug programs in classic Mac OS. See MPW debugging in the wiki.
As an alternative, you might do the main debugging in a Mac OS X/Darwin version of your program.
There are three major Pascal dialects: Turbo Pascal (extended to Delphi, supported by FreePascal, and partially by Gnu Pascal), Extended Pascal (an ISO standard, supported by Gnu Pascal, DEC Pascal, Prospero Pascal), and the dialect originating from Apple (commonly used in the Mac community, supported by MPW Pascal, Metrowerks Pascal and Think Pascal). We call this dialect Mac Pascal and there is a special language mode for it: MacPas.
Mode MacPas is a compatibility mode. It is probably not possible to mimic the Mac Pascal dialect in detail. So the goal is to implement often used constructs, if this doesn't require too much effort, as well as easy-to-implement constructs.
To use MacPas, add -Mmacpas to the command line or insert the compiler directive {$MODE MACPAS} in the source code.
Note that the mac pascal dialect and mac targets are not interrelated. It is thus possible to write a mac program with the turbo dialect and to write a Windows program with the mac dialect.
The following are supported: Mac compiler directives like $SETC, $IFC, $ELSEC, $ENDC, $J, $Z. Most of the constructs found in interface files, especially Apples Universal Interfaces. Cycle, Leave, Otherwise. More is planned.
More updated info on the Wiki page.
By Olle Raab
For questions and suggestions, we suggest subscribing on our mailing lists , in particular FPC-pascal for questions about using Free Pascal.
The Dwarfs Mac Os 11
Or write to olle.raab@freepascal.org
Mac Os Mojave
Latest modified 2005-07-28