Sign in Join
Wiki copytemporary

Mach-O: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11*(macOS only)*
22
33*Mach-O, short for Mach object file format, is a file format for executables, object code, shared libraries, dynamically-loaded code, and core dumps. A derivation of the a.out format, Mach-O offered more extensibility and faster access to information in the symbol table.* Source: [Wikipedia](http://en.wikipedia.org/wiki/Mach-O).
44
55The Apple file format reference can be found [here](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/CodeFootprint/Articles/MachOOverview.html)
66
77The following tools are used in macOS to view Mach-O files:
88
99**otool** - object file displaying tool
1010
1111**nm** - display name list (symbol table)
1212
1313## Objective-C segment
1414
1515There is no documentation about __OBJC segment and its sections. The following information has been gathered from cctools [sources](http://opensource.apple.com/source/cctools/cctools-667.3/)
1616
1717### Structures strings
1818
1919Some structures in sections contain name pointers. These names are stored in the c-strings section (segment: __TEXT; section: __cstring). The file offset for the string name can be evaluated in the following way:
2020
2121`string_file_offset := cstr_section.offset + (name_addr - cstr_section.addr);`
2222
2323## Sections
2424
2525### __image_info
2626
2727The section contains only the image info information:
2828
2929`imageInfo = packed record`\
3030`  version : uint32_t;  // zero`\
3131`  flags   : uint32_t;  // for objc 1.0 - zero`\
3232`end;`
3333
3434Flags values:
3535
3636`ImageInfo_F_and_C = $01;`\
3737`ImageInfo_GC      = $02;`\
3838`ImageInfo_GC_only = $04;`
3939
4040### __module_info
4141
4242(objc_module record is declared at objc headers).
4343
4444The number of objc_module structures depends on the number of .m files with objects declarations compiled. _symtab contains the number of classes and categories declared in the module.
4545
4646`objc_module = packed record`\
4747`  version : culong; // version number = 7 `\
4848`  size    : culong; // sizeof(objc_module)?`\
4949`  name    : PChar;  // virtual memory address of the module name`\
5050`                    // Usually mapped to NULL string`\
5151`  _symtab : Symtab; // virtual memory address of a proper objc_symtab structure (in __symbols section)`\
5252`end;`
5353
5454### __symbols
5555
5656the section contains symbol table for a module. (symtable record is declared at objc headers)
5757
5858` objc_symtab = record`\
5959`   sel_ref_cnt : culong;  // zero`\
6060`   refs        : PSEL;    // zero`\
6161`   cls_def_cnt : cushort; // number of declared classes in the module`\
6262`   cat_def_cnt : cushort; // number of declared categories`\
6363`   defs: array [0..cls_def_cnt+cat_def_cnt-1] of Pointer; // array of virtual address of declarations`\
6464`      // 0..cls_def_cnt - 1           : virtual address of class declarations (in "__class" section, can be empty)`\
6565`      // cls_def_cnt..cat_def_cnt-1   : virtual address of categories declarations (can be empty)`\
6666` end;`
6767
6868### __class, __meta_class
6969
7070*the section may omit, if none of modules declare any custom classes*
7171
7272Both sections use identical structure objc_class. (objc_class record is declared at objc header) Objective-C classes are declared in pair with their meta_classes.
7373
7474`objc_class = record`\
7575`  isa           : PChar;   // for class declaration: virtual address of meta-class declaration`\
7676`                           // for meta-class declaration: virtual address of "NSObject" string?`\
77-\
77+
7878`  super_class   : PChar;   // contains the pointer to super_class name`\
7979`  name          : PChar;   // pointer to class name        `\
8080`  version       : PChar;   // = 0 (for obj-c version 1?)`\
81-\
81+
8282`  info          : culong;  // CLS_CLASS for classes`\
8383`                           // CLS_META  for meta-classes `\
84-\
84+
8585`  instance_size : culong;  // size of the instance:`\
8686`                           // class: size of the class instance `\
8787`                           // meta-class: 48 bytes `\
8888`                           `\
8989`  ivars         : Pobjc_ivar_list;       // virtual address of objc_ivar_list (stored in "__instance_vars" section)`\
9090`                                         // meta-classes don't have ivars list (=0)`\
91-\
91+
9292`  methodLists   : PPobjc_method_list;    // virtual address of objc_method_list`\
9393`                                         // class declaration has instance methods list (stored in "__inst_meth" section)`\
9494`                                         // meta-class declaration has class methods list (stored in "__cls_meth" section)`\
9595` `\
9696`  cache         : Pobjc_cache;           // zero`\
9797`  protocols     : Pobjc_protocol_list;   // pointer to protocols list. (stored in "__cat_cls_meth" section)`\
9898`end;`
9999
100100### __instance_vars
101101
102102*the section is optional and may omit if none of classes declares instance variables*
103103
104104The section consists of number objc_ivar_list structutres. The number of structures depends upon number of declared classes using instance variables. (objc_ivar_list is declared in objc header)
105105
106106`objc_ivar_list = record`\
107107`  ivar_count  : cint;   // number of variables in the list`\
108108`  ivar_list   : array[0..ivar_count-1] of objc_ivar;  variable length structure }`\
109109`end;`
110110
111111`objc_ivar = record`\
112112`  ivar_name   : PChar; // vm addr of the variable name`\
113113`  ivar_type   : PChar; // vm addr of obj-c variable encoded type `\
114114`  ivar_offset : cint;  // offset from the start of the instance. (the lowest ivar_offset is 40,`\
115115`                       // because sizeof(objc_class) = 40, and objc_class is also part of the instance)`\
116116`end;`
117117
118118### __inst_meth, __cls_meth
119119
120120*the section is optional and may omit if none of classes declares any methods*
121121
122122Both section has identical format. They contain number of objc_method_list records. Number of records is depending on classes declared in modules.
123123
124124`objc_method_list = record`\
125125`  obsolete     : Pobjc_method_list;  // not used, always zero`\
126126`  method_count : cint;               // number of objc_method in method_list array `\
127127`  method_list  : array[0..method_count-1] of objc_method;  `\
128128`end;`
129129
130130`objc_method = record`\
131131`  method_name   : SEL;   // virtual address of the selector name `\
132132`                         // (selector name is stored as other names is in __TEXT __cstring section)`\
133133`                         // selector name is short: i.e. "methodName:", and not "+[className methodName:]"`\
134134`  method_types  : PChar; // obj-c encoded function parameters `\
135135`  method_imp    : IMP;   // virtual address of method implementation function entry point (in __TEXT __text section)`\
136136`end;`
137137
138138### __protocol
139139
140140### __cat_cls_meth (protocols list)
141141
142142### __cat_inst_meth
143143
144144### __cat_cls_meth
145145
146146## Mach-O additional 30Kb size
147147
148148FPC built mach-o executables are somehow larger, compared to the win32 target, for example
149149
150150`begin`\
151151`  writeln('hello world');`\
152152`end.`
153153
154154gives a 30k (stripped) executable for Win, and 60k for macOS.
155155
156156Jonas Maebe: *It's because there was a bug in older versions of the Darwin linker that required adding ".reference" assembler directives for routines that have more than one assembler name (most of the compiler helpers in the RTL have that). This fixed the problem, but as a result they are never smart linked out. It's only a fixed overhead of that 30kb (most programs don't contain any extra routines with multiple assembler names)*
157157
158158FPC 3.3.1 (trunk r44876) produces a 64 bit binary of 427,920 bytes; add -XX to smart link and it is reduced to 55,656 bytes; now strip it and it's just 47,224 bytes (~46K) which is pretty reasonable.
159159
160160---
161161*From the Free Pascal wiki, page "Mach-O", as it stood on 2020-05-17 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
162162Category: macOS

Back to history