------ Tagged ld64-95.9
-2009-02-13 Nick Kledzik <kledzik@apple.com>
+----- Tagged ld64-96.5
- <rdar://problem/6543423> Back out Linker changes for H2 hang
- * src/ld/Options.cpp: remove fPreventPageCrossingBranches
- * src/ld/MachOWriterExecutable.hpp: remove layout of __text so there are not page crossing branches
- * src/ld/MachOReaderRelocatable.hpp: parse but ignore ARM_THUMB_32BIT_BRANCH reloc
+2009-07-28 Nick Kledzik <kledzik@apple.com>
+ <rdar://problem/7073626> Thumb mode compilation isn't working on 3.1 beta 2
+ * Fix instructions used in kBranchIslandToThumb1 case
+
+
+----- Tagged ld64-96.4
+
+2009-06-22 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6992387> platform linker should use platform ld_classic
+ * Fix Options::gotoClassicLinker() to use realpath()s
+
+
+2009-06-22 Nick Kledzik <kledzik@apple.com>
+
+ * Fix Options::setIPhoneVersionMin() to handle 2.x through 9.x
+
+
+----- Tagged ld64-96.3
+
+2009-06-17 Nick Kledzik <kledzik@apple.com>
+
+ * Change section sorting so that arm and ppc stub section is immediately after __text section
+
+
+2009-06-17 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6975041> don't use no-PIC stubs in any dylibs - it might conflict with codesigning
+ * In StubAtom<arm>::StubAtom() don't use kStubNoPIC for OS dylibs
+
+
+----- Tagged ld64-96.2
+
+2009-06-09 Nick Kledzik <kledzik@apple.com>
+
+ * Back out page-cross branch work around
+
+
+----- Tagged ld64-96.1
+
+2009-06-05 Nick Kledzik <kledzik@apple.com>
+
+ * Fix "duplicate symbol cache-line-crossing-stub" error by giving placeholders unique names
+ * Fix -pie by allowing relocs in x86 stubs and stub helpers
+
+
+----- Tagged ld64-96
+
+2009-06-04 Nick Kledzik <kledzik@apple.com>
+
+ * Darwin x86_64 static codegen is really dynamic code gen, so use LTO_CODEGEN_PIC_MODEL_DYNAMIC
+
+
+2009-06-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6945923> use lto_codegen_set_assembler_path()
+
+
+2009-06-03 Nick Kledzik <kledzik@apple.com>
+
+ * In src/ld/LTOReader.hpp, move where -save-temps .bc file is saved to be after code model set
+
+
+2009-06-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6806033> Link Time Optimization error with 'dead code strip' + hidden symbol
+ * scan newAtoms returned from optimize() looking for ones already in the symbol table
+ * add test case unit-tests/test-cases/lto-dead_strip-all-hidden
+
+
+2009-05-19 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6881656> make dyld stubs smaller/faster
+ * Add new addSynthesizedAtoms() method to Writer, called before atoms are sorted
+ * Fix throwf() and warning() to check printf types
+ * Add arm::kPointerDiff12 to support fast arm stubs
+ * Add new ContentType values for stubs and (non)lazy pointers
+ * Add new variant of arm stub this is one instruction
+
+
+2009-05-13 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: add warnings to dyldinfo target
+ * src/other/dyldinfo.cpp: support classic LINKEDIT format
+
+
+2009-05-12 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/MachOWriterExecutable.hpp: fix optimization to skip branch islands with ARM bl instructions
+
+
+2009-05-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6836647> creation of __unwind_info section can fail if hundreds of functions cannot be compact encoded
+ * src/ld/MachOWriterExecutable.hpp: fix when to make regular vs compressed pages
+
+
+2009-05-08 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/ld.cpp: enhance -save-temps to also write out optimized bitcode file
+
+
+2009-05-08 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/ld.cpp: fix -order_file_statistics to print each symbol not found and correct total
+
+
+2009-05-08 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6870522> linker should be able to coalesce UTF16 strings
+ * src/ld/MachOReaderRelocatable.hpp: parse __ustring section by labels but synthesize an
+ atom name based on the content. Leverage for __cfstring section
+ * unit-tests/test-cases/cfstring-utf16: update test case
+
+
+2009-05-07 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/MachOWriterExecutable.hpp: put branch islands further apart if there is no thumb code
+
+
+2009-05-07 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6331300> LINKEDIT optimizations for iPhone
+ * src/ld/ObjectFile.h: Recognize iPhoneOS 3.1
+ * src/ld/Options.cpp: iPhoneOS 3.1 => use compressed LINKEDIT
+ * src/ld/MachOWriterExecutable.hpp: support generating compressed LINKEDIT for arm
+
+
+2009-05-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5716715> Add linker support for ARM branch islands
+ <rdar://problem/5253691> Add labels to linker synthesized jump islands
+ * src/ld/MachOWriterExecutable.hpp: reworked BranchIslandAtom and createBranchIslands to support arm/thumb
+ * src/ld/ObjectFile.h: added kBranchIsland
+ * unit-tests/test-cases/branch-islands: updated test case to check arm/thumb
+
+
+2009-04-30 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/Options.cpp: fix custom stack base address for arm
+
+
+2009-04-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6818272> likely incorrect warning about common symbols
+ * src/ld/Options.cpp: ignore LD_WARN_COMMONS in -r mode
+
----- Tagged ld64-95.8.3
* src/ld/MachOReaderRelocatable.hpp: support new ARM_THUMB_32BIT_BRANCH reloce
+----- Tagged ld64-95.2.10
+
+2009-04-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6805002> corrupt metaclass entry in dynamic library
+ * src/ld/ld.cpp: change Section constructor to copy segment and section names
+
+
+----- Tagged ld64-95.2.9
+
+2009-04-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6744267> Update ld64 for new triples introduced in 6654669 to support ARM LLVM
+ * src/ld/LTOReader.hpp: change "arm-" to "arm" so matching works for new triples
+
+
+----- Tagged ld64-95.2.8
+
+2009-03-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6713931> anonymous functions have the compact unwind info computed wrong
+ * ld/MachOReaderRelocatable.hpp: use new compact unwind function in AnonymousAtom
+
+
+----- Tagged ld64-95.2.7
+
+2009-03-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6670421> AddressBook incorrectly gets _objc_msgSend from WebKit
+ * src/ld/MachOReaderDylib.hpp: fix processIndirectLibraries() to not force a private re-export of a dylib
+ that is already explictly or implicitly linked.
+ * unit-tests/test-cases/re-export-optimizations-indirect: add test case
+
+
+2009-03-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6665853> dyld weak linking optimization leaves some symbols unbound
+ * src/ld/MachOWriterExecutable.hpp: be sure to create bind entry for a reference
+ to a symbol in a dylib that is a weak definition
+ * unit-tests/test-cases/coalesce_weak_def_in_dylib: add test case
+
+
+2009-03-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6666004> many OS i386 OS dylibs still have __IMPORT segment
+ * ld/MachOReaderRelocatable.hpp: moved where __IMPORT/__pointer is changed to __DATA/__nl_symbol_ptr
+ * unit-tests/test-cases/stripped-indirect-symbol-table: updated to test for this problem
+
+
+----- Tagged ld64-95.2.6
+
+2009-02-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6633530> ld might set MH_WEAK_DEFINES when it should not
+ * src/ld/MachOWriterExecutable.hpp: only consider atoms in fRegularDefAtomsThatOverrideADylibsWeakDef
+ that will be exported when computing MH_WEAK_DEFINES
+ * unit-tests/test-cases/operator-new: updated to reproduce issue
+
+
+----- Tagged ld64-95.2.5
+
+2009-02-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6605499> x86_64 obj-c runtime confused when static lib is stripped
+ * src/ld/MachOWriterExecutable.hpp: in setLocalNlist() don't use 'l' labels for x86_64 strings
+ * unit-tests/test-cases/objc-literal-pointers-strip: added test case
+
+
+----- Tagged ld64-95.2.4
+
+2009-02-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/MachOReaderRelocatable.hpp: ignore ARM_THUMB_32BIT_BRANCH relocs
+
+
+2009-02-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6583555> Writer<A>::symbolIndex() uses a linear search and does not scale
+ * src/ld/MachOWriterExecutable.hpp: build a std::map so symbolIndex() scales better
+
+
+2009-02-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6312070> Use new compact encodings that handle all register permutations
+ * src/ld/Architectures.hpp: add kSectionOffset24
+ * src/ld/ObjectFile.h: add getFDE()
+ * src/ld/MachOReaderRelocatable.hpp: use new libunwind functions to get new compact encoding
+ * src/ld/MachOWriterExecutable.hpp: use new compact encoding which includes offset in dwarf if needed
+ * src/other/unwinddump.cpp: update unwinddump output to display register save set
+
+
+2009-02-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6511619> runtime error with bundle for 10.5 that has weak external symols
+ * src/ld/ld.cpp: fix hybrid (10.5) compressed linkedit info for data pointing to weak definitions
+
+
+2009-02-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6583757> i386 relocation error with negative offsets from local labels
+ * src/ld/MachOReaderRelocatable.hpp: handle when base addr of scattered relocation does not point to a label
+ * unit-tests/test-cases/relocs-neg-from-local: add test case
+
+
+2009-02-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6578360> -dead_strip inhibits weak coalescing in no_dead_strip section
+ * src/ld/ld.cpp: remove atoms coalesced away from fLiveRootAtoms
+ * unit-tests/test-cases/dead_strip-weak-coalesce: added test case
+
+
+2009-02-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6581809> x86_64 weak_import broken for initialized data
+ * src/ld/MachOReaderRelocatable.hpp: use isWeakImportSymbol() in Reader<x86_64>::addRelocReference()
+ * src/other/dyldinfo.cpp: update to display weak_import attribute
+ * unit-tests/test-cases/weak_import: updated test case
+
+
+2009-02-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6541812> ld parsing of __eh_frame unwind information is slow
+ * src/ld/MachOReaderRelocatable.hpp: build a std::map of all __eh_frame relocations for x86_64
+
+
+----- Tagged ld64-95.2.3
+
+2009-02-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6545406> ld: warning: can't add line info to anonymous symbol
+ * src/ld/MachOReaderRelocatable.hpp: don't warn about line info in dyld stubs
+
+
+----- Tagged ld64-95.2.2
+
+2009-02-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6548268> ld -r does not preserve the N_NO_DEAD_STRIP bit
+ * src/ld/MachOWriterExecutable.hpp: set N_NO_DEAD_STRIP based on dontDeadStrip()
+ * unit-tests/test-cases/dead_strip-r_symbol_desc: added test case
+
+
+----- Tagged ld64-95.2.1
+
+----- Tagged ld64-95.2.10
+
+2009-04-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6805002> corrupt metaclass entry in dynamic library
+ * src/ld/ld.cpp: change Section constructor to copy segment and section names
+
+
+----- Tagged ld64-95.2.9
+
+2009-04-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6744267> Update ld64 for new triples introduced in 6654669 to support ARM LLVM
+ * src/ld/LTOReader.hpp: change "arm-" to "arm" so matching works for new triples
+
+
+----- Tagged ld64-95.2.8
+
+2009-03-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6713931> anonymous functions have the compact unwind info computed wrong
+ * ld/MachOReaderRelocatable.hpp: use new compact unwind function in AnonymousAtom
+
+
+----- Tagged ld64-95.2.7
+
+2009-03-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6670421> AddressBook incorrectly gets _objc_msgSend from WebKit
+ * src/ld/MachOReaderDylib.hpp: fix processIndirectLibraries() to not force a private re-export of a dylib
+ that is already explictly or implicitly linked.
+ * unit-tests/test-cases/re-export-optimizations-indirect: add test case
+
+
+2009-03-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6665853> dyld weak linking optimization leaves some symbols unbound
+ * src/ld/MachOWriterExecutable.hpp: be sure to create bind entry for a reference
+ to a symbol in a dylib that is a weak definition
+ * unit-tests/test-cases/coalesce_weak_def_in_dylib: add test case
+
+
+2009-03-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6666004> many OS i386 OS dylibs still have __IMPORT segment
+ * ld/MachOReaderRelocatable.hpp: moved where __IMPORT/__pointer is changed to __DATA/__nl_symbol_ptr
+ * unit-tests/test-cases/stripped-indirect-symbol-table: updated to test for this problem
+
+
+----- Tagged ld64-95.2.6
+
+2009-02-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6633530> ld might set MH_WEAK_DEFINES when it should not
+ * src/ld/MachOWriterExecutable.hpp: only consider atoms in fRegularDefAtomsThatOverrideADylibsWeakDef
+ that will be exported when computing MH_WEAK_DEFINES
+ * unit-tests/test-cases/operator-new: updated to reproduce issue
+
+
+----- Tagged ld64-95.2.5
+
+2009-02-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6605499> x86_64 obj-c runtime confused when static lib is stripped
+ * src/ld/MachOWriterExecutable.hpp: in setLocalNlist() don't use 'l' labels for x86_64 strings
+ * unit-tests/test-cases/objc-literal-pointers-strip: added test case
+
+
+----- Tagged ld64-95.2.4
+
+2009-02-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/MachOReaderRelocatable.hpp: ignore ARM_THUMB_32BIT_BRANCH relocs
+
+
+2009-02-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6583555> Writer<A>::symbolIndex() uses a linear search and does not scale
+ * src/ld/MachOWriterExecutable.hpp: build a std::map so symbolIndex() scales better
+
+
+2009-02-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6312070> Use new compact encodings that handle all register permutations
+ * src/ld/Architectures.hpp: add kSectionOffset24
+ * src/ld/ObjectFile.h: add getFDE()
+ * src/ld/MachOReaderRelocatable.hpp: use new libunwind functions to get new compact encoding
+ * src/ld/MachOWriterExecutable.hpp: use new compact encoding which includes offset in dwarf if needed
+ * src/other/unwinddump.cpp: update unwinddump output to display register save set
+
+
+2009-02-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6511619> runtime error with bundle for 10.5 that has weak external symols
+ * src/ld/ld.cpp: fix hybrid (10.5) compressed linkedit info for data pointing to weak definitions
+
+
+2009-02-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6583757> i386 relocation error with negative offsets from local labels
+ * src/ld/MachOReaderRelocatable.hpp: handle when base addr of scattered relocation does not point to a label
+ * unit-tests/test-cases/relocs-neg-from-local: add test case
+
+
+2009-02-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6578360> -dead_strip inhibits weak coalescing in no_dead_strip section
+ * src/ld/ld.cpp: remove atoms coalesced away from fLiveRootAtoms
+ * unit-tests/test-cases/dead_strip-weak-coalesce: added test case
+
+
+2009-02-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6581809> x86_64 weak_import broken for initialized data
+ * src/ld/MachOReaderRelocatable.hpp: use isWeakImportSymbol() in Reader<x86_64>::addRelocReference()
+ * src/other/dyldinfo.cpp: update to display weak_import attribute
+ * unit-tests/test-cases/weak_import: updated test case
+
+
+2009-02-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6541812> ld parsing of __eh_frame unwind information is slow
+ * src/ld/MachOReaderRelocatable.hpp: build a std::map of all __eh_frame relocations for x86_64
+
+
+----- Tagged ld64-95.2.3
+
+2009-02-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6545406> ld: warning: can't add line info to anonymous symbol
+ * src/ld/MachOReaderRelocatable.hpp: don't warn about line info in dyld stubs
+
+
+----- Tagged ld64-95.2.2
+
+2009-02-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6548268> ld -r does not preserve the N_NO_DEAD_STRIP bit
+ * src/ld/MachOWriterExecutable.hpp: set N_NO_DEAD_STRIP based on dontDeadStrip()
+ * unit-tests/test-cases/dead_strip-r_symbol_desc: added test case
+
+
+----- Tagged ld64-95.2.1
+
+2009-01-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6532377> gcc DejaGnu failure: building longcall/dylib library
+ * src/ld/MachOWriterExecutable.hpp: if no __DATA sections insert non-lazy pointers at end of __TEXT segment
+ * unit-tests/test-cases/no-data-bundle: added test case
+
+
----- Tagged ld64-95.2
2009-01-06 Nick Kledzik <kledzik@apple.com>
<rdar://problem/6476760> strip -S fails with "new trie is larger than original"
+ * src/other/PruneTrie.cpp: don't align trie more than original trie was aligned
+
+
+----- Tagged ld64-95.1
+
+2008-12-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/MachOWriterExecutable.hpp: in new linkedit format, make sure only exported symbols
+ make it into weak binding info
+
+
+----- Tagged ld64-95
+
+2008-12-18 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/Options.cpp: move check for fSharedRegionEligible until fPrebind has stabilized
+
+
+2008-12-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6305021> Generate new compressed LINKEDIT when targeting 10.6
+ * src/ld/Options.cpp: turn on compressed LINKEDIT by default
+
+
+----- Tagged ld64-94.1
+
+2008-12-16 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/Options.cpp: Fix -F handling in buildSearchPaths()
+
+
+----- Tagged ld64-94
+
+2008-12-15 Nick Kledzik <kledzik@apple.com>
+
+ * doc/man/man1/ld.1: document new options
+
+
+2008-12-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6134468> linker should enforce all .o files have same sub-type, and ignore sub-type of dylibs
+ * doc/man/man1/ld.1: update man page about -allow_sub_type_mismatches
+ * src/ld/ld.cpp: call validFile() with new arguments
+ * src/ld/MachOReaderRelocatable.hpp: add new arguments to validFile()
+ * src/ld/Options.cpp: Support LD_ALLOW_CPU_SUBTYPE_MISMATCHES and -allow_sub_type_mismatches
+
+
+2008-12-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6438270> -syslibroot should skip standard search paths not in the SDK
+ * src/ld/Options.cpp: in buildSearchPaths() if an SDK is specified don't add
+ standard search paths not in the SDK.
+
+
+2008-12-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6406609> ld: remove "can't make compact unwind encoding" warning
+ * src/ld/ObjectFile.h: add fWarnCompactUnwind
+ * src/ld/Options.cpp: -warn_compact_unwind --> fWarnCompactUnwind
+ * src/ld/MachOReaderRelocatable.hpp: test fWarnCompactUnwind before warning
+
+
+2008-12-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6442926> Add dtrace usdt support for arm to ld64
+ * src/ld/MachOWriterExecutable.hpp: handle arm::kDtraceIsEnabledSite
+ * unit-tests/test-cases/dtrace-static-probes: use is-enabled in test case
+
+
+----- Tagged ld64-93
+
+2008-12-11 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/ObjectFile.h: add fIPhoneVersionMin to track min iPhoneOS version
+ * src/ld/Options.cpp: use fIPhoneVersionMin
+
+
+2008-12-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6431277> non-lazy pointer to non-global tentative definition encoded wrong
+ * src/ld/MachOWriterExecutable.hpp: don't use INDIRECT_SYMBOL_LOCAL for tentative definitions
+ * unit-tests/test-cases/non-lazy-r: updated test case
+
+
+2008-12-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6437667> kernel fails to boot when ld64 used for intermediate ld -r step
+ * src/ld/MachOWriterExecutable.hpp: in -r mode when generating a scattered sect-diff reloc for
+ i386/arm, special case when from target is not the atom
+ the relocation is in.
+ * unit-tests/test-cases/relocs-asm: update test case
+
+
+2008-12-11 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/ld.cpp: handle new __program_vars section
+ * src/ld/MachOWriterExecutable.hpp: handle inserting synthesized sections when there is no __dyld section
+
+
+2008-12-11 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/MachOReaderRelocatable.hpp: Fix getDescription() to work when direct reference is to anonymous atom
+
+
+2008-12-10 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/Options.cpp: enable LD_FORCE_NO_PREBIND to be used with arm
+
+
+2008-12-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6258169> Developer tool to print the new compressed LINKEDIT information
+ * src/other/dyldinfo.cpp: fix typo in usage()
+
+
+2008-12-05 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6308882> SnowLeopard kernel should compile warning free
+ * src/ld/MachOReaderRelocatable.hpp: correct parse two global labels at end of section and make one an alias
+ * unit-tests/test-cases/end-label: update test case
+
+
+2008-12-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6342245> Better warning than "PPC_RELOC_JBSR should not be using an external relocation"
+ * src/ld/MachOReaderRelocatable.hpp: issue warning with .o path if it was compiled with -mlong-branch
+
+
+2008-12-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6408832> linker should not map __pointers -> __nl_symbol_ptr unless actually making new LINKEDIT
+ * src/ld/ObjectFile.h: add fMakeCompressedDyldInfo for readers to see
+ * src/ld/Options.cpp: set fMakeCompressedDyldInfo for readers to see
+ * src/ld/MachOReaderRelocatable.hpp: check fMakeCompressedDyldInfo
+
+
+2008-12-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/debugline.c: fix error handling in line_open()
+
+
+2008-11-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6401277> vtable with thumb entries broke after ld -r
+ * src/ld/MachOReaderRelocatable.hpp: if target of reloc is thumb, mask thumb bit off addend
+ * unit-tests/test-cases/thumb-pointer: added test case
+
+
+2008-11-26 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/Option.cpp: Fix how crashreporterBuffer is created to not miss some arguments
+
+
+2008-11-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6398605> Security.framework has some duplicate FDEs for some functions
+ * src/ld/ld.cpp: remove fDeadAtoms from fLiveAtoms when there are weak atoms overriden by late loads
+ * unit-tests/test-cases/dead_strip-archive-eh: added test case
+
+
+----- Tagged ld64-92
+
+2008-11-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/MachOReaderDylib.hpp: if export_size is zero, no need to parse trie
+ * src/abstraction/MachOTrie.hpp: gracefully handle empty trie
+
+
+2008-11-21 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6257854> strip(1) support for new compressed LINKEDIT information
+ * ld64.xcodeproj/project.pbxproj: build and install new libprunetrie.a
+ * src/other/prune_trie.h: added
+ * src/other/PruneTrie.cpp: implements prune_trie()
+
+
+2008-11-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld/ld.cpp: if an export file is used and all weak symbols are masked, don't set WEAK_DEFINES
+ * unit-tests/test-cases/weak-def-flag: added test case
+
+
+2008-11-20 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6305021> Generate new compressed LINKEDIT when targeting 10.6
+ * src/ld/MachOWriterExecutable.hpp: support generating new compressed format
+ * src/ld/MachOReaderRelocatable.hpp: new compress format implies non-lazy pointers in __DATA for i386
+ * src/ld/MachOReaderDylib.hpp: support linking aginst new format
+ * src/ld/Options.cpp: suppport -exported_symbols_order and -no_compact_linkedit
+ * src/ld/ld.cpp: track which atoms have weak counter parts in dylibs
+ * src/other/dyldinfo.cpp: added tool to display new LINKEDIT format
+ * ld64.xcodeproj/project.pbxproj: add dyldinfo tool
+ * unit-tests/*: lots of fixes to work with new format
+
+
+2008-11-20 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6389316> ld64 should preserve N_WEAK_REF when linking MH_KEXT_BUNDLEs
+ * src/ld/MachOWriterExecutable.hpp: set up fWeakImportMap in synthesizeKextGOT()
+
+
+2008-11-19 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6342406> VideoToolbox.framework has bad __TEXT.__eh_frame info
+ * src/ld/Options.cpp: add -no_eh_labels option for use with -r
+ * src/ld/MachOWriterExecutable.hpp: generate correct x86_64 labeless relocs in -r mode
+ * src/ld/MachOReaderRelocatable.hpp: now ignore all labels and relocations in
+ __TEXT/__eh_frame section and rely on getCFIs() from libunwind
+ * unit-tests/test-cases/eh-coalescing-no-labels: add test case
+
+
+2008-11-19 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6378110> LTO doesn't like dtrace symbols
+ * src/ld/LTOReader.hpp: ignore __dtrace_probe undefines in bitcode files
+
+
+2008-11-14 Nick Kledzik <kledzik@apple.com>
+
+ * src/abstraction/MachOFileAbstraction.hpp: fix to work with 10.5 headers
+
+
+----- Tagged ld64-91
+
+2008-11-07 Nick Kledzik <kledzik@apple.com>
+
+ Remove COMPACT_UNWIND_SUPPORT conditionalizing
+
+
+2008-11-06 Nick Kledzik <kledzik@apple.com>
+
+ Reorganize source layout. ld sources are now in "ld",
+ and other tools are in "other".
+
+
+2008-11-05 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: start installing unwinddump tool
+ * src/UnwindDump.cpp: support -arch option
+ * doc/man/man1/unwinddump.1: create man page
+
+
+2008-11-05 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6337329> linker should put cpusubtype in n_sect field of nlist entry for N_OSO debug note entries
+ * src/ld.cpp: in synthesizeDebugNotes() set other field of OSO to be subtype
+
+
+2008-11-05 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/3738966> Need a linker option to load all objects from one library
+ * src/Options.cpp: support -force_load option
+ * src/ArchiveReader.hpp: Add fForceLoad ivar
+ * doc/man/man1/ld.1: update man page with -force_load option
+ * unit-tests/test-cases/archive-force-load: add test case
+
+
+2008-11-05 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6308882> Dtrace Probe Warnings: SnowLeopard kernel should compile warning free
+ * src/ld.cpp: don't generate GSYM stabs for old style __dtrace_probe
+ * src/MachOReaderRelocatable.hpp: fix test for deciding if a symbol is an alias
+
+
+2008-11-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6294378> ADOBE: XCODE: ld: duplicate typeinfo in executable
+ * src/ld.cpp: in dead-strip mode, record overriden symbols and later rebind all uses
+ * unit-tests/test-cases/dead_strip-archive-weak: add test case
+
+
+2008-11-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6254202> support increased branch range in Thumb-2
+ * src/MachOReaderRelocatable.hpp: handle full branch range in addRelocReference()
+ * unit-tests/test-cases/branch-distance: added test case
+
+2008-10-31 Devang Patel <dpatel@apple.com>
+
+ <rdar://problem/5725712> Sqlite 3.5.4 built with lvm-gcc-4.2 -O4 fails regression test
+ * src/LTOReader.hpp: Use real atom scope when real atom is available.
+ Preserve globals while optimizing an executable.
+
+2008-10-30 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: support all encodings in getEncodedP()
+
+
+----- Tagged ld64-90
+
+2008-10-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6327584> icc has dwarf unwind info that is different than gcc
+ * src/MachOReaderRelocatable.hpp: support more encodings in getEncodedP()
+
+
+2008-10-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6088653> build ld64 for x86_64
+ * ld64.xcodeproj/project.pbxproj: add X86_64 to valid archs
+
+
+2008-10-23 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: use generated @$(DERIVED_FILE_DIR)/linker_opts for extra
+ linker options. This allows linker to be built if LTO headers and libs are missing.
+
+
+2008-10-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6273617> Linker warning not shown in the Xcode build log
+ * src/Options.cpp: add colon to format string in warning()
+
+
+----- Tagged ld64-89.3
+
+2008-10-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6317985> ld64-89 broke TOT OpenGL libProgrammability x86_64 build
+ * src/MachOReaderRelocatable.hpp: add cast in getEncodedP()
+
+
+----- Tagged ld64-89.2
+
+2008-10-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6312895> SnowLeopard: Libsystem built with ld64-89.1 causes crashes
+ * src/MachOReaderRelocatable.hpp: when FDE information causes __text atom to be split, make the
+ atoms follow-on pairs.
+
+
+----- Tagged ld64-89.1
+
+2008-10-22 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: for x86_64 __eh_frame force direct references
+
+
+2008-10-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/ObjectDump.cpp: Use getContentType() to see if content type is a cstring
+
+
+----- Tagged ld64-89
+
+2008-10-21 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6253171> 10A180 with QT-1119 roots: iTunes and QuickTime cannot play back purchased videos
+ <rdar://problem/5950453> linker should not need .eh labels
+ * src/MachOWriterExecutable.hpp: use kCFIType to set section attributes
+ * src/MachOReaderRelocatable.hpp: use libunwind's CFITuple to parse __eh_frame content
+ * src/ld.cpp: Add adjustScope() phase instead of demoting scope within symboltable.add()
+ * unit-tests/test-cases/eh-stripped-symbols: added test case
+
+
+----- Tagged ld64-88.1
+
+2008-10-16 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: Fix uses of COMPACT_UNWIND_SUPPORT
+ * src/MachOWriterExecutable.hpp: Fix uses of COMPACT_UNWIND_SUPPORT
+
+
+2008-09-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6255983> OBJC2: Reorder __DATA,__objc_* sections by writedness
+ * src/ld.cpp: change sorting order of Sections
+
+
+2008-09-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6159479> Executable produced by XCode 3.2 on 10.6 crashes on 10.3.9
+ * src/MachOWriterExecutable.hpp: set objc_module_info_addr field of module table
+
+
+----- Tagged ld64-88
+
+2008-09-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5935708> kexts need to be built as MH_BUNDLE mach-o files
+ * src/ld.cpp: use getUndefinedProxyAtom() with kKextBundle
+ * src/MachOFileAbstraction.hpp: add MH_KEXT_BUNDLE
+ * src/Options.cpp: support -kext for all architectures
+ * src/MachOWriterExecutable.hpp: support kKextBundle to make a bundle like kext
+ * unit-tests/test-cases/kext-basic: added test case
+
+
+2008-09-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6052546> ld invoking wrong ld_classic
+ * src/Options.cpp: first look for ld_classic relative to ld itself
+
+
+2008-09-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5855588> ld fails to link references from 32 bit code into 64 bit code
+ <rdar://problem/5955200> Desired 32-bit absolute relocation
+ * src/Architectures.hpp: add x86_64::kPointer32
+ * src/MachOReaderRelocatable.hpp: support X86_64_RELOC_UNSIGNED with length=2
+ * src/MachOWriterExecutable.hpp: support x86_64::kPointer32
+ * unit-tests/test-cases/relocs-asm/relocs-asm.s: added 32-bit pointer tests
+
+
+2008-09-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6075323> Should be able to mark dylibs as auto-dead-dylib-strip
+ * src/Options.h: add fMarkDeadStrippableDylib
+ * src/MachOReaderDylib.hpp: check MH_DEAD_STRIPPABLE_DYLIB
+ * src/ObjectFile.h: add deadStrippable()
+ * src/MachOFileAbstraction.hpp: add MH_DEAD_STRIPPABLE_DYLIB
+ * src/Options.cpp: support -mark_dead_strippable_dylib
+ * src/MachOWriterExecutable.hpp: test reader->deadStrippable(), set MH_DEAD_STRIPPABLE_DYLIB
+ * doc/man/man1/ld.1: update man page
+ * unit-tests/test-cases/dead_strippable_dylib: added test case
+
+
+2008-09-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6197601> ER: Add -seg_page_size option
+ * src/Options.cpp: add -seg_page_size option
+ * src/MachOWriterExecutable.hpp: use new page size info when laying out segments
+ * doc/man/man1/ld.1: update man page
+
+
+2008-09-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5798786> -arch_errors_fatal not working
+ * src/ld.cpp: check fOptions.errorOnOtherArchFiles()
+ * src/Options.cpp: turn -arch_errors_fatal into fOptions.errorOnOtherArchFiles()
+
+
+2008-09-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6161215> CrashTracer: [USER] 1 crash in ld at ld: 0x5ce02
+ * src/ld.cpp: abort if resolve() finds an unresolved reference, rather than allow a future crash
+
+
+2008-09-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6157989> linker crashes linking X86-64 with -fwritable-strings
+ * src/MachOReaderRelocatable.hpp: handle unbound cfstring references
+ * unit-tests/test-cases/cfstring-coalesce: update test case
+
+
+2008-09-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6213035> ld64: bl out of range (-17147704 max is +/-16M) on ppc
+ * src/MachOWriterExecutable.hpp: tweak branch island regions to be every 14MB instead of 15MB
+
+
+2008-09-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5907981> -filelist fails with comma in path
+ * src/Options.cpp: in loadFileList() first try without special comma meaning
+ * unit-tests/test-cases/filelist/Makefile: update test case
+
+
+2008-09-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6203068> nop not used when aligning functions in -r mode
+ * src/MachOWriterExecutable.hpp: change check for when to pad with nops to not test segment's name
+
+
+2008-09-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6238329> "-pie can only be used when linking a main executable" should be a warning, not an error
+ * src/Options.cpp: make -pie on a dylib or bundle be a warning instead of an error
+
+
+2008-09-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: add warning if dwarf cannot be encoded as compact unwind
+
+
+2008-09-18 Nick Kledzik <kledzik@apple.com>
+
+ * src/LTOReader.hpp: re-enable use of lto_codegen_debug_options()
+
+
+2008-09-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6219054> ld does not always set S_CSTRING_LITERALS on __TEXT,__cstring
+ * src/MachOReaderRelocatable.hpp: add getContentType() to SymbolAtom
+ * src/MachOWriterExecutable.hpp: for x86_64 don't override named cstrings with LC* name
+
+
+2008-09-10 Nick Kledzik <kledzik@apple.com>
+
+ * Options.cpp: add __crashreporter_info__ to communicate command line to crash reporter
+ * ld64.xcodeproj/project.pbxproj: leave local symbols in ld to provide better crash reports
+
+
+2008-09-08 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6126637> 161569 GCC 4.2 - breakpoints no longer work for a large number of functions
+ * src/MachOReaderRelocatable.hpp: support DW_FORM_strp out-of-line strings when parsing line table
+
+
+2008-09-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: fix compact unwind personality for dyld and -slow_stubs
+
+
+2008-08-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6186838> -weak_library no longer forces uses to be weak_import
+ * src/MachOWriterExecutable.hpp: use fWeakImport on dylib to force proxy atoms into fWeakImportMap
+ * unit-tests/test-cases/weak_import-force: added test case
+
+
+2008-08-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6061558> linker should order __DATA segment to reduce dyld dirtied pages
+ * src/Options.cpp: add fOrderData and support -no_data_order
+ * src/ld.cpp: modify tweakLayout() to sort atoms with relocations to start of __data section
+
+
+2008-08-27 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: back out <rdar://problem/6174493>
+
+
+----- Tagged ld64-87.5
+
+2008-08-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6174493> some projects show _Unwind_Resume coming from libSystem.B.dylib
+ * src/Options.cpp: swap any early symlinks to libSystem with libgcc_s
+
+
+----- Tagged ld64-87.4
+
+2008-08-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6174493> some projects show _Unwind_Resume coming from libSystem.B.dylib
+ * src/Options.cpp: swap any early libSystem with libgcc_s
+
+
+2008-08-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5898326> Unable to build ppc debug builds (linker out of range error)
+ * src/MachOWriterExecutable.hpp: in addPPCBranchIslands() look ahead so large atoms don't push out branch islands
+
+
+----- Tagged ld64-87.3.1
+
+2008-09-08 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6204202> i386 dylibs have incorrect personality pointers when put in dyld shared cache
+ * src/MachOWriterExecutable.hpp: in addCrossSegmentRef() handle kImageOffset32 to __IMPORT segment
+
+
+----- Tagged ld64-87.3
+
+2008-08-09 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6125381> work around compiler gcc_except_table alignment
+ * src/ObjectFile.h: change getLSDA() to return a reference instead of an atom
+ * src/MachOReaderRelocatable.hpp: special case __eh_frame 64-bit pointer diff relocations
+ * src/MachOWriterExecutable.hpp: track lsda offset when creating __unwind_info section
+ * src/UnwindDump.cpp: log when LDSA content does not start with 0xFF
+
+----- Tagged ld64-87.2
+
+2008-08-07 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6131559> 10A141: libuwind falls back to dwarf and makes whole system super slow
+ * src/MachOWriterExecutable.hpp: Fix sign extension bug with x86_64::kPointerDiff24
+ * src/UnwindDump.cpp: warn about mangled LSDA entries when dumping unwind section
+
+
+----- Tagged ld64-87.1
+
+2008-08-03 Nick Kledzik <kledzik@apple.com>
+
+ * src/LTOReader.hpp: Don't use lto_codegen_debug_options until newer libLTO.dylib is available
+
+
+----- Tagged ld64-87
+
+2008-07-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: Always set fAutoOrderInitializers=false for dyld
+
+
+2008-07-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix when regular vs compressed __unwind_info pages are generated
+ * src/UnwindDump.cpp: fix function name decoding in regular pages
+
+
+2008-07-21 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: don't allow ld to build for x86_64 until libdtrace.dylib is available
+
+
+2008-07-18 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: don't crash if debug_line section has no line table
+
+
+2008-07-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5628149> Duplicate probe firings in Security.framework
+ * src/LTOReader.hpp: optimize() now returns atoms optimized away
+ * src/ObjectFile.h: optimize() should return if it did anything
+ * src/ArchiveReader.hpp: pass through optimize() result
+ * src/ld.cpp: rework dtrace probe processing as a new pass to prevent double counting
+
+
+2008-07-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6061904> automatically order initializers to start of __TEXT
+ * src/Options.cpp: add -no_order_inits option
+ * src/MachOReaderRelocatable.hpp: merge __StaticInit into __text
+ * src/ObjectFile.h: add fAutoOrderInitializers
+ * src/ld.cpp: sort initializer to start of __text and terminators to end
+ * doc/man/man1/ld.1: add doc about -no_order_inits
+ * unit-tests/test-cases/init-order: add test case
+
+2008-07-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6073697> Only add LC_SEGMENT_SPLIT_INFO to dylibs that might be in the shared cache
+ * src/MachOWriterExecutable.hpp: re-layout load commands after split-seg data computed
+ * src/Options.cpp: non-public install name will disable split-seg load command
+
+
+2008-07-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6069861> ld -r for x86_64 is changing visibility of cstring constants
+ * src/MachOWriterExecutable.hpp: force x86_64 cstring labels to be local in -r mode
+ * unit-tests/test-cases/cstring-label: added test case
+
+
+2008-07-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6070190> ld not adding updating LC_SEGMENT_SPLIT_INFO with __unwind_info section
+ * src/MachOWriterExecutable.hpp: run createSplitSegContent() after __unwind_info section is created
+
+2008-07-10 Nick Kledzik <kledzik@apple.com>
+
+ * src/LTOReader.hpp: improve missing symbol error message
+
+
+2008-07-09 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6061558> linker should order __DATA segment to reduce dyld dirtied pages
+ * src/ld.cpp: first phase, order sections
+
+
+2008-07-08 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: remove "coal" sections when creating a final linked image
+
+
+2008-07-08 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6054476> ld: add support for mllvm LTO options
+ * src/Options.cpp: support -mllvm option
+ * src/LTOReader.hpp: call lto_codegen_debug_options() with -mllvm options
+ * src/ld.cpp: pass llvmOptions to optimize()
+ * src/Options.h: add fLLVMOptions
+ * src/ArchiveReader.hpp: add llvmOptions parameter to optimize()
+ * src/ObjectFile.h: add llvmOptions parameter to optimize()
+ * unit-tests/test-cases/lto-llvm-options: add test case
+
+
+2008-07-07 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6054296> Linker fails with: 24-bit pointer diff out of range in unwind info in unwind info from...
+ * src/MachOWriterExecutable.hpp: fix when to fallback to uncompressed unwind info
+
+
+2008-07-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6001472> ld crash with gcc-4.0 code that uses a zero sized array
+ * src/MachOReaderRelocatable.hpp: handle zero size atom in a zero sized section
+
+
+2008-07-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6016809> ld crashes when bad ppc relocs are found
+ * src/MachOReaderRelocatable.hpp: change all missing PAIR warnings to errors
+
+
+2008-07-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5881324> when linking a kext the static linker should leave a pad in the headers to allow code signing
+ * src/MachOWriterExecutable.hpp: add padding for load commands in object files
+ * unit-tests/test-cases/code-signed-object-file: added test case
+
+
+2008-07-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6048484> LC_SEGMENT_64 filesize incorrect for MH_OBJECT filetype
+ * src/MachOWriterExecutable.hpp: correctly set segment size info in object files
+ * unit-tests/test-cases/no-object-symbols: add test case
+
+
+2008-06-26 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: enable ld and rebase targets to build for x86_64
+ * src/rebase.cpp: remove unused fRelocBase field that was not 64-bit clean
+ * src/MachOReaderRelocatable.hpp: fix getEncodedP() to be 64-bit clean
+
+
+----- Tagged ld64-86.3
+
+2008-06-17 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: fix loadUndefines() to double check undefine symbol was not already loaded
+
+
+----- Tagged ld64-86.2
+
+2008-06-14 Nick Kledzik <kledzik@apple.com>
+
+ * srd/ld.cpp: Add NULL check in getTentativesNames()
+
+
+----- Tagged ld64-86.1
+
+2008-06-06 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix header padding calculation for dyld
+
+
+----- Tagged ld64-86
+
+2008-06-04 Nick Kledzik <kledzik@apple.com>
+
+ * src/LTOReader.hpp: if lto_codegen_add_module() fails, add explanation to error message
+
+
+2008-06-04 Nick Kledzik <kledzik@apple.com>
+
+ * src/ObjectFile.h: add deadAtoms parameter to optimize()
+ * src/ld.cpp: ditto
+ * src/ArchiveReader.hpp: ditto
+ * src/MachOReaderRelocatable.hpp: handle llvm use of 0x1B pointer encodings in CIEs
+ * src/LTOReader.hpp: make sure libLTO.dylib knows about any llvm symbol coalesced away
+ * unit-tests/test-cases/lto-weak-native-override: add test case
+
+
+2008-06-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5935600> LTO : 176.gcc and 177.mesa build failure at -O4
+ * src/LTOReader.hpp: make sure internal is returned by getAtoms()
+ * unit-tests/test-cases/lto-archive-dylib: update test case
+
+
+2008-06-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5894163> fix for 5613343 need to search for definitions for common symbols is broken
+ * src/ld.cpp: modify loadUndefines() to check for undefines in all files and tentative definitions but only in archives
+ * src/machochecker.cpp: check for undefine symbols and external symbols with same name
+ * unit-tests/test-cases/tentative-and-archive: update test case
+
+
+2008-06-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5935237> linker produces wrong result for 16-bit call relocations
+ * src/MachOReaderRelocatable.hpp: properly parse i386 scattered relocs for word sized pc-rel vanilla
+ * src/MachOWriterExecutable.hpp: propery compute displacement for x86::kPCRel16
+ * unit-tests/test-cases/relocs-asm: update test case with callw instructions
+
+
+2008-06-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5905900> Building kext x86_64 with unexported symbols file causes linking problems
+ * src/MachOWriterExecutable.hpp: better check when creating undefined proxy atoms
+ * unit-tests/test-cases/unexported_symbols_list-r: added test case
+
+
+2008-06-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5659338> S_CSTRING_LITERALS section type not preserved in executable
+ * src/ObjectFile.h: added ContentType
+ * src/MachOReaderRelocatable.hpp: set ContentType for anonymous string literals
+ * src/MachOWriterExecutable.hpp: set S_CSTRING_LITERALS if ContentType is kCStringType
+ * unit-tests/test-cases/cstring-custom-section: added test case
+
+
+2008-06-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5980194> linker should produce __unwind_info section in final linked images
+ * src/ld.cpp: sort __unwind_info then __eh_frame section to end of __TEXT
+ * src/Architectures.hpp: add kImageOffset32 and kPointerDiff24
+ * src/ObjectFile.h: add compact unwind info support
+ * src/MachOReaderRelocatable.hpp: add compact unwind info support
+ * src/MachOFileAbstraction.hpp: add C++ wrappers for unwind section layout
+ * src/UnwindDump.cpp: new tool for dumping __unwind_info section
+ * src/MachOWriterExecutable.hpp: create __unwind_info section when needed
+ * src/ObjectDump.cpp: print unwind info
+
+
+2008-06-02 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/llvm-integration: split out some test cases
+ * unit-tests/test-cases/lto-preload-pie: added
+ * unit-tests/test-cases/lto-archive-dylib: added
+
+
+2008-05-30 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests: fixes to build all tests with with gcc-4.2 on SnowLeopard
+
+
+2008-05-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5536348> support -preload option to generate MH_PRELOAD binaries compatible with mtoc(1) and EFI
+ * src/ld.cpp: add entryPoint parameter to optimize()
+ * src/ArchiveReader.hpp: ditto
+ * src/ObjectFile.h: ditto
+ * src/LTOReader.hpp: use entryPoint parameter to optimize()
+ * src/Options.h: add kPreload and segment alignment
+ * src/Options.cpp: support -preload and -segalign
+ * src/MachOWriterExecutable.hpp: support kPreload and non-page aligned segments
+
+
+2008-05-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4431008> ld should warn if passed -r and also dylibs
+ * src/ld.cpp: check for spurious dylibs in Linker::addDylib()
+
+
+----- Tagged ld64-85.6
+
+2008-11-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6254202> support increased branch range in Thumb-2
+ * src/MachOWriterExecutable.hpp: in fixUpReferenceFinal() support new longer branch range
+
+
+2008-11-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6104368> ld warning: unknown option to -iphoneos_version_min, not 1.x or 2.x
+ * src/Options.cpp: In setIPhoneVersionMin() support 3.x
+
+
+----- Tagged ld64-85.5
+
+2008-09-17 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6162415> vtable pointers can be missing thumb bit
+ * src/MachOWriterExecutable.hpp: Writer<arm>::fixUpReferenceFinal() OR in the 1 bit if the target
+ of a arm::kReadOnlyPointer is thumb.
+
+
+----- Tagged ld64-85.4
+
+2008-08-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6138961> ld should ignore LD_PREBIND when processing a static archive
+ * src/MachOWriterExecutable.hpp: in setImportNlist() never use N_PBUD for object files
+
+----- Tagged ld64-85.3
+
+2008-07-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/6060912> Prebinding busted in DTSB
+ * src/Options.cpp: check for libstdc++.6.0.[49] in seg_addr_table
+
+
+----- Tagged ld64-85.2
+
+2008-05-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5905889> ARM ld should take W bit off of maxprot for __TEXT segment
+ * src/MachOWriterExecutable.hpp: for iPhone always set maxprot to be initprot in all segments
+
+
+2008-05-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5914343> encryptable images may not be signable
+ * src/MachOWriterExecutable.hpp: use minimum header padding when aligning __text section
+
+
+----- Tagged ld64-85 (Xcode 3.1)
+
+2008-04-29 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: <llvm-c/lto.h> is moving from /usr/local/include to /Developer/usr/local/include
+
+
+2008-04-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5829579> ld doesn't honor "rightmost" -syslibroot argument
+ * src/Options.cpp: if last -syslibroot is /, then ignore all syslibroots
+
+
+2008-04-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5866582> GLRendererFloat has bad __eh_frame section caused by mixing llvm-gcc and gcc object files
+ * src/MachOReaderRelocatable.hpp: make all atoms in __eh_frame section have 1-byte alignment
+ * src/MachOWriterExecutable.hpp: make __eh_frame section have pointer sized alignment
+
+
+2008-04-17 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: better cpu subtype support
+
+
+2008-04-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5733759> ld64 has bad ARM branch island check
+ * src/MachOWriterExecutable.hpp: in addBranchIslands() don't force large arm programs to fail
+
+
+2008-04-10 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix stubs used with lazy dylibs
+
+
+----- Tagged ld64-84.4
+
+2008-04-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5847206> SPEC2000/eon built with -mdynamic-no-pic won't run
+ * src/Architectures.hpp: added arm::kReadOnlyPointer
+ * src/MachOReaderRelocatable.hpp: generate arm::kReadOnlyPointer
+ * src/MachOWriterExecutable.hpp: use arm::kReadOnlyPointer
+ * src/machochecker.cpp: allow MH_PIE bit
+ * unit-tests/test-cases/switch-jump-table: added test cases
+
+
+----- Tagged ld64-84.3
+
+2008-04-09 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5852023> -undefined dynamic_lookup busted
+ * src/ld.cpp: don't create proxy atom when scanning for dylib duplicates
+ * unit-tests/test-cases/tentative-and-archive: use -undefined dynamic_lookup
+
+
+----- Tagged ld64-84.2
+
+2008-04-04 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: don't add .eh symbols to symbol table in -r mode
+ * unit-tests/test-cases/eh-coalescing-r: update to test out of order coalescing
+
+
+----- Tagged ld64-84.1
+
+2008-03-28 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5720961> ld should prefer architecture-specific variant over generic in fat object file
+ * src/Options.cpp: fully process -arch arguments into fArchitecture and fSubArchitecture
+ * src/ld.cpp: when -arch with a subtype is used, try to find the exact subtype from fat files
+ * unit-tests/test-cases/cpu-sub-types-preference: added test cases for arm and ppc
+
+
+----- Tagged ld64-84
+
+2008-03-28 Nick Kledzik <kledzik@apple.com>
+
+ * src/LTOReader.hpp: don't print lto version, if lto is unavailable
+
+
+2008-03-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5575399> Add LD_WARN_COMMONS to BigBear builds
+ * src/Options.cpp: Add support for LD_WARN_FILE which copies all warnings to a side file
+
+
+2008-03-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5797713> Need encryption tag in mach-o file
+ <rdar://problem/5811920> linker should adjust arm final linked images so __text is never on the same page as the load commands
+ * src/MachOFileAbstraction.hpp: add support for encryption_info_command
+ * src/Options.cpp: add support for LD_NO_ENCRYPT and -no_encryption
+ * src/MachOWriterExecutable.hpp: add EncryptionLoadCommandsAtom
+ * src/machochecker.cpp: validate LC_ENCRYPTION_INFO
+
+
+2008-03-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5712533> ld64 does not recognize LLVM bitcode archive files
+ * src/MachOReaderArchive.hpp: renamed to src/ArchiveReader.hpp
+ * src/ArchiveReader.hpp: sniff each member and instantiate correct reader
+ * src/ld.cpp: rename mach_o::archive::Reader to archive::Reader
+ * ld64.xcodeproj/project.pbxproj: rename MachOReaderArchive.hpp to ArchiveReader.hpp
+ * unit-tests/test-cases/llvm-integration: added test case
+
+
+2008-03-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5771658> ld64 should switch to new libLTO.dylib interface
+ <rdar://problem/5675690> Produce llvm bc file in 'ld -r' mode if all .o files are llvm bc
+ * src/LTOReader.hpp: rewrite from LLVMReader.hpp to use new lto_* C interface
+ * unit-tests/test-cases/llvm-integration: update and comment
+ * ld64.xcodeproj/project.pbxproj: update to lazy load libLTO.dylib
+ * src/ld.cpp: rework and simplify Linker::optimize()
+ * src/ObjectDump.cpp: Add -nm option
+
+
+2008-03-25 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.cpp: Fix some .objc_class_name_ off by one problem
+ * src/MachOWriterExecutable.cpp: Fix some .objc_class_name_ off by one problem
+
+
+2008-03-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5814613> Xcode 3.1 breaks linkage of libgcj.9.dylib from gcc 4.3.0
+ * src/MachOWriterExecutable.cpp: Make sure all ivars in Writer are initialized.
+
+
+2008-03-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: warn if -seg1addr value is not page aligned
+
+
+2008-03-21 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5806437> Move ARM support outside of __OPEN_SOURCE__
+ * src/ld.cpp: remove __OPEN_SOURCE__ around arm support
+ * src/LLVMReader.hpp: remove __OPEN_SOURCE__ around arm support
+ * src/MachOReaderDylib.hpp: remove __OPEN_SOURCE__ around arm support
+ * src/ObjectFile.h: remove __OPEN_SOURCE__ around arm support
+ * src/MachOReaderRelocatable.hpp: remove __OPEN_SOURCE__ around arm support
+ * src/OpaqueSection.hpp: Cover arm support inside __OPEN_SOURCE__ macro check
+ * src/MachOWriterExecutable.hpp: remove __OPEN_SOURCE__ around arm support
+ * src/ObjectDump.cpp: remove __OPEN_SOURCE__ around arm support
+ * ld64.xcodeproj/project.pbxproj: remove ARM_SUPPORT from config.h
+
+
+----- Tagged ld64-83.2
+
+2008-03-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5801620> ld64-83 removes OBJC_CLASS_$ symbols from projects, causes catastrophic results
+ * src/Options.cpp: restore "case CPU_TYPE_ARM" in switch statement for .objc_class symbols in .exp files
+ * unit-tests/test-cases/objc-exported_symbols_list: added test case
+
+
+----- Tagged ld64-83.1
+
+2008-03-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5800466> -iphone_version_min ==> -iphoneos_version_min
+ * src/Options.cpp: support -iphoneos_version_min as well
+
+
+----- Tagged ld64-83
+
+2008-03-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5791543> ld needs to strip iphone_version_min option if invoking ld_classic
+ * src/Options.cpp: suppress -iphone_version_min from being passed to ld_classic
+
+
+2008-03-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4171253> ADOBE XCODE: Linker option to lazy load frameworks (cause dyld is too slow)
+ * src/MachOWriterExecutable.hpp: create lazy stubs and LC_LAZY_LOAD_DYLIB for lazy load dylibs
+ * src/Options.cpp: support -lazy-l, -lazy_library, and -lazy_framework
+ * src/MachOFileAbstraction.hpp: add LC_LAZY_LOAD_DYLIB and S_LAZY_DYLIB_SYMBOL_POINTERS until in cctools
+ * src/MachOReaderDylib.hpp: add isLazyLoadedDylib()
+ * src/ld.cpp: pass lazy helper atom to writer
+ * doc/man/man1/ld.1: document new options
+ * unit-tests/test-cases/lazy-dylib-objc: add test case
+ * unit-tests/test-cases/lazy-dylib: add test case
+
+
+----- Tagged ld64-82.7
+
+2008-03-07 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5787149> duplicate symbol literal-pointer@__OBJC@__message_refs@...
+ * src/MachOReaderRelocatable.hpp: AnonymousAtom from S_LITERAL_POINTERS section should be weak
+ * unit-tests/test-cases/objc-selector-coalescing: added test case
+
+
+----- Tagged ld64-82.6
+
+2008-03-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5779681> ld crashes building XsanFS for Snow Leopard Builds
+ * src/ld.cpp: add bool dylibsOnly parameter to addJustInTimeAtoms()
+ * unit-tests/test-cases/tentative-and-archive: added test case
+
+2008-03-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5775822> ld64 should not force building with gcc 4.0
+ * ld64.xcodeproj/project.pbxproj: change rules to use "system" compiler instead of 4.0
+
+
+2008-02-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5774730> Simulator frameworks are being build split-seg and not prebound
+ * src/Options.cpp: only splitseg if prebound
+
+
+2008-02-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5774231> Linker should not make GSYM debug note for .objc_category_* symbols
+ * src/ld.cpp: suppress GSYM debug notes for absolute symbols
+ * unit-tests/test-cases/objc-category-debug-notes: added test case
+
+
+2008-02-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5768970> non-ASCII CFString support is broken
+ * src/MachOReaderRelocatable.hpp: only name and coalesce cfstring constants if they use a __cstring
+ * unit-tests/test-cases/cfstring-utf16: add test case
+
+
+2008-02-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5366363> ld -r -x
+ * doc/man/man1/ld.1: update man page to explain -r -x produces auto-stripped labels
+
+
+----- Tagged ld64-82.5
+
+2008-02-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5738023> x86_64: -stack_size failure when large __bss is used
+ * src/ld.cpp: only move section already in __DATA segment to new __huge section
+ * unit-tests/test-cases/stack_size_no_addr: updated test case to add large bss section
+
+
+----- Tagged ld64-82.4
+
+2008-02-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5726215> comdat warnings with ld -r of C++ .o files
+ * unit-tests/test-cases/eh-coalescing-r: added test case
+ * src/ld.cpp: in ld -r mode don't warn about if .eh symbols are not static
+
+
+2008-02-06 Devang Patel <dpatel@apple.com>
+
+ <rdar://problem/5724990> LTO of Bom framework with -dead_strip causes ld(1) crash
+ * src/LLVMReader.hpp: Check fAtom while determining LLVMReference target binding.
+ * unit-tests/test-cases/llvm-integration/Makefile: Add new test case.
+ * unit-tests/test-cases/llvm-integration/a15.c: New.
+ * unit-tests/test-cases/llvm-integration/b15.c: New.
+ * unit-tests/test-cases/llvm-integration/c15.c: New.
+
+2008-02-05 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: fix for -arch ppc -mdynamic-no-pic -pie so PPC_RELOC_HA16 reloc is used
+
+----- Tagged ld64-82.3
+
+2008-02-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5721186> ld doesn't seem to understand $ld$add$os... and $ld$hide$os... for 10.6 moves
+ * src/ObjectFile.h: add 10.6
+ * src/Options.cpp: add 10.6 support
+ * src/MachOReaderDylib.hpp: recognize $os10.6$
+
+
+----- Tagged ld64-82.2
+
+2008-01-30 Devang Patel <dpatel@apple.com>
+
+ <rdar://problem/5714833> Can't build 64-bit Intel binaries with LTO
+ <rdar://problem/5714787> ld64 fails to build with llvm-gcc-4.2
+ * src/LLVMReader.hpp: Fix character count typo in strncmp call.
+ Use const char * to initialize temp. string.
+ * ld64.xcodeproj/project.pbxproj: use $(DEVELOPER_DIR) in header search construction
+ instead of hard coding /Developer.
+
+----- Tagged ld64-82.1
+
+2008-01-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: don't bus error if S_LITERAL_POINTERS is missing relocs
+
+
+2008-01-22 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5695496> ld uses 32-bits in some places to hold addresses when parsing 64-bit mach-o files
+ * src/MachOReaderRelocatable.hpp: use AddrToAtomMap type that switch address to 64-bits for 64-bit archs
+ * src/MachOWriterExecutable.hpp: verify BR14 does not overflow for external relocs
+ * unit-tests/test-cases/relocs-c: update test case to slide addresses to verify x86_64 .o files
+
+
+----- Tagged ld64-82
+
+2008-01-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5694612> Bad grammar used in ld warning: cannot exported hidden symbol
+ * src/ld.cpp: fix typo in warning string
+
+
+2008-01-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5565074> Bundle Loader does not work anymore when loader is a bundle
+ <rdar://problem/5590203> ld warns of incorrect architecture when linking a bundle to a bundle
+ * src/MachOReaderDylib.hpp: support linking against bundles via -bundle_loader. Clean up error messages
+ * unit-tests/test-cases/bundle_loader: update test case
+
+
+2008-01-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5366363> ld -r -x creates debug notes (stabs) when it should not with -x (keep only global symbols)
+ * src/Options.cpp: in reconfigureDefaults() if -r and -x then -S
+
+
+2008-01-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5566068> if ld crashes while writing output file, it should delete the half written file
+ * src/MachOWriterExecutable.hpp: wrap open/write/close in try block and add signal handlers all to delete
+ output file on failure.
+
+
+2008-01-16 Devang Patel <dpatel@apple.com>
+
+ * src/LLVMReader.hpp: Use __gnu_cxx::hash_map instead of hash supported by LLVM.
+
+
+2008-01-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5593537> GC-supported library can't be linked into GC-required executable
+ * src/ld.cpp: loosen constraint that all objc code must be compiled with same GC settings and
+ allow gc-compatible code to be linked into anything.
+ * unit-tests/test-cases/objc-gc-checks: update test case
+
+
+2008-01-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5687976> no debug notes for custom named data
+ * src/ld.cpp: in synthesizeDebugNotes() check getSymbolTableInclusion() instead of for leading underscore
+ * unit-tests/test-cases/dwarf-debug-notes: update test case
+
+----- Tagged ld64-81.5
+
+2008-01-14 Devang Patel <dpatel@apple.com>
+
+ <rdar://problem/5683813> llvm-gcc-4.2 fails to build Sqlite 3.5.4 with -O4
+ * src/LLVMReader.hpp: Resolve proxy references. Collect new unbounded references
+ after optimization.
+ * src/ld.cpp: Resolve additional unbounded references after optimization.
+
+
+2008-01-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5655246> PPC Leopard (Xcode 3.0) linker ld gets "Bus error" sometimes
+ * src/MachOReaderRelocatable.hpp: use same code as x86 to parse ppc and arm sect-diff relocs
+ * src/MachOWriterExecutable.hpp: use same code as x86 to write ppc and arm sect-diff relocs
+
+
+2008-01-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5637618> PPC Leopard (Xcode 3.0) linker ld reports "unknown scattered relocation type 4"
+ * src/MachOReaderRelocatable.hpp: add PPC_RELOC_HI16 to scattered reloc parsing
+ * unit-tests/test-cases/relocs-asm/relocs-asm.s: added tests for scattered hi/lo instructions
+
+
+2008-01-11 Nick Kledzik <kledzik@apple.com>
+
+ * doc/man/man1/ld.1: add doc for -no_implicit_dylibs, -read_only_stubs, -slow_stubs, -interposable_list
+
+
+2008-01-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4800212> ld64(1) man page uses ambiguous term "suffix"
+ * doc/man/man1/ld.1: make meaning of "suffix" more explicit
+
+
+2008-01-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5633081> Obj-C Symbols in Leopard Can't Be Weak Linked
+ * src/MachOWriterExecutable.hpp: set weak and lazy attributes on dummy .objc_class_name undefines
+ to dylibs to support Mac OS X 10.3.x dyld
+
+
+2008-01-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5669751> Unknown error with linker (dyld: unknown external relocation type)
+ * src/ld.cpp: fix crash when SO stabs are not balanced
+
+
+2008-01-11 Devang Patel <dpatel@apple.com>
+
+ <rdar://problem/5667433> LTO does not work if expected output is a dynamic library
+ * src/LLVMReader.hpp: Supply arguments describing output kind to optimizer. Communicate
+ visibility info.
+
+2000-01-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5680988> __cls_refs section is losing S_LITERAL_POINTERS section type
+ * src/MachOWriterExecutable.hpp: special case __cls_refs section
+ * unit-tests/test-cases/objc-literal-pointers: add test case
+
+
+2008-01-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5667688> wrong EH information might be used
+ Created new kGroupSubordinate reference kind to model group comdat. The "signature" atom
+ has kGroupSubordinate references to the other atoms in the group. If the signature atom
+ is coalesced away, the linker follows kGroupSubordinate references and throws away the
+ other members of the group.
+ * unit-tests/test-cases/eh-coalescing: added test case
+ * src/ld.cpp: added markDead() and use propagate to subordinates
+ * src/Architectures.hpp: added kGroupSubordinate
+ * src/MachOReaderRelocatable.hpp: add kGroupSubordinate reference from a function to its .eh atom
+ and if used, from .eh atom to its LSDA atom.
+ * src/MachOWriterExecutable.hpp: handle kGroupSubordinate like kNoFixUp
+
+----- Tagged ld64-81.4.1
+
+2007-12-19 Devang Patel <dpatel@apple.com>
+
+ * src/LLVMReader.hpp: Add LLVM_LTO_VERSION #ifdef check.
+
+2007-12-19 Devang Patel <dpatel@apple.com>
+
+ * src/LLVMReader.hpp: Add fOptimizer NULL check before calling printVersion().
+
+2007-12-19 Devang Patel <dpatel@apple.com>
+
+ <rdar://problem/5655956> print LLVM LTO version number in verbose mode
+ * src/LLVMReader.hpp: Add printLLVMVersion() to print llvm version string in verbose mode.
+ * src/Options.cpp: Use printLLVMVersion() in verbose mode.
+
+2007-12-19 Devang Patel <dpatel@apple.com>
+
+ <rdar://problem/5655956> print LLVM LTO version number in verbose mode
+ * src/Options.h: Add verbose() method to check fVerbose flag.
+ * src/LLVMReader.hpp: Print LLVM version string in verbose mode.
+
+----- Tagged ld64-81.4
+
+2007-12-18 Devang Patel <dpatel@apple.com>
+
+ * src/LLVMReader.hpp: Invalidate input architecture when optimizer is not available.
+
+----- Tagged ld64-81.3
+
+2007-12-17 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: remove extraneous header search paths
+
+
+2007-12-17 Devang Patel <dpatel@apple.com>
+
+ * src/LLVMReader.hpp: Do not throw exception if LLVMReader is not able to
+ dlopen LTO library. Instead just flag input file as an invalid LLVM bitcode file.
+
+
+2007-12-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5645908> gcc DejaGnu failure: gcc.dg/20020312-2.c (test for excess errors) (-fstack-protector-all)
+ * src/MachOWriterExecutable.hpp: fix Writer<x86>::generatesExternalTextReloc() to allow text relocs
+ * unit-tests/test-cases/read-only-relocs: updated test case to link a dynamic main executable compiled with -static
+
+
+2007-12-14 Devang Patel <dpatel@apple.com>
+
+ <rdar://problem/5648438> Enable Link Time Optimization in Opal
+ * src/LLVMReader.hpp: Locate LLVMlto.dylib relative to ld location in Developer folder.
+ * ld64.xcodeproj/project.pbxproj: Add {DEVELOPER_DIR}/usr/include in header search path.
+ * unit-tests/run-all-unit-tests: Set DYLD_FALLBACK_LIBRARY_PATH to find LLVMlto.dylib during unit testing.
+ * unit-tests/testcases/llvm-integration/Makefile: Point LLVMGCC and LLVMGXX to llvm-gcc-4.2 in Developer folder during unit testing.
+
+
+2007-12-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5645446> SWB: failures due to ld: pointer in read-only segment not allowed in slidable image, used in ...
+ * src/MachOReaderRelocatable.hpp: in Reader<x86>::addRelocReference() handle weak pc-rel 32-bit vanilla relocs properly
+
+----- Tagged ld64-81.2
+
+
+
+2007-12-07 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5615298> support 8-bit relocations for i386
+ * src/Architectures.hpp: add kPCRel8
+ * src/MachOReaderRelocatable.hpp: support 8-bit pc-rel relocations for intel
+ * src/MachOWriterExecutable.hpp: support 8-bit pc-rel relocations for intel
+ * unit-tests/test-cases/relocs-asm: add test cases
+
+
+----- Tagged ld64-81.1
+
+2007-12-06 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderDylib.hpp: rework cycle detection to remove some false positives
+
+
+2007-12-05 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5628149> Duplicate probe firings in Security.framework
+ * src/ld.cpp: check dtrace probe sites are not in fDeadAtoms before using
+ * unit-tests/test-cases/dtrace-static-probes-coalescing: add test case
+
+
+2007-12-05 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: fix CFString coalescing to work with -fwritable-strings
+ * unit-tests/test-cases/cfstring-coalesce: add -fwritable-strings to test case
+
+
+----- Tagged ld64-81
+
+2007-11-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4196067> ld64 should support runtime text relocations
+ * src/MachOWriterExecutable.hpp: add generatesLocalTextReloc() and generatesExternalTextReloc()
+ * src/Options.cpp: process -read_only_relocs option
+ * src/Options.h: add allowTextRelocs() and warnAboutTextRelocs()
+ * src/MachOReaderRelocatable.hpp: add hasLongBranchStubs()
+ * src/machochecker.cpp: allow relocs in read only segments, if section flags are set
+ * unit-tests/test-cases/read-only-relocs: update test case
+
+
+2007-11-08 Devang Patel <dpatel@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: add new build phase "build configure.h" for
+ ld target.
+ * src/ld.cpp: Include "configure.h"
+
+
+----- Tagged ld64-80.11
+
+2008-02-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5741312> Wrong section name for objc info for ARM when OBJC2 is used
+ * src/MachOWriterExecutable.hpp: switch segment/section name for ARM objc2 image info
+
+----- Tagged ld64-80.10
+
+2008-02-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5733578> ld64 does not support -aspen_version_min 2.0
+ * src/Options.cpp: allow 2.x for -aspen_version_min
+
+
+2008-02-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5733575> ld_classic: unknown flag: -aspen_version_min
+ * src/Options.cpp: change -aspen_version_min x.x to -macosx_version_min 10.5 when invoking ld_classic
+
+
+----- Tagged ld64-80.9
+
+2008-01-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5713054> -iphone_version_min ==> -aspen_version_min
+ * src/Options.cpp: support -aspen_version_min
+
+
+----- Tagged ld64-80.8
+
+2008-01-10 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: support transition to new objc ABI for ARM by allowing old .objc_class_name_*
+ style names in export files and map them to new _OBJC_CLASS_$_ style names.
+
+
+----- Tagged ld64-80.7
+
+2008-01-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5572168> BigBear5A18 isn't fully prebound
+ * src/Options.cpp: make fNeedsModuleTable true for arm
+
+----- Tagged ld64-80.6
+
+2007-11-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5620976> -iphone_version_min
+ * src/Options.cpp: handle -iphone_version_min option
+
+
+----- Tagged ld64-80.5
+
+2007-11-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5601142> need to special case some dylibs in seg_addr_table
+ * src/Options.cpp: retry seg_add_table lookup for a couple of unusual dylibs
+
+
+----- Tagged ld64-80.4
+
+2007-11-06 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: fix parsing of external and scattered thumb branch22 relocs
+ * unit-tests/test-cases/thumb-blx: add test case to keep blx issues from coming back
+
+----- Tagged ld64-80.3
+
+2007-11-03 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: remove recalc of dstAddr which could cause thumb branches to be +2
+ * src/MachOWriterExecutable.hpp: remove incorrect test for relocateableExternal
+
+----- Tagged ld64-80.2
+
+2007-11-01 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: hack my own prototype for log2() until math.h is cleaned up
+
+
+----- Tagged ld64-80.1
+
+2007-11-01 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: add HEADER_SEARCH_PATHS for cross builds
+ * src/ld.cpp: temporarily disable LLVM_SUPPORT
+ * src/MachOWriterExecutable.hpp: Don't use CC_MD5() directly
+
+
+2007-10-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5556038> Cannot build with libm_static.a statically linked
+ * src/MachOWriterExecutable.hpp: Fix makesExternalRelocatableReference() for -r -d case
+ * unit-tests/test-cases/tentative-to-real-hidden: add test case
+
+
+----- Tagged ld64-80
+
+2007-10-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4222696> linker should probably warn about trying to export a hidden symbol
+ * src/ld.cpp: if using -exported_symbols_list check each hidden atom as it is added to symbol table
+ * src/Options.h,.cpp: add hasExportMaskList()
+ * unit-tests/test-cases/exported_symbols_list-hidden: added test case
+
+
+2007-10-24 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: keep old style dtrace probes externel for kernel builds
+
+
+2007-10-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4556199> unify error and warning messages
+ <rdar://problem/5546450> -w should suppress warnings
+ * src/ld.cpp: use warning() function
+ * src/Options.h: remove emitWarnings()
+ * src/MachOReaderDylib.hpp: use warning() function
+ * src/MachOReaderRelocatable.hpp: use warning() function
+ * src/Options.cpp: use and implement warning()
+ * src/MachOWriterExecutable.hpp: use warning() function
+ * unit-tests/test-cases/visibility-warning: verify -w suppresses warnings
+
+
+2007-10-23 Devang Patel <dpatel@apple.com>
+
+ * src/ld.cpp: Cover arm support inside __OPEN_SOURCE__ macro check.
+ * src/LLVMReader.hpp: Cover arm support inside __OPEN_SOURCE__ macro check.
+ * src/MachOReaderDylib.hpp: Cover arm support inside __OPEN_SOURCE__ macro check.
+ * src/ObjectFile.h: Cover arm support inside __OPEN_SOURCE__ macro check.
+ * src/MachOReaderRelocatable.hpp: Cover arm support inside __OPEN_SOURCE__ macro check.
+ * src/OpaqueSection.hpp: Cover arm support inside __OPEN_SOURCE__ macro check
+ * src/MachOWriterExecutable.hpp: Cover arm support inside __OPEN_SOURCE__ macro check.
+ * src/ObjectDump.cpp: Cover arm support inside __OPEN_SOURCE__ macro check.
+
+
+2007-10-22 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: add support for LD_DEAD_STRIP and LD_WARN_COMMONS
+ * src/MachOReaderRelocatable.hpp: fix problem with -dead_strip of ObjC literal pointers
+
+
+2007-10-22 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: have -static arm code link with ld_classic (for now)
+
+
+2007-10-22 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5396826> Recognize all arm architectures
+ * src/MachOReaderRelocatable.hpp: add support for all ARM sub-types
+ * unit-tests/test-cases/cpu-sub-types: add test cases for all combinations of ARM sub-types
+
+
+2007-10-19 Nick Kledzik <kledzik@apple.com>
+
+ * src/*: merge in arm support
+ * unit-tests/test-cases/*: fix to work for arm and thumb
+
+----- Tagged ld64-79
+
+2007-10-16 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: if -r mode, always set custom alignment (SET_COMM_ALIGN) on common symbols
+ * unit-tests/test-cases/visibility-warning-dylib-v-archive/Makefile: fix warning
+ * unit-tests/test-cases/static-executable/Makefile: fix spurious failure
+
+
+2007-10-16 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix edge case in branch island generation
+
+
+2007-10-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5323449> Add option to create old, slow stubs for i386
+ * src/ObjectFile.h/.cpp: support -read_only_stubs
+ * src/MachOWriterExecutable.hpp: enhance StubAtom<x86> to support old style __symbol_stub/__la_symbol_ptr stubs
+ * unit-tests/test-cases/slow-x86-stubs: add test case
+
+
+2007-10-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5427952> ld64's re-export cycle detection logic prevents use of X11 libGL on Leopard
+ * src/Options.cpp: in findFileUsingPaths() don't search for embedded dylibs
+ * unit-tests/test-cases/indirect-path-search/Makefile: added case for a dylib embedded in a framework
+
+
+2007-10-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
+ * src/Options.cpp: add support for -no_implicit_dylibs
+ * src/ObjectFile.h: add fImplicitlyLinkPublicDylibs
+ * src/MachOReaderDylib.hpp: test fImplicitlyLinkPublicDylibs before hoisting an implicitly linked dylib
+ * unit-tests/test-cases/implicit_dylib: add test case
+
+
+2007-10-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5254413> -interposable_list
+ * src/Options.h/cpp: Add fInterposeList and fInterposeMode to support -interposable_list
+ * src/MachOWriterExecutable.hpp: pass symbol name to fOptions.interposable()
+ * unit-tests/test-cases/interposable_list: add test case
+
+
+2007-10-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5529626> If only weak_import symbols are used, linker should use LD_LOAD_WEAK_DYLIB
+ * src/MachOWriterExecutable.hpp: automatically use LC_LOAD_WEAK_DYLIB if all symbols used from a dylib are weak_import
+ * unit-tests/test-cases/weak_dylib: added test case
+
+
+2007-10-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5504954> linker does not error when dylib ordinal exceeds 250
+ * src/MachOWriterExecutable.hpp: error out if ordinals exceed max allowed
+
+
+2007-10-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4067110> overriding 'operator new' or 'operator delete' fails if no weak symbols are present
+ * src/ld.cpp: at end of checkUndefines() search dylibs for weak versions of any global external symbols
+ * src/ObjectFile.h: add hasWeakExternals() method to Reader
+ * src/MachOReaderDylib.hpp: implement hasWeakExternals() method in Reader
+ * src/ExecutableFile.h: add overridesDylibWeakDefines parameter to write()
+ * src/MachOWriterExecutable.hpp: use overridesDylibWeakDefines parameter to write()
+ * unit-tests/test-cases/operator-new: add test case
+
+
+2007-10-05 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5048861> No warning about tentative definition conflicting with dylib definition
+ <rdar://problem/5132652> .comm variables in shared library, worked with XCode 2.4.1, broken with XCode 3?
+ * src/ld.cpp: at end of checkUndefines() verify if any remaining commons conflict with dylibs
+ * doc/man/man1/ld.1: document -commons and -warn_commons options
+ * unit-tests/test-cases/tentative-and-dylib: added test case
+
+
+2007-10-05 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5346331> NS/CFString constants are not dead strippable
+ * src/MachOReaderRelocatable.hpp: break up __cfstring section into one atom per cfstring, make them coalesable
+ * unit-tests/test-cases/cfstring-coalesce: added test case
+
+
+2007-10-05 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5524973> Dead stripping + exported symbols list using wildcards doesn't seem to do the right thing
+ * src/Options.cpp/h: add hasWildCardExportRestrictList()
+ * src/ld.cpp: if dead stripping code and have wildcard exports, add all global atoms matching wildcards as roots
+ * unit-tests/test-cases/exported-symbols-wildcards-dead_strip: added test case
+
+
+2007-10-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5433882> ld shouldn't search /Network/Library/Frameworks by default
+ * src/Options.cpp: remove /Network/Library/Frameworks/ from default search path
+ * doc/man/man1/ld.1: document the change
+
+
+2007-10-04 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5341567> all binaries should get LD_UUID load commands, not just those with DWARF symbols
+ * src/ld.cpp: default fCreateUUID to be true for non object file output types
+ * unit-tests/test-cases/no-uuid/Makefile: update test case to match new rules
+
+
+----- Tagged ld64-78
+
+2007-09-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5476313> range check load commands
+ * src/MachOReaderDylib.hpp: check that load commands all fit in load command size from header
+ * src/MachOReaderRelocatable.hpp: check that load commands all fit in load command size from header
+
+
+2007-09-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5433355> Xc8M2540a: ld64 crashes when linking Pascal program
+ * src/ld.cpp: fix findAtomAndOffset() to handle where there are no function atoms
+
+
+2007-09-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5241179> ADOBE Xcode 3: ld -dead_strip does not work with -init from an archive
+ * src/ld.cpp: add bool parameter to entryPoint() so -init atom not looked for too soon
+ * unit-tests/test-cases/dead_strip-init-archive: added test case
+
+
+2007-09-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5459546> Spurious link warnings for inline members of C++ template classes
+ * src/ld.cpp: check definition kinds before warning about visibility mismatches
+ * unit-tests/test-cases/visibility-warning: added test case
+
+
+2007-09-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5394172> an empty .o file with zero load commands will crash linker
+ * src/MachOReaderRelocatable.hpp: have Reader constructor return early of no load commands
+ * unit-tests/test-cases/empty-object: added test case
+
+
+2007-09-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5453384> 9a527: ppc64 branch islands fail with 4GB pagezeo
+ * src/MachOWriterExecutable.hpp: start range calculations at start of __text not at zero.
+
+
+----- Tagged ld64-77 (Xcode 3.0)
+
+2007-07-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5351380> Kernel is linked with some global symbols unsorted
+ * src/MachOWriterExecutable.hpp: Add NListNameSorter to allow global atoms and extra labels to be sorted
+
+
+2007-07-20 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5254468> Can't do objc_msgSendSuper dispatches after loading a Fix&Continue bundle
+ * src/MachOWriterExecutable.hpp: when calculating what kind of reloc to use, never use an
+ external reloc to reference 32-bit ObjC symbols.
+
+
+2007-07-20 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5349847> Runtime crash with ICC math library on Leopard
+ * src/MachOReaderRelocatable.hpp: detect if section starts with a symbol that is not
+ aligned to section and correct it.
+
+
+----- Tagged ld64-76
+
+2007-06-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5303718> export hiding does not work for frameworks
+ * src/MachOReaderDylib.hpp: fix checks in isPublicLocation()
+ * unit-tests/test-cases/symbol-moving: update to test frameworks as well as dylibs
+
+
+2007-06-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5299907> linker should use undefines from flat dylibs when linking a main flat
+ * src/ObjectFile.h: added fLinkingMainExecutable
+ * src/Options.cpp: set up fLinkingMainExecutable
+ * src/MachOReaderDylib.hpp: when linking a main executable for flat namespace, the reader for
+ any loaded flat namespace dylib will have a new atoms that has references to all undefined
+ symbols in the dylib
+ * unit-tests/test-cases/flat-indirect-undefines: added test case
+ * doc/man/man1/ld.1: update man page to describe when dylib undefines are used
+
+
+2007-06-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5277857> OpenGL.framework and X11 both have a libGL.dylib which can cause ld to segfault if both are found
+ * src/MachOReaderDylib.hpp: add assertNoReExportCycles() method
+ * unit-tests/test-cases/dylib-re-export-cycle: added test case
+
+
+2007-06-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5286462> ld64 has slightly different warning message formats than the old ld
+ * src/ld.cpp: standardize all warning messages to start with "ld: warning"
+ * src/MachOWriterExecutable.hpp: ditto
+ * src/MachOReaderRelocatable.hpp: ditto
+ * src/MachOReaderDylib.hpp:ditto
+
+
+2007-06-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5297034> -dead_strip can cause duplicate external commons
+ * src/ld.cpp: don't use discarded coalesced global atoms as dead strip roots
+ * src/machochecker.cpp: error if duplicate external symbols
+ * unit-tests/test-cases/commons-coalesced-dead_strip: added test case
+
+
+2007-06-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4135857> update man page that linker does not search indirect libraries with two-level namespace
+ * doc/man/man1/ld.1: add new "Indirect dynamic libraries" section to man page
+
+
+2007-06-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5285473> Xc9A466: Exports file cannot use Mac line ends
+ * src/Options.cpp: check for \r or \n when parsing .exp files
+ * unit-tests/test-cases/exported_symbols_list-eol: added test case
+
+
+----- Tagged ld64-75
+
+2007-05-31 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4607755> Simplier, generalized way to re-export dylibs: LC_REEXPORT_DYLIB
+ * src/MachOWriterExecutable.hpp: Use LC_REEXPORT_DYLIB when targetting 10.5
+
+
+----- Tagged ld64-74.5
+
+2007-05-31 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5241902> set OSO timestamp to zero for when building in buildit
+ * src/ld.cpp: check for RC_RELEASE and if exists set all OSO timestamps to zero
+
+
+2007-05-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5224676> BUILD_STABS now causes ld of xnu to bus error
+ * src/ld.cpp: Change || to && in collectStabs()
+
+
+----- Tagged ld64-74.4
+
+2007-05-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5211667> static probes don't work with libraries in dyld shared cache
+ * src/OpaqueSection.hpp: the __TEXT segment is executable
+
+
+----- Tagged ld64-74.3
+
+2007-05-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5201463> ppc: linker adds stubs to cstring references
+ * src/MachOWriterExecutable.hpp: update ppc stubableReference() to only allow high/low references
+ to be stubed if they reference a symbol in some other dylib.
+ * unit-tests/test-cases/stub-generation: added test case
+
+
+2007-05-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5008421> ppc64: need to make LOCAL indirect symbol table entry for now local symbol
+ * src/MachOWriterExecutable.hpp: factored local tests into indirectSymbolIsLocal()
+ * unit-tests/test-cases/non-lazy-r: added test case
+
+
+2007-05-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5198807> ld64 drops fix&continue bit in __OBJC, __image_info.
+ * src/MachOReaderRelocatable.hpp: implement objcReplacementClasses()
+
+
+2007-05-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5066152> support __image_info in __DATA segment for 64-bits
+ * src/MachOReaderRelocatable.hpp: use strncmp() for __objc_imageinfo since it is 16 bytes long
+ * src/MachOWriterExecutable.hpp: specialize segment/section names for synthesized objc image info section
+
+
+2007-05-15 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/include/common.makefile: set COMPILER_PATH so harness works with latest compiler
+
+
+----- Tagged ld64-74.2
+
+2007-05-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5195447> ld64-74.1 breaks libstdc++ DejaGnu test (G5 only)
+ * src/MachOWriterExecutable.hpp: don't stub a reference if the target offset is non-zero
+
+
+----- Tagged ld64-74.1
+
+2007-05-09 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.h: add emitWarnings()
+ * src/Options.cpp: wire up -w to emitWarnings()
+
+
+2007-05-09 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5137285> ld64 won't link wine (regression from Tiger)
+ * src/Architectures.hpp: add x86::kPointerDiff16 and x86::kPCRel16
+ * src/MachOReaderRelocatable.hpp: add support to parse new relocs
+ * src/MachOWriterExecutable.hpp: add support fo new relocs
+
+
+2007-05-08 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5182537> need way for ld and dyld to see different exported symbols in a dylib
+ * src/MachOReaderDylib.hpp: update parse and use $ld$ symbols
+ * src/Options.h: move VersionMin to ReaderOptions
+ * src/ObjectFile.h: move VersionMin to ReaderOptions
+ * src/Options.cpp: move VersionMin to ReaderOptions
+ * src/MachOWriterExecutable.hpp: move VersionMin to ReaderOptions
+ * unit-tests/test-cases/symbol-moving: added test case
+
+
+2007-05-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5181105> typo in error message for linking -pie
+ * src/MachOWriterExecutable.hpp: fix typo in error messages
+
+
+----- Tagged ld64-74
+
+2007-05-03 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5171880> ld64 can't find @executable _path relative dylibs from our umbrella frameworks
+ <rdar://problem/4019497> ld64 should handle linking against dylibs that have @loader_path based dylib load commands
+ * src/ObjectFile.h: add from parameter to findDylib()
+ * src/MachOReaderDylib.hpp: supply from parameter to findDylib()
+ * src/ld.cpp: use from parameter for @loader_path substitution in findDylib()
+ * unit-tests/test-cases/re-export-relative-paths: added test case
+
+
+2007-05-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/ObjectFile.h: add fLogObjectFiles and fLogAllFiles
+ * src/Options.cpp: hook up -t to fLogAllFiles and -whatsloaded to fLogObjectFiles
+ * src/MachOReaderDylib.hpp: log if fLogAllFiles
+ * src/MachOReaderRelocatable.hpp: log if fLogObjectFiles or fLogAllFiles
+ * src/MachOReaderArchive.hpp: log if fLogAllFiles
+ * doc/man/man1/ld.1: update man page
+
+
+2007-05-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5177848> typo in message, frameowrk
+ * src/Options.cpp: fix typo
+
+
+2007-05-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4977301> "ld" man page is missing the description for many options
+ * doc/man/man1/ld.1: add documentation on all obsolete options
+
+
+2007-05-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5113424> ld doesn't handle -mlong-branch .o files that have had local symbols stripped
+ <rdar://problem/4965359> warning about dwarf line info with -mlong-branch
+ * src/MachOReaderRelocatable.hpp: don't lop -mlong-branch stubs off end of functions
+ * src/MachOWriterExecutable.hpp: allow code references besides BR24 to be stubable
+
+
+2007-04-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5065659> unable to link VTK because __textcoal_nt too large
+ * src/MachOReaderRelocatable.hpp: when doing a final link map __textcoal_nt to __text
+
+
+2007-04-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5062685> ld does not report error when -r is used and exported symbols are not defined.
+ <rdar://problem/4637139> ld leaves global common symbols not in exported symbols list.
+ * src/ld.cpp: stop special casing -r mode in checkUndefines()
+ * src/MachOWriterExecutable.hpp: don't create proxy atom in -r mode if it is supposed to be exported.
+ mark tentative definitions are private extern in -r mode even without -keep_private_externs
+ * unit-tests/test-cases/exported_symbols_list-r: added test case
+
+
+2007-04-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5137732> ld should keep looking when it finds a weak definition in a dylib
+ * src/ld.cpp: modified addJustInTimeAtoms() to keep looking when a weak defintion is found
+ * unit-tests/test-cases/weak-def-ordinal: added test case
+
+
+2007-04-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5166572> better error message for indirect dylibs missing required architecture
+ * src/ld.cpp: when loading indirect dylib add path to error messages
+
+
+2007-04-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5109373> the i386 slice of dyld does not need __IMPORT segment
+ * src/ObjectFile.h: add fForDyld
+ * src/Options.cpp: set up fForDyld
+ * src/MachOReaderRelocatable.hpp: if fForDyld, change __IMPORT segment to __DATA
+ * src/MachOWriterExecutable.hpp: recognize __DATA/__pointers in dyld as a non-lazy section
+
+
+2007-04-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5008421> ppc64: need to make LOCAL indirect symbol table entry for now local symbol
+ * src/MachOWriterExecutable.hpp: use INDIRECT_SYMBOL_LOCAL for any non-global symbol
+ * unit-tests/test-cases/strip_local: update test case
+
+
+2007-04-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5150407> ld64 -sectorder and -order_file files don't accept white space following the :
+ * src/Options.cpp: prune white space after colon and before symbol name
+ * unit-tests/test-cases/order_file: update test case to have a space after the colon
+
+
+2007-04-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5055233> ld64 corrupts debug symbol table entries, nm doesn't print them
+ * src/MachOWriterExecutable.hpp: properly set ilocalsym in module table
+
+
+2007-04-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5066152> support __image_info in __DATA segment for 64-bits
+ * src/MachOReaderRelocatable.hpp: look for new objc info section name too
+
+
+2007-04-24 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix -non_global_symbols_strip_list to work with -r
+ * unit-tests/test-cases/local-symbol-partial-stripping: update test case
+
+
+
+----- Tagged ld64-73.7
+
+2007-05-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5194804> can't use dtrace static probes in x86_64 dylib
+ * src/MachOWriterExecutable.hpp: x86_64:kPointerDiff32 is ok in shared region
+ * unit-tests/test-cases/dtrace-static-probes: update to build dylib too
+
+
+2007-05-09 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5191610> 9A430: using -dead_strip with static dtrace probes causes ld to crash
+ * src/ld.cpp: fix markLive() to look at right name in dtrace probe refernce
+ * unit-tests/test-cases/dtrace-static-probes: added -dead_strip case
+
+
+----- Tagged ld64-73.6
+
+2007-04-17 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5140897> Add options to do partial stripping of local symbols
+ * src/MachOWriterExecutable.hpp: use fOptions.keepLocalSymbol()
+ * src/Options.cpp: implement -non_global_symbols_no_strip_list and -non_global_symbols_strip_list
+ * src/Options.h: replace stripLocalSymbols() with localSymbolHandling() and keepLocalSymbol()
+ * doc/man/man1/ld.1: document -non_global_symbols_no_strip_list and -non_global_symbols_strip_list
+ * unit-tests/test-cases/local-symbol-partial-stripping: added test case
+
+
+----- Tagged ld64-73.5
+
+2007-04-17 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5129379> ld64-73.3 XBS logging incorrectly reporting "direct" dynamic libraries
+ * src/ld.cpp: restore direct vs indirect library for LD_TRACE_DYLIBS logging
+
+
+2007-04-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5067034> data initialized to a weak imported symbol is missing relocation
+ * src/MachOWriterExecutable.hpp: check for A::kPointerWeakImport in buildExecutableFixups()
+ * unit-tests/test-cases/weak_import: updated test case to catch this problem
+
+
+2007-04-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5071047> Support -U
+ * src/MachOWriterExecutable.hpp: create proxies for -U symbols
+ * src/Options.cpp: process -U
+ * src/Options.h: add allowedUndefined() and someAllowedUndefines()
+ * src/ld.cpp: create proxies for -U symbols
+ * doc/man/man1/ld.1: document -U and -undefined options
+ * unit-tests/test-cases/undefined-dynamic-lookup: added test case
+
+
+----- Tagged ld64-73.4
+
+2007-04-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5125280> ld changes needed to support read-only DOF
+ * src/Options.cpp: remove -read_only_dof
+ * src/Options.h: remove fReadOnlyDOFs
+ * src/ld.cpp: only generate read-only DOF sections
+
+
+----- Tagged ld64-73.3.1
+
+2007-04-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5130496> -framework vecLib -framework Accelerate causes bad ordinals
+ * src/MachOWriterExecutable.hpp: fix bug optimizeDylibReferences() when there are two readers with same install name
+
+
+----- Tagged ld64-73.3
+
+2007-04-03 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: read-only-dofs should use 32-bit offsets for x86_64
+ * src/MachOReaderDylib.hpp: if "public" re-export is not marked implict, still mark it as re-exported
+
+
+2007-04-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5105971> if replacement file for -dylib_file is missing, warn instead of error
+ * src/ld.cpp: a try/catch to turn -dylib_file error into a warning.
+ * unit-tests/test-cases/dylib_file-missing: add test case
+ * doc/man/man1/ld.1: update man page about -dead_strip_dylibs
+
+
+----- Tagged ld64-73.2
+
+2007-03-31 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5102873> ld64-73: atom sorting error with duplicate zero sized bss symbols
+ * src/MachOReaderRelocatable.hpp: suppress warning on sorting zero size zero fill atoms
+
+2007-03-31 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5102845> ld64-73 fails anything linking with -lm
+ * src/ld.cpp: when processing dylbs that are sylinks ensure that fDylibMap contains all paths
+ * src/MachOWriterExecutable.hpp: when dead stripping dylibs and renumbering ordinals make sure
+ aliases dylib get renumbered too
+ * unit-tests/test-cases/dylib-aliases: added
+
+
+----- Tagged ld64-73.1
+
+2007-03-30 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: back out use of LC_REEXPORT_DYLIB until rdar://problem/5009909 is in build fleet
+
+
+----- Tagged ld64-73
+
+2007-03-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4175790> ER: -dead_strip_dylibs
+ <rdar://problem/3904828> linker should add implicit load commands for indirectly used public dylibs
+ * src/ObjectFile.h: change dylib reader interface to implictly/explicitlyLinked
+ * src/ld.cpp: use new dylib reader interface
+ * src/Options.h: add deadStripDylibs()
+ * src/Options.cpp: support -dead_strip_dylibs
+ * src/MachOReaderDylib.hpp: use new dylib reader interface
+ * src/MachOWriterExecutable.hpp: remove dylib load commands for unused dylibs and alter ordinals
+ * unit-tests/test-cases/re-export-optimizations: added
+ * unit-tests/test-cases/dead_strip_dylibs: added
+
+
+2007-03-30 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: enable -lfoo to search for libfoo.so as well as libfoo.dylib,
+ remove seg addr table hack for transitioning to new linker
+
+2007-03-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5073800> ADOBE XCODE3: Linker is slow with large C++ .o files
+ * src/MachOReaderRelocatable.hpp: the compiler generates stubs to weak functions in the
+ same translation unit. Don't treat those like the spurios stubs to static functions.
+
+
+2007-03-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4739044> ld64 should link mach_kernel during xnu builds to support dtrace
+ * src/MachOReaderRelocatable.hpp: To handle duplicate labels properly, rework how atoms sizes are set
+ by iterating through sorted fAtoms rather than fAddrToAtom, . Change default alignment of commons
+ to be the natural alignment of the size rounded up to the closest power of two and max it at 12.
+ Build atoms in reverse symbol table order so that global atoms are constructed before locals.
+ This assures that if there is a global and local label at the same location, the global label
+ will become the atom's name and the local will be an alias. Properly handle a label
+ at the end of a section. Handle R_ABS in relocations. Handle sect-diff relocs with addends.
+ Don't auto-strip 'l' symbols in static executables (mach_kernel).
+ * src/OpaqueSection.hpp: opaque_section now has an ordinal
+ * src/ld.cpp: opaque_section now requires an ordinal
+ * src/ObjectFile.h: add ReaderOptions.fForStatic
+ * src/Options.cpp: set fForStatic when building a static executable
+ * src/MachOWriterExecutable.hpp: add from atom to StubAtom<ppc>. Properly write out i386
+ sect-diff relocs with addends. properly write out ppc PICbase relocs where pic base
+ is not in the atom.
+
+
+2007-03-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5085863> Typo in ld man page (-exported_symbols_list)
+ * doc/man/man1/ld.1: fix typo
+
+
+2007-03-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4727750> consider generating LC_UUID from a checksum of the file
+ * src/Options.h: change emitUUID() to getUUIDMode()
+ * src/Options.cpp: support -random_uuid
+ * src/MachOWriterExecutable.hpp: set uuid to be md5 hash of entire output file
+
+
+2007-03-24 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: restructure writeAtoms() to copy all atoms in memory if possible
+
+
+2007-03-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5082603> ld -r of stripped .o file can incorrectly merge non-lazy pointers
+ * src/MachOWriterExecutable.hpp: when generating a .o file, non-lazy pointer with target offsets should be
+ encoded as LOCAL in the indirect symbol table
+ * unit-tests/test-cases/stripped-indirect-symbol-table: added test case
+
+
+2007-03-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5084564> SWB: ld64-72 errors building with gcc-4.2
+ * src/MachOReaderDylib.hpp: add curly brackets in switch cases
+ * src/MachOWriterExecutable.hpp: rearrange classes so there are no template specialization forward references
+
+
+2007-03-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: fix -print_statistics when using -dead_strip
+
+
+2007-03-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: generate better names for non-lazy pointers to the interior of atoms
+
+
+2007-03-16 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: speed up ld -r a little by reversing relocs en mas
+
+
+2007-03-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4975277> ld Bus Error on missing command line arguments
+ * src/Options.cpp: check next argv[] is not NULL
+
+
+2007-03-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4832049> need to be able to order symbols in anonymous namespaces
+ * src/ld.cpp: add logic to do fuzzy matching of symbols with anonymous namespace usage
+ * unit-tests/test-cases/order_file-ans: added test case
+
+
+2007-03-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5042552> headerpad_max_install_names deprecated for 64-bit
+ * src/ld.cpp: make sure dylib load command order matches command line order
+ * src/Options.h: add maxMminimumHeaderPad()
+ * src/Options.cpp: add maxMminimumHeaderPad() set by -headerpad_max_install_names
+ * src/src/MachOWriterExecutable.hpp: check maxMminimumHeaderPad()
+ * doc/man/man1/ld.1: update man page about -headerpad_max_install_names
+
+
+2007-03-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4592484> Linker returns success although exported symbols are undefined.
+ * src/ld.cpp: turn missing symbols back into an error
+
+
+2007-03-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4019497> ld64 should handle linking against dylibs that have @loader_path based dylib load commands
+ * unit-tests/test-cases/loader_path: added test case
+
+
+2007-03-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/3904828> linker should add implicit load commands for indirectly used public dylibs
+ <rdar://problem/4142277> Indirect libraries should be found using -F and -L options
+ <rdar://problem/4607755> Simplier, generalized way to re-export dylibs: LC_REEXPORT_DYLIB
+ * src/ld.cpp: reworked all dylib processing. Readers can now add the dylib list.
+ * src/Options.h: add findFileUsingPaths()
+ * src/MachOReaderDylib.hpp: look in re-exported children instead of requring linker to do that
+ * src/ObjectFile.h: add processIndirectLibraries(), remove getDependentLibraryPaths()
+ * src/machochecker.cpp: support LC_REEXPORT_DYLIB
+ * src/ExecutableFile.h: simplify DyLibUsed
+ * src/Options.cpp: add findFileUsingPaths(). add new re-export options
+ * src/MachOWriterExecutable.hpp: Use LC_REEXPORT_DYLIB when targetting 10.5
+ * doc/man/man1/ld.1: updated with new re-export options
+ * unit-tests/test-cases/indirect-path-search: added tests that -F and -L work with indirect dylibs
+ * unit-tests/test-cases/re-export-cases: added tests for all combinations of re-exporting
+
+
+2007-03-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4982400> sort external relocations to optimize dyld performance
+ * src/MachOWriterExecutable.hpp: added ExternalRelocSorter
+ * src/machochecker.cpp: verify external relocations are grouped by symbol number
+ * unit-tests/test-cases/external-reloc-sorting: added test case
+
+
+----- Tagged ld64-72
+
+2007-03-06 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: ignore .objc_category_name_* symbols in .exp files
+
+
+2007-03-06 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: stop special casing mach_kernel and instead requre kernel to be built with -new_linker
+
+
+2007-03-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5044253> ld64-72 (experimental) is causing DejaGnu test failures
+ * src/MachOWriterExecutable.hpp: add optimizableGOTReferenceKind() to track GOT uses that cannot be optimized
+
+
+2007-03-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5026135> minimum header padding should be 32 to allow code signing
+ * src/Options.cpp: initialize fMinimumHeaderPad to 32
+ * src/MachOWriterExecutable.hpp: better calculation of header padding
+
+
+2007-03-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5033206> Linker crashes with -flat_namespace against two-level dylibs that might have re-exports
+ * src/ld.cpp: flat namespace should not allow NULL indirect readers
+
+
+2007-03-06 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: don't error on S_COALESCED sections with anonymous atoms
+ * src/MachOWriterExecutable.hpp: set MH_PIE bit when linking -pie
+ * ld64.xcodeproj/project.pbxproj: don't echo environment when running unit test
+
+
+2007-03-01 Nick Kledzik <kledzik@apple.com>
+
+ * doc/man/man1/ld.1: Add descriptions to all "rarely used options"
+
+
+2007-03-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4971033> Remove support for Essential Symbols: Warn about use of -Sp option; remove man page entry
+ * src/Options.cpp: make -Sp obsolete
+ * doc/man/man1/ld.1: make -Sp obsolete
+
+
+2007-03-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5040314> Support -pie
+ * src/Options.h: Add positionIndependentExecutable()
+ * src/Options.cpp: Support -pie option to set positionIndependentExecutable()
+ * src/MachOWriterExecutable: if -pie is used, add extra local relocations and error if any
+ absolute addressing is used
+
+
+2007-03-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4739044> ld64 should link mach_kernel during xnu builds to support dtrace
+ * src/ld.cpp: Ensure segments are laid out in discovery order. Add support for kAbsoluteSymbol.
+ Warn when merging symbols of different visiblity. Warn when a tentative definition
+ is replaced by one a real definition with a smaller size. Lay out __common section
+ so that ones built with -fno-commons come before regular commons.
+ * src/ObjectFile.h: remove SegmentOffset ivar and getter/setters
+ * src/machochecker.cpp: allow images with no r/w segments
+ * src/MachOReaderRelocatable: Add AbsoluteAtom. Sort tentative definitions by name instead of by size
+ Add support for custom commons alignment.
+ * src/Options.cpp: Fix spurious -sectalign warnings. Don't use ld_classic when linking mach_kernel
+ * src/MachOWriterExecutable.hpp: Support kAbsoluteSymbol atoms. In -r mode, set custom alignment
+ for commons if alignment is not its size. Support global __dtrace_probe labels.
+ * src/ObjectDump.cpp: add support for kAbsoluteSymbol atoms.
+ * unit-tests/test-cases/commons-alignment: Added test case for custom commons alignment
+ * unit-tests/test-cases/absolute-symbol: Added test case for basic absolute symbols
+ * unit-tests/test-cases/segment-order: Added test case that segments lay out in discovery order
+ * unit-tests/test-cases/commons-order: Added test case that commons lay out correctly
+ * unit-tests/test-cases/end-label: Added test case that a label used to mark the end of a section does not
+ get associcated with the next section.
+
+
+2007-02-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/3965017> gcc-5005: DejaGnu failures due to -frepo
+ * src/ld.cpp: Add quotes to referenced from name to make collect2 and -frepo happy
+
+
+2007-02-22 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: rework how padding after load commands is calculated
+
+
+2007-02-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: extend special case of __mh_execute_header to static executables too
+
+
+2007-02-21 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/3882294> gcc link map option ( "-M" ) should be redirectable to file
+ * doc/man/man1/ld.1: added -map option description
+ * src/Options.h: added generatedMapPath()
+ * src/Options.cpp: set up generatedMapPath() if -map option is used
+ * src/MachOWriterExecutable.hpp: add writeMap() method to generate map file
+
+
+2007-02-19 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4557734> Implement GOT Load elimination optimization
+ * src/ld.cpp: track size of all atoms and if > 2GB sort large zero-fill atoms to end
+ * src/MachOWriterExecutable.hpp: If image size < 2GB, only generate GOT entries if value must be
+ updatable by dyld. If > 2GB, only eliminate GOT entries to non-zero-fill atoms. Any use
+ of an eliminated GOT entry has its code changed from MOVQ _foo@GOT(%rip) to LEAQ _foo(%rip).
+ * unit-tests/test-cases/large-data: added
+ * unit-tests/test-cases/got-elimination: added
+
+
+----- Tagged ld64-71.2
+
+2007-02-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4995303> new ld ignores -segprot option
+ * src/Options.h: expose customSegmentProtections()
+ * src/Options.cpp: parse -segprot option and populate customSegmentProtections()
+ * src/MachOWriterExecutable.hpp: use customSegmentProtections()
+
+
+2007-02-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4988068> i386 -stack_addr doesn't work
+ * src/MachOWriterExecutable.hpp: use correct offset into thread state record
+
+
+----- Tagged ld64-71.1
+
+2007-02-07 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: sort __OBJC2 segment to be next to __OBJC segment
+
+
+2007-02-07 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: change missing -seg_addr_table from an error to a warning
+
+
+2007-02-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4977311> Leopard 9A357: -dylib_file broken?
+ * src/MachOWriterExecutable.hpp: remove use of fInstallPathOverride
+ * src/Options.cpp: wire up -dylib_file option
+ * src/Options.h: remove fInstallPathOverride. add fDylibOverrides
+ * src/ld.cpp: check dylibOverrides() for indirect libraries
+ * unit-tests/test-cases/dylib_file: add test case
+
+
+2007-02-05 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderDylib.hpp: don't warn about zero size __image_info sections
+
+
+2007-02-04 Rick Balocca <rbalocca@apple.com>
+ Enable the failing cases for missing command line arguments
+
+2007-02-04 Rick Balocca <rbalocca@apple.com>
+ Make sure that all .o's are checked by ObjectDump
+ and all macho are checked by machochecker
+
+2007-02-04 Rick Balocca <rbalocca@apple.com>
+ Fix an endian problem with machochecker
+ Fix blank-stubs Makefile
+
+----- Tagged ld64-71
+
+2007-02-02 Rick Balocca <rbalocca@apple.com>
+ blank-stubs test case: handle the case of a native ppc compile--this
+ sets the subtype, which must be passed to lipo
+
+2007-02-01 Rick Balocca <rbalocca@apple.com>
+ make cpu-sub-types test more robust
+
+2007-02-01 Rick Balocca <rbalocca@apple.com>
+ auto-arch tests were resulting in a false FAILs
+
+2007-02-01 Rick Balocca <rbalocca@apple.com>
+ test cpu-sub-types was resulting in a false FAIL
+
+2007-02-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4969335> STD:VSC: c99 -o writes to file that does not have write permission
+ * src/MachOWriterExecutable.hpp: check file is writable before using it
+
+2007-02-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4965743> debug map (N_OSO) timestamps for object files in ranlib archive are incorrect
+ * src/MachOReaderArchive.hpp: parse modTime for .o files out of archive header
+
+2007-01-31 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4967535> 9A354: ld -all_load does *NOT* produce the same dSYM as *.o or -u
+ * src/ld.cpp: when using -all_load don't assume that all atoms have same reader
+ * unit-tests/test-cases/dwarf-archive-all_load: added
+
+----- Tagged ld64-70.1
+
+2007-01-31 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: in addObjectRelocs_powerpc() mask scattered r_address to 16-bits
+
+----- Tagged ld64-70
+
+
+2007-01-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4810668> linker should verify GC consistency of modules being linked into library
+ <rdar://problem/4474195> Support cpu-sub-types for ppc
+ * src/ObjectFile.h: Add getObjCConstraint() and getCpuConstraint()
+ * src/MachOReaderRelocatable.hpp: don't make atom for __image_info section, instead parse constaints
+ * src/MachOReaderDylib.hpp: look at __image_info content to get constaints
+ * src/ld.cpp: add updateContraints() and checkObjc()
+ * src/MachOWriterExecutable.hpp: add ObjCInfoAtom to sythesize __image_info content
+
+
+2007-01-28 Nick Kledzik <kledzik@apple.com>
+
+ src/*: remove ObjectFile::requiresFollowOnAtom() method
+
+
+2007-01-28 Nick Kledzik <kledzik@apple.com>
+
+ src/ld.cpp: enable LLVM_SUPPORT by default
+ src/LLVMReader.hpp: don't use absolute paths for llvm headers and libraries
+
+
+2007-01-26 Rick Balocca <rbalocca@apple.com>
+ * src/ObjectDump.cpp: The usage() message was incorrect.
+
+
+2007-01-25 Rick Balocca <rbalocca@apple.com>
+ * unit-tests/test-cases/zero-fill3: It was reporting FAIL on ld64 error return.
+ It should have been checking for non-error return.
+
+
+2007-01-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4952297> x86 fast stubs should not cross 64-byte boundries
+ * src/MachOWriterExecutable.hpp: for x86, 64-byte align __jump_table section
+ and make 64-btye crossing stubs be empty entries with indirect symbol table
+ entry of INDIRECT_SYMBOL_ABS
+
+
+2007-01-19 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.h: add readOnlyx86Stubs()
+ * src/Options.cpp: support -read_only_stubs
+ * src/MachOWriterExecutable.hpp: make __IMPORT segment not writable if -read_only_stubs is used
+
+
+2007-01-16 Eric Christopher <echristo@apple.com>
+
+ <rdar://problem/4856341> ld64 --help isn't recognized
+ * src/Options.cpp (Options::parse): Support --help and -help.
+
+
+2007-01-15 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOFileAbstraction.hpp: add range checking on macho_scattered_relocation_info::set_r_address()
+
+
+2007-01-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4514409> Support wildcards in contents of -exported_symbols_list
+ * src/Options.h: add SetWithWildcards class
+ * src/Options.cpp: add -exported_symbol and -unexported_symbol and use SetWithWildcards
+ * doc/man/man1/ld.1: add -exported_symbol and wildcard explanation
+ * unit-tests/test-cases/exported-symbols-wildcards: added test case
+
+
+2007-01-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4868270> [U]SDT probes should use C calling convention
+ * src/Options.cpp: Add -read_only_dof
+ * src/ld.cpp: create __dof section(s) based on probe and isenabled sites
+ * src/MachOReaderRelocatable.hpp: parse new sdt 2.0 probes encoded in .o files
+ * src/MachOWriterExecutable.hpp: handle regenerating dtrace probes into .o files
+ * unit-tests/test-cases/dtrace-static-probes: added test case
+
+
+----- Tagged ld64-69.8
+
+2007-01-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4964508> Support LD_FORCE_NO_SEG_ADDR_TABLE
+ * src/Options.cpp: Support LD_FORCE_NO_SEG_ADDR_TABLE
+
+
+----- Tagged ld64-69.7
+
+2007-01-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4949507> Leopard9A351: CFM Apps Are Broken because CFM glue is missing
+ * src/MachOReaderRelocatable.hpp: check S_ATTR_NO_DEAD_STRIP in dontDeadStrip()
+
+
+----- Tagged ld64-69.6
+
+2007-01-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4947347> LD_TRACE_ARCHIVES should only print out when a .o is actually used from an archive
+ * src/ld.cpp: create and use logArchive()
+
+
+----- Tagged ld64-69.5
+
+2007-01-22 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4946075> 9A350: can't link ppc programs with ld_classic
+ * src/Options.cpp: Remove support for LD_NO_CLASSIC_LINKER. Add support for -classic_linker
+
+
+----- Tagged ld64-69.4
+
+2007-01-17 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4925645> QTComponents does not link with ld64
+ * src/MachOReaderRelocatable.hpp: handle N_RSYM and N_PSYM stabs
+
+
+----- Tagged ld64-69.3
+
+2007-01-03 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: If the same dylib is specified twice and the second is specified weak, make it weak
+
+
+----- Tagged ld64-69.2
+
+2006-12-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4889729> -dead_strip without -exported_symbols_list should not strip global functions from archives
+ * src/ld.cpp: when adding a .o file from an archive, add all its global symbols to live roots
+ * unit-tests/test-cases/dead_strip-archive: added
+
+
+2006-12-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4889409> flat_namespace main executables do not need to indirect interior references
+ * src/MachOWriterExecutable.hpp: don't indirect references to global symbols in main executables
+ * unit-tests/test-cases/flat-main: updated to test for indirection
+ * unit-tests/test-cases/flat-dylib: added
+
+
+----- Tagged ld64-69.1
+
+2006-12-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4886721> -flat_namespace does not work with -mdynamic-no-pic
+ * src/MachOWriterExecutable.hpp: rework checking for use of ppc absolute addressing to allow them as long as
+ the target is within the same linkage unit.
+
+
+2006-12-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4886652> -ObjC should only load .o with .objc_ symbols
+ * src/Options.cpp: remove warning from -ObjC and have it instead set fLoadAllObjcObjectsFromArchives
+ * src/MachOReaderArchive.hpp: when -ObjC is used, preload all .o files from archives that contain .objc_ symbols
+
+
+----- Tagged ld64-69
+
+2006-12-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4879913> prebound interior pointers must be non-zero
+ * src/MachOWriterExecutable.hpp: in fixUpReference_powerpc() set lazy pointers bound to with the dylib to
+ their target value. Properly set REFERENCE_FLAG_UNDEFINED_* flags in reference table and n_desc
+
+
+2006-12-09 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4868738> ld64 fails to detect error that ld_classic does
+ * src/MachOWriterExecutable.hpp: check for absolute reloc to an external symbol
+ * src/MachOReaderRelocatable.hpp: ignore -mlong-branch stubs in .o files
+
+
+2006-12-09 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4874209> symbols with REFERENCED_DYNAMICALLY should never be stripped
+ * src/MachOWriterExecutable.hpp: update Writer<A>::shouldExport() to check for kSymbolTableInAndNeverStrip
+ * unit-tests/test-cases/main-stripped: add test that dynamically referenced symbol cannot be stripped
+
+
+2006-12-08 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/allowable-client: add variant test cases (e.g. CoreServices_profile)
+ * src/ld.cpp: allow frameworks with variant install names (e.g. CoreServices_profile) to be private clients
+
+
+2006-12-08 Nick Kledzik <kledzik@apple.com>
+
+ * doc/man/man1/ld.1: rewrite man page
+ * src/Options.h: add warnObsolete()
+ * src/Options.cpp: use warnObsolete() on many options. Make nonWeak the weak-mis-match default.
+ Make -ObjC mean -all_load.
+
+----- Tagged ld64-68.3
+
+2006-12-05 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: allow umbrella frameworks to have variant install names (e.g. CoreServices_profile) and still link
+
+
+----- Tagged ld64-68.2
+
+2006-12-05 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.cpp: Use N_PBUD in the symbol table for undefined symbols in prebound dylibs
+
+
+----- Tagged ld64-68.1
+
+2006-12-01 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: always generate module tables for 32-bit architectures so that ld_classic
+ can link against them
+
+
+----- Tagged ld64-68
+
+2006-12-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4858299> seg_addr_table needs matching fuzziness
+ * src/Options.cpp: special case a how a dozen dylib are looked up in the seg_addr_table
+
+
+2006-12-01 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: have all -static links for 32-bit archs roll over to ld_classic unless
+ LD_NO_CLASSIC_LINKER_STATIC is set.
+ * unit-tests/bin/make-recursive.pl: set LD_NO_CLASSIC_LINKER_STATIC for unit tests
+
+
+2006-11-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4855542> ld64-67: QTComponents fails to build
+ * src/MachOReaderRelocatable.hpp: don't error out when a local non-lazy pointer does not point to a symbol
+ * unit-tests/test-cases/strip_local: added test case
+
+
+2006-11-28 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4433496> Need a way to mark libraries usable by dynamic linker but unusable by static linker
+ * src/Options.cpp: allow -client_name to be used with main executables
+ * src/ld.cpp: generalize -allowable_client. Any dylib can now restrict who can link against it. As a convention
+ linking with -allowable_client '!' will mean no one can statically link with the dylib. It can still be loaded
+ dynamically, or by any existing clients, but no new clients can link with it.
+ * unit-tests/test-cases/allowable-client/Makefile: enable previously commented out test cases. Add test cases
+ of a dylib that allows no clients and just one client
+
+2006-11-27 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4795615> -final_output should be used if -install_name not used
+ * src/Options.cpp: fall back to using -final_output for install name
+
+
+----- Tagged ld64-67
+
+2006-11-17 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: support __IMPORT segment being slide independently of __DATA segment in shared cache
+
+
+2006-11-16 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4838262> 9a303: ld -filelist Bus Error
+ * src/Options.cpp: add check that -filelist is followed by an argument
+
+
+2006-11-16 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: when building split-seg dylibs, LINKEDIT goes in read-only side
+
+
+2006-11-15 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: set proper attributes for __eh_frame in ld -r mode
+ * unit-tests/test-cases/eh_frame: added test case
+
+
+2006-11-10 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: redirect references to static weak stubs to the real target
+
+
+2006-11-09 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: r_address is offset from first LC_SEGMENT vmaddr - not from segment with lowest address
+
+
+----- Tagged ld64-66.1
+
+2006-11-09 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: initialize fModuleInfoAtom to zero
+
+
+2006-11-08 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4821985> FSF GCC's libjava doesn't link with Ochre ld64
+ * src/MachOReaderRelocatable.hpp: ignore debug_line section if debug_info section is missing or empty
+
+----- Tagged ld64-66
+
+2006-11-07 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4824368> SWB: d64-65 does not built usage split-seg dylibs
+ * src/MachOWriterExecutable.hpp: when prebinding split-seg correctly set r_address fields and on
+ disk values for external relocations
+ * unit-tests/test-cases/prebound-split-seg: added test case
+
+
+2006-11-03 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderDylib.hpp: don't report dependent libraries if MH_NO_REEXPORTED_DYLIBS bit is set
+ * src/MachOWriterExecutable.hpp: set MH_NO_REEXPORTED_DYLIBS bit if dylib does not logically re-export any other dylibs
+ * unit-tests/test-cases/re-export-flag: added test case
+ * src/machochecker.cpp: validate use of MH_NO_REEXPORTED_DYLIBS
+
+
+2006-11-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4814565> Mysterious messages from ld64 with MACOSX_DEPLOYMENT_TARGET = 10.5
+ * src/MachOWriterExecutable.hpp: kPointerWeakImport is a valid reference type to cross segments
+
+
+2006-11-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp,h: Add support for -rpath
+ * src/MachOFileAbstraction.hpp: add macho_rpath_command
+ * src/MachOWriterExecutable.hpp: add RPathLoadCommandsAtom to create LC_RPATH for each -rpath
+
+
+----- Tagged ld64-65
+
+2006-10-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4729162> x86_64 default stack_addr is wrong
+ * src/Options.cpp: change default 64-bit stack location when using -stack_size
+
+
+2006-10-30 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4474316> dylibs need modules for 10.3 and for ld_classic in Salt
+ * src/MachOWriterExecutable.hpp: add ModuleInfoLinkEditAtom to create module table stuff
+ * src/Options.cpp,h: Add needsModuleTable()
+ * src/MachOFileAbstraction.hpp: Add macho_dylib_module, macho_dylib_reference, and macho_dylib_table_of_contents
+
+
+2006-10-27 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/no-uuid/Makefile: add -gstabs+ to be compatible with latest compiler
+ * unit-tests/test-cases/stabs-coalesce/Makefile: add -gstabs+ to be compatible with latest compiler
+
+
+2006-10-26 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4585230> i386 -mdynamic-no-pic switch statement jump table is out of line
+ * src/MachOWriterExecutable.hpp: for i386 don't check for direct references to weak symbols
+
+
+2006-10-26 Devang Patel <dpatel@apple.com>
+
+ * src/LLVMReader.hpp: Supply final output file path to optimizer.
+
+2006-10-26 Devang Patel <dpatel@apple.com>
+
+ * src/ObjectFile.h: Make setSection* methods virtual.
+ * src/LLVMReader.hpp: Override setSection* methods.
+
+2006-10-26 Devang Patel <dpatel@apple.com>
+
+ * unit-tests/test-case/llvm-integration/a13.h: New.
+ * unit-tests/test-case/llvm-integration/a13.cc: New.
+ * unit-tests/test-case/llvm-integration/main13.cc: New.
+
+2006-10-26 Devang Patel <dpatel@apple.com>
+
+ * src/options.h, src/options.cpp: Add -save-temps command line option.
+ * src/LLVMReader.hpp: Use saveTemps option.
+
+
+2006-10-26 Devang Patel <dpatel@apple.com>
+
+ * src/LLVMReader.hpp: Remove invalid module from memory.
+
+2006-10-26 Devang Patel <dpatel@apple.com>
+
+ * src/LLVMReader.hpp: Collect symbol alignment info from LLVM optimizer.
+
+2006-10-21 Eric Christopher <echristo@apple.com>
+
+ * src/ld.cpp (Linker::Linker): Check for LD_NO_CLASSIC_LINKER before
+ invoking ld_classic.
+ * unit-tests/test-cases/relocs-literals/Makefile: Run for -mdynamic-no-pic
+ and pic.
+ * unit-tests/test-cases/static-executable/Makefile: Skip for 64-bit. Add
+ -dead_strip to command line.
+
+----- Tagged ld64-64.2
+
+2006-10-19 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: stop copying LLVMReader.hpp into man1 directory
+
+----- Tagged ld64-64.1
+
+2006-10-19 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4791643> ld64-63.1 erroneously coalesces an empty string with a non-empty string
+ * src/MachOReaderRelocatable.hpp: rework cstring parsing to not assume all strings are start
+ at section alignment boundaries, and when coalescing empty strings always use one with greatest
+ alignment requirement
+ * src/MachOWriterExecutable.hpp: in -r mode, don't pad end of cstring section
+ * src/ObjectFile.h: correctly name leadingZeros() as trailingZeros()
+ * src/ld.cpp: leadingZeros() --> trailingZeros()
+
+
+2006-10-18 Eric Christopher <echristo@apple.com>
+
+ * unit-tests/test-cases/read-only-relocs/Makefile: Skip for x86_64.
+ * unit-tests/test-cases/llvm-integration/Makefile: Skip if llvm isn't
+ present.
+
+2006-10-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4783853> ld64 change required to go with assembler cstring change
+ <rdar://problem/4732996> ld64 should error when a local relocation references an address outside its section
+ * src/MachOReaderRelocatable.hpp: for x86_64 in order to work with local or external relocations to cstrings
+ change parser to allow atoms with a pending name that is resolved after references are instantiated.
+ Make direct references to kRegularDefinition atoms.
+ * src/MachOWriterExecutable.hpp: in -r mode for x86_64 generate L* labels for cstrings and use external relocations
+ * unit-tests/test-cases/relocs-literals/test.c: add two cases of cstring literal plus addend
+
+
+2006-10-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4786250> check MACOSX_DEPLOYMENT_TARGET if -macosx_version_min is not used
+ * src/Options.cpp: if -macosx_version_min is not used, check MACOSX_DEPLOYMENT_TARGET, if
+ that is unused, default to 10.5
+
+----- Tagged ld64-64
+
+2006-10-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4756806> crash in ppc64 program - bl to saveFP, but saveFP is too far away?
+ * src/MachOWriterExecutable.hpp: in addPPCBranchIslands(), properly account for growth of __text
+
+
+2006-10-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4769120> Linker-defined alias converts reference into definition and generates error.
+ * src/MachOReaderRelocatable.hpp: only alias symbols actually in the symbol table
+
+
+2006-10-06 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/dwarf-debug-notes/Makefile: crt1.o no longer has stabs, so don't need to strip it
+ * unit-tests/test-cases/dwarf-debug-notes-r/Makefile: crt1.o no longer has stabs, so don't need to strip it
+
+
+2006-10-06 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: rework dwarf line parsing to fix warnings that starting
+ showing up with gcc-5421
+
+
+2006-10-05 Eric Christopher <echristo@apple.com>
+
+ <rdar://problem/4760935> ld64 needs to support libtool options
+ * src/Options.cpp (Options::parse): Add -noall_load, -install_name,
+ -current_version and -compatibility_version.
+
+2006-10-03 Eric Christopher <echristo@apple.com>
+
+ * src/Options.cpp (Options::gotoClassicLinker): Use execvp
+ to call ld_classic.
+
+2006-10-03 Eric Christopher <echristo@apple.com>
+
+ * unit-tests/test-cases/tentative-to-real/Makefile: Clean up after tests.
+
+2006-10-03 Eric Christopher <echristo@apple.com>
+
+ * unit-tests/include/common.makefile (VALID_ARCHS): Add x86_64.
+ (OTOOL): Remove munging based on ARCH.
+
+2006-09-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4743925> problem merging .o files built with and without -fno-common
+ src/Options.*: make MakeTentativeDefinitionsReal a reader option
+ src/ObjectFile.h: make MakeTentativeDefinitionsReal a reader option
+ src/MachOWriterExecutable.hpp: make MakeTentativeDefinitionsReal a reader option
+ src/MachOReaderRelocatable.hpp: only assign a section name of __common to
+ tentative defintions when making a final linked image
+
+
+2006-09-28 Nick Kledzik <kledzik@apple.com>
+
+ src/Options.h/.cpp: add support for -segaddr option
+ src/MachOWriterExecutable.hpp: In Writer::assignFileOffsets(), use -segaddr info
+
+
+2006-09-28 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4587349> Emit new CPU subtypes for ppc64 and x86-64 when targeting 10.5 or later
+ src/MachOWriterExecutable.hpp: set high bit of cpusubtype of 64-bit main executables when targeting 10.5 or later
+
+
+2006-09-28 Devang Patel <dpatel@apple.com>
+
+ Add LLVM LTO support
+ src/LLVMReader.hpp: New file.
+ src/ld.cpp: Add optimization phase. Use LLVM LTO.
+ unit-tests/test-cases/llvm-integration: New tests.
+
+2006-09-27 Nick Kledzik <kledzik@apple.com>
+
+ ld64.xcodeproj/project.pbxproj: remove accidental install of source file into man1
+
+
+2006-09-25 Nick Kledzik <kledzik@apple.com>
+
+ src/Architectures.hpp: add kPointerDiff16 for ppc and ppc64
+ src/MachOReaderRelocatable.hpp: support kPointerDiff16
+ src/MachOWriterExecutable.hpp: support kPointerDiff16
+
+----- Tagged ld64-63.1
+
+2006-09-22 Nick Kledzik <kledzik@apple.com>
+
+ src/MachOWriterExecutable.hpp: include stubs in LC_SEGMENT_SPLIT_INFO
+
+
+2006-09-21 Nick Kledzik <kledzik@apple.com>
+
+ src/Options.cpp: disable split-seg dylibs for 64-bit architectures
+
+
+2006-09-19 Nick Kledzik <kledzik@apple.com>
+
+ src/MachOReaderRelocatable.hpp: rework __cstring parsing to better handle mixed alignment cstrings
+ src/MachOWriterExecutable.hpp: in -r mode, make all __cstrings aligned to section alignment
+
+
+2006-09-19 Nick Kledzik <kledzik@apple.com>
+
+ src/MachOWriterExecutable.hpp: rework encoding of LC_SEGMENT_SPLIT_INFO
+
+
+2006-09-19 Nick Kledzik <kledzik@apple.com>
+
+ src/Options.cpp: check for -search_paths_first in first pass
+
+
+----- Tagged ld64-63
+
+2006-09-15 Nick Kledzik <kledzik@apple.com>
+
+ src/Options.cpp: since the ld64 will repeatedly search an archive, and some project list archives
+ multiple times on command line to work with traditional linkers, automatically ignore duplicate libraries
+ unit-tests/test-cases/archive-duplicate: added test case
+
+
+2006-09-15 Nick Kledzik <kledzik@apple.com>
+
+ src/Options.cpp: support -r -static
+ src/MachOWriterExecutable.hpp: support -r -static an don't generate LC_DYSYMTAB
+
+
+2006-09-14 Nick Kledzik <kledzik@apple.com>
+
+ src/MachOWriterExecutable.hpp: in -r mode references to weak symbols should not create external relocations
+ as that can cause nmedit to errror later.
+
+
+2006-09-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4718189> ld64: Handle .objc_class_name exports specially
+ src/Options.cpp: add hack so that .objc_class_name_XXX in -exported_symbols_list imples _OBJC_CLASS_$_XXX
+ src/ld.cpp: add hack to supporess errors about .objc_class_name_XXX or _OBJC_CLASS_$_XXX being undefined
+
+
+2006-09-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4474172> Support -prebind when targeting ppc and OS < 10.4
+ src/Options.h: add splitSeg() and baseWritableAddress()
+ src/Options.cpp: Add support for -seg_addr_table and LD_SEG_ADDR_TABLE, and -prebind and LD_PREBIND.
+ src/src/MachOWriterExecutable.hpp: support split-seg and canonical prebound files to be generated
+
+
+2006-09-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4464904> Linking a dylib or binary from identical binaries should produce the same output
+ src/MachOWriterExecutable.hpp: set the timestamps to be constant
+
+
+2006-09-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4070025> Linker support for ordering all sections and symbols
+ src/Options.cpp: Add -order_file_statistics. Allow architecture prefixes in order files
+ src/ld.cpp: Use fOptions.printOrderFileStatistics()
+
+
+2006-09-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/3894079> Support -sectorder
+ unit-tests/test-cases/order_file: added test case
+ src/ld.cpp: Implement order file support in Linker::sortAtoms()
+ src/Options.h: add Options.orderedSymbols()
+ src/Options.cpp: add parseOrderFile(), implement -order_file
+
+
+2006-09-07 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4637023> need -i for 64-bit (or equivalent)
+ <rdar://problem/4014529> Support -i for aliasing exported symbols
+ unit-tests/test-cases/alias-objects: added
+ unit-tests/test-cases/alias-command-line: added
+ src/ObjectFile.h: Added Atom::getOrdinal() as new way to sort atoms. Added ReaderOptions.fAliases
+ src/MachOReaderRelocatable.hpp: Added SymbolAliasAtom to handle multiple symbols to same address
+ src/MachOReaderArchive.hpp: implement Atom::getOrdinal() to space out atom ordinals across member objects
+ src/Options.cpp: support -i, -alias, -alias_list. Move search of /Network/Library/Frameworks to after /System/Library/Frameworks
+ src/MachOWriterExecutable.hpp: pad out seg_info data. Implement getOrdinal().
+ src/ObjectDump.cpp: call constructors directly instead of using make() wrapper
+
+
+2006-09-01 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4458878> Need the ability to tag libraries/plug-ins with security attributes
+ src/MachOReaderDylib.hpp: add warning if using -root_safe or -setuid_safe and link against dylib that is not
+ src/ObjectFile.h: add ReaderOption fRootSafe and fSetuidSafe
+ src/Options.cpp: handle -root_safe or -setuid_safe command line options
+ src/MachOWriterExecutable.hpp: set MH_ROOT_SAFE and MH_SETUID_SAFE flags
+
+
+2006-08-31 Nick Kledzik <kledzik@apple.com>
+
+ src/ld.cpp: Add Linker::processDTrace() for processing dtrace static probes
+ src/OpaqueSection.hpp: renamed, add symbol name, add ability to add references
+ ld64.xcodeproj/project.pbxproj: remove SectCreate.cpp, add OpaqueSection.hpp
+
+
+2006-08-28 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4571042> Add convention for removing symbols at link time
+ <rdar://problem/3962731> Assembler -L option causes ld64 to split stubs
+ unit-tests/test-cases/special-labels: added test case
+ src/MachOReaderRelocatable.hpp: ignore L* labels, make l* labels as kSymbolTableNotIn
+
+
+2006-08-28 Nick Kledzik <kledzik@apple.com>
+
+ src/lObjectFile.h: refactor isTargetUnbound() into getTargetBinding()
+ src/ld.cpp: create __dof section in final linked images from dtrace static probes
+ src/Architectures.hpp: add kDtraceProbe
+ src/Options.h/cpp: Add support for -dtrace
+ src/machochecker.cpp: support LC_SEGMENT_SPLIT_INFO
+ src/MachOWriterExecutable.hpp: support kDtraceProbe
+ src/MachOReaderRelocatable.hpp: suppport kDtraceProbe
+
+
+2006-08-25 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4701529> generate LC_SEGMENT_SPLIT_INFO for 10.5 or later dylibs
+ src/Options.h&.cpp: implement sharedRegionEligible() to control when LC_SEGMENT_SPLIT_INFO is added
+ src/MachOFileAbstraction.hpp: add macho_linkedit_data_command
+ src/MachOWriterExecutable.hpp: generate LC_SEGMENT_SPLIT_INFO load command and linkedit content
+
+----- Tagged ld64-62
+
+2006-08-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4681062> wrong error message when symbol is found in unused indirect library
+ src/ld.cpp: remove indirect libraries if they are not re-exported
+ unit-tests/test-cases/indirect-dylib: added test case
+
+
+2006-08-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/3930461> alignment needs to be richer
+ src/ObjectFile.h: define ObjectFile::Alignment class for tracking rich alignment info
+ src/ld.cpp: modify SymbolTable::add() to work with new Alignment type
+ src/MachOReaderRelocatable.hpp: use new Alignment type. Remove alignAtLeast() and handleAnonymousNonLazyPointers()
+ src/MachOWriterExecutable.hpp: update for new Alignment type, use modulus when calculating layout address
+ src/ObjectDump.cpp: print richer Alignment info
+ unit-tests/test-cases/align-modulus: added test case
+
+
+2006-08-11 Nick Kledzik <kledzik@apple.com>
+
+ remove OPEN_SOURCE conditionals around x86_64 support
+
+
+2006-07-31 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4654131> ld64 while linking cc1 [ when dead_strip is ON]
+ src/ld.cpp: Add ivar fAtomsWithUnresolvedReferences to track atoms not initially resolvable
+ unit-tests/test-cases/dead_strip-archive: added test case
+
+
+2006-07-31 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4656617> x86_64: instructions with immediate and rip-relative operands need to use new relocation types
+ src/MachOWriterExecutable.hpp: generate new reloc types in -r mode
+ src/MachOReaderRelocatable.hpp: parse new reloc types
+ unit-tests/test-cases/relocs-asm/relocs-asm.s: add test cases for new reloc type
+
+
+2006-07-18 Nick Kledzik <kledzik@apple.com>
+
+ src/MachOReaderRelocatable.hpp: suppress warning about dwarf info parsing for one benign no-op case
+ the compiler emits when there are not functions in the __text section
+
+
+2006-07-17 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4634840> faster debug note generation
+ src/ld.cpp: rework collectDebugInfo() to produce all debug notes in one pass, intead of a
+ pass per .o file. Added timing info for collectDebugInfo() to -print_statistics
+ unit-tests/test-cases/dwarf-debug-notes-r/Makefile: add expliced -arch to ld -r
+ unit-tests/test-cases/dwarf-debug-notes-r/expected-stabs: alter for new debug notes order
+
+
+2006-07-17 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4623994> ld64 VSIZE is 1.18GB when building Finder ppc64
+ src/ld.cpp: fixed typo in createReader() that prevented dylibs from being unmapped
+
+----- Tagged ld64-61.1
+
+2006-07-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4622049> ld64-61: gcc DejaGnu tests failing due to -arch followed by unknown architecture name
+ src/Options.cpp: map ppc750, ppc7400, ppc7450, and ppc970 to ppc. Improve error message
+
+2006-07-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4622769> If -arch is missing, rollover to ld_classic does not happen
+ src/Options.h: make gotoClassicLinker() public
+ src/ld.cpp: call gotoClassicLinker() if the inferred architecture is ppc or i386
+
+----- Tagged ld64-61
+
+2006-06-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4606628> ld64 should be renamed to ld
+ src/Options.cpp: exec() ld_classic if -arch ppc or -arch i386 is seen
+ src/ld.cpp: alter version string
+ ld64.xcodeproj/project.pbxproj: change install location to /usr/bin/ld, add symlink from /usr/bin/ld64
+ doc/man/man1/ld.1: added
+
+----- Tagged ld64-60
+
+2006-06-28 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4604539> Can't link large ppc64 program: ld64 says "bl out of range"
+ MachOWriterExecutable.hpp: fix branch island generation to work for weak_import functions
+ and properly chain together branch islands
+ MachOReaderRelocatable.hpp: improve performance of huge .o file reading by sorted references
+ only when done
+
+2006-06-28 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4603454> MySQL-36 fails to build with ld64-59
+ src/MachOReaderRelocatable.hpp: back out fix for 4585335
+ src/MachOWriterExecutable.hpp: back out fix for 4585335
+
+2006-06-27 Nick Kledzik <kledzik@apple.com>
+
+ src/MachOReaderRelocatable.hpp: handle N_GSYM without ending :G() since that is how
+ dwarf debug notes are formed.
+
+2006-06-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4599239 objc class with no superclass causes bad undefined symbol
+ src/MachOReaderRelocatable.hpp: handle NULL superclass in objc_class
+ unit-tests/test-cases/relocs-objc/test.m: add case with no super class
+
+
+2006-06-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4313369> ld64 doesn't support variant linking -framework fw,_debug
+ src/Options.cpp: enhance findFramework() to support suffixes
+
+----- Tagged ld64-59
+
+2006-06-22 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4596726> ld64 lost DWARF debug notes
+ src/MachOReaderRelocatable.hpp: add fHasUUID so kDebugInfoStabsUUID can be set later
+ unit-tests/test-cases/dwarf-debug-notes-r: added test case
+
+2006-06-21 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4567995> python 64-bit address miscalculation
+ src/MachOReaderRelocatable.hpp: change getTargetOffset() to sign extend the 32-bit value to 64-bits
+
+2006-06-21 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4535036> ld64 seems to offset things incorrectly when using -r
+ src/MachOWriterExecutable.hpp: in -r mode, virtual sections should not increment address
+
+
+----- Tagged ld64-58
+
+2006-06-16 Nick Kledzik <kledzik@apple.com>
+
+ src/rebase.cpp: fix page alignment problem
+ src/rebase.cpp: fix endianess problem with local non-lazy pointers
+
+2006-06-15 Nick Kledzik <kledzik@apple.com>
+
+ src/rebase.cpp: fix to build in CurryWeed
+ ld64.xcodeproj/project.pbxproj: fix to build properly in CurryWeed
+
+2006-06-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4495309> Support .objc_class_name_* symbols
+ src/ObjectFile.h: Add kSymbolTableInAsAbsolute
+ src/MachOReaderRelocatable.hpp: synthesize references to required objc classes
+ src/MachOWriterExecutable.hpp: write objc_class_name as absolute symbol
+ unit-tests/test-cases/objc-references: added
+
+2006-06-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4484369> SECTION_ATTRIBUTES unset in ppc64 mach-o header
+ src/MachOWriterExecutable.hpp: add section attribute for sections with code
+
+2006-06-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4569407> ld64 bogus duplicate symbol name linking GNU libobjc
+ src/MachOReaderRelocatable.hpp: only special case Apple objc runtime objc classes
+
+2006-06-15 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4582999> x86_64: ".align" directive not honored
+ src/MachOReaderRelocatable.hpp: change code alignment to not depend on atom size
+
+2006-06-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4585335> jump table into middle of weak symbol causes error
+ src/MachOReaderRelocatable.hpp: create direct references to the interior of weak symbols
+ src/MachOWriterExecutable.hpp: do not error on absolute references to interior of weak symbols
+
+2006-06-13 Nick Kledzik <kledzik@apple.com>
+
+ src/Options.cpp: allow -image_base as an alias for -seg1addr
+
+2006-06-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4585115> implement -d
+ src/Options.h: add fMakeTentativeDefinitionsReal
+ src/Options.cpp: set fMakeTentativeDefinitionsReal if -d option is found
+ src/MachOWriterExecutable.hpp: turn tentative into real definition if makeTentativeDefinitionsReal
+ unit-tests/test-cases/btentative-to-real: added test case
+
+2006-06-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4584355> implement -bundle_loader
+ src/Options.h: add fBundleLoader bit to DynamicLibraryOptions
+ src/Options.cpp: handle -bundle_loader
+ src/ld.cpp: pass fBundleLoader bit to MachOReaderDylib
+ src/MachOReaderDylib.hpp: support reading MH_EXECUTE files if fBundleLoader is set
+ src/MachOWriterExecutable.hpp: set bundle loader ordinal as EXECUTABLE_ORDINAL
+ unit-tests/test-cases/bundle_loader: added test case
+
+2006-06-12 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4583347> -syslibroot can cause "can't find ordinal for imported" error
+ src/MachOReaderDylib.hpp: in Reader::reExports() compare install path in addition to load path
+
+
+2006-06-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4548935> Need rebasing tool
+ src/rebase.cpp: added
+ unit-tests/test-cases/rebase-basic: added
+ doc/man/man1/rebase.1: added
+ ld64.xcodeproj/project.pbxproj: added rebase target. changed all targets to build with dwarf
+
+
+2006-06-10 Nick Kledzik <kledzik@apple.com>
+
+ src/machochecker.cpp: add some ppc reloc sanity checking
+
+----- Tagged ld64-57
+
+2006-06-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4565088> ld64 is not adding a final '/' char on the initial directory-name SO stab debug map entry
+ ld.cpp: Change Linker::synthesizeStabs() to assure directory SO always has a trailing slash
+ unit-tests/test-cases/dwarf-debug-notes/expected-stabs: update with trailing /
+
+2006-06-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4572702> -sectcreate of a 0-byte section fails
+ MachOWriterExecutable.cpp: Don't error out on zero length segments
+ MachOWriterExecutable.cpp: For ppc64 reloc base address is the first writable segment iff
+ there is a writable segment >4GB from base address
+
+2006-06-04 Eric Christopher <echristo@apple.com>
+
+ Radar 4560240
+ Radar 3964999
+ * src/ld.cpp (createReader): Fixed error message.
+ (resolve): Ditto.
+ (resolveFrom): Ditto.
+ (checkUndefines): Ditto.
+
+----- Tagged ld64-56
+
+2006-05-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4558079> No debug notes for ObjC methods when linking with ld64
+ ld.cpp: don't limit debug notes to functions starting with underscore
+
+2006-05-22 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4556982> ld64 spends much time in mach_o::relocatable::Reader<x86_64>::findAtomByName
+ * src/MachOReaderRelocatable.hpp: add makeReferenceToSymbol() so that x86_64 does not need to do by-name lookups
+
+2006-05-22 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4535044> remove inferring warning
+ * ld.cpp: Remove "inferring" warning. If a link failed and now arch was specifed add which arch was
+ inferred to error message
+
+2006-05-19 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4544001> ld64 does not honor -arch_multiple
+ * ld.cpp: If fOptions.printArchPrefix(), add architecture name to error message
+
+2006-05-19 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4555973> Support S_16BYTE_LITERALS section types
+ * src/MachOReaderRelocatable.hpp: support S_16BYTE_LITERALS
+ * src/MachOWriterExecutable.hpp: support S_16BYTE_LITERALS
+
+2006-05-19 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4548803> "warning can't parse dwarf compilation unit info" warnings building debug
+ * src/MachOReaderRelocatable.hpp: fix bugs in dwarf line table parsing
+
+----- Tagged ld64-55
+
+2006-05-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4534339> Default the pagezero size to 4GB for x86-64
+ * src/Options.cpp: Chnage default the pagezero size to 4GB for x86-64
+
+2006-05-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4552825> x86_64 CarbonCore fails to link with "atom not found in symbolIndex"
+ * src/MachOWriterExecutable.hpp: in buildObjectFileFixups() don't call addObjectRelocs() on kNoFixUp references
+
+2006-05-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4553555> ld64: .section defaults to read-only
+ * src/MachOReaderRelocatable.hpp: default unknown segments to r/w
+
+2006-05-18 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4551990> -fvisibility=hidden causes crashes for x86_64
+ * src/MachOWriterExecutable.hpp: properly handle RIP relative tentative definitions
+
+2006-05-12 Nick Kledzik <kledzik@apple.com>
+
+ * src/Architectures.hpp: add x86::kAbsolute32
+ * src/MachOReaderRelocatable.hpp: generate x86::kAbsolute32 for mdynamic-no-pic instructions
+ * src/MachOWriterExecutable.hpp: process x86::kAbsolute32 reference kind
+
+----- Tagged ld64-54
+
+2006-05-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4545108> CF-393 failes to link for x86_64
+ * src/MachOWriterExecutable.cpp: fix sign extension for Rel32 relocs in Writer<x86_64>::fixUpReferenceRelocatable
+
+2006-05-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4501434> warning arch x86_64 not found using i386
+ * src/ld.cpp: remove hack to allow x86_64 to link against i386 dylibs
+
+
+2006-05-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4543754> x86_64: .objc_class_name symbol names scrambled
+ * src/MachOReaderRelocatable.hpp: properly compute alignment of __OBJC __class sections
+
+
+2006-05-08 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/3894083> Support -dead_strip
+ * src/Options.h/cpp: implement -why_load and -why_live. Enable -dead_strip.
+ * src/MachOReaderArchive.hpp: implement -why_load
+ * src/MachOReaderRelocatable.hpp: suppress GCC_except_table* symbols in final output
+ * src/ld.cpp: implement dead code stripping
+ * unit-tests/test-cases/dead_strip: added
+
+----- Tagged ld64-53
+
+2006-05-05 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: make 10.4 be minimum OS version for newer architectures
+
+2006-05-05 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4147604> N_SO symbols in 64-bit builds have a zero address for n.n_value
+ * src/ld.cpp: for SO stabs, associate first and last atom in the SO range
+ * src/MachOWriterExecutable.hpp: use atom associated with SO stab to set ins n_value
+
+2006-05-05 Nick Kledzik <kledzik@apple.com>
+
+ * MachOWriterExecutable.hpp: fix end FUN stab to have length of function
+
+
+2006-05-02 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4496250> 64-bit main executables should have 4GB zero page by default
+ * src/Opptions.cpp: change default pagezero_size to 4GB for ppc64
+ <rdar://problem/4492850> 64 bit: apps with -mdynamic-no-pic seg fault when page zero > 4GB
+ * src/MachOWriterExecutable.cpp: rework pagezero for ppc64 so that if any mdynamic-no-pic code
+ is found, the code is kept in the low 2GB, and a new segment is create to map away up to 4GB.
+
+2006-05-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/Opptions.cpp: remove warning about -stack_addr not specified. Add warning if 32-bit stack
+ overlaps shared region
+
+----- Tagged ld64-52.1
+
+2006-05-01 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.cpp: rework handleAnonymousNonLazyPointers() to handle anl's in the middle
+ the __data section too.
+
+----- Tagged ld64-52
+
+2006-04-28 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4513304> 64-bit: 9A152 TextEdit crashes in dlopen on bring-up
+ * src/MachOReaderRelocatable.cpp: rework anonymous non-lazy-pointer detection
+
+2006-04-28 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4528054> 64 Bit: Development build of ppc64 TextEdit gets confused about static variables
+ * src/MachOReaderRelocatable.cpp: mark non-lazy-pointer atoms as scopeTranslationUnit if targetting a static symbol
+
+
+
+2006-04-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: fix default address for ppc64 custom stack
+ * src/MachOWriterExecutable.cpp: fix set up of ppc64 custom stack
+
+
+2006-04-14 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: fix -sub_library processing to work it dylib is specifed with leaf name
+
+----- Tagged ld64-51.1
+
+2006-04-13 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4513304> 64-bit: 9A152 TextEdit crashes in dlopen on bring-up
+ * src/MachOReaderRelocatable.hpp: when detecting anonymous non-lazy-pointers disqualify data
+ that points to static or global symbols
+ * src/ld.cpp: print version of ld64 in error messages
+
+
+----- Tagged ld64-51
+
+2006-04-11 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4499168> exported symbols not properly stripped
+ * src/MachOReaderRelocatable.hpp: enable AnonymousAtom::setScope()
+
+2006-03-31 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4498391> ld64 fails when linking debug ppc64 HIToolbox
+ * src/MachOReaderRelocatable.hpp: handle anonymous non-lazy pointers encoded with local relocations
+ * src/MachOWriterExecutable.hpp: in -r mode, only generated INDIRECT_SYMBOL_LOCAL for non-lazy targets that
+
+
+2006-03-31 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4496499> ld64 should remove generated file if link errors out
+ * src/MachOWriterExecutable.hpp: catch exceptions in Writer<A>::write(), delete output file, and rethrow
+
+
+----- Tagged ld64-50
+
+
+2006-03-29 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: synthesize .objc_class_name symbols
+ * src/MachOFileAbstraction.hpp: use strncpy for sect/seg names to zero fill trailing space
+
+2006-03-28 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: fix spurious warning about dwarf line info
+
+----- Tagged ld64-49.1
+
+2006-03-25 Nick Kledzik <kledzik@apple.com>
+
+ * MachOWriterExecutable.hpp : don't complain about ppc64 dyld being based > 4GB
+
+----- Tagged ld64-49
+
+2006-03-24 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: dyld is allowed to have synthesized non-lazy pointers
+ <rdar://problem/4488113> ld64 is after processing bad GSYM stabs
+ * src/MachOReaderRelocatable.hpp: if a GSYM is found that does not match any data symbol, suppress it
+
+2006-03-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: in Writer<x86>::fixUpReferenceFinal() fix when x86::kPointer is for an
+ external relocation
+
+2006-03-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: change macosx-min-version to default to a per-architecture setting
+ add warning if -pagezero_size is not page aligned
+ * src/MachOWriterExecutable.hpp: properly handle external relocations for ppc64 with 4GB pagezero
+ * src/machochecker.cpp: sanity check relocation records
+
+----- Tagged ld64-48
+
+2006-03-21 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4481406> 64bit: passing function pointer to another function passes the wrong function address
+ * src/MachOReaderRelocatable.hpp: when processing a non-lazy pointer to a static function, don't accidentally
+ match it to a STAB symbol.
+
+2006-03-21 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4180168> .eh symbols make up 13% of libstdc++'s stripped binary size
+ * src/ObjectFile.h: add ReaderOptions.fForFinalLinkedImage
+ * src/Options.cpp: setup ReaderOptions.fForFinalLinkedImage
+ * src/MachOReaderRelocatable.hpp: mark .eh symbols kSymbolTableNotIn when building final linked image
+
+2006-03-21 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4473742> ld64 does not parse optional second argument to -filelist
+ * unit-tests/test-cases/filelist: added
+ * src/Options.cpp: in Options::loadFileList() handle comma option
+
+
+----- Tagged ld64-47.1
+
+
+----- Tagged ld64-47
+
+
+----- Tagged ld64-46
+
+2006-03-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4419505> ld64 should figure out architecture from .o files
+ * unit-tests/test-cases/auto-arch: added
+ * src/ld.cpp: added Linker::inferArchitecture() to scan .o files are infer architecture to link
+ * src/MachOReaderArchive.hpp: enhanced validFile() to look deeper into archive and really valdate
+ * src/MachOWriterExecutable.hpp: stop using fOptions.architecture()
+ * src/Options.cpp: stop defaulting to ppc64
+
+
+2006-03-09 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4465004> Need "intentionally left blank" dylib stubs
+ * unit-tests/include/common.makefile: add VALID_ARCHS
+ * unit-tests/run-all-unit-tests: set up VALID_ARCHS
+ * unit-tests/test-cases/blank-stubs: add test case
+ * src/ld.cpp: in addDylib(), detect and ignore blank stubs
+ * src/MachOReaderDylib.hpp: in constructor, handle blank stubs
+
+2006-03-09 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4471424> crash in stub with 2GB pagezero
+ * src/MachOWriterExecutable.hpp: StubAtom<ppc64> can't be no-pic if a large zero-page is used
+
+2006-03-06 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: addSectionAlignment, warn if -sectalign alignment is not a power of two
+
+----- Tagged ld64-45
+
+
+2006-03-06 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4466930> LP64/9A122: ld64: hang when trying to link DiscRecording framework
+ * src/Options.cpp: addSectionAlignment, warn on zero. Use log2() for alignment conversion
+
+
+----- Tagged ld64-44
+
+2006-03-04 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: fix again test for detection of anonymous non-lazy-pointer.
+ Error out if .o file contains old __DWARFA style dwarf.
+
+2006-03-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: only re-map page aligned sub-parts of a fat file. A conformat mmap() requires alignment.
+
+----- Tagged ld64-43
+
+
+2006-03-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: <rdar://problem/4464370> tighten detection of anonymous non-lazy-pointer
+
+----- Tagged ld64-42
+
+2006-02-28 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: fix x86 __IMPORT permissions for class Segment
+
+2006-02-28 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4461240> SWB: ld64-37 (can't resolve symbol ___dso_handle)
+ * src/MachOWriterExecutable.hpp: add class DsoHandleAtom
+
+2006-02-28 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/literals-coalesce-alignment: added test case
+ * src/ld.cpp: when coalescing strings pick one with greater alignment
+ <rdar://problem/4458660> ld64: CG link failed because lo14 reference to anonymous non-lazy-pointer not aligned
+ * unit-tests/test-cases/relocs-c/test.c: tweak to fail like 4458660
+ * src/MachOReaderRelocatable.hpp: detect anonymous non-lazy-pointer and transform into real non-lazy-pointers
+
+----- Tagged ld64-41
+
+2006-02-24 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: Warning about -no_dead_strip_inits_and_terms and -i options.
+ Fix -weak-l option.
+
+----- Tagged ld64-40
+
+2006-02-24 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4454698> Leopard9A113: ppc64 libstdc++.dylib initializer crashes in pthread_once
+ * unit-tests/test-cases/multiple-entry-points: added
+ * src/MachOReaderRelocatable.hpp: make sure that if there are multiple symbols with the same
+ address, that we properly make zero length atoms for all but last symbol
+
+2006-02-24 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: <rdar://problem/4456093> ld64 doesn't realpath(3) B&I tracing paths
+
+2006-02-24 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: <rdar://problem/4457078> 9A110: ld64 can't deal with section names >16 chars
+
+2006-02-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: use vector.reserve() to minimize re-allocations
+ * src/Options.cpp: use vector.reserve() to minimize re-allocations
+ * src/MachOReaderRelocatable.hpp: use vector.reserve() to minimize re-allocations
+ * src/MachOReaderDylib.hpp: use vector.reserve() to minimize re-allocations
+ * src/ld.cpp: use vector.reserve() to minimize re-allocations
+
+2006-02-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4455927> ld64 creates corrupt executables (and has malloc errors) with -headerpad option
+ * src/MachOWriterExecutable.hpp: Change LoadCommandsPaddingAtom<A>::setSize() to update fLargestAtomSize
+ * unit-tests/test-cases/header-pad: added
+
+2006-02-23 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/4455192> ld64 creates invalid static executables
+ * src/MachOWriterExecutable.hpp: Change MachHeaderAtom<A>::copyRawContent() to create correct header
+ for static executables. Change SymbolTableLoadCommandsAtom to skip LC_DYSYMTAB for static executables
+ * src/machochecker.cpp: Add tests that static executables are well formed
+ * unit-tests/test-cases/static-executable: added
+
+2006-02-22 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: <rdar://problem/4453468> chnage printf on unknown arg to a throw
+
+----- Tagged ld64-39
+
+2006-02-20 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/read-only-relocs: added new test case
+ * src/MachOWriterExecutable.hpp: <rdar://problem/4448922> detect and error on relocs in read-only sections
+ * src/MachOReaderRelocatable.hpp: fix parsing of i386 absolute addressing relocs
+
+2006-02-20 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/stabs-coalesce: added new test case
+ * src/ld.cpp.hpp: <rdar://problem/4449226> in collectStabs removed unused stabs
+
+----- Tagged ld64-38
+
+2006-02-17 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: <rdar://problem/4434578> set correct n_sect field of stabs
+
+2006-02-15 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderArchive.hpp: <rdar://problem/4441920> with -all_load skip over both kinds of SYMDEFs
+ * unit-tests/test-cases/archive-basic/Makefile: add -all_load test case
+
+----- Tagged ld64-37
+
+2006-02-13 Eric Christopher <echristo@apple.com>
+
+ * src/MachOWriterExecutable.hpp (assignFileOffsets): Simplify. Add comments.
+ Adjust whitespace.
+
+2006-02-13 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: in Writer<x86>::fixUpReferenceRelocatable() fix kPCRel32 for external case
+
+2006-02-13 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/zero-fill: added
+ * src/machochecker.cpp: check that S_ZEROFILL have no file offset
+ * src/MachOWriterExecutable.hpp: rework assignFileOffsets() to fix rdar://problem/4441145
+
+2006-02-12 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: <rdar://problem/4440880> fix use of first zero-length c-string in .o file
+
+2006-02-12 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: <rdar://problem/4440905> fix uninitialized fAlignment
+
+2006-02-12 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/relocs-asm/relocs-asm.s: add pointer-diff cases
+ * src/Architectures.hpp: make size explicit in ppc/ppc64 kPointerDiff
+ * src/MachOReaderRelocatable.hpp: don't allow kPointerDiff64 for ppc (just ppc64)
+ * src/MachOWriterExecutable.cpp: set proper r_length for ld -r of kPointerDiff
+
+----- Tagged ld64-36
+
+2006-02-08 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.cpp: rdar://problem/4438677 Handle when a .o file dwarf line info entries but no functions
+
+2006-02-08 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.cpp: Properly set address of first TEXT section
+ Keep S_COALESCED attribute for __eh_frame
+
+2006-02-08 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: Temporarily turn allowable client errors into warnings
+ * unit-tests/test-cases/allowable-clientMakefile: Temporarily let warnings be ok for above
+ * src/MachOWriterExecutable.hpp: fix ld -r to not use external relocations for symbols make static
+
+2006-02-08 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: A sibling in an umbrella can always link with its other siblings
+ * unit-tests/test-cases/allowable-client: add test case for above
+
+2006-02-08 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: support LOCAL non-lazy pointers to hidden symbols
+ * src/machochecker.cpp: verify indirect symbol table
+ * unit-tests/test-cases/private-non-lazy: added test case
+
+2006-02-07 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix calculation of file offsets in ld -r mode
+ * src/machochecker.cpp: verify segment file offsets are within file
+
+----- Tagged ld64-35
+
+2006-02-06 Nick Kledzik <kledzik@apple.com>
+
+ * ld.cpp: allow parent of sub-framework to link
+ * unit-tests/test-cases/allowable-client/Makefile: added cases for parent and clients of parent
+
+2006-02-04 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/relocs-c/test.c: added some array cases
+ * src/MachOReaderRelocatable.hpp: factor out makeReferenceToEH()
+ * src/MachOWriterExecutable.hpp: add initial support for non-lazy pointer synthesis
+
+----- Tagged ld64-34
+
+2006-02-04 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: <rdar://problem/4432917> fix -no_arch_warnings
+ <rdar://problem/4432932> fix -undefined warning
+ Do BINCL/EINCL optimization for gfull stabs
+ Implement "essential symbols" for stabs (-Sp)
+ Fix allowable clients to only test on direct libraries
+ * src/MachOReaderRelocatable.hpp: support BINCL/EINCL stabs
+
+2006-02-03 Nick Kledzik <kledzik@apple.com>
+
+ * src/machochecker.cpp: add code to check load command alignment
+ * src/MachOWriterExecutable.hpp: make load command alignment depend on architecture
+
+2006-02-03 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/literals-coalesce: added
+ * src/MachOReaderRelocatable.hpp: assure all targets of low14 ppc relocs are at least 4-byte alignmented
+
+----- Tagged ld64-33
+
+2006-02-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: properly coalesce 8-byte literals
+ * src/MachOWriterExecutable.hpp: support ppc64::kPointerDiff32
+
+----- Tagged ld64-32
+
+2006-02-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: support anonymous zero fill atoms
+
+2006-02-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: A weak definition is good enough, do not search archives for a non-weak one
+ * unit-tests/test-cases/archive-weak: add test case for above
+ * src/MachOReaderRelocatable.hpp: an atom should never have a by-name reference to itself
+ * src/Options.cpp: prevent .eh symbols from being exported via a -exported_symbols_list
+
+2006-02-01 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: Support -macosx_version_min 10.5
+
+2006-02-01 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: don't try to parse debug_line dwarf if no symboled atoms
+
+----- Tagged ld64-31
+
+2006-02-01 Eric Christopher <echristo@apple.com>
+
+ * unit-tests/test-cases/allow-stack-execute/Makefile: Move otool handling...
+ * unit-tests/include/common.makefile: ... here.
+ * unit-tests/bin/fail-if-stdin.pl: New.
+ * unit-tests/test-cases/no-uuid: Ditto.
+ * src/ld.cpp (Linker::) Add fCreateUUID.
+ (::Linker): Initialize.
+ (::collectStabs): Use. Set if dwarf or we have a UUID already.
+ (::writeOutput): Pass as argument to Writer::write along with option.
+ * src/Options.h (Option::emitUUID): Declare.
+ (Option::fEmitUUID): Ditto.
+ * src/Options.cpp (Option::emitUUID): New.
+ (parse): Handle -no_uuid.
+ * src/MachOReaderRelocatable (Reader::Reader): Handle LC_UUID.
+ * src/ExecutableFile.h (Writer::Write): Add createUUID boolean.
+ * src/MachOWriterExecutable: Add UUID forward declaration.
+ (fUUIDAtom): New.
+ (UUIDLoadCommandAtom): Emit LC_UUID if fEmit. New function emit. Size
+ to zero at start.
+ (Writer::writer): Add handle for LC_UUID. If createUUID emit LC_UUID.
+ (MachHeaderAtom::copyRawContent): Don't count a load command if its size is
+ 0.
+ (UUIDLoadCommandAtom::copyRawContent): Depend on fEmit.
+
+
+2006-01-31 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/dwarf-debug-notes : Added
+ * src/ld.cpp: don't generate debug note for .eh symbols
+ * src/MachOReaderRelocatable.hpp: make dwarf line info to atom matching faster and better
+
+2006-01-31 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj : Make buildable on Leopard
+ * src/MachOFileAbstraction.hpp: make buildable without latest cctools headers
+
+2006-01-31 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: better error message for bad relocs
+ * src/ObjectDump.cpp: add emacs tab settings
+ * src/SectCreate.h: ditto
+ * src/SectCreate.cpp: ditto
+ * src/machochecker.cpp: ditto
+ * src/ExecutableFile.h: ditto
+
+2006-01-30 Eric Christopher <echristo@apple.com>
+
+ * src/ExecutableFile.h: Indent.
+
+2006-01-30 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: performance improvements
+ * src/ld.cpp: now that stubs are synthesized in write, don't need to special case anymore
+
+2006-01-30 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: fix parsing of pcc relocs
+ * unit-tests/test-cases/relocs-asm/relocs-asm.s: add test case for above
+
+2006-01-29 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/weak_import: added test case
+ * src/ld.cpp: move code for weak_import mismatch to writer
+ * src/ObjectFile.h: remove ImportWeakness methods
+ * src/MachOReaderDylib.hpp: ditto
+ * src/SectCreate.cpp: ditto
+ * src/Architectures.hpp: add new ReferenceKinds for weak_imports
+ * src/MachOReaderRelocatable.hpp: implement new ReferenceKinds
+ * src/MachOWriterExecutable.hpp: handle new ReferenceKinds and weak_import mismatches
+
+2006-01-29 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp: verify -allow_stack_execute is only used on main executables
+
+2006-01-29 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: sync with latest dwarf reader from Geoff
+ * src/debugline.c: sync with latest dwarf reader from Geoff
+
+2006-01-27 Eric Christopher <echristo@apple.com>
+
+ * src/ld.cpp (Linker::syntesizeStabs): Correct spelling. Update all uses.
+
+2006-01-27 Eric Christopher <echristo@apple.com>
+
+ * src/Options.h (Options): Add hasExecutableStack, fExecutableStack.
+ * src/Options.cpp (Options::hasExecutableStack): New.
+ (Options::parse): Parse -allow_stack_execute.
+ * src/MachOWriterExecutable.hpp (MachHeaderAtom::copyRawContent):
+ Implement MH_ALLOW_STACK_EXECUTION.
+ * unit-tests/include/common.makefile (FAIL_IF_EMPTY): New.
+ * unit-tests/bin/fail-if-no-stdin.pl: New file.
+ * unit-tests/test-cases/allow-stack-execute: New directory.
+
+2006-01-27 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOFileAbstraction.hpp: rely on latest system headers
+ * src/MachOWriterExecutable.hpp: fix ppc stubs.
+ wrote new relocationNeededInFinalLinkedImage() to replace common code
+
+2006-01-27 Eric Christopher <echristo@apple.com>
+
+ * src/ld.cpp (logTraceInfo): New.
+ (Linker::addArchive): Use.
+ (Linker::addDylib): Ditto.
+ * src/ObjectFile (ReaderOptions::fTraceOutputFile): New.
+ * src/MachOReaderArchive.hpp (Reader::Reader): Move trace
+ logging to Linker::addArchive.
+ * src/Options.cpp (parsePreCommandLineEnvironment): Check
+ LD_PRINT_FILE if tracing dylibs or archives.
+
+2006-01-26 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: handle NULL strings in SO debug notes
+
+2006-01-26 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix header padding calculation and thread state
+
+2006-01-26 Nick Kledzik <kledzik@apple.com>
+
+ Rewrite all stabs processing.
+ Move sythesize of debug notes into ld.cpp
+
+2006-01-26 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix ppc and ppc64 stub relocs
+
+2006-01-25 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: special case building in Curry
+
+2006-01-25 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix bugs in stub/lazy-pointer synthesis
+
+2006-01-24 Eric Christopher <echristo@apple.com>
+
+ * src/ld.cpp (Linker::createReaders): Change logging title to XBS.
+ (Linker::addDylib): Ditto.
+ * src/MachOReaderArchive.hpp (Reader::Reader): Ditto.
+ * src/Options.h (fPrintOptions): New.
+ * src/Options.cpp (Options::Options): Initialize above.
+ (Options::checkForFile): Change logging title to XBS.
+ (Options::findFramework): Ditto.
+ (Options::parse): Add log for options.
+ (Options::parsePreCommandLineEnvironmentSettings): Add LD_TRACE_ARCHIVES,
+ LD_TRACE_DYLIBS, and LD_PRINT_OPTIONS.
+
+2006-01-24 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: better C++ eh parsing
+
+2006-01-23 Eric Christopher <echristo@apple.com>
+
+ * unit-tests/bin/fail-if-exit-zero.pl: New.
+ * unit-tests/include/common.makefile (FAIL_IF_SUCCESS): Use.
+ * unit-tests/allowable-client: New test.
+ * src/ld.cpp (Linker::addDylib): Check allowable clients before adding dylib.
+ * src/Options.h (allowableClients): New.
+ (clientName): Ditto.
+ (fAllowableClients): Ditto.
+ (fClientName): Ditto.
+ * src/Options.cpp: Implement above.
+ (parse): Handle -allowable_client and -client_name.
+ * src/MachOReaderDylib.hpp (getAllowableClients): New.
+ (fAllowableClients): Ditto.
+ (Reader): Process LC_SUB_CLIENT load command.
+ * src/ObjectFile.h (parentUmbrella): New.
+ (getAllowableClients): New.
+ * src/MachOWriterExecutable.hpp (AllowableClientLoadCommandsAtom): New.
+
+2006-01-23 Nick Kledzik <kledzik@apple.com>
+
+ * unit-tests/test-cases/archive-basic: added
+ * src/ld.cpp: fix shadowed local variable
+ * src/FileAbstraction.hpp: <rdar://problem/4417372> ld64 shouldn't inline when building debug
+
+2006-01-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: fix symbol not found error message
+ * src/MachOReaderDylib.hpp: add logging to hash table
+ * src/MachOReaderRelocatable.hpp: enable stabs processing. Handle static functions with stubs
+ handle labeled cstrings.
+ * src/MachOWriterExecutable.hpp: properly suppress atoms not in symbol table. fix low14 error check.
+ add StubAtomHelper.
+ * unit-tests/test-cases/relocs-literals/test.c: add more interesting edge cases
+
+2006-01-17 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: tweaks to synthesizing debug notes
+
+2006-01-16 Nick Kledzik <kledzik@apple.com>
+
+ * src/debugline.{sh}: added
+ * src/MachOReaderRelocatable.hpp: synthesize debug notes SOL from dwarf
+ * src/MachOWriterExecutable.hpp: fix lazy pointer section
+ * src/ObjectDump.hpp: Fix conditionalization
+ * unit-tests/test-cases/dwarf-strip: added
+
+2006-01-11 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: support Tiger crt1.o build with old ld64
+ * src/ObjectDump.hpp: Support -arch option
+
+2006-01-10 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix stubs for ppc64
+ * src/MachOFileAbstraction.hpp: fix typo for macho_routines
+ * ld64.xcodeproj/project.pbxproj: add machochecker target
+ * src/machochecker.cpp: new skeleton for checking mach-o file bit
+ * unit-tests/: Add support for running machochecker
+
+2006-01-10 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: warn if dwarf can't be parsed
+ * src/MachOReaderArchive.hpp: modTime for OSO stabs from archives is .a modTime
+
+2006-01-09 Nick Kledzik <kledzik@apple.com>
+
+ * track modification time of .o files so that sythesized OSO stab will have it
+
+2006-01-09 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOFileAbstraction.hpp: add macho_uuid_command
+ * src/MachOWriterExecutable.cpp: add UUID load command to generated files
+
+2006-01-09 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderDylib.hpp: no longer keep dylib memory mapped
+ * src/ld.cpp: don't track dylib sizes because they are not longer memory mapped
+
+2006-01-05 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: support new relocations
+
+2006-01-05 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderDylib.hpp: support MH_DYLIB_STUB
+ * src/MachOReaderRelocatable.hpp: Add Geoff's comp unit extractor
+
+2006-01-05 Nick Kledzik <kledzik@apple.com>
+
+ refactor: transform Atom::dontStripName() to getSymbolTableInclusion()
+ * src/ld.cpp: pass dyld_stub_binding_helper to writer
+ * src/MachOReaderRelocatable.hpp: update synthesized stabs
+ Ignore stubs and lazy pointers in .o files
+ Support initializers and terminators
+ * src/MachOWriterExecutable.hpp: synthesize stubs and lazy pointers as needed
+ * ld64.xcodeproj/project.pbxproj: change Release target to build with dwarf
+
+2006-01-03 Eric Christopher <echristo@apple.com>
+
+ * src/Options.h (multipleDefinitionsInDylibs): Declare.
+ (overridingDefinitionInDependentDylib): Ditto.
+ (warnOnMultipleDefinitionsInObjectFiles): Ditto.
+ (multiplyDefined): Remove.
+ (multiplyDefinedUnused): Ditto.
+ (fMultiplyDefined): Ditto.
+ (fWarnOnMultiplyDefined): New.
+ (fMultiplyDefinedDynamic): Ditto.
+ * src/Options.cpp (Options::Options): Initialize above.
+ (overridingDefinitionInDependentDylib): New.
+ (multipleDefinitionsInDylibs): Ditto.
+ (warnOnMultipleDefinitionsInObjectFiles): Ditto.
+ (parse): Update comments. Fix parsing of -y option.
+ Update error message for -dead_strip. Parse above
+ options.
+
+2006-01-02 Nick Kledzik <kledzik@apple.com>
+
+ * Refactor: move Atom::writeContent() to Writer
+
+2005-12-23 Nick Kledzik <kledzik@apple.com>
+
+ * Reworked, simplify, and document test harness
+ * unit-tests/README: Added
+
+2005-12-23 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: fixes for Objective-C
+ * unit-tests/test-cases/relocs-objc: Added
+
+2005-12-22 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: fix check that next reloc is pair
+ * src/MachOReaderRelocatable.hpp: Add code to synthesize essential stabs from dwarf
+
+2005-12-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: Fix parsing of literal sections
+ * src/MachOWriterExecutable.hpp: Fix writing of literal sections
+ * unit-tests/test-cases/relocs-literals: Added
+
+2005-12-15 Eric Christopher <echristo@apple.com>
+
+ * src/Options.h (enum Treatment): New.
+ (enum PICTreatment): Delete.
+ (enum VersionMin): New.
+ (prebind): Declare.
+ (macosxVersionMin): Ditto.
+ (multiplyDefined): Ditto.
+ (multiplyDefinedUnused): Ditto.
+ (setVersionMin): Ditto.
+ (setPICTreatment): Delete.
+ (setReadOnlyRelocTreatment): Ditto.
+ (picTreatment): Adjust return type.
+ (parseTreatment): New.
+ (fPrebind): Ditto.
+ (fVersionMin): Ditto.
+ (fPICTreatment): Change type.
+ (fMultiplyDefined): New.
+ (fMultiplyDefinedUnused): Ditto.
+ (fLimitUndefinedSymbols): Ditto.
+
+ * src/Options.cpp: Fix whitespace. Add comments on options.
+ (Options::Options): Add initializers for new variables.
+ (Options::prebind): New.
+ (Options::macosxVersionMin): Ditto.
+ (Options::parseTreatment): Ditto.
+ (Options::setVersionMin): Ditto.
+ (Options::setReadOnlyRelocTreatment): Delete.
+ (Options::setPICTreatment): Ditto.
+ (Options::Parse): Update for above. Add comments.
+
+2005-12-15 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: Add comments about dwarf
+
+2005-12-14 Nick Kledzik <kledzik@apple.com>
+
+ * src/ELFFileAbstraction.hpp: Added
+ * src/ELFReaderRelocatable.hpp: Added
+ * Lot of fixes for new architecture
+ * Added __OPEN_SOURCE__ to "Preprocessor Macros" to disable new architecture support by default
+
+2005-12-13 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: check for S_ATTR_DEBUG and ignore those sections
+ * unit-tests/test-cases/dwarf-ignore: added
+
+2005-12-12 Nick Kledzik <kledzik@apple.com>
+
+ * Added test harness and three initial tests:
+ relocs-asm, relocs-c, and hello-world
+
+2005-12-12 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: Massive refactoring:
+ Now there are three Atom classes, Chopping into Atoms
+ is done on label boundaries or by knowledge of special
+ sections, Share lots of ppc/ppc64 code.
+ Stabs process code is temporarily disabled.
+
+2005-12-12 Nick Kledzik <kledzik@apple.com>
+
+ * src/ObjectDump.cpp: Add command line options: -no_content, -stabs, -no_sort
+
+2005-12-11 Eric Christopher <echristo@apple.com>
+
+ * src/Options.cpp: Reformat.
+ * src/Options.h: Ditto.
+
+2005-12-07 Eric Christopher <echristo@apple.com>
+
+ * src/MachOReaderRelocatable.hpp (Atom::getAlignment):
+ When calculating alignment of an Atom, take into account
+ the alignment from which we pulled the Atom.
+
+2005-12-06 Nick Kledzik <kledzik@apple.com>
+
+ * src/Options.cpp src/Options.h: Add design comments
+
+2005-12-05 Eric Christopher <echristo@apple.com>
+
+ * src/ld.cpp (Linker::createWriter): Uncomment ppc64 and
+ i386 linkers.
+
+2005-12-05 Eric Christopher <echristo@apple.com>
+
+ * ChangeLog: New file.
+
+2005-12-02 Nick Kledzik <kledzik@apple.com>
+
+ * src/ObjectFile.h: Add design comments
+
+2005-11-30 Nick Kledzik <kledzik@apple.com>
+
+ * Fix uses of __OPEN_SOURCE__
+
+2005-11-28 Nick Kledzik <kledzik@apple.com>
+
+ * Refactor Atom to use getDefinitionKind()
+
+2005-11-21 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: don't generate section for commons in -r mode
+
+2005-11-18 Nick Kledzik <kledzik@apple.com>
+
+ * x86 tweaks
+
+2005-11-18 Nick Kledzik <kledzik@apple.com>
+
+ * src/ObjectDump.cpp: make work with command line arguments
+
+2005-11-18 Nick Kledzik <kledzik@apple.com>
+
+ * Massive rework to remove preprocessor conditionals and use templates
+
+2005-11-14 Nick Kledzik <kledzik@apple.com>
+
+ * Created new Subversion repository for ld64 from cvs tag ld64-27.2
F933D91D09291AC90083EAC8 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ARCHS = x86_64;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+ GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
+ GCC_WARN_MISSING_PARENTHESES = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
+ GCC_WARN_UNUSED_LABEL = NO;
+ GCC_WARN_UNUSED_VALUE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = /usr/local/bin;
PREBINDING = NO;
PRODUCT_NAME = dyldinfo;
+ WARNING_CFLAGS = "-Wall";
};
name = Debug;
};
void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); }
const uint8_t* uuid() const INLINE { return fields.uuid; }
- void set_uuid(uint8_t uuid[16]) INLINE { memcpy(&fields.uuid, uuid, 16); }
+ void set_uuid(uint8_t u[16]) INLINE { memcpy(&fields.uuid, u, 16); }
typedef typename P::E E;
private:
enum ReferenceKinds { kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff, kPointerDiff32=kPointerDiff, kPointerDiff16,
kPCRel32, kPCRel32WeakImport, kAbsolute32, kPCRel16, kPCRel8,
- kImageOffset32, kPointerDiff24,
+ kImageOffset32, kPointerDiff24, kSectionOffset24,
kDtraceProbe, kDtraceProbeSite, kDtraceIsEnabledSite, kDtraceTypeReference };
};
kBranchPCRel32, kBranchPCRel32WeakImport,
kPCRel32GOTLoad, kPCRel32GOTLoadWeakImport,
kPCRel32GOT, kPCRel32GOTWeakImport, kBranchPCRel8, kGOTNoFixUp,
- kImageOffset32, kPointerDiff24,
+ kImageOffset32, kPointerDiff24, kSectionOffset24,
kDtraceProbe, kDtraceProbeSite, kDtraceIsEnabledSite, kDtraceTypeReference };
};
{
typedef Pointer32<LittleEndian> P;
- enum ReferenceKinds { kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff, kPointerDiff32=kPointerDiff, kReadOnlyPointer,
+ enum ReferenceKinds { kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff,
+ kPointerDiff32=kPointerDiff, kReadOnlyPointer, kPointerDiff12,
kBranch24, kBranch24WeakImport, kThumbBranch22, kThumbBranch22WeakImport,
kDtraceProbe, kDtraceProbeSite, kDtraceIsEnabledSite, kDtraceTypeReference };
};
/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
*
- * Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
virtual ObjectFile::Atom& makeObjcInfoAtom(ObjectFile::Reader::ObjcConstraint objcContraint,
bool objcReplacementClasses) = 0;
virtual class ObjectFile::Atom* getUndefinedProxyAtom(const char* name) = 0;
+ virtual void addSynthesizedAtoms(const std::vector<class ObjectFile::Atom*>& existingAtoms,
+ class ObjectFile::Atom* dyldClassicHelperAtom,
+ class ObjectFile::Atom* dyldCompressedHelperAtom,
+ class ObjectFile::Atom* dyldLazyDylibHelperAtom,
+ bool biggerThanTwoGigs,
+ uint32_t dylibSymbolCount,
+ std::vector<class ObjectFile::Atom*>& newAtoms) = 0;
virtual uint64_t write(std::vector<class ObjectFile::Atom*>& atoms,
std::vector<class ObjectFile::Reader::Stab>& stabs,
class ObjectFile::Atom* entryPointAtom,
- class ObjectFile::Atom* dyldClassicHelperAtom,
- class ObjectFile::Atom* dyldCompressedHelperAtom,
- class ObjectFile::Atom* dyldLazyDylibHelperAtom,
bool createUUID, bool canScatter,
ObjectFile::Reader::CpuConstraint cpuConstraint,
- bool biggerThanTwoGigs,
std::set<const class ObjectFile::Atom*>& atomsThatOverrideWeak,
bool hasExternalWeakDefinitions) = 0;
/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
*
- * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
case CPU_TYPE_X86_64:
return "x86_64-";
case CPU_TYPE_ARM:
- return "arm-";
+ return "arm";
}
return "";
}
warning("could not produce merged bitcode file");
}
- // if requested, save off merged bitcode file
- if ( saveTemps ) {
- char tempBitcodePath[MAXPATHLEN];
- strcpy(tempBitcodePath, outputFilePath);
- strcat(tempBitcodePath, ".lto.bc");
- ::lto_codegen_write_merged_modules(generator, tempBitcodePath);
- }
-
// set code-gen model
lto_codegen_model model = LTO_CODEGEN_PIC_MODEL_DYNAMIC;
switch ( outputKind ) {
model = LTO_CODEGEN_PIC_MODEL_DYNAMIC;
break;
case Options::kStaticExecutable:
- model = LTO_CODEGEN_PIC_MODEL_STATIC;
+ // darwin x86_64 "static" code model is really dynamic code model
+ if ( fArchitecture == CPU_TYPE_X86_64 )
+ model = LTO_CODEGEN_PIC_MODEL_DYNAMIC;
+ else
+ model = LTO_CODEGEN_PIC_MODEL_STATIC;
break;
}
if ( ::lto_codegen_set_pic_model(generator, model) )
throwf("could not create set codegen model: %s", lto_get_error_message());
+ // if requested, save off merged bitcode file
+ if ( saveTemps ) {
+ char tempBitcodePath[MAXPATHLEN];
+ strcpy(tempBitcodePath, outputFilePath);
+ strcat(tempBitcodePath, ".lto.bc");
+ ::lto_codegen_write_merged_modules(generator, tempBitcodePath);
+ }
+
+#if LTO_API_VERSION >= 3
+ // find assembler next to linker
+ char path[PATH_MAX];
+ uint32_t bufSize = PATH_MAX;
+ if ( _NSGetExecutablePath(path, &bufSize) != -1 ) {
+ char* lastSlash = strrchr(path, '/');
+ if ( lastSlash != NULL ) {
+ strcpy(lastSlash+1, "as");
+ struct stat statInfo;
+ if ( stat(path, &statInfo) == 0 )
+ ::lto_codegen_set_assembler_path(generator, path);
+ }
+ }
+#endif
// run code generator
size_t machOFileLen;
const uint8_t* machOFile = (uint8_t*)::lto_codegen_compile(generator, &machOFileLen);
::write(fd, machOFile, machOFileLen);
::close(fd);
}
- }
+ // save off merged bitcode file
+ char tempOptBitcodePath[MAXPATHLEN];
+ strcpy(tempOptBitcodePath, outputFilePath);
+ strcat(tempOptBitcodePath, ".lto.opt.bc");
+ ::lto_codegen_write_merged_modules(generator, tempOptBitcodePath);
+ }
// parse generated mach-o file into a MachOReader
ObjectFile::Reader* machoReader = this->makeMachOReader(machOFile, machOFileLen, nextInputOrdinal);
}; // namespace lto
-extern void printLTOVersion(Options &opts);
+extern void printLTOVersion(Options& opts);
-void printLTOVersion(Options &opts) {
+void printLTOVersion(Options& opts) {
const char* vers = lto_get_version();
if ( vers != NULL )
fprintf(stderr, "%s\n", vers);
//fprintf(stderr, "processIndirectLibraries() implicitly linking %s\n", child->getInstallPath());
((Reader<A>*)child)->setImplicitlyLinked();
}
- else
+ else if ( child->explicitlyLinked() || child->implicitlyLinked() ) {
+ //fprintf(stderr, "processIndirectLibraries() parent is not directly linked, but child is, so no need to re-export child\n");
+ }
+ else {
fReExportedChildren.push_back(child);
+ //fprintf(stderr, "processIndirectLibraries() parent is not directly linked, so parent=%s will re-export child=%s\n", this->getInstallPath(), it->path);
+ }
}
else {
// add all child's symbols to me
fReExportedChildren.push_back(child);
- //fprintf(stderr, "processIndirectLibraries() parent=%s will re-export child=%s\n", this->getInstallPath(), it->path);
+ //fprintf(stderr, "processIndirectLibraries() child is not public, so parent=%s will re-export child=%s\n", this->getInstallPath(), it->path);
}
}
else if ( !fExplictReExportFound ) {
virtual ObjectFile::UnwindInfo::iterator beginUnwind() { return fHasCompactUnwindInfo ? &fSingleUnwindInfo[0] : NULL; }
virtual ObjectFile::UnwindInfo::iterator endUnwind() { return fHasCompactUnwindInfo ? &fSingleUnwindInfo[1] : NULL; }
virtual ObjectFile::Reference* getLSDA();
+ virtual ObjectFile::Reference* getFDE();
virtual Atom* getPersonalityPointer();
virtual void setCompactUnwindEncoding(uint64_t ehAtomAddress);
return NULL;
}
+ObjectFile::Reference* BaseAtom::getFDE()
+{
+ const uint8_t groupKind = this->getLSDAReferenceKind();
+ const std::vector<ObjectFile::Reference*>& refs = this->getReferences();
+ for (std::vector<ObjectFile::Reference*>::const_iterator it=refs.begin(); it != refs.end(); it++) {
+ ObjectFile::Reference* ref = *it;
+ if ( (ref->getKind() == groupKind) && (ref->getTarget().getContentType() == ObjectFile::Atom::kCFIType) ) {
+ return ref;
+ }
+ }
+ return NULL;
+}
+
ObjectFile::Atom* BaseAtom::getPersonalityPointer()
{
const uint8_t personalityKind = this->getPersonalityReferenceKind();
fAlignment.modulus = 0;
}
+
template <typename A>
bool SymbolAtom<A>::dontDeadStrip() const
{
virtual void setSize(uint64_t size) { fSize = size; }
virtual void addReference(ObjectFile::Reference* ref) { fReferences.push_back((Reference<A>*)ref); }
virtual void sortReferences() { std::sort(fReferences.begin(), fReferences.end(), ReferenceSorter()); }
- virtual void addLineInfo(const ObjectFile::LineInfo& info) { warning("can't add line info to anonymous symbol %s from %s", this->getDisplayName(), this->getFile()->getPath()); }
+ virtual void addLineInfo(const ObjectFile::LineInfo& info);
virtual const ObjectFile::ReaderOptions& getOptions() const { return fOwner.fOptions; }
virtual uint64_t getObjectAddress() const { return fAddress; }
virtual const void* getSectionRecord() const { return (const void*)fSection; }
if ( !fOwner.fOptions.fNoEHLabels )
fSymbolTableInclusion = ObjectFile::Atom::kSymbolTableIn;
}
+ else if ( section == owner.fUTF16Section ) {
+ if ( fOwner.fOptions.fForFinalLinkedImage ) {
+ fDontDeadStrip = false;
+ fScope = ObjectFile::Atom::scopeLinkageUnit;
+ fKind = ObjectFile::Atom::kWeakDefinition;
+ char* name = new char[16+5*size];
+ strcpy(name, "utf16-string=");
+ char* s = &name[13];
+ const uint16_t* words = (uint16_t*)((char*)(owner.fHeader) + section->offset() + addr - section->addr());
+ unsigned int wordCount = size/2;
+ // note, the compiler sometimes puts trailing zeros on the end of the data
+ if ( E::get32(words[wordCount-1]) == 0 )
+ --wordCount;
+ bool needSeperator = false;
+ for(unsigned int i=0; i < wordCount; ++i) {
+ if ( needSeperator )
+ strcpy(s++, ".");
+ sprintf(s, "%04X", E::get32(words[i]));
+ s += 4;
+ needSeperator = true;
+ }
+ fSynthesizedName = name;
+ }
+ else {
+ asprintf((char**)&fSynthesizedName, "lutf16-0x%X", addr);
+ }
+ }
break;
case S_CSTRING_LITERALS:
{
const char* str = (char*)(owner.fHeader) + section->offset() + addr - section->addr();
- if ( strcmp(fSection->sectname(), "__cstring") == 0 )
+ if ( (strcmp(fSection->sectname(), "__cstring") == 0) && (strcmp(section->segname(), "__TEXT") == 0) )
asprintf((char**)&fSynthesizedName, "cstring=%s", str);
else
asprintf((char**)&fSynthesizedName, "cstring%s%s=%s", fSection->segname(), fSection->sectname(), str);
case S_LAZY_SYMBOL_POINTERS:
case S_NON_LAZY_SYMBOL_POINTERS:
{
+ // transform i386 __IMPORT/__pointers to __DATA/__nl_symbol_ptr when
+ // generating the new compressed LINKEDIT format
+ if ( (type == S_NON_LAZY_SYMBOL_POINTERS) && fOwner.fOptions.fMakeCompressedDyldInfo && (strcmp(fSection->segname(),"__IMPORT") == 0) ) {
+ macho_section<P>* dummySection = new macho_section<P>(*fSection);
+ dummySection->set_segname("__DATA");
+ dummySection->set_sectname("__nl_symbol_ptr");
+ fSection = dummySection;
+ fSegment = new Segment<A>(fSection);
+ }
+
fDontDeadStrip = false;
fScope = ObjectFile::Atom::scopeLinkageUnit;
uint32_t index = (fAddress - fSection->addr()) / sizeof(pint_t);
// add direct reference to target later, because its atom may not be constructed yet
fOwner.fLocalNonLazys.push_back(this);
fScope = ObjectFile::Atom::scopeTranslationUnit;
+ fType = ObjectFile::Atom::kNonLazyPointer;
return;
}
else if ( (sym->n_value() < nonLazyPtrValue) && ((closestSym == NULL) || (sym->n_value() > closestSym->n_value())) ) {
}
fScope = ObjectFile::Atom::scopeTranslationUnit;
fOwner.fLocalNonLazys.push_back(this);
+ fType = ObjectFile::Atom::kNonLazyPointer;
return;
}
const macho_nlist<P>* targetSymbol = &fOwner.fSymbols[symbolIndex];
const char* name = &fOwner.fStrings[targetSymbol->n_strx()];
char* str = new char[strlen(name)+16];
strcpy(str, name);
- if ( type == S_LAZY_SYMBOL_POINTERS )
+ if ( type == S_LAZY_SYMBOL_POINTERS ) {
strcat(str, "$lazy_ptr");
- else
+ fType = ObjectFile::Atom::kLazyPointer;
+ }
+ else {
strcat(str, "$non_lazy_ptr");
+ fType = ObjectFile::Atom::kNonLazyPointer;
+ }
fSynthesizedName = str;
- // transform i386 __IMPORT/__pointers to __DATA/__nl_symbol_ptr when
- // generating the new compressed LINKEDIT format
- if ( fOwner.fOptions.fMakeCompressedDyldInfo && (strcmp(fSection->segname(),"__IMPORT") == 0) ) {
- macho_section<P>* dummySection = new macho_section<P>(*fSection);
- dummySection->set_segname("__DATA");
- dummySection->set_sectname("__nl_symbol_ptr");
- fSection = dummySection;
- fSegment = new Segment<A>(fSection);
- }
-
if ( type == S_NON_LAZY_SYMBOL_POINTERS )
fKind = ObjectFile::Atom::kWeakDefinition;
-
+
if ( (targetSymbol->n_type() & N_EXT) == 0 ) {
// target is translation unit scoped, so add direct reference to target
//fOwner.makeReference(A::kPointer, addr, targetSymbol->n_value());
}
break;
default:
- throwf("section type %d not supported with address=0x%08X", type, addr);
+ throwf("section type %d not supported with address=0x%08llX", type, (uint64_t)addr);
}
//fprintf(stderr, "AnonymousAtom(%p) %s \n", this, this->getDisplayName());
}
template <> bool AnonymousAtom<x86_64>::cstringsHaveLabels() { return true; }
template <typename A> bool AnonymousAtom<A>::cstringsHaveLabels() { return false; }
+template <typename A>
+void AnonymousAtom<A>::addLineInfo(const ObjectFile::LineInfo& info)
+{
+ // <rdar://problem/6545406> don't warn if line table has entries for stubs
+ if ( (fSection->flags() & SECTION_TYPE) != S_SYMBOL_STUBS )
+ warning("can't add line info to anonymous symbol %s from %s", this->getDisplayName(), this->getFile()->getPath());
+}
template <typename A>
void AnonymousAtom<A>::resolveName()
if ( (superStr != NULL) && (strncmp(superStr, "cstring=", 8) == 0) ) {
asprintf((char**)&fSynthesizedName, "cfstring=%s", &superStr[8]);
}
+ else if ( (superStr != NULL) && (strncmp(superStr, "utf16-string=", 13) == 0) ) {
+ asprintf((char**)&fSynthesizedName, "cfstring-utf16=%s", &superStr[13]);
+ }
else {
// compiled with -fwritable-strings or a non-ASCII string
fKind = ObjectFile::Atom::kRegularDefinition; // these are not coalescable
private:
const void* mappedAddress(pint_t addr, pint_t* relocTarget=NULL);
pint_t relocated(uint32_t sectOffset, uint32_t relocsOffset, uint32_t relocsCount);
+ void buildRelocatedMap(const macho_section<P>* sect, std::map<uint32_t,uint64_t>& map);
Reader<A>& fReader;
const uint8_t* fMappingStart;
const macho_section<P>* fSectionsStart;
const macho_section<P>* fSectionsEnd;
+ std::map<uint32_t,uint64_t> fEHFrameOffsetToTargetMap;
};
fMappingStart = (uint8_t*)fReader.fHeader;
fSectionsStart = (macho_section<P>*)((char*)fReader.fSegment + sizeof(macho_segment_command<P>));
fSectionsEnd = &fSectionsStart[fReader.fSegment->nsects()];
+ // find __eh_frame section and build map of relocations for performance
+ buildRelocatedMap(fReader.fehFrameSection, fEHFrameOffsetToTargetMap);
+ }
+ // special case lookups in __eh_frame section to be fast
+ const macho_section<P>* ehSect = fReader.fehFrameSection;
+ if ( (ehSect->addr() <= addr) && (addr < (ehSect->addr()+ehSect->size())) ) {
+ pint_t offsetOfAddrInSection = addr - ehSect->addr();
+ if ( relocTarget != NULL ) {
+ std::map<uint32_t,uint64_t>::iterator pos = fEHFrameOffsetToTargetMap.find(offsetOfAddrInSection);
+ if ( pos != fEHFrameOffsetToTargetMap.end() )
+ *relocTarget = pos->second;
+ else
+ *relocTarget = 0;
+ }
+ return fMappingStart + ehSect->offset() + offsetOfAddrInSection;
}
- for (const macho_section<P>* sect=fSectionsStart; sect < fSectionsEnd; ++sect) {
- if ( (sect->addr() <= addr) && (addr < (sect->addr()+sect->size())) ) {
- pint_t offsetOfAddrInSection = addr - sect->addr();
- if ( (sect->flags() & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS ) {
- const uint32_t indirectTableOffset = sect->reserved1();
- const uint32_t sectionIndex = offsetOfAddrInSection/sizeof(pint_t);
- const uint32_t symbolIndex = A::P::E::get32(fReader.fIndirectTable[indirectTableOffset+sectionIndex]);
- // return pointer to symbol name which this non-lazy-pointer will point to
- if ( relocTarget != NULL )
- *relocTarget = (uintptr_t)&fReader.fStrings[fReader.fSymbols[symbolIndex].n_strx()];
- }
- else {
- if ( relocTarget != NULL )
- *relocTarget = relocated(offsetOfAddrInSection, sect->reloff(), sect->nreloc());
+ else {
+ for (const macho_section<P>* sect=fSectionsStart; sect < fSectionsEnd; ++sect) {
+ if ( (sect->addr() <= addr) && (addr < (sect->addr()+sect->size())) ) {
+ pint_t offsetOfAddrInSection = addr - sect->addr();
+ if ( (sect->flags() & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS ) {
+ const uint32_t indirectTableOffset = sect->reserved1();
+ const uint32_t sectionIndex = offsetOfAddrInSection/sizeof(pint_t);
+ const uint32_t symbolIndex = A::P::E::get32(fReader.fIndirectTable[indirectTableOffset+sectionIndex]);
+ // return pointer to symbol name which this non-lazy-pointer will point to
+ if ( relocTarget != NULL )
+ *relocTarget = (uintptr_t)&fReader.fStrings[fReader.fSymbols[symbolIndex].n_strx()];
+ }
+ else {
+ if ( relocTarget != NULL )
+ *relocTarget = relocated(offsetOfAddrInSection, sect->reloff(), sect->nreloc());
+ }
+ return fMappingStart + sect->offset() + offsetOfAddrInSection;
}
- return fMappingStart + sect->offset() + offsetOfAddrInSection;
}
+ throwf("ObjectFileAddressSpace::mappedAddress(0x%0lX) not in any section", (long)addr);
}
- throwf("ObjectFileAddressSpace::mappedAddress(0x%0lX) not in any section", (long)addr);
}
ObjectFile::Reader::DebugInfoKind fDebugInfo;
bool fHasUUID;
const macho_section<P>* fehFrameSection;
+ const macho_section<P>* fUTF16Section;
std::set<BaseAtom*> fLSDAAtoms;
const macho_section<P>* fDwarfDebugInfoSect;
const macho_section<P>* fDwarfDebugAbbrevSect;
Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime, const ObjectFile::ReaderOptions& options, uint32_t ordinalBase)
: fPath(strdup(path)), fModTime(modTime), fOrdinalBase(ordinalBase), fOptions(options), fHeader((const macho_header<P>*)fileContent),
fStrings(NULL), fSymbols(NULL), fSymbolCount(0), fSegment(NULL), fIndirectTable(NULL),
- fDebugInfo(kDebugInfoNone), fHasUUID(false), fehFrameSection(NULL),
+ fDebugInfo(kDebugInfoNone), fHasUUID(false), fehFrameSection(NULL), fUTF16Section(NULL),
fDwarfDebugInfoSect(NULL), fDwarfDebugAbbrevSect(NULL), fDwarfDebugLineSect(NULL),
fDwarfTranslationUnitDir(NULL), fDwarfTranslationUnitFile(NULL), fAppleObjc(false), fHasDTraceProbes(false),
fHaveIndirectSymbols(false), fReplacementClasses(false), fHasLongBranchStubs(false),
for (const macho_section<P>* sect=fSectionsStart; sect < fSectionsEnd; ++sect) {
if ( (strcmp(sect->sectname(), "__eh_frame") == 0) && (strcmp(sect->segname(), "__TEXT") == 0) ) {
fehFrameSection = sect;
- if ( libunwind::CFI_Parser<ObjectFileAddressSpace<A> >::getCFIs(fObjectAddressSpace, sect->addr(), sect->size(),
- fCIEInfos, fFDEInfos) ) {
+ const char* msg = libunwind::CFI_Parser<ObjectFileAddressSpace<A> >::getCFIs(fObjectAddressSpace, sect->addr(),
+ sect->size(), fFDEInfos, fCIEInfos);
+ if ( msg != NULL ) {
+ throwf("malformed __eh_frame section: %s", msg);
+ }
+ else {
//fprintf(stderr, "%lu CIEs, %lu FDEs\n", fCIEInfos.size(), fFDEInfos.size());
// add anonymous atoms for each CIE
for (typename std::vector<CIE_Atom_Info>::const_iterator it = fCIEInfos.begin(); it != fCIEInfos.end(); ++it) {
}
}
}
- else {
- throw "malformed __eh_frame section";
+ }
+ else if ( (strcmp(sect->sectname(), "__ustring") == 0) && (strcmp(sect->segname(), "__TEXT") == 0) ) {
+ // if there is a __ustring section parse it into AnonymousAtoms based on labels
+ fUTF16Section = sect;
+ std::vector<pint_t> utf16Addreses;
+ for (int i=fSymbolCount-1; i >= 0 ; --i) {
+ const macho_nlist<P>& sym = fSymbols[i];
+ if ( (sym.n_type() & N_STAB) == 0 ) {
+ uint8_t type = (sym.n_type() & N_TYPE);
+ if ( type == N_SECT ) {
+ if ( &fSectionsStart[sym.n_sect()-1] == fUTF16Section ) {
+ utf16Addreses.push_back(sym.n_value());
+ }
+ }
+ }
+ }
+ utf16Addreses.push_back(fUTF16Section->addr()+fUTF16Section->size());
+ std::sort(utf16Addreses.begin(), utf16Addreses.end());
+ for(int i=utf16Addreses.size()-2; i >=0 ; --i) {
+ pint_t size = utf16Addreses[i+1] - utf16Addreses[i];
+ AnonymousAtom<A>* strAtom = new AnonymousAtom<A>(*this, fUTF16Section, utf16Addreses[i], size);
+ fAtoms.push_back(strAtom);
+ fAddrToAtom[utf16Addreses[i]] = strAtom;
}
}
}
else if ( section == fehFrameSection ) {
// ignore labels in __eh_frame section
}
+ else if ( section == fUTF16Section ) {
+ // ignore labels in __ustring section
+ }
else {
// ignore labels for atoms in other sections
switch ( section->flags() & SECTION_TYPE ) {
}
+template <>
+void ObjectFileAddressSpace<x86_64>::buildRelocatedMap(const macho_section<P>* sect, std::map<uint32_t,uint64_t>& map)
+{
+ // mach-o x86_64 is different, the content of a section with a relocation is the addend
+ const macho_relocation_info<P>* relocs = (macho_relocation_info<P>*)((char*)(fReader.fHeader) + sect->reloff());
+ const macho_relocation_info<P>* relocsEnd = &relocs[sect->nreloc()];
+ for (const macho_relocation_info<P>* reloc = relocs; reloc < relocsEnd; ++reloc) {
+ std::map<uint32_t,uint64_t>::iterator pos;
+ switch ( reloc->r_type() ) {
+ case X86_64_RELOC_UNSIGNED:
+ pos = map.find(reloc->r_address());
+ if ( pos != map.end() )
+ pos->second += fReader.fSymbols[reloc->r_symbolnum()].n_value();
+ else
+ map[reloc->r_address()] = fReader.fSymbols[reloc->r_symbolnum()].n_value();
+ break;
+ case X86_64_RELOC_SUBTRACTOR:
+ map[reloc->r_address()] = -fReader.fSymbols[reloc->r_symbolnum()].n_value();
+ break;
+ case X86_64_RELOC_GOT:
+ // there is no good address to return here.
+ // GOT slots are synthsized by the linker
+ // this is used for the reference to the personality function in CIEs
+ map[reloc->r_address()] = 0;
+ break;
+ default:
+ fprintf(stderr, "ObjectFileAddressSpace::buildRelocatedMap() unexpected relocation at r_address=0x%08X\n", reloc->r_address());
+ break;
+ }
+ }
+}
+
+template <typename A>
+void ObjectFileAddressSpace<A>::buildRelocatedMap(const macho_section<P>* sect, std::map<uint32_t,uint64_t>& map)
+{
+ // in all architectures except x86_64, the section contents are already fixed up to point
+ // to content in the same object file.
+}
template <>
uint64_t ObjectFileAddressSpace<x86_64>::relocated(uint32_t sectOffset, uint32_t relocsOffset, uint32_t relocsCount)
{
pint_t lsda;
pint_t personality;
+ char warningBuffer[1024];
uint32_t result = libunwind::DwarfInstructions<class ObjectFileAddressSpace<x86>, libunwind::Registers_x86>::createCompactEncodingFromFDE(
- fOwner.fObjectAddressSpace, ehAtomAddress, &lsda, &personality);
- if ( (result & UNWIND_X86_CASE_MASK) == UNWIND_X86_UNWIND_REQUIRES_DWARF ) {
+ fOwner.fObjectAddressSpace, ehAtomAddress, &lsda, &personality, warningBuffer);
+ if ( (result & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF ) {
//if ( fOwner.fOptions.fForDyld )
// throwf("can't make compact unwind encoding from dwarf for %s", this->getDisplayName());
//else
if ( fOwner.fOptions.fWarnCompactUnwind )
- warning("can't make compact unwind encoding from dwarf for %s in %s", this->getDisplayName(), fOwner.getPath());
+ warning("can't make compact unwind encoding from dwarf for %s in %s because %s", this->getDisplayName(), fOwner.getPath(), warningBuffer);
}
return result;
}
{
pint_t lsda;
pint_t personality;
+ char warningBuffer[1024];
uint32_t result = libunwind::DwarfInstructions<class ObjectFileAddressSpace<x86_64>, libunwind::Registers_x86_64>::createCompactEncodingFromFDE(
- fOwner.fObjectAddressSpace, ehAtomAddress, &lsda, &personality);
- if ( (result & UNWIND_X86_64_CASE_MASK) == UNWIND_X86_64_UNWIND_REQUIRES_DWARF ) {
+ fOwner.fObjectAddressSpace, ehAtomAddress, &lsda, &personality, warningBuffer);
+ if ( (result & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF ) {
//if ( fOwner.fOptions.fForDyld )
// throwf("can't make compact unwind encoding from dwarf for %s", this->getDisplayName());
//else
if ( fOwner.fOptions.fWarnCompactUnwind )
- warning("can't make compact unwind encoding from dwarf for %s in %s", this->getDisplayName(), fOwner.getPath());
+ warning("can't make compact unwind encoding from dwarf for %s in %s because %s", this->getDisplayName(), fOwner.getPath(), warningBuffer);
}
return result;
}
{
pint_t lsda;
pint_t personality;
+ char warningBuffer[1024];
uint32_t result = libunwind::DwarfInstructions<class ObjectFileAddressSpace<x86>, libunwind::Registers_x86>::createCompactEncodingFromFDE(
- fOwner.fObjectAddressSpace, ehAtomAddress, &lsda, &personality);
- if ( (result & UNWIND_X86_CASE_MASK) == UNWIND_X86_UNWIND_REQUIRES_DWARF ) {
+ fOwner.fObjectAddressSpace, ehAtomAddress, &lsda, &personality, warningBuffer);
+ if ( (result & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF ) {
//if ( fOwner.fOptions.fForDyld )
// throwf("can't make compact unwind encoding from dwarf for %s", this->getDisplayName());
//else
+ if ( fOwner.fOptions.fWarnCompactUnwind )
warning("can't make compact unwind encoding from dwarf for %s in %s", this->getDisplayName(), fOwner.getPath());
}
return result;
{
pint_t lsda;
pint_t personality;
+ char warningBuffer[1024];
uint32_t result = libunwind::DwarfInstructions<class ObjectFileAddressSpace<x86_64>, libunwind::Registers_x86_64>::createCompactEncodingFromFDE(
- fOwner.fObjectAddressSpace, ehAtomAddress, &lsda, &personality);
- if ( (result & UNWIND_X86_64_CASE_MASK) == UNWIND_X86_64_UNWIND_REQUIRES_DWARF ) {
+ fOwner.fObjectAddressSpace, ehAtomAddress, &lsda, &personality, warningBuffer);
+ if ( (result & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF ) {
//if ( fOwner.fOptions.fForDyld )
// throwf("can't make compact unwind encoding from dwarf for %s", this->getDisplayName());
//else
+ if ( fOwner.fOptions.fWarnCompactUnwind )
warning("can't make compact unwind encoding from dwarf for %s in %s", this->getDisplayName(), fOwner.getPath());
}
return result;
}
}
}
- // no atom found
- return AtomAndOffset(NULL);
+ // no atom found that matched section, fall back to one orginally found
+ return ao;
}
template <typename A>
return result;
}
// getting here means we have a scattered relocation to an address without a label
- // we should never get here...
- // one case we do get here is because sometimes the compiler generates non-lazy pointers in the __data section
- return findAtomAndOffset(realAddr);
+ // so, find the atom that contains the baseAddr, and offset from that to the readAddr
+ AtomAndOffset result = findAtomAndOffset(baseAddr);
+ result.offset += (realAddr-baseAddr);
+ return result;
}
kind = x86_64::kPointer32;
break;
case 3:
- kind = x86_64::kPointer;
+ if ( reloc->r_extern() && isWeakImportSymbol(targetSymbol) )
+ kind = x86_64::kPointerWeakImport;
+ else
+ kind = x86_64::kPointer;
break;
}
dstAddr = E::get64(*((uint64_t*)fixUpPtr));
break;
case ARM_THUMB_32BIT_BRANCH:
- // work around for <rdar://problem/6489480>
+ // ignore old unnecessary relocs
break;
default:
sprintf(temp, "offset 0x%04X, absolute32 reference to ", fFixUpOffsetInSrc);
break;
case x86::kImageOffset32:
- sprintf(temp, "offset 0x%04X, 32bit offset of ", fFixUpOffsetInSrc);
+ sprintf(temp, "offset 0x%04X, 32-bit offset of ", fFixUpOffsetInSrc);
break;
case x86::kPointerDiff24:
sprintf(temp, "offset 0x%04X, 24-bit pointer difference: (&%s + 0x%08X) - (&%s + 0x%08X)",
this->getFromTargetDisplayName(), fFromTarget.offset );
return temp;
break;
+ case x86::kSectionOffset24:
+ sprintf(temp, "offset 0x%04X, 24-bit section offset of ", fFixUpOffsetInSrc);
+ break;
case x86::kDtraceProbe:
sprintf(temp, "offset 0x%04X, dtrace static probe ", fFixUpOffsetInSrc);
break;
case x86_64::kImageOffset32:
sprintf(temp, "offset 0x%04llX, 32bit offset of ", fFixUpOffsetInSrc);
break;
+ case x86_64::kSectionOffset24:
+ sprintf(temp, "offset 0x%04llX, 24-bit section offset of ", fFixUpOffsetInSrc);
+ break;
case x86_64::kDtraceProbe:
sprintf(temp, "offset 0x%04llX, dtrace static probe ", fFixUpOffsetInSrc);
break;
fromQuotes, this->getFromTargetDisplayName(), fromQuotes, fFromTarget.offset );
return temp;
}
+ case arm::kPointerDiff12:
+ {
+ // by-name references have quoted names
+ const char* targetQuotes = (&(this->getTarget()) == NULL) ? "\"" : "";
+ const char* fromQuotes = (&(this->getFromTarget()) == NULL) ? "\"" : "";
+ sprintf(temp, "offset 0x%04X, 12-bit pointer difference: (&%s%s%s + %d) - (&%s%s%s + %d)",
+ fFixUpOffsetInSrc, targetQuotes, this->getTargetDisplayName(), targetQuotes, fToTarget.offset,
+ fromQuotes, this->getFromTargetDisplayName(), fromQuotes, fFromTarget.offset );
+ return temp;
+ }
case arm::kReadOnlyPointer:
sprintf(temp, "offset 0x%04X, read-only pointer to ", fFixUpOffsetInSrc);
break;
template <typename A> class LazyPointerAtom;
template <typename A> class NonLazyPointerAtom;
template <typename A> class DylibLoadCommandsAtom;
+template <typename A> class BranchIslandAtom;
// SectionInfo should be nested inside Writer, but I can't figure out how to make the type accessible to the Atom classes
virtual ObjectFile::Atom& makeObjcInfoAtom(ObjectFile::Reader::ObjcConstraint objcContraint,
bool objcReplacementClasses);
virtual class ObjectFile::Atom* getUndefinedProxyAtom(const char* name);
+ virtual void addSynthesizedAtoms(const std::vector<class ObjectFile::Atom*>& existingAtoms,
+ class ObjectFile::Atom* dyldClassicHelperAtom,
+ class ObjectFile::Atom* dyldCompressedHelperAtom,
+ class ObjectFile::Atom* dyldLazyDylibHelperAtom,
+ bool biggerThanTwoGigs,
+ uint32_t dylibSymbolCount,
+ std::vector<class ObjectFile::Atom*>& newAtoms);
virtual uint64_t write(std::vector<class ObjectFile::Atom*>& atoms,
std::vector<class ObjectFile::Reader::Stab>& stabs,
class ObjectFile::Atom* entryPointAtom,
- class ObjectFile::Atom* dyldClassicHelperAtom,
- class ObjectFile::Atom* dyldCompressedHelperAtom,
- class ObjectFile::Atom* dyldLazyDylibHelperAtom,
bool createUUID, bool canScatter,
ObjectFile::Reader::CpuConstraint cpuConstraint,
- bool biggerThanTwoGigs,
std::set<const class ObjectFile::Atom*>& atomsThatOverrideWeak,
bool hasExternalWeakDefinitions);
enum RelocKind { kRelocNone, kRelocInternal, kRelocExternal };
void assignFileOffsets();
- void synthesizeStubs();
- void synthesizeKextGOT();
+ void synthesizeStubs(const std::vector<class ObjectFile::Atom*>& existingAtoms,
+ std::vector<class ObjectFile::Atom*>& newAtoms);
+ void synthesizeKextGOT(const std::vector<class ObjectFile::Atom*>& existingAtoms,
+ std::vector<class ObjectFile::Atom*>& newAtoms);
void createSplitSegContent();
void synthesizeUnwindInfoTable();
void insertDummyStubs();
void partitionIntoSections();
bool addBranchIslands();
- bool addPPCBranchIslands();
- bool isBranch24Reference(uint8_t kind);
+ bool createBranchIslands();
+ bool isBranchThatMightNeedIsland(uint8_t kind);
+ uint32_t textSizeWhenMightNeedBranchIslands();
+ uint32_t maxDistanceBetweenIslands();
void adjustLoadCommandsAndPadding();
void createDynamicLinkerCommand();
void createDylibCommands();
friend class LazyPointerAtom<A>;
friend class NonLazyPointerAtom<A>;
friend class DylibLoadCommandsAtom<A>;
+ friend class BranchIslandAtom<A>;
const char* fFilePath;
Options& fOptions;
std::vector<class ObjectFile::Atom*> fLocalSymbolAtoms;
std::vector<macho_nlist<P> > fLocalExtraLabels;
std::vector<macho_nlist<P> > fGlobalExtraLabels;
+ std::map<ObjectFile::Atom*, uint32_t> fAtomToSymbolIndex;
class SectionRelocationsLinkEditAtom<A>* fSectionRelocationsAtom;
class CompressedRebaseInfoLinkEditAtom<A>* fCompressedRebaseInfoAtom;
class CompressedBindingInfoLinkEditAtom<A>* fCompressedBindingInfoAtom;
uint32_t fSymbolTableImportCount;
uint32_t fSymbolTableImportStartIndex;
uint32_t fLargestAtomSize;
+ uint32_t fDylibSymbolCountUpperBound;
bool fEmitVirtualSections;
bool fHasWeakExports;
bool fReferencesWeakImports;
bool fNoReExportedDylibs;
bool fBiggerThanTwoGigs;
bool fSlideable;
+ bool fHasThumbBranches;
std::map<const ObjectFile::Atom*,bool> fWeakImportMap;
std::set<const ObjectFile::Reader*> fDylibReadersWithNonWeakImports;
std::set<const ObjectFile::Reader*> fDylibReadersWithWeakImports;
virtual void copyRawContent(uint8_t buffer[]) const;
void addUnwindInfo(ObjectFile::Atom* func, uint32_t offset, uint32_t encoding,
- ObjectFile::Reference* lsda, ObjectFile::Atom* personalityPointer);
+ ObjectFile::Reference* fdeRef, ObjectFile::Reference* lsda,
+ ObjectFile::Atom* personalityPointer);
void generate();
private:
using WriterAtom<A>::fWriter;
typedef typename A::P P;
- struct Info { ObjectFile::Atom* func; ObjectFile::Atom* lsda; uint32_t lsdaOffset; ObjectFile::Atom* personalityPointer; uint32_t encoding; };
+ struct Info { ObjectFile::Atom* func; ObjectFile::Atom* fde; ObjectFile::Atom* lsda; uint32_t lsdaOffset; ObjectFile::Atom* personalityPointer; uint32_t encoding; };
struct LSDAEntry { ObjectFile::Atom* func; ObjectFile::Atom* lsda; uint32_t lsdaOffset; };
- struct RegFixUp { uint8_t* contentPointer; ObjectFile::Atom* func; };
+ struct RegFixUp { uint8_t* contentPointer; ObjectFile::Atom* func; ObjectFile::Atom* fde; };
struct CompressedFixUp { uint8_t* contentPointer; ObjectFile::Atom* func; ObjectFile::Atom* fromFunc; };
+ struct CompressedEncodingFixUp { uint8_t* contentPointer; ObjectFile::Atom* fde; };
+ bool encodingMeansUseDwarf(compact_unwind_encoding_t encoding);
void compressDuplicates(std::vector<Info>& uniqueInfos);
void findCommonEncoding(const std::vector<Info>& uniqueInfos, std::map<uint32_t, unsigned int>& commonEncodings);
void makeLsdaIndex(const std::vector<Info>& uniqueInfos, std::map<ObjectFile::Atom*, uint32_t>& lsdaIndexOffsetMap);
std::vector<LSDAEntry> fLSDAIndex;
std::vector<RegFixUp> fRegFixUps;
std::vector<CompressedFixUp> fCompressedFixUps;
+ std::vector<CompressedEncodingFixUp> fCompressedEncodingFixUps;
std::vector<ObjectFile::Reference*> fReferences;
};
class BranchIslandAtom : public WriterAtom<A>
{
public:
- BranchIslandAtom(Writer<A>& writer, const char* name, int islandRegion, ObjectFile::Atom& target, uint32_t targetOffset);
+ BranchIslandAtom(Writer<A>& writer, const char* name, int islandRegion, ObjectFile::Atom& target,
+ ObjectFile::Atom& finalTarget, uint32_t finalTargetOffset);
virtual const char* getName() const { return fName; }
virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
virtual uint64_t getSize() const;
+ virtual bool isThumb() const { return (fIslandKind == kBranchIslandToThumb2); }
+ virtual ObjectFile::Atom::ContentType getContentType() const { return ObjectFile::Atom::kBranchIsland; }
+ virtual ObjectFile::Atom::SymbolTableInclusion getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableIn; }
virtual const char* getSectionName() const { return "__text"; }
virtual void copyRawContent(uint8_t buffer[]) const;
+ uint64_t getFinalTargetAdress() const { return fFinalTarget.getAddress() + fFinalTargetOffset; }
private:
using WriterAtom<A>::fWriter;
+ enum IslandKind { kBranchIslandToARM, kBranchIslandToThumb2, kBranchIslandToThumb1 };
const char* fName;
ObjectFile::Atom& fTarget;
- uint32_t fTargetOffset;
+ ObjectFile::Atom& fFinalTarget;
+ uint32_t fFinalTargetOffset;
+ IslandKind fIslandKind;
};
template <typename A>
StubAtom(Writer<A>& writer, ObjectFile::Atom& target, bool forLazyDylib);
virtual const char* getName() const { return fName; }
virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
+ virtual ObjectFile::Atom::ContentType getContentType() const { return ObjectFile::Atom::kStub; }
virtual uint64_t getSize() const;
virtual ObjectFile::Alignment getAlignment() const;
virtual const char* getSectionName() const { return "__symbol_stub1"; }
virtual std::vector<ObjectFile::Reference*>& getReferences() const { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
virtual void copyRawContent(uint8_t buffer[]) const;
ObjectFile::Atom* getTarget() { return &fTarget; }
+ virtual uint32_t getOrdinal() const { return fSortingOrdinal; }
+ void setSortingOrdinal(uint32_t o) { fSortingOrdinal = o; }
private:
static const char* stubName(const char* importName);
- bool pic() const { return fWriter.fSlideable; }
+ friend class LazyPointerAtom<A>;
using WriterAtom<A>::fWriter;
+ enum StubKind { kStubPIC, kStubNoPIC, kStubShort, kJumpTable };
const char* fName;
ObjectFile::Atom& fTarget;
std::vector<ObjectFile::Reference*> fReferences;
bool fForLazyDylib;
+ StubKind fKind;
+ uint32_t fSortingOrdinal;
};
virtual const char* getName() const { return " stub helpers"; } // name sorts to start of helpers
virtual ObjectFile::Atom::SymbolTableInclusion getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableIn; }
virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
+ virtual ObjectFile::Atom::ContentType getContentType() const { return ObjectFile::Atom::kStubHelper; }
virtual uint64_t getSize() const;
virtual const char* getSectionName() const { return "__stub_helper"; }
virtual std::vector<ObjectFile::Reference*>& getReferences() const { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
virtual void copyRawContent(uint8_t buffer[]) const;
virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(0); }
+ virtual uint32_t getOrdinal() const { return 0; }
protected:
using WriterAtom<A>::fWriter;
std::vector<ObjectFile::Reference*> fReferences;
virtual const char* getName() const { return " stub helpers"; } // name sorts to start of helpers
virtual ObjectFile::Atom::SymbolTableInclusion getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableIn; }
virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
+ virtual ObjectFile::Atom::ContentType getContentType() const { return ObjectFile::Atom::kStubHelper; }
virtual uint64_t getSize() const;
virtual const char* getSectionName() const { return "__stub_helper"; }
virtual std::vector<ObjectFile::Reference*>& getReferences() const { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
virtual void copyRawContent(uint8_t buffer[]) const;
virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(0); }
+ virtual uint32_t getOrdinal() const { return 0; }
protected:
using WriterAtom<A>::fWriter;
std::vector<ObjectFile::Reference*> fReferences;
virtual const char* getName() const { return fName; }
virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
+ virtual ObjectFile::Atom::ContentType getContentType() const { return ObjectFile::Atom::kStubHelper; }
virtual const char* getSectionName() const { return "__stub_helper"; }
virtual std::vector<ObjectFile::Reference*>& getReferences() const { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
ObjectFile::Atom* getTarget() { return &fTarget; }
virtual ObjectFile::Alignment getAlignment() const { return ObjectFile::Alignment(0); }
+ virtual uint32_t getOrdinal() const { return 1; }
protected:
static const char* stubName(const char* importName);
using WriterAtom<A>::fWriter;
LazyPointerAtom(Writer<A>& writer, ObjectFile::Atom& target,
StubAtom<A>& stub, bool forLazyDylib);
virtual const char* getName() const { return fName; }
- virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
+ virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeTranslationUnit; }
+ virtual ObjectFile::Atom::ContentType getContentType() const { return fForLazyDylib ? ObjectFile::Atom::kLazyDylibPointer : ObjectFile::Atom::kLazyPointer; }
virtual uint64_t getSize() const { return sizeof(typename A::P::uint_t); }
- virtual const char* getSectionName() const { return fForLazyDylib ? "__ld_symbol_ptr" : "__la_symbol_ptr"; }
+ virtual const char* getSectionName() const;
virtual std::vector<ObjectFile::Reference*>& getReferences() const { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
virtual void copyRawContent(uint8_t buffer[]) const;
ObjectFile::Atom* getTarget() { return &fExternalTarget; }
void setLazyBindingInfoOffset(uint32_t off) { fLazyBindingOffset = off; }
uint32_t getLazyBindingInfoOffset() { return fLazyBindingOffset; }
+ virtual uint32_t getOrdinal() const { return fSortingOrdinal; }
+ void setSortingOrdinal(uint32_t o) { fSortingOrdinal = o; }
private:
using WriterAtom<A>::fWriter;
static const char* lazyPointerName(const char* importName);
ObjectFile::Atom& fExternalTarget;
std::vector<ObjectFile::Reference*> fReferences;
bool fForLazyDylib;
+ bool fCloseStub;
uint32_t fLazyBindingOffset;
+ uint32_t fSortingOrdinal;
};
NonLazyPointerAtom(Writer<A>& writer);
virtual const char* getName() const { return fName; }
virtual ObjectFile::Atom::Scope getScope() const { return ObjectFile::Atom::scopeLinkageUnit; }
+ virtual ObjectFile::Atom::ContentType getContentType() const { return ObjectFile::Atom::kNonLazyPointer; }
virtual uint64_t getSize() const { return sizeof(typename A::P::uint_t); }
virtual const char* getSectionName() const { return (fWriter.fOptions.outputKind() == Options::kKextBundle) ? "__got" : "__nl_symbol_ptr"; }
virtual std::vector<ObjectFile::Reference*>& getReferences() const { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
virtual void copyRawContent(uint8_t buffer[]) const;
ObjectFile::Atom* getTarget() { return fTarget; }
+ virtual uint32_t getOrdinal() const { return fSortingOrdinal; }
+ void setSortingOrdinal(uint32_t o) { fSortingOrdinal = o; }
private:
using WriterAtom<A>::fWriter;
static const char* nonlazyPointerName(const char* importName);
const char* fName;
ObjectFile::Atom* fTarget;
std::vector<ObjectFile::Reference*> fReferences;
+ uint32_t fSortingOrdinal;
};
buffer[2] = 0x00;
buffer[3] = 0x00;
buffer[4] = 0x00;
- buffer[5] = 0xFF; // jmp *_fast_lazy_bind(%rip)
+ buffer[5] = 0xFF; // jmp *_fast_lazy_bind
buffer[6] = 0x25;
buffer[7] = 0x00;
buffer[8] = 0x00;
}
+template <>
+FastStubHelperHelperAtom<arm>::FastStubHelperHelperAtom(Writer<arm>& writer)
+ : WriterAtom<arm>(writer, Segment::fgTextSegment)
+{
+ fReferences.push_back(new WriterReference<arm>(28, arm::kPointerDiff, new NonLazyPointerAtom<arm>(writer), 0, this, 16));
+ fReferences.push_back(new WriterReference<arm>(32, arm::kPointerDiff, writer.fFastStubGOTAtom, 0, this, 28));
+}
+
+template <>
+uint64_t FastStubHelperHelperAtom<arm>::getSize() const
+{
+ return 36;
+}
+
+template <>
+void FastStubHelperHelperAtom<arm>::copyRawContent(uint8_t buffer[]) const
+{
+ // push lazy-info-offset
+ OSWriteLittleInt32(&buffer[ 0], 0, 0xe52dc004); // str ip, [sp, #-4]!
+ // push address of dyld_mageLoaderCache
+ OSWriteLittleInt32(&buffer[ 4], 0, 0xe59fc010); // ldr ip, L1
+ OSWriteLittleInt32(&buffer[ 8], 0, 0xe08fc00c); // add ip, pc, ip
+ OSWriteLittleInt32(&buffer[12], 0, 0xe52dc004); // str ip, [sp, #-4]!
+ // jump through _fast_lazy_bind
+ OSWriteLittleInt32(&buffer[16], 0, 0xe59fc008); // ldr ip, L2
+ OSWriteLittleInt32(&buffer[20], 0, 0xe08fc00c); // add ip, pc, ip
+ OSWriteLittleInt32(&buffer[24], 0, 0xe59cf000); // ldr pc, [ip]
+ OSWriteLittleInt32(&buffer[28], 0, 0x00000000); // L1: .long fFastStubGOTAtom - (helperhelper+16)
+ OSWriteLittleInt32(&buffer[32], 0, 0x00000000); // L2: .long _fast_lazy_bind - (helperhelper+28)
+}
+
+template <>
+ObjectFile::Alignment StubHelperAtom<arm>::getAlignment() const { return ObjectFile::Alignment(2); }
+
+template <>
+FastStubHelperAtom<arm>::FastStubHelperAtom(Writer<arm>& writer, ObjectFile::Atom& target,
+ class LazyPointerAtom<arm>& lazyPointer, bool forLazyDylib)
+ : StubHelperAtom<arm>(writer, target, lazyPointer, forLazyDylib)
+{
+ if ( fgHelperHelperAtom == NULL ) {
+ fgHelperHelperAtom = new FastStubHelperHelperAtom<arm>::FastStubHelperHelperAtom(fWriter);
+ fWriter.fAllSynthesizedStubHelpers.push_back(fgHelperHelperAtom);
+ }
+ fReferences.push_back(new WriterReference<arm>(4, arm::kBranch24, fgHelperHelperAtom));
+}
+
+template <>
+uint64_t FastStubHelperAtom<arm>::getSize() const
+{
+ return 12;
+}
+
+template <>
+void FastStubHelperAtom<arm>::copyRawContent(uint8_t buffer[]) const
+{
+ OSWriteLittleInt32(&buffer[0], 0, 0xe59fc000); // ldr ip, [pc, #0]
+ OSWriteLittleInt32(&buffer[4], 0, 0xea000000); // b _helperhelper
+ // the lazy binding info is created later than this helper atom, so there
+ // is no Reference to update. Instead we blast the offset here.
+ OSWriteLittleInt32(&buffer[8], 0, fLazyPointerAtom.getLazyBindingInfoOffset());
+}
+
+
template <>
HybridStubHelperHelperAtom<x86>::HybridStubHelperHelperAtom(Writer<x86>& writer)
: WriterAtom<x86>(writer, Segment::fgTextSegment)
memcpy(&buffer[1], &offset, 4);
}
-
+template <typename A>
+const char* LazyPointerAtom<A>::getSectionName() const
+{
+ if ( fCloseStub )
+ return "__lazy_symbol";
+ else if ( fForLazyDylib )
+ return "__ld_symbol_ptr";
+ else
+ return "__la_symbol_ptr";
+}
// specialize lazy pointer for x86_64 to initially pointer to stub helper
template <>
LazyPointerAtom<x86_64>::LazyPointerAtom(Writer<x86_64>& writer, ObjectFile::Atom& target, StubAtom<x86_64>& stub, bool forLazyDylib)
: WriterAtom<x86_64>(writer, Segment::fgDataSegment), fName(lazyPointerName(target.getName())), fTarget(target),
- fExternalTarget(*stub.getTarget()), fForLazyDylib(forLazyDylib), fLazyBindingOffset(0)
+ fExternalTarget(*stub.getTarget()), fForLazyDylib(forLazyDylib), fCloseStub(false), fLazyBindingOffset(0)
{
if ( forLazyDylib )
writer.fAllSynthesizedLazyDylibPointers.push_back(this);
template <>
LazyPointerAtom<x86>::LazyPointerAtom(Writer<x86>& writer, ObjectFile::Atom& target, StubAtom<x86>& stub, bool forLazyDylib)
: WriterAtom<x86>(writer, Segment::fgDataSegment), fName(lazyPointerName(target.getName())), fTarget(target),
- fExternalTarget(*stub.getTarget()), fForLazyDylib(forLazyDylib)
+ fExternalTarget(*stub.getTarget()), fForLazyDylib(forLazyDylib), fCloseStub(false), fLazyBindingOffset(0)
{
if ( forLazyDylib )
writer.fAllSynthesizedLazyDylibPointers.push_back(this);
fReferences.push_back(new WriterReference<x86>(0, x86::kPointer, helper));
}
+// specialize lazy pointer for arm to initially pointer to stub helper
+template <>
+LazyPointerAtom<arm>::LazyPointerAtom(Writer<arm>& writer, ObjectFile::Atom& target, StubAtom<arm>& stub, bool forLazyDylib)
+ : WriterAtom<arm>(writer, Segment::fgDataSegment), fName(lazyPointerName(target.getName())), fTarget(target),
+ fExternalTarget(*stub.getTarget()), fForLazyDylib(forLazyDylib), fCloseStub(false), fLazyBindingOffset(0)
+{
+ if ( forLazyDylib )
+ writer.fAllSynthesizedLazyDylibPointers.push_back(this);
+ else
+ writer.fAllSynthesizedLazyPointers.push_back(this);
+
+ // The one instruction stubs must be close to the lazy pointers
+ if ( stub.fKind == StubAtom<arm>::kStubShort )
+ fCloseStub = true;
+
+ ObjectFile::Atom* helper;
+ if ( forLazyDylib ) {
+ if ( writer.fDyldLazyDylibHelper == NULL )
+ throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
+ helper = writer.fDyldLazyDylibHelper;
+ }
+ else if ( writer.fOptions.makeCompressedDyldInfo() ) {
+ if ( target.getDefinitionKind() == ObjectFile::Atom::kWeakDefinition )
+ helper = ⌖
+ else
+ helper = new FastStubHelperAtom<arm>(writer, target, *this, forLazyDylib);
+ }
+ else {
+ if ( writer.fDyldClassicHelperAtom == NULL )
+ throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+ helper = writer.fDyldClassicHelperAtom;
+ }
+ fReferences.push_back(new WriterReference<arm>(0, arm::kPointer, helper));
+}
+
template <typename A>
LazyPointerAtom<A>::LazyPointerAtom(Writer<A>& writer, ObjectFile::Atom& target, StubAtom<A>& stub, bool forLazyDylib)
: WriterAtom<A>(writer, Segment::fgDataSegment), fName(lazyPointerName(target.getName())), fTarget(target),
- fExternalTarget(*stub.getTarget()), fForLazyDylib(forLazyDylib)
+ fExternalTarget(*stub.getTarget()), fForLazyDylib(forLazyDylib), fCloseStub(false), fLazyBindingOffset(0)
{
if ( forLazyDylib )
writer.fAllSynthesizedLazyDylibPointers.push_back(this);
-template <>
-bool StubAtom<ppc64>::pic() const
-{
- // no-pic stubs for ppc64 don't work if lazy pointer is above low 2GB.
- // Usually that only happens if page zero is very large
- return ( fWriter.fSlideable || ((fWriter.fPageZeroAtom != NULL) && (fWriter.fPageZeroAtom->getSize() > 4096)) );
-}
-
-
-template <>
-bool StubAtom<arm>::pic() const
-{
- return fWriter.fSlideable;
-}
template <>
ObjectFile::Alignment StubAtom<ppc>::getAlignment() const
lp = new LazyPointerAtom<ppc>(writer, *writer.fDyldClassicHelperAtom, *this, forLazyDylib);
}
}
- if ( pic() ) {
+ fKind = ( fWriter.fSlideable ? kStubPIC : kStubNoPIC );
+ if ( fKind == kStubPIC ) {
// picbase is 8 bytes into atom
fReferences.push_back(new WriterReference<ppc>(12, ppc::kPICBaseHigh16, lp, 0, this, 8));
fReferences.push_back(new WriterReference<ppc>(20, ppc::kPICBaseLow16, lp, 0, this, 8));
throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
lp = new LazyPointerAtom<ppc64>(writer, *writer.fDyldClassicHelperAtom, *this, forLazyDylib);
}
- if ( pic() ) {
+ if ( fWriter.fSlideable || ((fWriter.fPageZeroAtom != NULL) && (fWriter.fPageZeroAtom->getSize() > 4096)) )
+ fKind = kStubPIC;
+ else
+ fKind = kStubNoPIC;
+ if ( fKind == kStubPIC ) {
// picbase is 8 bytes into atom
fReferences.push_back(new WriterReference<ppc64>(12, ppc64::kPICBaseHigh16, lp, 0, this, 8));
fReferences.push_back(new WriterReference<ppc64>(20, ppc64::kPICBaseLow14, lp, 0, this, 8));
fName(NULL), fTarget(target), fForLazyDylib(forLazyDylib)
{
if ( writer.fOptions.makeCompressedDyldInfo() || forLazyDylib ) {
+ fKind = kStubNoPIC;
fName = stubName(target.getName());
LazyPointerAtom<x86>* lp = new LazyPointerAtom<x86>(writer, target, *this, forLazyDylib);
fReferences.push_back(new WriterReference<x86>(2, x86::kAbsolute32, lp));
writer.fAllSynthesizedStubs.push_back(this);
}
else {
+ fKind = kJumpTable;
if ( &target == NULL )
- fName = "cache-line-crossing-stub";
+ asprintf((char**)&fName, "cache-line-crossing-stub %p", this);
else {
fName = stubName(target.getName());
writer.fAllSynthesizedStubs.push_back(this);
: WriterAtom<arm>(writer, Segment::fgTextSegment), fName(stubName(target.getName())), fTarget(target)
{
writer.fAllSynthesizedStubs.push_back(this);
-
- LazyPointerAtom<arm>* lp;
- if ( fWriter.fOptions.prebind() && !forLazyDylib ) {
- // for prebound arm, lazy pointer starts out pointing to target symbol's address
- // if target is a weak definition within this linkage unit or zero if in some dylib
- lp = new LazyPointerAtom<arm>(writer, target, *this, forLazyDylib);
+ if ( (writer.fDylibSymbolCountUpperBound < 900)
+ && writer.fOptions.makeCompressedDyldInfo()
+ && (writer.fOptions.outputKind() != Options::kDynamicLibrary)
+ && !forLazyDylib ) {
+ // dylibs might have __TEXT and __DATA pulled apart to live in shared region
+ // if > 1000 stubs, the displacement to the lazy pointer my be > 12 bits.
+ fKind = kStubShort;
+ }
+ else if ( fWriter.fSlideable ) {
+ fKind = kStubPIC;
}
else {
- // for non-prebound arm, lazy pointer starts out pointing to dyld_stub_binding_helper glue code
- ObjectFile::Atom* helper;
- if ( forLazyDylib ) {
- if ( writer.fDyldLazyDylibHelper == NULL )
- throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
- helper = writer.fDyldLazyDylibHelper;
- }
- else {
- if ( writer.fDyldClassicHelperAtom == NULL )
- throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
- helper = writer.fDyldClassicHelperAtom;
- }
- lp = new LazyPointerAtom<arm>(writer, *helper, *this, forLazyDylib);
+ fKind = kStubNoPIC;
+ }
+ LazyPointerAtom<arm>* lp = new LazyPointerAtom<arm>(writer, target, *this, forLazyDylib);
+ switch ( fKind ) {
+ case kStubPIC:
+ fReferences.push_back(new WriterReference<arm>(12, arm::kPointerDiff, lp, 0, this, 12));
+ break;
+ case kStubNoPIC:
+ fReferences.push_back(new WriterReference<arm>(8, arm::kReadOnlyPointer, lp));
+ break;
+ case kStubShort:
+ fReferences.push_back(new WriterReference<arm>(0, arm::kPointerDiff12, lp, 0, this, 8));
+ break;
+ default:
+ throw "internal error";
}
- if ( pic() )
- fReferences.push_back(new WriterReference<arm>(12, arm::kPointerDiff, lp, 0, this, 12));
- else
- fReferences.push_back(new WriterReference<arm>(8, arm::kPointer, lp));
}
+
+
template <typename A>
const char* StubAtom<A>::stubName(const char* name)
{
template <>
uint64_t StubAtom<ppc>::getSize() const
{
- return ( pic() ? 32 : 16 );
+
+ return ( (fKind == kStubPIC) ? 32 : 16 );
}
template <>
uint64_t StubAtom<ppc64>::getSize() const
{
- return ( pic() ? 32 : 16 );
+ return ( (fKind == kStubPIC) ? 32 : 16 );
}
template <>
uint64_t StubAtom<arm>::getSize() const
{
- return ( pic() ? 16 : 12 );
+ switch ( fKind ) {
+ case kStubPIC:
+ return 16;
+ case kStubNoPIC:
+ return 12;
+ case kStubShort:
+ return 4;
+ default:
+ throw "internal error";
+ }
}
template <>
uint64_t StubAtom<x86>::getSize() const
{
- if ( fWriter.fOptions.makeCompressedDyldInfo() || fForLazyDylib )
- return 6;
- else
- return 5;
+ switch ( fKind ) {
+ case kStubNoPIC:
+ return 6;
+ case kJumpTable:
+ return 5;
+ default:
+ throw "internal error";
+ }
}
template <>
template <>
ObjectFile::Alignment StubAtom<x86>::getAlignment() const
{
- if ( fWriter.fOptions.makeCompressedDyldInfo() || fForLazyDylib )
- return 1;
- else
- return 0; // special case x86 self-modifying stubs to be byte aligned
+ switch ( fKind ) {
+ case kStubNoPIC:
+ return 1;
+ case kJumpTable:
+ return 0; // special case x86 self-modifying stubs to be byte aligned
+ default:
+ throw "internal error";
+ }
}
template <>
void StubAtom<ppc64>::copyRawContent(uint8_t buffer[]) const
{
- if ( pic() ) {
+ if ( fKind == kStubPIC ) {
OSWriteBigInt32(&buffer [0], 0, 0x7c0802a6); // mflr r0
OSWriteBigInt32(&buffer[ 4], 0, 0x429f0005); // bcl 20,31,Lpicbase
OSWriteBigInt32(&buffer[ 8], 0, 0x7d6802a6); // Lpicbase: mflr r11
template <>
void StubAtom<ppc>::copyRawContent(uint8_t buffer[]) const
{
- if ( pic() ) {
+ if ( fKind == kStubPIC ) {
OSWriteBigInt32(&buffer[ 0], 0, 0x7c0802a6); // mflr r0
OSWriteBigInt32(&buffer[ 4], 0, 0x429f0005); // bcl 20,31,Lpicbase
OSWriteBigInt32(&buffer[ 8], 0, 0x7d6802a6); // Lpicbase: mflr r11
template <>
void StubAtom<x86>::copyRawContent(uint8_t buffer[]) const
{
- if ( fWriter.fOptions.makeCompressedDyldInfo() || fForLazyDylib ) {
- buffer[0] = 0xFF; // jmp *foo$lazy_pointer
- buffer[1] = 0x25;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = 0x00;
- buffer[5] = 0x00;
- }
- else {
- if ( fWriter.fOptions.prebind() ) {
- uint32_t address = this->getAddress();
- int32_t rel32 = 0 - (address+5);
- buffer[0] = 0xE9;
- buffer[1] = rel32 & 0xFF;
- buffer[2] = (rel32 >> 8) & 0xFF;
- buffer[3] = (rel32 >> 16) & 0xFF;
- buffer[4] = (rel32 >> 24) & 0xFF;
- }
- else {
- buffer[0] = 0xF4;
- buffer[1] = 0xF4;
- buffer[2] = 0xF4;
- buffer[3] = 0xF4;
- buffer[4] = 0xF4;
- }
+ switch ( fKind ) {
+ case kStubNoPIC:
+ buffer[0] = 0xFF; // jmp *foo$lazy_pointer
+ buffer[1] = 0x25;
+ buffer[2] = 0x00;
+ buffer[3] = 0x00;
+ buffer[4] = 0x00;
+ buffer[5] = 0x00;
+ break;
+ case kJumpTable:
+ if ( fWriter.fOptions.prebind() ) {
+ uint32_t address = this->getAddress();
+ int32_t rel32 = 0 - (address+5);
+ buffer[0] = 0xE9;
+ buffer[1] = rel32 & 0xFF;
+ buffer[2] = (rel32 >> 8) & 0xFF;
+ buffer[3] = (rel32 >> 16) & 0xFF;
+ buffer[4] = (rel32 >> 24) & 0xFF;
+ }
+ else {
+ buffer[0] = 0xF4;
+ buffer[1] = 0xF4;
+ buffer[2] = 0xF4;
+ buffer[3] = 0xF4;
+ buffer[4] = 0xF4;
+ }
+ break;
+ default:
+ throw "internal error";
}
}
template <>
void StubAtom<arm>::copyRawContent(uint8_t buffer[]) const
{
- if ( pic() ) {
- OSWriteLittleInt32(&buffer[ 0], 0, 0xe59fc004); // ldr ip, pc + 12
- OSWriteLittleInt32(&buffer[ 4], 0, 0xe08fc00c); // add ip, pc, ip
- OSWriteLittleInt32(&buffer[ 8], 0, 0xe59cf000); // ldr pc, [ip]
- OSWriteLittleInt32(&buffer[12], 0, 0x00000000); // .long L_foo$lazy_ptr - (L1$scv + 8)
- }
- else {
- OSWriteLittleInt32(&buffer[ 0], 0, 0xe59fc000); // ldr ip, [pc, #0]
- OSWriteLittleInt32(&buffer[ 4], 0, 0xe59cf000); // ldr pc, [ip]
- OSWriteLittleInt32(&buffer[ 8], 0, 0x00000000); // .long L_foo$lazy_ptr
+ switch ( fKind ) {
+ case kStubPIC:
+ OSWriteLittleInt32(&buffer[ 0], 0, 0xe59fc004); // ldr ip, pc + 12
+ OSWriteLittleInt32(&buffer[ 4], 0, 0xe08fc00c); // add ip, pc, ip
+ OSWriteLittleInt32(&buffer[ 8], 0, 0xe59cf000); // ldr pc, [ip]
+ OSWriteLittleInt32(&buffer[12], 0, 0x00000000); // .long L_foo$lazy_ptr - (L1$scv + 8)
+ break;
+ case kStubNoPIC:
+ OSWriteLittleInt32(&buffer[ 0], 0, 0xe59fc000); // ldr ip, [pc, #0]
+ OSWriteLittleInt32(&buffer[ 4], 0, 0xe59cf000); // ldr pc, [ip]
+ OSWriteLittleInt32(&buffer[ 8], 0, 0x00000000); // .long L_foo$lazy_ptr
+ break;
+ case kStubShort:
+ OSWriteLittleInt32(&buffer[ 0], 0, 0xE59FF000);// ldr pc, [pc, #foo$lazy_ptr]
+ break;
+ default:
+ throw "internal error";
}
}
template <>
const char* StubAtom<ppc>::getSectionName() const
{
- return ( pic() ? "__picsymbolstub1" : "__symbol_stub1");
+ return ( (fKind == kStubPIC) ? "__picsymbolstub1" : "__symbol_stub1");
}
template <>
const char* StubAtom<ppc64>::getSectionName() const
{
- return ( pic() ? "__picsymbolstub1" : "__symbol_stub1");
+ return ( (fKind == kStubPIC) ? "__picsymbolstub1" : "__symbol_stub1");
}
template <>
const char* StubAtom<arm>::getSectionName() const
{
- return ( pic() ? "__picsymbolstub4" : "__symbol_stub4");
+ switch ( fKind ) {
+ case kStubPIC:
+ return "__picsymbolstub4";
+ case kStubNoPIC:
+ return "__symbol_stub4";
+ case kStubShort:
+ return "__symbolstub1";
+ default:
+ throw "internal error";
+ }
}
template <>
const char* StubAtom<x86>::getSectionName() const
{
- if ( fWriter.fOptions.makeCompressedDyldInfo() || fForLazyDylib )
- return "__symbol_stub";
- else
- return "__jump_table";
+ switch ( fKind ) {
+ case kStubNoPIC:
+ return "__symbol_stub";
+ case kJumpTable:
+ return "__jump_table";
+ default:
+ throw "internal error";
+ }
}
fLargestAtomSize(1),
fEmitVirtualSections(false), fHasWeakExports(false), fReferencesWeakImports(false),
fCanScatter(false), fWritableSegmentPastFirst4GB(false), fNoReExportedDylibs(false),
- fBiggerThanTwoGigs(false), fSlideable(false),
+ fBiggerThanTwoGigs(false), fSlideable(false), fHasThumbBranches(false),
fFirstWritableSegment(NULL), fAnonNameIndex(1000)
{
switch ( fOptions.outputKind() ) {
fLibraryToLoadCommand[dylibInfo.reader] = dyliblc;
fWriterSynthesizedAtoms.push_back(dyliblc);
if ( dylibInfo.options.fReExport
- && (fOptions.macosxVersionMin() < ObjectFile::ReaderOptions::k10_5)
+ && !fOptions.useSimplifiedDylibReExports()
&& (fOptions.outputKind() == Options::kDynamicLibrary) ) {
// see if child has sub-framework that is this
bool isSubFramework = false;
return *(new ObjCInfoAtom<A>(*this, objcContraint, objcReplacementClasses));
}
+template <typename A>
+void Writer<A>::addSynthesizedAtoms(const std::vector<class ObjectFile::Atom*>& existingAtoms,
+ class ObjectFile::Atom* dyldClassicHelperAtom,
+ class ObjectFile::Atom* dyldCompressedHelperAtom,
+ class ObjectFile::Atom* dyldLazyDylibHelperAtom,
+ bool biggerThanTwoGigs,
+ uint32_t dylibSymbolCount,
+ std::vector<class ObjectFile::Atom*>& newAtoms)
+{
+ fDyldClassicHelperAtom = dyldClassicHelperAtom;
+ fDyldCompressedHelperAtom = dyldCompressedHelperAtom;
+ fDyldLazyDylibHelper = dyldLazyDylibHelperAtom;
+ fBiggerThanTwoGigs = biggerThanTwoGigs;
+ fDylibSymbolCountUpperBound = dylibSymbolCount;
+
+ // create inter-library stubs
+ synthesizeStubs(existingAtoms, newAtoms);
+}
+
template <typename A>
uint64_t Writer<A>::write(std::vector<class ObjectFile::Atom*>& atoms,
std::vector<class ObjectFile::Reader::Stab>& stabs,
class ObjectFile::Atom* entryPointAtom,
- class ObjectFile::Atom* dyldClassicHelperAtom,
- class ObjectFile::Atom* dyldCompressedHelperAtom,
- class ObjectFile::Atom* dyldLazyDylibHelperAtom,
bool createUUID, bool canScatter, ObjectFile::Reader::CpuConstraint cpuConstraint,
- bool biggerThanTwoGigs,
std::set<const class ObjectFile::Atom*>& atomsThatOverrideWeak,
bool hasExternalWeakDefinitions)
{
fAllAtoms = &atoms;
fStabs = &stabs;
fEntryPoint = entryPointAtom;
- fDyldClassicHelperAtom = dyldClassicHelperAtom;
- fDyldCompressedHelperAtom = dyldCompressedHelperAtom;
- fDyldLazyDylibHelper = dyldLazyDylibHelperAtom;
fCanScatter = canScatter;
fCpuConstraint = cpuConstraint;
- fBiggerThanTwoGigs = biggerThanTwoGigs;
fHasWeakExports = hasExternalWeakDefinitions; // dyld needs to search this image as if it had weak exports
fRegularDefAtomsThatOverrideADylibsWeakDef = &atomsThatOverrideWeak;
// check for mdynamic-no-pic codegen
scanForAbsoluteReferences();
- // create inter-library stubs
- synthesizeStubs();
-
// create table of unwind info
synthesizeUnwindInfoTable();
desc |= N_ARM_THUMB_DEF;
if ( atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableInAndNeverStrip )
desc |= REFERENCED_DYNAMICALLY;
+ if ( atom->dontDeadStrip() && (fOptions.outputKind() == Options::kObjectFile) )
+ desc |= N_NO_DEAD_STRIP;
if ( atom->getDefinitionKind() == ObjectFile::Atom::kWeakDefinition ) {
desc |= N_WEAK_DEF;
fHasWeakExports = true;
const char* symbolName = this->symbolTableName(atom);
char anonName[32];
if ( (fOptions.outputKind() == Options::kObjectFile) && !fOptions.keepLocalSymbol(symbolName) ) {
- sprintf(anonName, "l%u", fAnonNameIndex++);
- symbolName = anonName;
+ if ( stringsNeedLabelsInObjects() && (atom->getContentType() == ObjectFile::Atom::kCStringType) ) {
+ // don't use 'l' labels for x86_64 strings
+ // <rdar://problem/6605499> x86_64 obj-c runtime confused when static lib is stripped
+ }
+ else {
+ sprintf(anonName, "l%u", fAnonNameIndex++);
+ symbolName = anonName;
+ }
}
entry->set_n_strx(this->fStringsAtom->add(symbolName));
// set n_desc
uint16_t desc = 0;
+ if ( atom->dontDeadStrip() && (fOptions.outputKind() == Options::kObjectFile) )
+ desc |= N_NO_DEAD_STRIP;
if ( atom->getDefinitionKind() == ObjectFile::Atom::kWeakDefinition )
desc |= N_WEAK_DEF;
if ( atom->isThumb() )
// set up module table
if ( fModuleInfoAtom != NULL )
fModuleInfoAtom->setName();
+
+ // create atom to symbol index map
+ // imports
+ int i = 0;
+ for(std::vector<ObjectFile::Atom*>::iterator it=fImportedAtoms.begin(); it != fImportedAtoms.end(); ++it) {
+ fAtomToSymbolIndex[*it] = i + fSymbolTableImportStartIndex;
+ ++i;
+ }
+ // locals
+ i = 0;
+ for(std::vector<ObjectFile::Atom*>::iterator it=fLocalSymbolAtoms.begin(); it != fLocalSymbolAtoms.end(); ++it) {
+ fAtomToSymbolIndex[*it] = i + fSymbolTableLocalStartIndex;
+ ++i;
+ }
+ // exports
+ i = 0;
+ for(std::vector<ObjectFile::Atom*>::iterator it=fExportedAtoms.begin(); it != fExportedAtoms.end(); ++it) {
+ fAtomToSymbolIndex[*it] = i + fSymbolTableExportStartIndex;
+ ++i;
+ }
+
}
fImportedAtoms.reserve(100);
fExportedAtoms.reserve(atomCount/2);
fLocalSymbolAtoms.reserve(atomCount);
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
- // only named atoms go in symbol table
- if ( atom->getName() != NULL ) {
- // put atom into correct bucket: imports, exports, locals
- //fprintf(stderr, "collectExportedAndImportedAndLocalAtoms() name=%s\n", atom->getDisplayName());
- switch ( atom->getDefinitionKind() ) {
- case ObjectFile::Atom::kExternalDefinition:
- case ObjectFile::Atom::kExternalWeakDefinition:
- fImportedAtoms.push_back(atom);
- break;
- case ObjectFile::Atom::kTentativeDefinition:
- if ( (fOptions.outputKind() == Options::kObjectFile) && !fOptions.readerOptions().fMakeTentativeDefinitionsReal ) {
- fImportedAtoms.push_back(atom);
- break;
+
+ for (std::vector<SegmentInfo*>::iterator segit = fSegmentInfos.begin(); segit != fSegmentInfos.end(); ++segit) {
+ std::vector<SectionInfo*>& sectionInfos = (*segit)->fSections;
+ for (std::vector<SectionInfo*>::iterator secit = sectionInfos.begin(); secit != sectionInfos.end(); ++secit) {
+ std::vector<ObjectFile::Atom*>& sectionAtoms = (*secit)->fAtoms;
+ for (std::vector<ObjectFile::Atom*>::iterator ait = sectionAtoms.begin(); ait != sectionAtoms.end(); ++ait) {
+ ObjectFile::Atom* atom = *ait;
+ // only named atoms go in symbol table
+ if ( atom->getName() != NULL ) {
+ // put atom into correct bucket: imports, exports, locals
+ //fprintf(stderr, "collectExportedAndImportedAndLocalAtoms() name=%s\n", atom->getDisplayName());
+ switch ( atom->getDefinitionKind() ) {
+ case ObjectFile::Atom::kExternalDefinition:
+ case ObjectFile::Atom::kExternalWeakDefinition:
+ fImportedAtoms.push_back(atom);
+ break;
+ case ObjectFile::Atom::kTentativeDefinition:
+ if ( (fOptions.outputKind() == Options::kObjectFile) && !fOptions.readerOptions().fMakeTentativeDefinitionsReal ) {
+ fImportedAtoms.push_back(atom);
+ break;
+ }
+ // else fall into
+ case ObjectFile::Atom::kWeakDefinition:
+ if ( stringsNeedLabelsInObjects()
+ && (fOptions.outputKind() == Options::kObjectFile)
+ && (atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableIn)
+ && (atom->getScope() == ObjectFile::Atom::scopeLinkageUnit)
+ && (atom->getContentType() == ObjectFile::Atom::kCStringType) ) {
+ fLocalSymbolAtoms.push_back(atom);
+ break;
+ }
+ // else fall into
+ case ObjectFile::Atom::kRegularDefinition:
+ case ObjectFile::Atom::kAbsoluteSymbol:
+ if ( this->shouldExport(*atom) )
+ fExportedAtoms.push_back(atom);
+ else if ( (atom->getSymbolTableInclusion() != ObjectFile::Atom::kSymbolTableNotIn)
+ && ((fOptions.outputKind() == Options::kObjectFile) || fOptions.keepLocalSymbol(atom->getName())) )
+ fLocalSymbolAtoms.push_back(atom);
+ break;
}
- // else fall into
- case ObjectFile::Atom::kWeakDefinition:
- if ( stringsNeedLabelsInObjects()
- && (fOptions.outputKind() == Options::kObjectFile)
- && (atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableIn)
- && (atom->getScope() == ObjectFile::Atom::scopeLinkageUnit)
- && (atom->getContentType() == ObjectFile::Atom::kCStringType) ) {
- fLocalSymbolAtoms.push_back(atom);
- break;
+ }
+ // when geneating a .o file, dtrace static probes become local labels
+ if ( (fOptions.outputKind() == Options::kObjectFile) && !fOptions.readerOptions().fForStatic ) {
+ std::vector<ObjectFile::Reference*>& references = atom->getReferences();
+ for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
+ ObjectFile::Reference* ref = *rit;
+ if ( ref->getKind() == A::kDtraceProbe ) {
+ // dtrace probe points to be add back into generated .o file
+ this->addLocalLabel(*atom, ref->getFixUpOffset(), ref->getTargetName());
+ }
}
- // else fall into
- case ObjectFile::Atom::kRegularDefinition:
- case ObjectFile::Atom::kAbsoluteSymbol:
- if ( this->shouldExport(*atom) )
- fExportedAtoms.push_back(atom);
- else if ( (atom->getSymbolTableInclusion() != ObjectFile::Atom::kSymbolTableNotIn)
- && ((fOptions.outputKind() == Options::kObjectFile) || fOptions.keepLocalSymbol(atom->getName())) )
- fLocalSymbolAtoms.push_back(atom);
- break;
- }
- }
- // when geneating a .o file, dtrace static probes become local labels
- if ( (fOptions.outputKind() == Options::kObjectFile) && !fOptions.readerOptions().fForStatic ) {
- std::vector<ObjectFile::Reference*>& references = atom->getReferences();
- for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
- ObjectFile::Reference* ref = *rit;
- if ( ref->getKind() == A::kDtraceProbe ) {
- // dtrace probe points to be add back into generated .o file
- this->addLocalLabel(*atom, ref->getFixUpOffset(), ref->getTargetName());
}
- }
- }
- // when linking kernel, old style dtrace static probes become global labels
- else if ( fOptions.readerOptions().fForStatic ) {
- std::vector<ObjectFile::Reference*>& references = atom->getReferences();
- for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
- ObjectFile::Reference* ref = *rit;
- if ( ref->getKind() == A::kDtraceProbe ) {
- // dtrace probe points to be add back into generated .o file
- this->addGlobalLabel(*atom, ref->getFixUpOffset(), ref->getTargetName());
+ // when linking kernel, old style dtrace static probes become global labels
+ else if ( fOptions.readerOptions().fForStatic ) {
+ std::vector<ObjectFile::Reference*>& references = atom->getReferences();
+ for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
+ ObjectFile::Reference* ref = *rit;
+ if ( ref->getKind() == A::kDtraceProbe ) {
+ // dtrace probe points to be add back into generated .o file
+ this->addGlobalLabel(*atom, ref->getFixUpOffset(), ref->getTargetName());
+ }
+ }
}
}
}
template <typename A>
uint32_t Writer<A>::symbolIndex(ObjectFile::Atom& atom)
{
- // search imports
- int i = 0;
- for(std::vector<ObjectFile::Atom*>::iterator it=fImportedAtoms.begin(); it != fImportedAtoms.end(); ++it) {
- if ( &atom == *it )
- return i + fSymbolTableImportStartIndex;
- ++i;
- }
-
- // search locals
- i = 0;
- for(std::vector<ObjectFile::Atom*>::iterator it=fLocalSymbolAtoms.begin(); it != fLocalSymbolAtoms.end(); ++it) {
- if ( &atom == *it )
- return i + fSymbolTableLocalStartIndex;
- ++i;
- }
-
- // search exports
- i = 0;
- for(std::vector<ObjectFile::Atom*>::iterator it=fExportedAtoms.begin(); it != fExportedAtoms.end(); ++it) {
- if ( &atom == *it )
- return i + fSymbolTableExportStartIndex;
- ++i;
- }
-
+ std::map<ObjectFile::Atom*, uint32_t>::iterator pos = fAtomToSymbolIndex.find(&atom);
+ if ( pos != fAtomToSymbolIndex.end() )
+ return pos->second;
throwf("atom not found in symbolIndex(%s) for %s", atom.getDisplayName(), atom.getFile()->getPath());
}
case x86_64::kImageOffset32:
throw "internal linker error, kImageOffset32 can't be encoded into object files";
+ case x86_64::kSectionOffset24:
+ throw "internal linker error, kSectionOffset24 can't be encoded into object files";
+
case x86_64::kDtraceTypeReference:
case x86_64::kDtraceProbe:
// generates no relocs
case x86::kImageOffset32:
throw "internal linker error, kImageOffset32 can't be encoded into object files";
+ case x86::kSectionOffset24:
+ throw "internal linker error, kSectionOffset24 can't be encoded into object files";
+
case x86::kDtraceTypeReference:
case x86::kDtraceProbe:
// generates no relocs
fSectionRelocs.push_back(reloc1);
return 1;
+ case arm::kPointerDiff12:
+ throw "internal error. no reloc for 12-bit pointer diffs";
+
case arm::kDtraceTypeReference:
case arm::kDtraceProbe:
// generates no relocs
reloc.set_r_type(GENERIC_RELOC_VANILLA);
fInternalRelocs.push_back(reloc);
atomSection->fHasTextLocalRelocs = true;
+ if ( fOptions.makeCompressedDyldInfo() ) {
+ fRebaseInfo.push_back(RebaseInfo(REBASE_TYPE_TEXT_ABSOLUTE32, atom.getAddress() + ref.getFixUpOffset()));
+ }
return true;
}
return false;
uint64_t addresss = atom->getAddress();
if ( targetRequiresWeakBinding(ref->getTarget()) ) {
fWeakBindingInfo.push_back(BindingInfo(type, ref->getTarget().getName(), false, addresss, 0));
- // if this is a non-lazy pointer to a weak definition with this linkage unit
+ // if this is a non-lazy pointer to a weak definition within this linkage unit
// the pointer needs to initially point within linkage unit and have
- // rease command to slide it.
- if ( ref->getTarget().getDefinitionKind() == ObjectFile::Atom::kWeakDefinition )
- fRebaseInfo.push_back(RebaseInfo(REBASE_TYPE_POINTER,atom->getAddress()));
+ // rebase command to slide it.
+ if ( ref->getTarget().getDefinitionKind() == ObjectFile::Atom::kWeakDefinition ) {
+ // unless if this is a hybrid format, in which case the non-lazy pointer
+ // is zero on disk. So use a bind instead of a rebase to set initial value
+ if ( fOptions.makeClassicDyldInfo() )
+ fBindingInfo.push_back(BindingInfo(type, BIND_SPECIAL_DYLIB_SELF, ref->getTarget().getName(), false, addresss, 0));
+ else
+ fRebaseInfo.push_back(RebaseInfo(REBASE_TYPE_POINTER,atom->getAddress()));
+ }
+ // if this is a non-lazy pointer to a weak definition in a dylib,
+ // the pointer needs to initially bind to the dylib
+ else if ( ref->getTarget().getDefinitionKind() == ObjectFile::Atom::kExternalWeakDefinition ) {
+ int ordinal = compressedOrdinalForImortedAtom(pointerTarget);
+ fBindingInfo.push_back(BindingInfo(BIND_TYPE_POINTER, ordinal, pointerTarget->getName(), false, addresss, 0));
+ }
}
else {
int ordinal = compressedOrdinalForImortedAtom(pointerTarget);
uint8_t type = BIND_TYPE_POINTER;
if ( targetRequiresWeakBinding(ref->getTarget()) ) {
fWeakBindingInfo.push_back(BindingInfo(type, ref->getTarget().getName(), false, addresss, addend));
+ if ( fOptions.makeClassicDyldInfo() && (ref->getTarget().getDefinitionKind() == ObjectFile::Atom::kWeakDefinition) ) {
+ // hybrid linkedit puts addend in data, so we need bind phase to reset pointer to local definifion
+ fBindingInfo.push_back(BindingInfo(type, BIND_SPECIAL_DYLIB_SELF, ref->getTarget().getName(), false, addresss, addend));
+ }
+ // if this is a pointer to a weak definition in a dylib,
+ // the pointer needs to initially bind to the dylib
+ else if ( ref->getTarget().getDefinitionKind() == ObjectFile::Atom::kExternalWeakDefinition ) {
+ int ordinal = compressedOrdinalForImortedAtom(&ref->getTarget());
+ fBindingInfo.push_back(BindingInfo(BIND_TYPE_POINTER, ordinal, ref->getTarget().getName(), false, addresss, addend));
+ }
}
else {
int ordinal = compressedOrdinalForImortedAtom(&ref->getTarget());
uint64_t atomSize = atom->getSize();
if ( streaming ) {
if ( atomSize > fLargestAtomSize )
- throwf("ld64 internal error: atom \"%s\"is larger than expected 0x%X > 0x%llX",
+ throwf("ld64 internal error: atom \"%s\"is larger than expected 0x%llX > 0x%X",
atom->getDisplayName(), atomSize, fLargestAtomSize);
}
else {
break;
}
}
+ else if ( !fOptions.makeClassicDyldInfo()
+ && (ref->getTarget().getDefinitionKind() == ObjectFile::Atom::kWeakDefinition) ) {
+ // when using only compressed dyld info, pointer is initially set to point directly to weak definition
+ if ( ref->getTarget().isThumb() )
+ targetAddr |= 1;
+ LittleEndian::set32(*fixUp, targetAddr);
+ }
else {
// external relocation ==> pointer contains addend
LittleEndian::set32(*fixUp, ref->getTargetOffset());
case arm::kBranch24WeakImport:
case arm::kBranch24:
displacement = targetAddr - (inAtom->getAddress() + ref->getFixUpOffset());
+ // check if this is a branch to a branch island that can be skipped
+ if ( ref->getTarget().getContentType() == ObjectFile::Atom::kBranchIsland ) {
+ uint64_t finalTargetAddress = ((BranchIslandAtom<arm>*)(&(ref->getTarget())))->getFinalTargetAdress();
+ int64_t altDisplacment = finalTargetAddress - (inAtom->getAddress() + ref->getFixUpOffset());
+ if ( (altDisplacment < 33554428LL) && (altDisplacment > (-33554432LL)) ) {
+ //fprintf(stderr, "using altDisplacment = %lld\n", altDisplacment);
+ // yes, we can skip the branch island
+ displacement = altDisplacment;
+ }
+ }
// The pc added will be +8 from the pc
displacement -= 8;
- // fprintf(stderr, "bl/blx fixup to %s at 0x%08llX, displacement = 0x%08llX\n", ref->getTarget().getDisplayName(), ref->getTarget().getAddress(), displacement);
+ //fprintf(stderr, "bl/blx fixup to %s at 0x%08llX, displacement = 0x%08llX\n", ref->getTarget().getDisplayName(), ref->getTarget().getAddress(), displacement);
// max positive displacement is 0x007FFFFF << 2
// max negative displacement is 0xFF800000 << 2
if ( (displacement > 33554428LL) || (displacement < (-33554432LL)) ) {
- throwf("b/bl/blx out of range (%lld max is +/-32M) from %s in %s to %s in %s",
- displacement, inAtom->getDisplayName(), inAtom->getFile()->getPath(),
- ref->getTarget().getDisplayName(), ref->getTarget().getFile()->getPath());
+ throwf("b/bl/blx out of range (%lld max is +/-32M) from 0x%08llX %s in %s to 0x%08llX %s in %s",
+ displacement, inAtom->getAddress(), inAtom->getDisplayName(), inAtom->getFile()->getPath(),
+ ref->getTarget().getAddress(), ref->getTarget().getDisplayName(), ref->getTarget().getFile()->getPath());
}
instruction = LittleEndian::get32(*fixUp);
// Make sure we are calling arm with bl, thumb with blx
case arm::kDtraceProbe:
// nothing to fix up
break;
- default:
- throw "boom shaka laka";
+ case arm::kPointerDiff12:
+ displacement = (ref->getTarget().getAddress() + ref->getTargetOffset()) - (ref->getFromTarget().getAddress() + ref->getFromTargetOffset());
+ if ( (displacement > 4092LL) || (displacement <-4092LL) ) {
+ throwf("ldr 12-bit displacement out of range (%lld max +/-4096) in %s", displacement, inAtom->getDisplayName());
+ }
+ instruction = LittleEndian::get32(*fixUp);
+ if ( displacement >= 0 ) {
+ instruction &= 0xFFFFF000;
+ instruction |= ((uint32_t)displacement & 0xFFF);
+ }
+ else {
+ instruction &= 0xFF7FF000;
+ instruction |= ((uint32_t)(-displacement) & 0xFFF);
+ }
+ LittleEndian::set32(*fixUp, instruction);
+ break;
}
}
case arm::kDtraceTypeReference:
// nothing to fix up
break;
+ case arm::kPointerDiff12:
+ throw "internal error. no reloc for 12-bit pointer diffs";
}
}
break;
}
}
- else if ( fOptions.makeCompressedDyldInfo()
+ else if ( !fOptions.makeClassicDyldInfo()
&& (ref->getTarget().getDefinitionKind() == ObjectFile::Atom::kWeakDefinition) ) {
- // lazy pointer is initially set to point directly to weak definition
+ // when using only compressed dyld info, pointer is initially set to point directly to weak definition
LittleEndian::set32(*fixUp, ref->getTarget().getAddress() + ref->getTargetOffset());
}
else {
temp |= (displacement & 0x00FFFFFF);
LittleEndian::set32(*fixUp, temp);
break;
+ case x86::kSectionOffset24:
+ displacement = ref->getTarget().getSectionOffset();
+ if ( (displacement > kSixteenMegLimit) || (displacement < 0) )
+ throwf("24-bit pointer diff out of range in %s", inAtom->getDisplayName());
+ temp = LittleEndian::get32(*fixUp);
+ temp &= 0xFF000000;
+ temp |= (displacement & 0x00FFFFFF);
+ LittleEndian::set32(*fixUp, temp);
+ break;
case x86::kDtraceProbeSite:
// change call site to a NOP
dtraceProbeSite = (uint8_t*)fixUp;
throw "internal linker error, kPointerDiff24 can't be encoded into object files";
case x86::kImageOffset32:
throw "internal linker error, kImageOffset32 can't be encoded into object files";
+ case x86::kSectionOffset24:
+ throw "internal linker error, kSectionOffset24 can't be encoded into object files";
case x86::kDtraceProbe:
case x86::kDtraceTypeReference:
// nothing to fix up
if ( &ref->getTarget() != NULL ) {
//fprintf(stderr, "fixUpReferenceFinal: %s reference to %s\n", this->getDisplayName(), target.getDisplayName());
if ( this->relocationNeededInFinalLinkedImage(ref->getTarget()) == kRelocExternal) {
- if ( fOptions.makeCompressedDyldInfo()
- && (ref->getTarget().getDefinitionKind() == ObjectFile::Atom::kWeakDefinition) ) {
- // lazy pointer is initially set to point directly to weak definition
+ if ( !fOptions.makeClassicDyldInfo()
+ && (ref->getTarget().getDefinitionKind() == ObjectFile::Atom::kWeakDefinition) ) {
+ // when using only compressed dyld info, pointer is initially set to point directly to weak definition
LittleEndian::set64(*fixUp, ref->getTarget().getAddress() + ref->getTargetOffset());
}
else {
temp |= (displacement & 0x00FFFFFF);
LittleEndian::set32(*((uint32_t*)fixUp), temp);
break;
+ case x86_64::kSectionOffset24:
+ displacement = ref->getTarget().getSectionOffset();
+ if ( (displacement > kSixteenMegLimit) || (displacement < 0) )
+ throwf("24-bit pointer diff out of range in %s", inAtom->getDisplayName());
+ temp = LittleEndian::get32(*((uint32_t*)fixUp));
+ temp &= 0xFF000000;
+ temp |= (displacement & 0x00FFFFFF);
+ LittleEndian::set32(*((uint32_t*)fixUp), temp);
+ break;
case x86_64::kPCRel32GOTLoad:
case x86_64::kPCRel32GOTLoadWeakImport:
// if GOT entry was optimized away, change movq instruction to a leaq
}
else {
if ( (displacement > twoGigLimit) || (displacement < (-twoGigLimit)) ) {
- fprintf(stderr, "call out of range from %s (%llX) in %s to %s (%llX) in %s\n",
+ fprintf(stderr, "reference out of range from %s (%llX) in %s to %s (%llX) in %s\n",
inAtom->getDisplayName(), inAtom->getAddress(), inAtom->getFile()->getPath(), ref->getTarget().getDisplayName(), ref->getTarget().getAddress(), ref->getTarget().getFile()->getPath());
throw "rel32 out of range";
}
throw "internal linker error, kPointerDiff24 can't be encoded into object files";
case x86_64::kImageOffset32:
throw "internal linker error, kImageOffset32 can't be encoded into object files";
+ case x86_64::kSectionOffset24:
+ throw "internal linker error, kSectionOffset24 can't be encoded into object files";
case x86_64::kDtraceTypeReference:
case x86_64::kDtraceProbe:
// nothing to fix up
switch ( (arm::ReferenceKinds)kind ) {
case arm::kBranch24:
case arm::kBranch24WeakImport:
+ return true;
case arm::kThumbBranch22:
case arm::kThumbBranch22WeakImport:
+ fHasThumbBranches = true;
return true;
case arm::kNoFixUp:
case arm::kFollowOn:
case arm::kDtraceProbeSite:
case arm::kDtraceIsEnabledSite:
case arm::kDtraceTypeReference:
+ case arm::kPointerDiff12:
return false;
}
return false;
if ( fOptions.positionIndependentExecutable() && !fOptions.allowTextRelocs() ) {
for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
ObjectFile::Atom* atom = *it;
+ if ( atom->getContentType() == ObjectFile::Atom::kStub )
+ continue;
+ if ( atom->getContentType() == ObjectFile::Atom::kStubHelper )
+ continue;
std::vector<ObjectFile::Reference*>& references = atom->getReferences();
for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
ObjectFile::Reference* ref = *rit;
template <typename A>
-void Writer<A>::synthesizeKextGOT()
+void Writer<A>::synthesizeKextGOT(const std::vector<class ObjectFile::Atom*>& existingAtoms,
+ std::vector<class ObjectFile::Atom*>& newAtoms)
{
// walk every atom and reference
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
+ for (std::vector<ObjectFile::Atom*>::const_iterator it=existingAtoms.begin(); it != existingAtoms.end(); it++) {
+ const ObjectFile::Atom* atom = *it;
std::vector<ObjectFile::Reference*>& references = atom->getReferences();
for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
ObjectFile::Reference* ref = *rit;
if ( pos == fGOTMap.end() ) {
nlp = new NonLazyPointerAtom<A>(*this, target);
fGOTMap[&target] = nlp;
+ newAtoms.push_back(nlp);
}
else {
nlp = pos->second;
}
}
}
-
- // add non-lazy pointers to fAllAtoms
- if ( fAllSynthesizedNonLazyPointers.size() != 0 ) {
- ObjectFile::Section* curSection = NULL;
- ObjectFile::Atom* prevAtom = NULL;
- bool inserted = false;
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
- ObjectFile::Section* nextSection = atom->getSection();
- if ( nextSection != curSection ) {
- if ( (prevAtom != NULL) && (strcmp(prevAtom->getSectionName(), "__data") == 0) ) {
- // found end of __data section, insert lazy pointers here
- fAllAtoms->insert(it, fAllSynthesizedNonLazyPointers.begin(), fAllSynthesizedNonLazyPointers.end());
- inserted = true;
- break;
- }
- curSection = nextSection;
- }
- prevAtom = atom;
- }
- if ( !inserted ) {
- throw "can't insert non-lazy pointers, __data section not found";
- }
- }
-
}
template <typename A>
-void Writer<A>::synthesizeStubs()
+void Writer<A>::synthesizeStubs(const std::vector<class ObjectFile::Atom*>& existingAtoms,
+ std::vector<class ObjectFile::Atom*>& newAtoms)
{
switch ( fOptions.outputKind() ) {
case Options::kObjectFile:
return;
case Options::kKextBundle:
// new kext need a synthesized GOT only
- synthesizeKextGOT();
+ synthesizeKextGOT(existingAtoms, newAtoms);
return;
case Options::kStaticExecutable:
case Options::kDyld:
}
// walk every atom and reference
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
+ for (std::vector<ObjectFile::Atom*>::const_iterator it=existingAtoms.begin(); it != existingAtoms.end(); it++) {
ObjectFile::Atom* atom = *it;
std::vector<ObjectFile::Reference*>& references = atom->getReferences();
for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
// sort stubs
std::sort(fAllSynthesizedStubs.begin(), fAllSynthesizedStubs.end(), AtomByNameSorter());
- std::sort(fAllSynthesizedStubHelpers.begin(), fAllSynthesizedStubHelpers.end(), AtomByNameSorter());
-
// add dummy self-modifying stubs (x86 only)
if ( ! fOptions.makeCompressedDyldInfo() )
this->insertDummyStubs();
+ // set ordinals so sorting is preserved
+ uint32_t sortOrder = 0;
+ for (typename std::vector<StubAtom<A>*>::iterator it=fAllSynthesizedStubs.begin(); it != fAllSynthesizedStubs.end(); it++)
+ (*it)->setSortingOrdinal(sortOrder++);
+ std::sort(fAllSynthesizedStubHelpers.begin(), fAllSynthesizedStubHelpers.end(), AtomByNameSorter());
// sort lazy pointers
std::sort(fAllSynthesizedLazyPointers.begin(), fAllSynthesizedLazyPointers.end(), AtomByNameSorter());
+ sortOrder = 0;
+ for (typename std::vector<LazyPointerAtom<A>*>::iterator it=fAllSynthesizedLazyPointers.begin(); it != fAllSynthesizedLazyPointers.end(); it++)
+ (*it)->setSortingOrdinal(sortOrder++);
std::sort(fAllSynthesizedLazyDylibPointers.begin(), fAllSynthesizedLazyDylibPointers.end(), AtomByNameSorter());
-
-
- // add stubs to fAllAtoms
- if ( fAllSynthesizedStubs.size() != 0 ) {
- std::vector<ObjectFile::Atom*> textStubs;
- std::vector<ObjectFile::Atom*> importStubs;
- for (typename std::vector<class StubAtom<A>*>::iterator sit=fAllSynthesizedStubs.begin(); sit != fAllSynthesizedStubs.end(); ++sit) {
- ObjectFile::Atom* stubAtom = *sit;
- if ( strcmp(stubAtom->getSegment().getName(), "__TEXT") == 0 )
- textStubs.push_back(stubAtom);
- else
- importStubs.push_back(stubAtom);
- }
- // any helper stubs go right after regular stubs
- if ( fAllSynthesizedStubHelpers.size() != 0 )
- textStubs.insert(textStubs.end(), fAllSynthesizedStubHelpers.begin(), fAllSynthesizedStubHelpers.end());
- // insert text stubs right after __text section
- ObjectFile::Section* curSection = NULL;
- ObjectFile::Atom* prevAtom = NULL;
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
- ObjectFile::Section* nextSection = atom->getSection();
- if ( nextSection != curSection ) {
- if ( (prevAtom != NULL) && (strcmp(prevAtom->getSectionName(), "__text") == 0) ) {
- // found end of __text section, insert stubs here
- fAllAtoms->insert(it, textStubs.begin(), textStubs.end());
- break;
- }
- curSection = nextSection;
- }
- prevAtom = atom;
- }
- if ( importStubs.size() != 0 ) {
- // insert __IMPORTS stubs right before __LINKEDIT
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
- ObjectFile::Section* nextSection = atom->getSection();
- if ( nextSection != curSection ) {
- // for i386 where stubs are not in __TEXT segment
- if ( ((prevAtom != NULL) && (strcmp(prevAtom->getSegment().getName(), "__IMPORT") == 0))
- || (strcmp(atom->getSegment().getName(), "__LINKEDIT") == 0) ) {
- // insert stubs at end of __IMPORT segment, or before __LINKEDIT
- fAllAtoms->insert(it, importStubs.begin(), importStubs.end());
- break;
- }
- curSection = nextSection;
- }
- prevAtom = atom;
- }
- }
- }
-
-
- // add non-lazy pointers to fAllAtoms
- if ( fAllSynthesizedNonLazyPointers.size() != 0 ) {
- ObjectFile::Section* curSection = NULL;
- ObjectFile::Atom* prevAtom = NULL;
- bool inserted = false;
- // first try to insert at end of __nl_symbol_ptr
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
- ObjectFile::Section* nextSection = atom->getSection();
- if ( nextSection != curSection ) {
- if ( (prevAtom != NULL) && (strcmp(prevAtom->getSectionName(), "__nl_symbol_ptr") == 0) ) {
- // found end of __nl_symbol_ptr section, insert non-lazy pointers at end of it
- fAllAtoms->insert(it, fAllSynthesizedNonLazyPointers.begin(), fAllSynthesizedNonLazyPointers.end());
- inserted = true;
- break;
- }
- curSection = nextSection;
- }
- prevAtom = atom;
- }
- if ( !inserted ) {
- // next try to insert after __dyld section
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
- ObjectFile::Section* nextSection = atom->getSection();
- if ( nextSection != curSection ) {
- if ( strcmp(atom->getSegment().getName(), "__DATA") == 0 ) {
- const char* prevSectionName = (prevAtom != NULL) ? prevAtom->getSectionName() : "";
- if ( (strcmp(prevSectionName, "__dyld") != 0)
- && (strcmp(prevSectionName, "__program_vars") != 0)
- && (strcmp(prevSectionName, "__mod_init_func") != 0) ) {
- // found end of __dyld section, insert non-lazy pointers here
- fAllAtoms->insert(it, fAllSynthesizedNonLazyPointers.begin(), fAllSynthesizedNonLazyPointers.end());
- inserted = true;
- break;
- }
- }
- }
- prevAtom = atom;
- }
- if ( !inserted ) {
- // might not be any __DATA sections, insert after end of __TEXT
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
- ObjectFile::Section* nextSection = atom->getSection();
- if ( nextSection != curSection ) {
- if ( (prevAtom != NULL) && (strcmp(prevAtom->getSegment().getName(), "__TEXT") == 0) && (strcmp(atom->getSegment().getName(), "__TEXT") != 0)) {
- // found end of __TEXT segment, insert non-lazy pointers at end of it
- fAllAtoms->insert(it, fAllSynthesizedNonLazyPointers.begin(), fAllSynthesizedNonLazyPointers.end());
- inserted = true;
- break;
- }
- curSection = nextSection;
- }
- prevAtom = atom;
- }
- }
- if ( !inserted )
- throw "can't insert non-lazy pointers, __dyld section not found";
- }
- }
-
- // add lazy dylib pointers to fAllAtoms
- if ( fAllSynthesizedLazyDylibPointers.size() != 0 ) {
- ObjectFile::Section* curSection = NULL;
- ObjectFile::Atom* prevAtom = NULL;
- bool inserted = false;
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
- ObjectFile::Section* nextSection = atom->getSection();
- if ( nextSection != curSection ) {
- if ( (prevAtom != NULL) &&
- ( (strcmp(prevAtom->getSectionName(), "__dyld") == 0)
- || (strcmp(prevAtom->getSectionName(), "__program_vars") == 0)
- || (strcmp(prevAtom->getSectionName(), "__nl_symbol_ptr") == 0) ) ) {
- // found end of __dyld section, insert lazy pointers here
- fAllAtoms->insert(it, fAllSynthesizedLazyDylibPointers.begin(), fAllSynthesizedLazyDylibPointers.end());
- inserted = true;
- break;
- }
- curSection = nextSection;
- }
- prevAtom = atom;
- }
- if ( !inserted ) {
- throw "can't insert lazy pointers, __dyld section not found";
- }
- }
-
- // add lazy pointers to fAllAtoms
- if ( fAllSynthesizedLazyPointers.size() != 0 ) {
- ObjectFile::Section* curSection = NULL;
- ObjectFile::Atom* prevAtom = NULL;
- bool inserted = false;
- for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
- ObjectFile::Atom* atom = *it;
- ObjectFile::Section* nextSection = atom->getSection();
- if ( nextSection != curSection ) {
- if ( (prevAtom != NULL) &&
- ( (strcmp(prevAtom->getSectionName(), "__dyld") == 0)
- || (strcmp(prevAtom->getSectionName(), "__program_vars") == 0)
- || (strcmp(prevAtom->getSectionName(), "__nl_symbol_ptr") == 0) ) ) {
- // found end of __dyld section, insert lazy pointers here
- fAllAtoms->insert(it, fAllSynthesizedLazyPointers.begin(), fAllSynthesizedLazyPointers.end());
- inserted = true;
- break;
- }
- curSection = nextSection;
- }
- prevAtom = atom;
- }
- if ( !inserted ) {
- throw "can't insert lazy pointers, __dyld section not found";
- }
- }
+ // sort non-lazy pointers
+ std::sort(fAllSynthesizedNonLazyPointers.begin(), fAllSynthesizedNonLazyPointers.end(), AtomByNameSorter());
+ sortOrder = 0;
+ for (typename std::vector<NonLazyPointerAtom<A>*>::iterator it=fAllSynthesizedNonLazyPointers.begin(); it != fAllSynthesizedNonLazyPointers.end(); it++)
+ (*it)->setSortingOrdinal(sortOrder++);
+ std::sort(fAllSynthesizedNonLazyPointers.begin(), fAllSynthesizedNonLazyPointers.end(), AtomByNameSorter());
+
+ // tell linker about all synthesized atoms
+ newAtoms.insert(newAtoms.end(), fAllSynthesizedStubs.begin(), fAllSynthesizedStubs.end());
+ newAtoms.insert(newAtoms.end(), fAllSynthesizedStubHelpers.begin(), fAllSynthesizedStubHelpers.end());
+ newAtoms.insert(newAtoms.end(), fAllSynthesizedLazyPointers.begin(), fAllSynthesizedLazyPointers.end());
+ newAtoms.insert(newAtoms.end(), fAllSynthesizedLazyDylibPointers.begin(), fAllSynthesizedLazyDylibPointers.end());
+ newAtoms.insert(newAtoms.end(), fAllSynthesizedNonLazyPointers.begin(), fAllSynthesizedNonLazyPointers.end());
}
if ( atom->beginUnwind() == atom->endUnwind() ) {
// be sure to mark that we have no unwind info for stuff in the TEXT segment without unwind info
if ( strcmp(atom->getSegment().getName(), "__TEXT") == 0 )
- fUnwindInfoAtom->addUnwindInfo(atom, 0, 0, NULL, NULL);
+ fUnwindInfoAtom->addUnwindInfo(atom, 0, 0, NULL, NULL, NULL);
}
else {
// atom has unwind
for ( ObjectFile::UnwindInfo::iterator uit = atom->beginUnwind(); uit != atom->endUnwind(); ++uit ) {
- fUnwindInfoAtom->addUnwindInfo(atom, uit->startOffset, uit->unwindInfo, atom->getLSDA(), atom->getPersonalityPointer());
+ fUnwindInfoAtom->addUnwindInfo(atom, uit->startOffset, uit->unwindInfo, atom->getFDE(), atom->getLSDA(), atom->getPersonalityPointer());
}
}
}
}
-
template <typename A>
void Writer<A>::partitionIntoSections()
{
fLoadCommandsSection = currentSectionInfo;
fLoadCommandsSegment = currentSegmentInfo;
}
- if ( (strcmp(currentSectionInfo->fSegmentName, "__DATA") == 0) && (strcmp(currentSectionInfo->fSectionName, "__la_symbol_ptr") == 0) )
- currentSectionInfo->fAllLazyPointers = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__DATA") == 0) && (strcmp(currentSectionInfo->fSectionName, "__la_sym_ptr2") == 0) )
- currentSectionInfo->fAllLazyPointers = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__DATA") == 0) && (strcmp(currentSectionInfo->fSectionName, "__ld_symbol_ptr") == 0) )
- currentSectionInfo->fAllLazyDylibPointers = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__DATA") == 0) && (strcmp(currentSectionInfo->fSectionName, "__nl_symbol_ptr") == 0) )
- currentSectionInfo->fAllNonLazyPointers = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__IMPORT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__pointers") == 0) )
- currentSectionInfo->fAllNonLazyPointers = true;
- if ( (fOptions.outputKind() == Options::kDyld) && (strcmp(currentSectionInfo->fSegmentName, "__DATA") == 0) && (strcmp(currentSectionInfo->fSectionName, "__pointers") == 0) )
- currentSectionInfo->fAllNonLazyPointers = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__TEXT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__picsymbolstub1") == 0) )
- currentSectionInfo->fAllStubs = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__TEXT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__symbol_stub1") == 0) )
- currentSectionInfo->fAllStubs = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__TEXT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__picsymbolstub2") == 0) )
- currentSectionInfo->fAllStubs = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__TEXT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__symbol_stub") == 0) )
- currentSectionInfo->fAllStubs = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__TEXT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__picsymbolstub4") == 0) )
- currentSectionInfo->fAllStubs = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__TEXT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__symbol_stub4") == 0) )
- currentSectionInfo->fAllStubs = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__IMPORT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__jump_table") == 0) ) {
- currentSectionInfo->fAllSelfModifyingStubs = true;
- currentSectionInfo->fAlignment = 6; // force x86 fast stubs to start on 64-byte boundary
- }
- if ( (strcmp(currentSectionInfo->fSegmentName, "__TEXT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__stub_helper") == 0) )
- currentSectionInfo->fAllStubHelpers = true;
- if ( (strcmp(currentSectionInfo->fSegmentName, "__TEXT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__eh_frame") == 0) )
- currentSectionInfo->fAlignment = __builtin_ctz(sizeof(pint_t)); // always start CFI info pointer aligned
- curSection = atom->getSection();
- if ( currentSectionInfo->fAllNonLazyPointers || currentSectionInfo->fAllLazyPointers || currentSectionInfo->fAllLazyDylibPointers
- || currentSectionInfo->fAllStubs || currentSectionInfo->fAllSelfModifyingStubs ) {
+ switch ( atom->getContentType() ) {
+ case ObjectFile::Atom::kLazyPointer:
+ currentSectionInfo->fAllLazyPointers = true;
+ fSymbolTableCommands->needDynamicTable();
+ break;
+ case ObjectFile::Atom::kNonLazyPointer:
+ currentSectionInfo->fAllNonLazyPointers = true;
fSymbolTableCommands->needDynamicTable();
+ break;
+ case ObjectFile::Atom::kLazyDylibPointer:
+ currentSectionInfo->fAllLazyDylibPointers = true;
+ break;
+ case ObjectFile::Atom::kStubHelper:
+ currentSectionInfo->fAllStubHelpers = true;
+ break;
+ case ObjectFile::Atom::kCFIType:
+ currentSectionInfo->fAlignment = __builtin_ctz(sizeof(pint_t)); // always start CFI info pointer aligned
+ break;
+ case ObjectFile::Atom::kStub:
+ if ( (strcmp(currentSectionInfo->fSegmentName, "__IMPORT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__jump_table") == 0) ) {
+ currentSectionInfo->fAllSelfModifyingStubs = true;
+ currentSectionInfo->fAlignment = 6; // force x86 fast stubs to start on 64-byte boundary
+ }
+ else {
+ currentSectionInfo->fAllStubs = true;
+ }
+ fSymbolTableCommands->needDynamicTable();
+ break;
+ default:
+ break;
}
+ curSection = atom->getSection();
}
// any non-zero fill atoms make whole section marked not-zero-fill
if ( currentSectionInfo->fAllZeroFill && ! atom->isZeroFill() )
template <>
bool Writer<ppc>::addBranchIslands()
{
- return this->addPPCBranchIslands();
+ return this->createBranchIslands();
}
template <>
bool Writer<ppc64>::addBranchIslands()
{
- return this->addPPCBranchIslands();
+ return this->createBranchIslands();
}
template <>
template <>
bool Writer<arm>::addBranchIslands()
{
- // arm branch islands not (yet) supported
- // you can instead compile with -mlong-call
- return false;
+ return this->createBranchIslands();
}
template <>
-bool Writer<ppc>::isBranch24Reference(uint8_t kind)
+bool Writer<ppc>::isBranchThatMightNeedIsland(uint8_t kind)
{
switch (kind) {
case ppc::kBranch24:
}
template <>
-bool Writer<ppc64>::isBranch24Reference(uint8_t kind)
+bool Writer<ppc64>::isBranchThatMightNeedIsland(uint8_t kind)
{
switch (kind) {
case ppc64::kBranch24:
return false;
}
+template <>
+bool Writer<arm>::isBranchThatMightNeedIsland(uint8_t kind)
+{
+ switch (kind) {
+ case arm::kBranch24:
+ case arm::kBranch24WeakImport:
+ case arm::kThumbBranch22:
+ case arm::kThumbBranch22WeakImport:
+ return true;
+ }
+ return false;
+}
+
+template <>
+uint32_t Writer<ppc>::textSizeWhenMightNeedBranchIslands()
+{
+ return 16000000;
+}
+
+template <>
+uint32_t Writer<ppc64>::textSizeWhenMightNeedBranchIslands()
+{
+ return 16000000;
+}
+
+template <>
+uint32_t Writer<arm>::textSizeWhenMightNeedBranchIslands()
+{
+ if ( fHasThumbBranches == false )
+ return 32000000; // ARM can branch +/- 32MB
+ else if ( fOptions.preferSubArchitecture() && fOptions.subArchitecture() == CPU_SUBTYPE_ARM_V7 )
+ return 16000000; // thumb2 can branch +/- 16MB
+ else
+ return 4000000; // thumb1 can branch +/- 4MB
+}
+
+template <>
+uint32_t Writer<ppc>::maxDistanceBetweenIslands()
+{
+ return 14*1024*1024;
+}
+
+template <>
+uint32_t Writer<ppc64>::maxDistanceBetweenIslands()
+{
+ return 14*1024*1024;
+}
+
+template <>
+uint32_t Writer<arm>::maxDistanceBetweenIslands()
+{
+ if ( fHasThumbBranches == false )
+ return 30*1024*1024;
+ else if ( fOptions.preferSubArchitecture() && fOptions.subArchitecture() == CPU_SUBTYPE_ARM_V7 )
+ return 14*1024*1024;
+ else
+ return 3500000;
+}
+
+
//
// PowerPC can do PC relative branches as far as +/-16MB.
// If a branch target is >16MB then we insert one or more
// "branch islands" between the branch and its target that
-// allows island hoping to the target.
+// allows island hopping to the target.
//
// Branch Island Algorithm
//
// If the __TEXT segment < 16MB, then no branch islands needed
// Otherwise, every 14MB into the __TEXT segment a region is
-// added which can contain branch islands. Every out of range
+// added which can contain branch islands. Every out-of-range
// bl instruction is checked. If it crosses a region, an island
// is added to that region with the same target and the bl is
// adjusted to target the island instead.
// could grow the __TEXT enough that other previously in-range
// bl branches could be pushed out of range. We reduce the
// probability this could happen by placing the ranges every
-// 15MB which means the region would have to be 1MB (256K islands)
+// 14MB which means the region would have to be 2MB (512,000 islands)
// before any branches could be pushed out of range.
//
template <typename A>
-bool Writer<A>::addPPCBranchIslands()
+bool Writer<A>::createBranchIslands()
{
bool log = false;
bool result = false;
// Can only possibly need branch islands if __TEXT segment > 16M
- if ( fLoadCommandsSegment->fSize > 16000000 ) {
+ if ( fLoadCommandsSegment->fSize > textSizeWhenMightNeedBranchIslands() ) {
if ( log) fprintf(stderr, "ld: checking for branch islands, __TEXT segment size=%llu\n", fLoadCommandsSegment->fSize);
- const uint32_t kBetweenRegions = 14*1024*1024; // place regions of islands every 14MB in __text section
+ const uint32_t kBetweenRegions = maxDistanceBetweenIslands(); // place regions of islands every 14MB in __text section
SectionInfo* textSection = NULL;
for (std::vector<SectionInfo*>::iterator it=fLoadCommandsSegment->fSections.begin(); it != fLoadCommandsSegment->fSections.end(); it++) {
if ( strcmp((*it)->fSectionName, "__text") == 0 ) {
AtomToIsland regionsMap[kIslandRegionsCount];
std::vector<ObjectFile::Atom*> regionsIslands[kIslandRegionsCount];
unsigned int islandCount = 0;
- if ( log) fprintf(stderr, "ld: will use %u branch island regions\n", kIslandRegionsCount);
+ if (log) fprintf(stderr, "ld: will use %u branch island regions\n", kIslandRegionsCount);
// create islands for branch references that are out of range
for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
std::vector<ObjectFile::Reference*>& references = atom->getReferences();
for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
ObjectFile::Reference* ref = *rit;
- if ( this->isBranch24Reference(ref->getKind()) ) {
+ if ( this->isBranchThatMightNeedIsland(ref->getKind()) ) {
ObjectFile::Atom& target = ref->getTarget();
int64_t srcAddr = atom->getAddress() + ref->getFixUpOffset();
int64_t dstAddr = target.getAddress() + ref->getTargetOffset();
int64_t displacement = dstAddr - srcAddr;
TargetAndOffset finalTargetAndOffset = { &target, ref->getTargetOffset() };
- const int64_t kFifteenMegLimit = kBetweenRegions;
- if ( displacement > kFifteenMegLimit ) {
+ const int64_t kBranchLimit = kBetweenRegions;
+ if ( displacement > kBranchLimit ) {
// create forward branch chain
ObjectFile::Atom* nextTarget = ⌖
- uint64_t nextTargetOffset = ref->getTargetOffset();
for (int i=kIslandRegionsCount-1; i >=0 ; --i) {
AtomToIsland* region = ®ionsMap[i];
int64_t islandRegionAddr = kBetweenRegions * (i+1) + textSection->getBaseAddress();
if ( (srcAddr < islandRegionAddr) && (islandRegionAddr <= dstAddr) ) {
AtomToIsland::iterator pos = region->find(finalTargetAndOffset);
if ( pos == region->end() ) {
- BranchIslandAtom<A>* island = new BranchIslandAtom<A>(*this, target.getDisplayName(), i, *nextTarget, nextTargetOffset);
+ BranchIslandAtom<A>* island = new BranchIslandAtom<A>(*this, target.getDisplayName(), i, *nextTarget, *finalTargetAndOffset.atom, finalTargetAndOffset.offset);
island->setSection(textSection);
(*region)[finalTargetAndOffset] = island;
if (log) fprintf(stderr, "added island %s to region %d for %s\n", island->getDisplayName(), i, atom->getDisplayName());
regionsIslands[i].push_back(island);
++islandCount;
nextTarget = island;
- nextTargetOffset = 0;
}
else {
nextTarget = pos->second;
- nextTargetOffset = 0;
}
}
}
if (log) fprintf(stderr, "using island %s for branch to %s from %s\n", nextTarget->getDisplayName(), target.getDisplayName(), atom->getDisplayName());
- ref->setTarget(*nextTarget, nextTargetOffset);
+ ref->setTarget(*nextTarget, 0);
}
- else if ( displacement < (-kFifteenMegLimit) ) {
+ else if ( displacement < (-kBranchLimit) ) {
// create back branching chain
ObjectFile::Atom* prevTarget = ⌖
- uint64_t prevTargetOffset = ref->getTargetOffset();
for (int i=0; i < kIslandRegionsCount ; ++i) {
AtomToIsland* region = ®ionsMap[i];
int64_t islandRegionAddr = kBetweenRegions * (i+1);
if ( (dstAddr <= islandRegionAddr) && (islandRegionAddr < srcAddr) ) {
AtomToIsland::iterator pos = region->find(finalTargetAndOffset);
if ( pos == region->end() ) {
- BranchIslandAtom<A>* island = new BranchIslandAtom<A>(*this, target.getDisplayName(), i, *prevTarget, prevTargetOffset);
+ BranchIslandAtom<A>* island = new BranchIslandAtom<A>(*this, target.getDisplayName(), i, *prevTarget, *finalTargetAndOffset.atom, finalTargetAndOffset.offset);
island->setSection(textSection);
(*region)[finalTargetAndOffset] = island;
if (log) fprintf(stderr, "added back island %s to region %d for %s\n", island->getDisplayName(), i, atom->getDisplayName());
regionsIslands[i].push_back(island);
++islandCount;
prevTarget = island;
- prevTargetOffset = 0;
}
else {
prevTarget = pos->second;
- prevTargetOffset = 0;
}
}
}
if (log) fprintf(stderr, "using back island %s for %s\n", prevTarget->getDisplayName(), atom->getDisplayName());
- ref->setTarget(*prevTarget, prevTargetOffset);
+ ref->setTarget(*prevTarget, 0);
}
}
}
uint64_t alignment = 1 << (islandAtom->getAlignment().powerOf2);
sectionOffset = ( (sectionOffset+alignment-1) & (-alignment) );
islandAtom->setSectionOffset(sectionOffset);
+ if ( log ) fprintf(stderr, "assigning __text offset 0x%08llx to %s\n", sectionOffset, islandAtom->getDisplayName());
sectionOffset += islandAtom->getSize();
}
++regionIndex;
uint64_t alignment = 1 << (islandAtom->getAlignment().powerOf2);
sectionOffset = ( (sectionOffset+alignment-1) & (-alignment) );
islandAtom->setSectionOffset(sectionOffset);
+ if ( log ) fprintf(stderr, "assigning __text offset 0x%08llx to %s\n", sectionOffset, islandAtom->getDisplayName());
sectionOffset += islandAtom->getSize();
}
}
offset += atomSize;
fLoadCommandsSection->fSize = offset;
}
+ const uint32_t sizeOfLoadCommandsPlusHeader = offset + sizeof(macho_header<typename A::P>);
std::vector<SectionInfo*>& sectionInfos = fLoadCommandsSegment->fSections;
const int sectionCount = sectionInfos.size();
// mach-o MH_PRELOAD files need no padding between load commands and first section
paddingSize = 0;
}
- else if ( fOptions.makeEncryptable() ) {
- // want load commands to end on a page boundary, so __text starts on page boundary
- paddingSize = 4096 - ((totalSizeOfTEXTLessHeaderAndLoadCommands+fOptions.minimumHeaderPad()) % 4096) + fOptions.minimumHeaderPad();
- fEncryptionLoadCommand->setStartEncryptionOffset(totalSizeOfTEXTLessHeaderAndLoadCommands+paddingSize);
- }
else {
// work backwards from end of segment and lay out sections so that extra room goes to padding atom
uint64_t addr = 0;
int extraPages = (minPad - paddingSize + fOptions.segmentAlignment() - 1)/fOptions.segmentAlignment();
paddingSize += extraPages * fOptions.segmentAlignment();
}
+
+ if ( fOptions.makeEncryptable() ) {
+ // load commands must be on a separate non-encrypted page
+ int loadCommandsPage = (sizeOfLoadCommandsPlusHeader + minPad)/fOptions.segmentAlignment();
+ int textPage = (sizeOfLoadCommandsPlusHeader + paddingSize)/fOptions.segmentAlignment();
+ if ( loadCommandsPage == textPage ) {
+ paddingSize += fOptions.segmentAlignment();
+ textPage += 1;
+ }
+
+ //paddingSize = 4096 - ((totalSizeOfTEXTLessHeaderAndLoadCommands+fOptions.minimumHeaderPad()) % 4096) + fOptions.minimumHeaderPad();
+ fEncryptionLoadCommand->setStartEncryptionOffset(textPage*fOptions.segmentAlignment());
+ }
}
// adjust atom size and update section size
else {
address = ( (address+alignment-1) & (-alignment) );
}
-
// adjust file offset to match address
if ( prevSection != NULL ) {
if ( virtualSectionOccupyAddressSpace || !prevSection->fVirtualSection )
cmd->set_cmd(LC_LAZY_LOAD_DYLIB);
else if ( fInfo.options.fWeakImport || autoWeakLoadDylib )
cmd->set_cmd(LC_LOAD_WEAK_DYLIB);
- else if ( fInfo.options.fReExport && (fWriter.fOptions.macosxVersionMin() >= ObjectFile::ReaderOptions::k10_5) )
+ else if ( fInfo.options.fReExport && fWriter.fOptions.useSimplifiedDylibReExports() )
cmd->set_cmd(LC_REEXPORT_DYLIB);
else
cmd->set_cmd(LC_LOAD_DYLIB);
template <typename A>
void UnwindInfoAtom<A>::addUnwindInfo(ObjectFile::Atom* func, uint32_t offset, uint32_t encoding,
- ObjectFile::Reference* lsdaRef, ObjectFile::Atom* personalityPointer)
+ ObjectFile::Reference* fdeRef, ObjectFile::Reference* lsdaRef,
+ ObjectFile::Atom* personalityPointer)
{
Info info;
info.func = func;
+ if ( fdeRef != NULL )
+ info.fde = &fdeRef->getTarget();
+ else
+ info.fde = NULL;
if ( lsdaRef != NULL ) {
info.lsda = &lsdaRef->getTarget();
info.lsdaOffset = lsdaRef->getTargetOffset();
// encoding, info.lsda, info.lsdaOffset, personalityPointer, func->getDisplayName());
}
+template <>
+bool UnwindInfoAtom<x86>::encodingMeansUseDwarf(compact_unwind_encoding_t encoding)
+{
+ return ( (encoding & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_DWARF);
+}
+
+template <>
+bool UnwindInfoAtom<x86_64>::encodingMeansUseDwarf(compact_unwind_encoding_t encoding)
+{
+ return ( (encoding & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_DWARF);
+}
+
+template <typename A>
+bool UnwindInfoAtom<A>::encodingMeansUseDwarf(compact_unwind_encoding_t encoding)
+{
+ return false;
+}
+
template <typename A>
void UnwindInfoAtom<A>::compressDuplicates(std::vector<Info>& uniqueInfos)
last.personalityPointer = NULL;
last.encoding = 0xFFFFFFFF;
for(typename std::vector<Info>::iterator it=fInfos.begin(); it != fInfos.end(); ++it) {
- Info newInfo = *it;
+ Info& newInfo = *it;
+ bool newNeedsDwarf = encodingMeansUseDwarf(newInfo.encoding);
// remove infos which have same encoding and personalityPointer as last one
- if ( (newInfo.encoding != last.encoding) || (newInfo.personalityPointer != last.personalityPointer)
+ if ( newNeedsDwarf || (newInfo.encoding != last.encoding) || (newInfo.personalityPointer != last.personalityPointer)
|| (newInfo.lsda != NULL) || (last.lsda != NULL) ) {
uniqueInfos.push_back(newInfo);
}
std::map<uint32_t, unsigned int> encodingsUsed;
unsigned int mostCommonEncodingUsageCount = 0;
for(typename std::vector<Info>::const_iterator it=uniqueInfos.begin(); it != uniqueInfos.end(); ++it) {
+ // never put dwarf into common table
+ if ( encodingMeansUseDwarf(it->encoding) )
+ continue;
std::map<uint32_t, unsigned int>::iterator pos = encodingsUsed.find(it->encoding);
if ( pos == encodingsUsed.end() ) {
encodingsUsed[it->encoding] = 1;
RegFixUp fixup;
fixup.contentPointer = (uint8_t*)(&entryTable[i]);
fixup.func = info.func;
- fRegFixUps.push_back(fixup);
+ fixup.fde = ( encodingMeansUseDwarf(info.encoding) ? info.fde : NULL );
+ fRegFixUps.push_back(fixup);
}
//fprintf(stderr, "regular page with %u entries\n", entriesToAdd);
pageEnd = pageStart;
uint32_t pageSize, unsigned int endIndex, uint8_t*& pageEnd)
{
const bool log = false;
+ if (log) fprintf(stderr, "makeCompressedSecondLevelPage(pageSize=%u, endIndex=%u)\n", pageSize, endIndex);
// first pass calculates how many compressed entries we could fit in this sized page
// keep adding entries to page until:
// 1) encoding table plus entry table plus header exceed page size
encodingIndex = pos->second;
}
else {
- std::map<uint32_t, unsigned int>::iterator ppos = pageSpecificEncodings.find(info.encoding);
+ // no commmon entry, so add one on this page
+ uint32_t encoding = info.encoding;
+ if ( encodingMeansUseDwarf(encoding) ) {
+ // make unique pseudo encoding so this dwarf will gets is own encoding entry slot
+ encoding += (index+1);
+ }
+ std::map<uint32_t, unsigned int>::iterator ppos = pageSpecificEncodings.find(encoding);
if ( ppos != pageSpecificEncodings.end() ) {
encodingIndex = pos->second;
}
else {
encodingIndex = commonEncodings.size() + pageSpecificEncodings.size();
if ( encodingIndex <= 255 ) {
- pageSpecificEncodings[info.encoding] = encodingIndex;
+ pageSpecificEncodings[encoding] = encodingIndex;
}
else {
canDo = false; // case 3)
++entryCount;
}
// check room for entry
- if ( (pageSpecificEncodings.size()+entryCount) > space4 ) {
+ if ( (pageSpecificEncodings.size()+entryCount) >= space4 ) {
canDo = false; // case 1)
--entryCount;
if (log) fprintf(stderr, "end of compressed page with %u entries because full\n", entryCount);
}
+ //if (log) fprintf(stderr, "space4=%d, pageSpecificEncodings.size()=%ld, entryCount=%d\n", space4, pageSpecificEncodings.size(), entryCount);
}
- // sanity check that we fit more entries into this page than a regular page would hold
- const int compressPageUsed = sizeof(unwind_info_compressed_second_level_page_header)
+ // check for cases where it would be better to use a regular (non-compressed) page
+ const unsigned int compressPageUsed = sizeof(unwind_info_compressed_second_level_page_header)
+ pageSpecificEncodings.size()*sizeof(uint32_t)
+ entryCount*sizeof(uint32_t);
- const int regularEntriesPerPage = (compressPageUsed - sizeof(unwind_info_regular_second_level_page_header))/sizeof(unwind_info_regular_second_level_entry);
- if ( entryCount < regularEntriesPerPage ) {
- return makeRegularSecondLevelPage(uniqueInfos, pageSize, endIndex, pageEnd);
+ if ( (compressPageUsed < (pageSize-4) && (index >= 0) ) ) {
+ const int regularEntriesPerPage = (pageSize - sizeof(unwind_info_regular_second_level_page_header))/sizeof(unwind_info_regular_second_level_entry);
+ if ( entryCount < regularEntriesPerPage ) {
+ return makeRegularSecondLevelPage(uniqueInfos, pageSize, endIndex, pageEnd);
+ }
}
-
+
+ // check if we need any padding because adding another entry would take 8 bytes but only have room for 4
+ uint32_t pad = 0;
+ if ( compressPageUsed == (pageSize-4) )
+ pad = 4;
+
// second pass fills in page
- uint8_t* pageStart = pageEnd - compressPageUsed;
+ uint8_t* pageStart = pageEnd - compressPageUsed - pad;
macho_unwind_info_compressed_second_level_page_header<P>* page = (macho_unwind_info_compressed_second_level_page_header<P>*)pageStart;
page->set_kind(UNWIND_SECOND_LEVEL_COMPRESSED);
page->set_entryPageOffset(sizeof(macho_unwind_info_compressed_second_level_page_header<P>));
page->set_entryCount(entryCount);
page->set_encodingsPageOffset(page->entryPageOffset()+entryCount*sizeof(uint32_t));
page->set_encodingsCount(pageSpecificEncodings.size());
+ uint32_t* const encodingsArray = (uint32_t*)&pageStart[page->encodingsPageOffset()];
// fill in entry table
uint32_t* const entiresArray = (uint32_t*)&pageStart[page->entryPageOffset()];
ObjectFile::Atom* firstFunc = uniqueInfos[endIndex-entryCount].func;
for(unsigned int i=endIndex-entryCount; i < endIndex; ++i) {
const Info& info = uniqueInfos[i];
uint8_t encodingIndex;
- std::map<uint32_t, unsigned int>::const_iterator pos = commonEncodings.find(info.encoding);
- if ( pos != commonEncodings.end() )
- encodingIndex = pos->second;
- else
- encodingIndex = pageSpecificEncodings[info.encoding];
+ if ( encodingMeansUseDwarf(info.encoding) ) {
+ // dwarf entries are always in page specific encodings
+ encodingIndex = pageSpecificEncodings[info.encoding+i];
+ }
+ else {
+ std::map<uint32_t, unsigned int>::const_iterator pos = commonEncodings.find(info.encoding);
+ if ( pos != commonEncodings.end() )
+ encodingIndex = pos->second;
+ else
+ encodingIndex = pageSpecificEncodings[info.encoding];
+ }
uint32_t entryIndex = i - endIndex + entryCount;
A::P::E::set32(entiresArray[entryIndex], encodingIndex << 24);
- CompressedFixUp fixup;
- fixup.contentPointer = (uint8_t*)(&entiresArray[entryIndex]);
- fixup.func = info.func;
- fixup.fromFunc = firstFunc;
- fCompressedFixUps.push_back(fixup);
+ CompressedFixUp funcStartFixUp;
+ funcStartFixUp.contentPointer = (uint8_t*)(&entiresArray[entryIndex]);
+ funcStartFixUp.func = info.func;
+ funcStartFixUp.fromFunc = firstFunc;
+ fCompressedFixUps.push_back(funcStartFixUp);
+ if ( encodingMeansUseDwarf(info.encoding) ) {
+ CompressedEncodingFixUp dwarfStartFixup;
+ dwarfStartFixup.contentPointer = (uint8_t*)(&encodingsArray[encodingIndex-commonEncodings.size()]);
+ dwarfStartFixup.fde = info.fde;
+ fCompressedEncodingFixUps.push_back(dwarfStartFixup);
+ }
}
// fill in encodings table
- uint32_t* const encodingsArray = (uint32_t*)&pageStart[page->encodingsPageOffset()];
- for(std::map<uint32_t, unsigned int>::iterator it = pageSpecificEncodings.begin(); it != pageSpecificEncodings.end(); ++it) {
+ for(std::map<uint32_t, unsigned int>::const_iterator it = pageSpecificEncodings.begin(); it != pageSpecificEncodings.end(); ++it) {
A::P::E::set32(encodingsArray[it->second-commonEncodings.size()], it->first);
}
fPagesSize = 0;
if ( fPagesContentForDelete == NULL )
throw "could not allocate space for compact unwind info";
- ObjectFile::Atom* secondLevelFirstFuncs[pageCount];
- uint8_t* secondLevelPagesStarts[pageCount];
+ ObjectFile::Atom* secondLevelFirstFuncs[pageCount*3];
+ uint8_t* secondLevelPagesStarts[pageCount*3];
// make last second level page smaller so that all other second level pages can be page aligned
uint32_t maxLastPageSize = unwindSectionInfo->fFileOffset % 4096;
for (typename std::vector<RegFixUp>::iterator it = fRegFixUps.begin(); it != fRegFixUps.end(); ++it) {
uint32_t offset = (it->contentPointer - fPagesContent) + fHeaderSize;
fReferences.push_back(new WriterReference<A>(offset, A::kImageOffset32, it->func));
+ if ( it->fde != NULL )
+ fReferences.push_back(new WriterReference<A>(offset+4, A::kSectionOffset24, it->fde));
}
// make references for compressed second level entries
for (typename std::vector<CompressedFixUp>::iterator it = fCompressedFixUps.begin(); it != fCompressedFixUps.end(); ++it) {
uint32_t offset = (it->contentPointer - fPagesContent) + fHeaderSize;
fReferences.push_back(new WriterReference<A>(offset, A::kPointerDiff24, it->func, 0, it->fromFunc, 0));
}
+ for (typename std::vector<CompressedEncodingFixUp>::iterator it = fCompressedEncodingFixUps.begin(); it != fCompressedEncodingFixUps.end(); ++it) {
+ uint32_t offset = (it->contentPointer - fPagesContent) + fHeaderSize;
+ fReferences.push_back(new WriterReference<A>(offset, A::kSectionOffset24, it->fde));
+ }
// update section record with new size
unwindSectionInfo->fSize = this->getSize();
template <typename A>
-BranchIslandAtom<A>::BranchIslandAtom(Writer<A>& writer, const char* name, int islandRegion, ObjectFile::Atom& target, uint32_t targetOffset)
- : WriterAtom<A>(writer, Segment::fgTextSegment), fTarget(target), fTargetOffset(targetOffset)
+BranchIslandAtom<A>::BranchIslandAtom(Writer<A>& writer, const char* name, int islandRegion, ObjectFile::Atom& target,
+ ObjectFile::Atom& finalTarget, uint32_t finalTargetOffset)
+ : WriterAtom<A>(writer, Segment::fgTextSegment), fTarget(target), fFinalTarget(finalTarget), fFinalTargetOffset(finalTargetOffset)
{
- char* buf = new char[strlen(name)+32];
- if ( targetOffset == 0 ) {
+ if ( finalTargetOffset == 0 ) {
if ( islandRegion == 0 )
- sprintf(buf, "%s$island", name);
+ asprintf((char**)&fName, "%s$island", name);
else
- sprintf(buf, "%s$island_%d", name, islandRegion);
+ asprintf((char**)&fName, "%s$island$%d", name, islandRegion+1);
}
else {
- sprintf(buf, "%s_plus_%d$island_%d", name, targetOffset, islandRegion);
+ asprintf((char**)&fName, "%s_plus_%d$island$%d", name, finalTargetOffset, islandRegion);
+ }
+
+ if ( finalTarget.isThumb() ) {
+ if ( writer.fOptions.preferSubArchitecture() && writer.fOptions.subArchitecture() == CPU_SUBTYPE_ARM_V7 ) {
+ fIslandKind = kBranchIslandToThumb2;
+ }
+ else {
+ fIslandKind = kBranchIslandToThumb1;
+ }
+ }
+ else {
+ fIslandKind = kBranchIslandToARM;
}
- fName = buf;
}
template <>
void BranchIslandAtom<ppc>::copyRawContent(uint8_t buffer[]) const
{
- int64_t displacement = fTarget.getAddress() + fTargetOffset - this->getAddress();
+ int64_t displacement;
+ const int64_t bl_sixteenMegLimit = 0x00FFFFFF;
+ if ( fTarget.getContentType() == ObjectFile::Atom::kBranchIsland ) {
+ displacement = getFinalTargetAdress() - this->getAddress();
+ if ( (displacement > bl_sixteenMegLimit) && (displacement < (-bl_sixteenMegLimit)) ) {
+ displacement = fTarget.getAddress() - this->getAddress();
+ }
+ }
+ else {
+ displacement = fTarget.getAddress() + fFinalTargetOffset - this->getAddress();
+ }
int32_t branchInstruction = 0x48000000 | ((uint32_t)displacement & 0x03FFFFFC);
OSWriteBigInt32(buffer, 0, branchInstruction);
}
template <>
void BranchIslandAtom<ppc64>::copyRawContent(uint8_t buffer[]) const
{
- int64_t displacement = fTarget.getAddress() + fTargetOffset - this->getAddress();
+ int64_t displacement;
+ const int64_t bl_sixteenMegLimit = 0x00FFFFFF;
+ if ( fTarget.getContentType() == ObjectFile::Atom::kBranchIsland ) {
+ displacement = getFinalTargetAdress() - this->getAddress();
+ if ( (displacement > bl_sixteenMegLimit) && (displacement < (-bl_sixteenMegLimit)) ) {
+ displacement = fTarget.getAddress() - this->getAddress();
+ }
+ }
+ else {
+ displacement = fTarget.getAddress() + fFinalTargetOffset - this->getAddress();
+ }
int32_t branchInstruction = 0x48000000 | ((uint32_t)displacement & 0x03FFFFFC);
OSWriteBigInt32(buffer, 0, branchInstruction);
}
+template <>
+void BranchIslandAtom<arm>::copyRawContent(uint8_t buffer[]) const
+{
+ const bool log = false;
+ switch ( fIslandKind ) {
+ case kBranchIslandToARM:
+ {
+ int64_t displacement;
+ // an ARM branch can branch farther than a thumb branch. The branch
+ // island generation was conservative and put islands every thumb
+ // branch distance apart. Check to see if this is a an island
+ // hopping branch that could be optimized to go directly to target.
+ if ( fTarget.getContentType() == ObjectFile::Atom::kBranchIsland ) {
+ displacement = getFinalTargetAdress() - this->getAddress() - 8;
+ if ( (displacement < 33554428LL) && (displacement > (-33554432LL)) ) {
+ // can skip branch island and jump straight to target
+ if (log) fprintf(stderr, "%s: optimized jump to final target at 0x%08llX, thisAddr=0x%08llX\n", fName, getFinalTargetAdress(), this->getAddress());
+ }
+ else {
+ // ultimate target is too far, jump to island
+ displacement = fTarget.getAddress() - this->getAddress() - 8;
+ if (log) fprintf(stderr, "%s: jump to branch island at 0x%08llX\n", fName, fTarget.getAddress());
+ }
+ }
+ else {
+ // target of island is ultimate target
+ displacement = fTarget.getAddress() + fFinalTargetOffset - this->getAddress() - 8;
+ if (log) fprintf(stderr, "%s: jump to target at 0x%08llX\n", fName, fTarget.getAddress());
+ }
+ uint32_t imm24 = (displacement >> 2) & 0x00FFFFFF;
+ int32_t branchInstruction = 0xEA000000 | imm24;
+ OSWriteLittleInt32(buffer, 0, branchInstruction);
+ }
+ break;
+ case kBranchIslandToThumb2:
+ {
+ int64_t displacement;
+ // an ARM branch can branch farther than a thumb branch. The branch
+ // island generation was conservative and put islands every thumb
+ // branch distance apart. Check to see if this is a an island
+ // hopping branch that could be optimized to go directly to target.
+ if ( fTarget.getContentType() == ObjectFile::Atom::kBranchIsland ) {
+ displacement = getFinalTargetAdress() - this->getAddress() - 4;
+ if ( (displacement < 16777214) && (displacement > (-16777216LL)) ) {
+ // can skip branch island and jump straight to target
+ if (log) fprintf(stderr, "%s: optimized jump to final target at 0x%08llX, thisAddr=0x%08llX\n", fName, getFinalTargetAdress(), this->getAddress());
+ }
+ else {
+ // ultimate target is too far, jump to island
+ displacement = fTarget.getAddress() - this->getAddress() - 4;
+ if (log) fprintf(stderr, "%s: jump to branch island at 0x%08llX\n", fName, fTarget.getAddress());
+ }
+ }
+ else {
+ // target of island is ultimate target
+ displacement = fTarget.getAddress() + fFinalTargetOffset - this->getAddress() - 4;
+ if (log) fprintf(stderr, "%s: jump to target at 0x%08llX\n", fName, fTarget.getAddress());
+ }
+ if ( (displacement > 16777214) || (displacement < (-16777216LL)) ) {
+ throwf("internal branch island error: thumb2 b/bx out of range (%lld max is +/-16M) from %s to %s in %s",
+ displacement, this->getDisplayName(),
+ fTarget.getDisplayName(), fTarget.getFile()->getPath());
+ }
+ // The instruction is really two instructions:
+ // The lower 16 bits are the first instruction, which contains the high
+ // 11 bits of the displacement.
+ // The upper 16 bits are the second instruction, which contains the low
+ // 11 bits of the displacement, as well as differentiating bl and blx.
+ uint32_t s = (uint32_t)(displacement >> 24) & 0x1;
+ uint32_t i1 = (uint32_t)(displacement >> 23) & 0x1;
+ uint32_t i2 = (uint32_t)(displacement >> 22) & 0x1;
+ uint32_t imm10 = (uint32_t)(displacement >> 12) & 0x3FF;
+ uint32_t imm11 = (uint32_t)(displacement >> 1) & 0x7FF;
+ uint32_t j1 = (i1 == s);
+ uint32_t j2 = (i2 == s);
+ uint32_t opcode = 0x9000F000;
+ uint32_t nextDisp = (j1 << 13) | (j2 << 11) | imm11;
+ uint32_t firstDisp = (s << 10) | imm10;
+ uint32_t newInstruction = opcode | (nextDisp << 16) | firstDisp;
+ //warning("s=%d, j1=%d, j2=%d, imm10=0x%0X, imm11=0x%0X, opcode=0x%08X, first=0x%04X, next=0x%04X, new=0x%08X, disp=0x%llX for %s to %s\n",
+ // s, j1, j2, imm10, imm11, opcode, firstDisp, nextDisp, newInstruction, displacement, inAtom->getDisplayName(), ref->getTarget().getDisplayName());
+ OSWriteLittleInt32(buffer, 0, newInstruction);
+ }
+ break;
+ case kBranchIslandToThumb1:
+ {
+ // There is no large displacement thumb1 branch instruction.
+ // Instead use ARM instructions that can jump to thumb.
+ // we use a 32-bit displacement, so we can directly jump to target which means no island hopping
+ int64_t displacement = getFinalTargetAdress() - (this->getAddress() + 12);
+ if ( fFinalTarget.isThumb() )
+ displacement |= 1;
+ if (log) fprintf(stderr, "%s: 4 ARM instruction jump to final target at 0x%08llX\n", fName, getFinalTargetAdress());
+ OSWriteLittleInt32(&buffer[ 0], 0, 0xe59fc004); // ldr ip, pc + 4
+ OSWriteLittleInt32(&buffer[ 4], 0, 0xe08fc00c); // add ip, pc, ip
+ OSWriteLittleInt32(&buffer[ 8], 0, 0xe12fff1c); // bx ip
+ OSWriteLittleInt32(&buffer[12], 0, displacement); // .long target-this
+ }
+ break;
+ };
+}
+
template <>
uint64_t BranchIslandAtom<ppc>::getSize() const
{
return 4;
}
+template <>
+uint64_t BranchIslandAtom<arm>::getSize() const
+{
+ switch ( fIslandKind ) {
+ case kBranchIslandToARM:
+ return 4;
+ case kBranchIslandToThumb1:
+ return 16;
+ case kBranchIslandToThumb2:
+ return 4;
+ };
+ throw "internal error: no ARM branch island kind";
+}
+
template <typename A>
std::vector<binding_tmp> mid;
const SegmentInfo* currentSegment = NULL;
unsigned int segIndex = 0;
- int ordinal = 0;
+ int ordinal = 0x80000000;
const char* symbolName = NULL;
uint8_t type = 0;
uint64_t address = (uint64_t)(-1);
p->opcode = BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED;
p->operand1 = p->operand1/sizeof(pint_t);
}
+ else if ( (p->opcode == BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB) && (p->operand1 <= 15) ) {
+ p->opcode = BIND_OPCODE_SET_DYLIB_ORDINAL_IMM;
+ }
}
dst->opcode = BIND_OPCODE_DONE;
-
// convert to compressed encoding
const static bool log = false;
fEncodedData.reserve(info.size()*2);
fForFinalLinkedImage(false), fNoEHLabels(false), fForStatic(false), fForDyld(false), fMakeTentativeDefinitionsReal(false),
fWhyLoad(false), fRootSafe(false), fSetuidSafe(false),fDebugInfoStripping(kDebugInfoFull),
fImplicitlyLinkPublicDylibs(true),
- fAddCompactUnwindEncoding(false),
+ fAddCompactUnwindEncoding(true),
fWarnCompactUnwind(false),
fRemoveDwarfUnwindIfCompactExists(false),
fMakeCompressedDyldInfo(false),
fTraceOutputFile(NULL), fMacVersionMin(kMinMacVersionUnset), fIPhoneVersionMin(kMinIPhoneVersionUnset) {}
enum DebugInfoStripping { kDebugInfoNone, kDebugInfoMinimal, kDebugInfoFull };
enum MacVersionMin { kMinMacVersionUnset, k10_1, k10_2, k10_3, k10_4, k10_5, k10_6 };
- enum IPhoneVersionMin { kMinIPhoneVersionUnset, k2_0, k2_1, k2_2, k3_0 };
+ enum IPhoneVersionMin { kMinIPhoneVersionUnset, k2_0, k3_0, k3_1 };
struct AliasPair {
const char* realName;
public:
enum Scope { scopeTranslationUnit, scopeLinkageUnit, scopeGlobal };
enum DefinitionKind { kRegularDefinition, kWeakDefinition, kTentativeDefinition, kExternalDefinition, kExternalWeakDefinition, kAbsoluteSymbol };
- enum ContentType { kUnclassifiedType, kCStringType, kCFIType, kLSDAType, kSectionStart, kSectionEnd };
+ enum ContentType { kUnclassifiedType, kCStringType, kCFIType, kLSDAType, kSectionStart, kSectionEnd, kBranchIsland,
+ kLazyPointer, kStub, kNonLazyPointer, kLazyDylibPointer, kStubHelper };
enum SymbolTableInclusion { kSymbolTableNotIn, kSymbolTableIn, kSymbolTableInAndNeverStrip, kSymbolTableInAsAbsolute };
virtual Reader* getFile() const = 0;
virtual UnwindInfo::iterator beginUnwind() { return NULL; }
virtual UnwindInfo::iterator endUnwind() { return NULL; }
virtual Reference* getLSDA() { return NULL; }
+ virtual Reference* getFDE() { return NULL; }
virtual Atom* getPersonalityPointer() { return NULL; }
uint64_t getSectionOffset() const { return fSectionOffset; }
fDeadStripDylibs(false), fAllowTextRelocs(false), fWarnTextRelocs(false),
fUsingLazyDylibLinking(false), fEncryptable(true),
fOrderData(true), fMarkDeadStrippableDylib(false),
- fMakeClassicDyldInfo(true), fMakeCompressedDyldInfo(true), fAllowCpuSubtypeMismatches(false), fSaveTempFiles(false)
+ fMakeClassicDyldInfo(true), fMakeCompressedDyldInfo(true), fAllowCpuSubtypeMismatches(false),
+ fUseSimplifiedDylibReExports(false), fSaveTempFiles(false)
{
this->checkForClassic(argc, argv);
this->parsePreCommandLineEnvironmentSettings();
{
if ( version == NULL )
throw "-iphoneos_version_min argument missing";
-
- if ( strncmp(version, "1.", 2) == 0 ) {
- warning("pre-2.0 iPhone OS version not supported");
+ if ( ! isdigit(version[0]) )
+ throw "-iphoneos_version_min argument is not a number";
+ if ( version[1] != '.' )
+ throw "-iphoneos_version_min argument is missing period as second character";
+ if ( ! isdigit(version[2]) )
+ throw "-iphoneos_version_min argument is not a number";
+
+ if ( version[0] == '2' )
fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_0;
- }
- else if ( strncmp(version, "2.", 2) == 0 ) {
- int num = version[2] - '0';
- switch ( num ) {
- case 0:
- fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_0;
- break;
- case 1:
- fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_1;
- break;
- case 2:
- fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_2;
- break;
- default:
- fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_2;
- break;
- }
- }
- else if ( strncmp(version, "3.", 2) == 0 ) {
- int num = version[2] - '0';
- switch ( num ) {
- case 0:
- fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k3_0;
- break;
- default:
- fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k3_0;
- break;
- }
- }
+ else if ( (version[0] == '3') && (version[2] == '0') )
+ fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_0;
+ else if ( (version[0] == '3') && (version[2] >= '1') )
+ fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k3_1;
+ else if ( (version[0] >= '4') )
+ fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k3_1;
else {
- warning("unknown option to -iphoneos_version_min, not 2.x or 3.x");
+ fReaderOptions.fIPhoneVersionMin = ObjectFile::ReaderOptions::k2_0;
+ warning("unknown option to -iphoneos_version_min, not 2.x, 3.x, or 4.x");
}
}
// determine if info for shared region should be added
if ( fOutputKind == Options::kDynamicLibrary ) {
- if ( minOS(ObjectFile::ReaderOptions::k10_5, ObjectFile::ReaderOptions::k3_0) )
+ if ( minOS(ObjectFile::ReaderOptions::k10_5, ObjectFile::ReaderOptions::k3_1) )
if ( !fPrebind )
if ( (strncmp(this->installPath(), "/usr/lib/", 9) == 0)
|| (strncmp(this->installPath(), "/System/Library/", 16) == 0) )
break;
}
- // only use compressed LINKEDIT for x86_64 and i386
+ // only use compressed LINKEDIT for:
+ // x86_64 and i386 on Mac OS X 10.6 or later
+ // arm on iPhoneOS 3.1 or later
if ( fMakeCompressedDyldInfo ) {
switch (fArchitecture) {
case CPU_TYPE_I386:
else if ( fReaderOptions.fMacVersionMin < ObjectFile::ReaderOptions::k10_5 )
fMakeCompressedDyldInfo = false;
break;
- case CPU_TYPE_POWERPC:
case CPU_TYPE_ARM:
+ if ( fReaderOptions.fIPhoneVersionMin >= ObjectFile::ReaderOptions::k3_1 )
+ fMakeClassicDyldInfo = false;
+ else if ( fReaderOptions.fIPhoneVersionMin < ObjectFile::ReaderOptions::k3_1 )
+ fMakeCompressedDyldInfo = false;
+ break;
+ case CPU_TYPE_POWERPC:
case CPU_TYPE_POWERPC64:
default:
fMakeCompressedDyldInfo = false;
}
}
+
// only use compressed LINKEDIT for final linked images
if ( fMakeCompressedDyldInfo ) {
// only final linked images can not optimize zero fill sections
if ( fOutputKind == Options::kObjectFile )
fReaderOptions.fOptimizeZeroFill = true;
-
+
+ // only dynamic final linked images should warn about use of commmons
+ if ( fWarnCommons ) {
+ switch ( fOutputKind ) {
+ case Options::kDynamicExecutable:
+ case Options::kDynamicLibrary:
+ case Options::kDynamicBundle:
+ break;
+ case Options::kPreload:
+ case Options::kStaticExecutable:
+ case Options::kObjectFile:
+ case Options::kDyld:
+ case Options::kKextBundle:
+ fWarnCommons = false;
+ break;
+ }
+ }
+
+ // Mac OS X 10.5 and iPhoneOS 2.0 support LC_REEXPORT_DYLIB
+ if ( minOS(ObjectFile::ReaderOptions::k10_5, ObjectFile::ReaderOptions::k2_0) )
+ fUseSimplifiedDylibReExports = true;
}
void Options::checkIllegalOptionCombinations()
warning("custom stack placement overlaps and will disable shared region");
break;
case CPU_TYPE_ARM:
- if ( fStackSize > 0xFFFFFFFF )
- throw "-stack_size must be < 4G for 32-bit processes";
+ if ( fStackSize > 0x2F000000 )
+ throw "-stack_size must be < 752MB";
if ( fStackAddr == 0 )
- fStackAddr = 0x30000000;
- if ( fStackAddr > 0x40000000)
- throw "-stack_addr must be < 1G for arm";
+ fStackAddr = 0x2F000000;
+ if ( fStackAddr > 0x30000000)
+ throw "-stack_addr must be < 0x30000000 for arm";
case CPU_TYPE_POWERPC64:
case CPU_TYPE_X86_64:
if ( fStackAddr == 0 ) {
if ( fZeroPageSize != ULLONG_MAX ) {
for (std::vector<SegmentStart>::iterator it = fCustomSegmentAddresses.begin(); it != fCustomSegmentAddresses.end(); ++it) {
if ( (it->address >= 0) && (it->address < fZeroPageSize) )
- throwf("-segaddr %s 0x%X conflicts with -pagezero_size", it->name, it->address);
+ throwf("-segaddr %s 0x%llX conflicts with -pagezero_size", it->name, it->address);
}
}
// verify no duplicates
void Options::gotoClassicLinker(int argc, const char* argv[])
{
argv[0] = "ld_classic";
+ char rawPath[PATH_MAX];
char path[PATH_MAX];
uint32_t bufSize = PATH_MAX;
- if ( _NSGetExecutablePath(path, &bufSize) != -1 ) {
- char* lastSlash = strrchr(path, '/');
- if ( lastSlash != NULL ) {
- strcpy(lastSlash+1, "ld_classic");
- execvp(path, (char**)argv);
+ if ( _NSGetExecutablePath(rawPath, &bufSize) != -1 ) {
+ if ( realpath(rawPath, path) != NULL ) {
+ char* lastSlash = strrchr(path, '/');
+ if ( lastSlash != NULL ) {
+ strcpy(lastSlash+1, "ld_classic");
+ argv[0] = path;
+ execvp(path, (char**)argv);
+ }
}
}
// in case of error in above, try searching for ld_classic via PATH
#include "ObjectFile.h"
-extern void throwf (const char* format, ...) __attribute__ ((noreturn));
-extern void warning(const char* format, ...);
+extern void throwf (const char* format, ...) __attribute__ ((noreturn,format(printf, 1, 2)));
+extern void warning(const char* format, ...) __attribute__((format(printf, 1, 2)));
class LibraryOptions
{
bool errorOnOtherArchFiles() { return fErrorOnOtherArchFiles; }
bool markAutoDeadStripDylib() { return fMarkDeadStrippableDylib; }
bool removeEHLabels() { return fReaderOptions.fNoEHLabels; }
+ bool useSimplifiedDylibReExports() { return fUseSimplifiedDylibReExports; }
private:
class CStringEquals
bool fMakeCompressedDyldInfo;
bool fNoEHLabels;
bool fAllowCpuSubtypeMismatches;
+ bool fUseSimplifiedDylibReExports;
std::vector<const char*> fInitialUndefines;
NameSet fAllowedUndefined;
NameSet fWhyLive;
/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
- * Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
typedef __gnu_cxx::hash_map<const char*, class Section*, __gnu_cxx::hash<const char*>, CStringEquals> NameToSection;
//typedef std::map<const char*, class Section*, CStringComparor> NameToSection;
- const char* fSectionName;
- const char* fSegmentName;
+ char fSectionName[18];
+ char fSegmentName[18];
bool fZeroFill;
bool fUntrustedZeroFill;
Section::NameToOrdinal Section::fgSegmentDiscoverOrder;
Section::Section(const char* sectionName, const char* segmentName, bool zeroFill, bool untrustedZeroFill)
- : fSectionName(sectionName), fSegmentName(segmentName), fZeroFill(zeroFill), fUntrustedZeroFill(untrustedZeroFill)
+ : fZeroFill(zeroFill), fUntrustedZeroFill(untrustedZeroFill)
{
+ strlcpy(fSectionName, sectionName, sizeof(fSectionName));
+ strlcpy(fSegmentName, segmentName, sizeof(fSegmentName));
+
this->fIndex = fgSections.size() + 20; // room for 20 standard sections
// special placement of some sections
if ( strcmp(segmentName, "__TEXT") == 0 ) {
+ // sort mach header and load commands to start of TEXT
+ if ( strcmp(sectionName, "._mach_header") == 0 )
+ this->fIndex = 1;
+ else if ( strcmp(sectionName, "._load_commands") == 0 )
+ this->fIndex = 2;
+ else if ( strcmp(sectionName, "._load_cmds_pad") == 0 )
+ this->fIndex = 3;
+ // sort __text after load commands
+ else if ( strcmp(sectionName, "__text") == 0 )
+ this->fIndex = 10;
+ // sort arm/ppc stubs after text to make branch islands feasible
+ else if ( strcmp(sectionName, "__picsymbolstub4") == 0 )
+ this->fIndex = 11;
+ else if ( strcmp(sectionName, "__symbol_stub4") == 0 )
+ this->fIndex = 11;
+ else if ( strcmp(sectionName, "__picsymbolstub1") == 0 )
+ this->fIndex = 11;
+ else if ( strcmp(sectionName, "__symbol_stub1") == 0 )
+ this->fIndex = 11;
// sort unwind info to end of segment
- if ( strcmp(sectionName, "__eh_frame") == 0 )
+ else if ( strcmp(sectionName, "__eh_frame") == 0 )
this->fIndex = INT_MAX;
else if ( strcmp(sectionName, "__unwind_info") == 0 )
this->fIndex = INT_MAX-1;
else if ( strcmp(sectionName, "__gcc_except_tab") == 0 )
- this->fIndex = INT_MAX-2;
+ this->fIndex = INT_MAX-2;
+ else if ( strcmp(sectionName, "__symbolstub1") == 0 )
+ this->fIndex = INT_MAX-3; // sort to end of __TEXT to be close to lazy pointers
}
else if ( strcmp(segmentName, "__DATA") == 0 ) {
+ // sort arm lazy symbol pointers that must be at start of __DATA
+ if ( strcmp(sectionName, "__lazy_symbol") == 0 )
+ this->fIndex = 0;
// sort sections dyld will touch to start of segment
- if ( strcmp(sectionName, "__dyld") == 0 )
+ else if ( strcmp(sectionName, "__dyld") == 0 )
this->fIndex = 1;
else if ( strcmp(sectionName, "__program_vars") == 0 )
this->fIndex = 1;
this->fIndex = 18;
else if ( strcmp(sectionName, "__objc_imageinfo") == 0 )
this->fIndex = 19;
+ else if ( strcmp(sectionName, "__huge") == 0 )
+ this->fIndex = INT_MAX;
}
void loadAndResolve();
void processDTrace();
void checkObjC();
+ void addSynthesizedAtoms();
void loadUndefines();
void checkUndefines();
void resolveReferences();
void require(const char* name);
bool add(ObjectFile::Atom& atom);
ObjectFile::Atom* find(const char* name);
+ void erase(const char* name);
unsigned int getRequireCount() { return fRequireCount; }
void getUndefinesNames(std::vector<const char*>& undefines);
void getTentativesNames(std::vector<const char*>& tents);
bool hasExternalTentativeDefinitions() { return fHasExternalTentativeDefinitions; }
bool hasExternalWeakDefinitions() { return fHasExternalWeakDefinitions; }
void setHasExternalWeakDefinitions(bool value) { fHasExternalWeakDefinitions = value; }
+ uint32_t dylibSymbolCount() { return fDylibSymbolCount; }
Mapper::iterator begin() { return fTable.begin(); }
Mapper::iterator end() { return fTable.end(); }
unsigned int fRequireCount;
bool fHasExternalTentativeDefinitions;
bool fHasExternalWeakDefinitions;
+ uint32_t fDylibSymbolCount;
};
class AtomSorter
}
}
+void Linker::addSynthesizedAtoms()
+{
+ // give write a chance to synthesize stub, GOT, and lazy pointer atoms
+ std::vector<class ObjectFile::Atom*> newAtoms;
+ fOutputFile->addSynthesizedAtoms(fAllAtoms, this->dyldClassicHelper(),
+ this->dyldCompressedHelper(), this->dyldLazyLibraryHelper(),
+ fBiggerThanTwoGigOutput,
+ fGlobalSymbolTable.dylibSymbolCount(),
+ newAtoms);
+
+ // add all newly created atoms to fAllAtoms and update symbol table
+ this->addAtoms(newAtoms);
+}
+
void Linker::optimize()
{
// give each reader a chance to do any optimizations
// only do next steps if some optimization was actually done
if ( didSomething ) {
+
+ if ( fOptions.deadStrip() != Options::kDeadStripOff ) {
+ for(std::vector<class ObjectFile::Atom*>::iterator itr = newAtoms.begin(); itr != newAtoms.end(); ++itr) {
+ ObjectFile::Atom* atom = *itr;
+ const char* name = atom->getName();
+ if ( name != NULL ) {
+ ObjectFile::Atom* existingAtom = fGlobalSymbolTable.find(name);
+ if ( (existingAtom != NULL) && fLiveAtoms.count(existingAtom) == 0 ) {
+ // While dead code stripping, the atoms were not removed from fGlobalSymbolTable
+ // for performance reasons. Normally, libLTO will never recreate an atom
+ // that was previously dead stripped away, but if it does remove
+ // the remnents of the previous so the new one can be added
+ fGlobalSymbolTable.erase(name);
+ }
+ }
+ }
+ }
+
// add all newly created atoms to fAllAtoms and update symbol table
this->addAtoms(newAtoms);
this->checkObjC();
this->processDTrace();
this->tweakLayout();
+ this->addSynthesizedAtoms();
this->sortSections();
this->sortAtoms();
this->writeDotOutput();
uint64_t offset = offsetsInDOF[i];
//fprintf(stderr, "%s offset[%d]=0x%08llX\n", providerName, i, offset);
if ( offset > dofSectionSize )
- throwf("offsetsInDOF[i]=%0llX > dofSectionSize=%0lX\n", i, offset, dofSectionSize);
+ throwf("offsetsInDOF[%d]=%0llX > dofSectionSize=%0lX\n", i, offset, dofSectionSize);
reader->addSectionReference(pcRelKind(fArchitecture), offset, probes[i].atom, probes[i].offset, reader->getAtoms()[0], 0);
}
this->addAtoms(reader->getAtoms());
theOrdinalOverrideMap[atom] = index;
if (log ) fprintf(stderr, "override ordinal %u assigned to %s from %s\n", index, atom->getDisplayName(), atom->getFile()->getPath());
}
+ ++matchCount;
}
else {
- ++matchCount;
- //fprintf(stderr, "can't find match for order_file entry %s/%s\n", it->objectFileName, it->symbolName);
+ if ( fOptions.printOrderFileStatistics() ) {
+ if ( it->objectFileName == NULL )
+ warning("can't find match for order_file entry: %s", it->symbolName);
+ else
+ warning("can't find match for order_file entry: %s/%s", it->objectFileName, it->symbolName);
+ }
}
++index;
}
//fprintf(stderr, "Sorted atoms:\n");
//for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms.begin(); it != fAllAtoms.end(); it++) {
- // fprintf(stderr, "\t%p, %u %s\t%s\n", (*it)->getSection(), (*it)->getSection()->getIndex(), (*it)->getDisplayName(), (*it)->getFile()->getPath());
+ // fprintf(stderr, "\t%s, %u %s\t%s\n", (*it)->getSectionName(), (*it)->getSection()->getIndex(), (*it)->getDisplayName(), (*it)->getFile()->getPath());
//}
}
fStartWriteTime = mach_absolute_time();
// tell writer about each segment's atoms
fOutputFileSize = fOutputFile->write(fAllAtoms, fStabs, this->entryPoint(true),
- this->dyldClassicHelper(),this->dyldCompressedHelper(), this->dyldLazyLibraryHelper(),
fCreateUUID, fCanScatter,
- fCurrentCpuConstraint, fBiggerThanTwoGigOutput,
+ fCurrentCpuConstraint,
fRegularDefAtomsThatOverrideADylibsWeakDef,
fGlobalSymbolTable.hasExternalWeakDefinitions());
}
case ObjectFile::Atom::kWeakDefinition:
fHasExternalWeakDefinitions = true;
break;
+ case ObjectFile::Atom::kExternalDefinition:
+ case ObjectFile::Atom::kExternalWeakDefinition:
+ ++fDylibSymbolCount;
+ break;
default:
break;
}
return NULL;
}
+void Linker::SymbolTable::erase(const char* name) {
+ fTable.erase(name);
+}
void Linker::SymbolTable::getUndefinesNames(std::vector<const char*>& undefines)
{
/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
static bool printExport = false;
static bool printExportGraph = false;
static cpu_type_t sPreferredArch = CPU_TYPE_I386;
+static cpu_type_t sPreferredSubArch = 0;
__attribute__((noreturn))
void printLazyBindingOpcodes();
void printExportInfo();
void printExportInfoGraph();
+ void printRelocRebaseInfo();
+ void printSymbolTableExportInfo();
+ void printClassicLazyBindingInfo();
+ void printClassicBindingInfo();
+ pint_t relocBase();
+ const char* relocTypeName(uint8_t r_type);
+ uint8_t segmentIndexForAddress(pint_t addr);
void processExportNode(const uint8_t* const start, const uint8_t* p, const uint8_t* const end,
char* cummulativeString, int curStrOffset);
void processExportGraphNode(const uint8_t* const start, const uint8_t* const end,
const char* sectionName(uint8_t segIndex, pint_t address);
const char* getSegAndSectName(uint8_t segIndex, pint_t address);
const char* ordinalName(int libraryOrdinal);
+ const char* classicOrdinalName(int libraryOrdinal);
+ pint_t* mappedAddressForVMAddress(pint_t vmaddress);
+
const char* fPath;
uint32_t fSymbolCount;
const macho_dyld_info_command<P>* fInfo;
uint64_t fBaseAddress;
+ const macho_dysymtab_command<P>* fDynamicSymbolTable;
+ const macho_segment_command<P>* fFirstSegment;
+ const macho_segment_command<P>* fFirstWritableSegment;
+ bool fWriteableSegmentWithAddrOver4G;
std::vector<const macho_segment_command<P>*>fSegments;
std::vector<const char*> fDylibs;
};
return false;
}
-
template <typename A>
DyldInfoPrinter<A>::DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path)
: fHeader(NULL), fLength(fileLength),
- fStrings(NULL), fStringsEnd(NULL), fSymbols(NULL), fSymbolCount(0), fInfo(NULL), fBaseAddress(0)
+ fStrings(NULL), fStringsEnd(NULL), fSymbols(NULL), fSymbolCount(0), fInfo(NULL),
+ fBaseAddress(0), fDynamicSymbolTable(NULL), fFirstSegment(NULL), fFirstWritableSegment(NULL),
+ fWriteableSegmentWithAddrOver4G(false)
{
// sanity check
if ( ! validFile(fileContent) )
const macho_load_command<P>* const cmds = (macho_load_command<P>*)((uint8_t*)fHeader + sizeof(macho_header<P>));
const macho_load_command<P>* cmd = cmds;
for (uint32_t i = 0; i < cmd_count; ++i) {
- uint32_t size = cmd->cmdsize();
const uint8_t* endOfCmd = ((uint8_t*)cmd)+cmd->cmdsize();
if ( endOfCmd > endOfLoadCommands )
throwf("load command #%d extends beyond the end of the load commands", i);
fSegments.push_back(segCmd);
if ( (segCmd->fileoff() == 0) && (segCmd->filesize() != 0) )
fBaseAddress = segCmd->vmaddr();
+ if ( fFirstSegment == NULL )
+ fFirstSegment = segCmd;
+ if ( (segCmd->initprot() & VM_PROT_WRITE) != 0 ) {
+ if ( fFirstWritableSegment == NULL )
+ fFirstWritableSegment = segCmd;
+ if ( segCmd->vmaddr() > 0x100000000ULL )
+ fWriteableSegmentWithAddrOver4G = true;
+ }
}
break;
case LC_LOAD_DYLIB:
}
}
break;
+ case LC_DYSYMTAB:
+ fDynamicSymbolTable = (macho_dysymtab_command<P>*)cmd;
+ break;
+ case LC_SYMTAB:
+ {
+ const macho_symtab_command<P>* symtab = (macho_symtab_command<P>*)cmd;
+ fSymbolCount = symtab->nsyms();
+ fSymbols = (const macho_nlist<P>*)((char*)fHeader + symtab->symoff());
+ fStrings = (char*)fHeader + symtab->stroff();
+ fStringsEnd = fStrings + symtab->strsize();
+ }
+ break;
}
cmd = (const macho_load_command<P>*)endOfCmd;
}
- if ( printRebase )
- printRebaseInfo();
- if ( printBind )
- printBindingInfo();
+ if ( printRebase ) {
+ if ( fInfo != NULL )
+ printRebaseInfo();
+ else
+ printRelocRebaseInfo();
+ }
+ if ( printBind ) {
+ if ( fInfo != NULL )
+ printBindingInfo();
+ else
+ printClassicBindingInfo();
+ }
if ( printWeakBind )
printWeakBindingInfo();
- if ( printLazyBind )
- printLazyBindingInfo();
- if ( printExport )
- printExportInfo();
+ if ( printLazyBind ) {
+ if ( fInfo != NULL )
+ printLazyBindingInfo();
+ else
+ printClassicLazyBindingInfo();
+ }
+ if ( printExport ) {
+ if ( fInfo != NULL )
+ printExportInfo();
+ else
+ printSymbolTableExportInfo();
+ }
if ( printOpcodes ) {
printRebaseInfoOpcodes();
printBindingInfoOpcodes(false);
return "??";
}
+template <typename A>
+uint8_t DyldInfoPrinter<A>::segmentIndexForAddress(pint_t address)
+{
+ for(unsigned int i=0; i < fSegments.size(); ++i) {
+ if ( (fSegments[i]->vmaddr() <= address) && (address < (fSegments[i]->vmaddr()+fSegments[i]->vmsize())) ) {
+ return i;
+ }
+ }
+ throwf("address 0x%llX is not in any segment", (uint64_t)address);
+}
+
+template <typename A>
+typename A::P::uint_t* DyldInfoPrinter<A>::mappedAddressForVMAddress(pint_t vmaddress)
+{
+ for(unsigned int i=0; i < fSegments.size(); ++i) {
+ if ( (fSegments[i]->vmaddr() <= vmaddress) && (vmaddress < (fSegments[i]->vmaddr()+fSegments[i]->vmsize())) ) {
+ unsigned long offsetInMappedFile = fSegments[i]->fileoff()+vmaddress-fSegments[i]->vmaddr();
+ return (pint_t*)((uint8_t*)fHeader + offsetInMappedFile);
+ }
+ }
+ throwf("address 0x%llX is not in any segment", (uint64_t)vmaddress);
+}
+
template <typename A>
const char* DyldInfoPrinter<A>::ordinalName(int libraryOrdinal)
{
}
if ( libraryOrdinal < BIND_SPECIAL_DYLIB_FLAT_LOOKUP )
throw "unknown special ordinal";
- if ( libraryOrdinal > fDylibs.size() )
+ if ( libraryOrdinal > (int)fDylibs.size() )
throw "libraryOrdinal out of range";
return fDylibs[libraryOrdinal-1];
}
+template <typename A>
+const char* DyldInfoPrinter<A>::classicOrdinalName(int libraryOrdinal)
+{
+ switch ( libraryOrdinal) {
+ case SELF_LIBRARY_ORDINAL:
+ return "this-image";
+ case EXECUTABLE_ORDINAL:
+ return "main-executable";
+ case DYNAMIC_LOOKUP_ORDINAL:
+ return "flat-namespace";
+ }
+ if ( libraryOrdinal > (int)fDylibs.size() )
+ throw "libraryOrdinal out of range";
+ return fDylibs[libraryOrdinal-1];
+}
template <typename A>
void DyldInfoPrinter<A>::printRebaseInfo()
printf("no compressed rebase info\n");
}
else {
- printf("rebase information:\n");
+ printf("rebase information (from compressed dyld info):\n");
printf("segment section address type\n");
const uint8_t* p = (uint8_t*)fHeader + fInfo->rebase_off();
}
else {
printf("bind information:\n");
- printf("segment section address type addend dylib symbol\n");
+ printf("segment section address type weak addend dylib symbol\n");
const uint8_t* p = (uint8_t*)fHeader + fInfo->bind_off();
const uint8_t* end = &p[fInfo->bind_size()];
pint_t segStartAddr = 0;
const char* segName = "??";
const char* typeName = "??";
+ const char* weak_import = "";
bool done = false;
while ( !done && (p < end) ) {
uint8_t immediate = *p & BIND_IMMEDIATE_MASK;
while (*p != '\0')
++p;
++p;
+ if ( (immediate & BIND_SYMBOL_FLAGS_WEAK_IMPORT) != 0 )
+ weak_import = "weak";
+ else
+ weak_import = "";
break;
case BIND_OPCODE_SET_TYPE_IMM:
type = immediate;
segOffset += read_uleb128(p, end);
break;
case BIND_OPCODE_DO_BIND:
- printf("%-7s %-16s 0x%08llX %10s %5lld %-16s %s\n", segName, sectionName(segIndex, segStartAddr+segOffset), segStartAddr+segOffset, typeName, addend, fromDylib, symbolName );
+ printf("%-7s %-16s 0x%08llX %10s %4s %5lld %-16s %s\n", segName, sectionName(segIndex, segStartAddr+segOffset), segStartAddr+segOffset, typeName, weak_import, addend, fromDylib, symbolName );
segOffset += sizeof(pint_t);
break;
case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
- printf("%-7s %-16s 0x%08llX %10s %5lld %-16s %s\n", segName, sectionName(segIndex, segStartAddr+segOffset), segStartAddr+segOffset, typeName, addend, fromDylib, symbolName );
+ printf("%-7s %-16s 0x%08llX %10s %4s %5lld %-16s %s\n", segName, sectionName(segIndex, segStartAddr+segOffset), segStartAddr+segOffset, typeName, weak_import, addend, fromDylib, symbolName );
segOffset += read_uleb128(p, end) + sizeof(pint_t);
break;
case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
- printf("%-7s %-16s 0x%08llX %10s %5lld %-16s %s\n", segName, sectionName(segIndex, segStartAddr+segOffset), segStartAddr+segOffset, typeName, addend, fromDylib, symbolName );
+ printf("%-7s %-16s 0x%08llX %10s %4s %5lld %-16s %s\n", segName, sectionName(segIndex, segStartAddr+segOffset), segStartAddr+segOffset, typeName, weak_import, addend, fromDylib, symbolName );
segOffset += immediate*sizeof(pint_t) + sizeof(pint_t);
break;
case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
count = read_uleb128(p, end);
skip = read_uleb128(p, end);
for (uint32_t i=0; i < count; ++i) {
- printf("%-7s %-16s 0x%08llX %10s %5lld %-16s %s\n", segName, sectionName(segIndex, segStartAddr+segOffset), segStartAddr+segOffset, typeName, addend, fromDylib, symbolName );
+ printf("%-7s %-16s 0x%08llX %10s %4s %5lld %-16s %s\n", segName, sectionName(segIndex, segStartAddr+segOffset), segStartAddr+segOffset, typeName, weak_import, addend, fromDylib, symbolName );
segOffset += skip + sizeof(pint_t);
}
break;
printf("no compressed lazy binding info\n");
}
else {
- printf("lazy binding information:\n");
+ printf("lazy binding information (from lazy_bind part of dyld info):\n");
printf("segment section address index dylib symbol\n");
const uint8_t* const start = (uint8_t*)fHeader + fInfo->lazy_bind_off();
const uint8_t* const end = &start[fInfo->lazy_bind_size()];
}
-#if 0
- uint8_t type = BIND_TYPE_POINTER;
- uint8_t flags;
- uint64_t address = fBaseAddress;
- const char* symbolName = NULL;
- int libraryOrdinal = 0;
- int64_t addend = 0;
- uint32_t segmentIndex = 0;
- uint32_t count;
- uint32_t skip;
- for (const uint8_t* p = start; p < end; ) {
- uint8_t immediate = *p & BIND_IMMEDIATE_MASK;
- uint8_t opcode = *p & BIND_OPCODE_MASK;
- uint32_t opcodeOffset = p-start;
- ++p;
- switch (opcode) {
- case BIND_OPCODE_DONE:
- printf("0x%08X BIND_OPCODE_DONE\n", opcodeOffset);
- break;
- case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
- libraryOrdinal = immediate;
- printf("0x%08X BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(%d)\n", opcodeOffset, libraryOrdinal);
- break;
- case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
- libraryOrdinal = read_uleb128(p, end);
- printf("0x%08X BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB(%d)\n", opcodeOffset, libraryOrdinal);
- break;
- case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:
- // the special ordinals are negative numbers
- if ( immediate == 0 )
- libraryOrdinal = 0;
- else {
- int8_t signExtended = BIND_OPCODE_MASK | immediate;
- libraryOrdinal = signExtended;
- }
- printf("0x%08X BIND_OPCODE_SET_DYLIB_SPECIAL_IMM(%d)\n", opcodeOffset, libraryOrdinal);
- break;
- case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
- flags = immediate;
- symbolName = (char*)p;
- while (*p != '\0')
- ++p;
- ++p;
- printf("0x%08X BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x%02X, %s)\n", opcodeOffset, flags, symbolName);
- break;
- case BIND_OPCODE_SET_TYPE_IMM:
- type = immediate;
- printf("0x%08X BIND_OPCODE_SET_TYPE_IMM(%d)\n", opcodeOffset, type);
- break;
- case BIND_OPCODE_SET_ADDEND_SLEB:
- addend = read_sleb128(p, end);
- printf("0x%08X BIND_OPCODE_SET_ADDEND_SLEB(%lld)\n", opcodeOffset, addend);
- break;
- case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
- segmentIndex = immediate;
- address = read_uleb128(p, end);
- printf("0x%08X BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x%02X, 0x%08llX)\n", opcodeOffset, segmentIndex, address);
- break;
- case BIND_OPCODE_ADD_ADDR_ULEB:
- skip = read_uleb128(p, end);
- printf("0x%08X BIND_OPCODE_ADD_ADDR_ULEB(0x%08X)\n", opcodeOffset, skip);
- break;
- case BIND_OPCODE_DO_BIND:
- printf("0x%08X BIND_OPCODE_DO_BIND()\n", opcodeOffset);
- break;
- case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:
- skip = read_uleb128(p, end);
- printf("0x%08X BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB(0x%08X)\n", opcodeOffset, skip);
- break;
- case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
- skip = immediate*sizeof(pint_t) + sizeof(pint_t);
- printf("0x%08X BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED(0x%08X)\n", opcodeOffset, skip);
- break;
- case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:
- count = read_uleb128(p, end);
- skip = read_uleb128(p, end);
- printf("0x%08X BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB(%d, 0x%08X)\n", opcodeOffset, count, skip);
- break;
- default:
- throwf("unknown bind opcode %d", *p);
- }
- }
-#endif
-
template <typename A>
void DyldInfoPrinter<A>::printLazyBindingOpcodes()
{
printf("no compressed export info\n");
}
else {
+ printf("export information (from trie):\n");
const uint8_t* start = (uint8_t*)fHeader + fInfo->export_off();
const uint8_t* end = &start[fInfo->export_size()];
std::vector<mach_o::trie::Entry> list;
const uint8_t* children = p + terminalSize;
if ( terminalSize != 0 ) {
uint32_t flags = read_uleb128(p, end);
+ (void)flags; // currently unused
uint64_t address = read_uleb128(p, end);
printf("\tnode%03ld [ label=%s,addr0x%08llX ];\n", (long)(me-start), cummulativeString, address);
}
}
+template <>
+ppc::P::uint_t DyldInfoPrinter<ppc>::relocBase()
+{
+ if ( fHeader->flags() & MH_SPLIT_SEGS )
+ return fFirstWritableSegment->vmaddr();
+ else
+ return fFirstSegment->vmaddr();
+}
+
+template <>
+ppc64::P::uint_t DyldInfoPrinter<ppc64>::relocBase()
+{
+ if ( fWriteableSegmentWithAddrOver4G )
+ return fFirstWritableSegment->vmaddr();
+ else
+ return fFirstSegment->vmaddr();
+}
+
+template <>
+x86::P::uint_t DyldInfoPrinter<x86>::relocBase()
+{
+ if ( fHeader->flags() & MH_SPLIT_SEGS )
+ return fFirstWritableSegment->vmaddr();
+ else
+ return fFirstSegment->vmaddr();
+}
+
+template <>
+x86_64::P::uint_t DyldInfoPrinter<x86_64>::relocBase()
+{
+ // check for split-seg
+ return fFirstWritableSegment->vmaddr();
+}
+
+template <>
+arm::P::uint_t DyldInfoPrinter<arm>::relocBase()
+{
+ if ( fHeader->flags() & MH_SPLIT_SEGS )
+ return fFirstWritableSegment->vmaddr();
+ else
+ return fFirstSegment->vmaddr();
+}
+template <>
+const char* DyldInfoPrinter<ppc>::relocTypeName(uint8_t r_type)
+{
+ if ( r_type == GENERIC_RELOC_VANILLA )
+ return "pointer";
+ else if ( r_type == PPC_RELOC_PB_LA_PTR )
+ return "pb pointer";
+ else
+ return "??";
+}
+
+template <>
+const char* DyldInfoPrinter<ppc64>::relocTypeName(uint8_t r_type)
+{
+ if ( r_type == GENERIC_RELOC_VANILLA )
+ return "pointer";
+ else
+ return "??";
+}
+
+template <>
+const char* DyldInfoPrinter<x86>::relocTypeName(uint8_t r_type)
+{
+ if ( r_type == GENERIC_RELOC_VANILLA )
+ return "pointer";
+ else if ( r_type == GENERIC_RELOC_PB_LA_PTR )
+ return "pb pointer";
+ else
+ return "??";
+}
+
+template <>
+const char* DyldInfoPrinter<x86_64>::relocTypeName(uint8_t r_type)
+{
+ if ( r_type == X86_64_RELOC_UNSIGNED )
+ return "pointer";
+ else
+ return "??";
+}
+
+template <>
+const char* DyldInfoPrinter<arm>::relocTypeName(uint8_t r_type)
+{
+ if ( r_type == ARM_RELOC_VANILLA )
+ return "pointer";
+ else if ( r_type == ARM_RELOC_PB_LA_PTR )
+ return "pb pointer";
+ else
+ return "??";
+}
+
+
+template <typename A>
+void DyldInfoPrinter<A>::printRelocRebaseInfo()
+{
+ if ( fDynamicSymbolTable == NULL ) {
+ printf("no classic dynamic symbol table");
+ }
+ else {
+ printf("rebase information (from local relocation records and indirect symbol table):\n");
+ printf("segment section address type\n");
+ // walk all local relocations
+ pint_t rbase = relocBase();
+ const macho_relocation_info<P>* const relocsStart = (macho_relocation_info<P>*)(((uint8_t*)fHeader) + fDynamicSymbolTable->locreloff());
+ const macho_relocation_info<P>* const relocsEnd = &relocsStart[fDynamicSymbolTable->nlocrel()];
+ for (const macho_relocation_info<P>* reloc=relocsStart; reloc < relocsEnd; ++reloc) {
+ if ( (reloc->r_address() & R_SCATTERED) == 0 ) {
+ pint_t addr = reloc->r_address() + rbase;
+ uint8_t segIndex = segmentIndexForAddress(addr);
+ const char* typeName = relocTypeName(reloc->r_type());
+ const char* segName = segmentName(segIndex);
+ const char* sectName = sectionName(segIndex, addr);
+ printf("%-8s %-16s 0x%08llX %s\n", segName, sectName, (uint64_t)addr, typeName);
+ }
+ else {
+ const macho_scattered_relocation_info<P>* sreloc = (macho_scattered_relocation_info<P>*)reloc;
+ pint_t addr = sreloc->r_address() + rbase;
+ uint8_t segIndex = segmentIndexForAddress(addr);
+ const char* typeName = relocTypeName(sreloc->r_type());
+ const char* segName = segmentName(segIndex);
+ const char* sectName = sectionName(segIndex, addr);
+ printf("%-8s %-16s 0x%08llX %s\n", segName, sectName, (uint64_t)addr, typeName);
+ }
+ }
+ // look for local non-lazy-pointers
+ const uint32_t* indirectSymbolTable = (uint32_t*)(((uint8_t*)fHeader) + fDynamicSymbolTable->indirectsymoff());
+ uint8_t segIndex = 0;
+ for(typename std::vector<const macho_segment_command<P>*>::iterator segit=fSegments.begin(); segit != fSegments.end(); ++segit, ++segIndex) {
+ const macho_segment_command<P>* segCmd = *segit;
+ macho_section<P>* const sectionsStart = (macho_section<P>*)((char*)segCmd + sizeof(macho_segment_command<P>));
+ macho_section<P>* const sectionsEnd = §ionsStart[segCmd->nsects()];
+ for(macho_section<P>* sect = sectionsStart; sect < sectionsEnd; ++sect) {
+ uint8_t type = sect->flags() & SECTION_TYPE;
+ if ( type == S_NON_LAZY_SYMBOL_POINTERS ) {
+ uint32_t indirectOffset = sect->reserved1();
+ uint32_t count = sect->size() / sizeof(pint_t);
+ for (uint32_t i=0; i < count; ++i) {
+ uint32_t symbolIndex = E::get32(indirectSymbolTable[indirectOffset+i]);
+ if ( symbolIndex == INDIRECT_SYMBOL_LOCAL ) {
+ pint_t addr = sect->addr() + i*sizeof(pint_t);
+ const char* typeName = "pointer";
+ const char* segName = segmentName(segIndex);
+ const char* sectName = sectionName(segIndex, addr);
+ printf("%-8s %-16s 0x%08llX %s\n", segName, sectName, (uint64_t)addr, typeName);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+template <typename A>
+void DyldInfoPrinter<A>::printSymbolTableExportInfo()
+{
+ if ( fDynamicSymbolTable == NULL ) {
+ printf("no classic dynamic symbol table");
+ }
+ else {
+ printf("export information (from symbol table):\n");
+ const macho_nlist<P>* lastExport = &fSymbols[fDynamicSymbolTable->iextdefsym()+fDynamicSymbolTable->nextdefsym()];
+ for (const macho_nlist<P>* sym = &fSymbols[fDynamicSymbolTable->iextdefsym()]; sym < lastExport; ++sym) {
+ const char* flags = "";
+ if ( sym->n_desc() & N_WEAK_DEF )
+ flags = "[weak_def] ";
+ pint_t thumb = 0;
+ if ( sym->n_desc() & N_ARM_THUMB_DEF )
+ thumb = 1;
+ printf("0x%08llX %s%s\n", sym->n_value()+thumb, flags, &fStrings[sym->n_strx()]);
+ }
+ }
+}
+
+
+template <typename A>
+void DyldInfoPrinter<A>::printClassicBindingInfo()
+{
+ if ( fDynamicSymbolTable == NULL ) {
+ printf("no classic dynamic symbol table");
+ }
+ else {
+ printf("binding information (from relocations and indirect symbol table):\n");
+ printf("segment section address type weak addend dylib symbol\n");
+ // walk all external relocations
+ pint_t rbase = relocBase();
+ const macho_relocation_info<P>* const relocsStart = (macho_relocation_info<P>*)(((uint8_t*)fHeader) + fDynamicSymbolTable->extreloff());
+ const macho_relocation_info<P>* const relocsEnd = &relocsStart[fDynamicSymbolTable->nextrel()];
+ for (const macho_relocation_info<P>* reloc=relocsStart; reloc < relocsEnd; ++reloc) {
+ pint_t addr = reloc->r_address() + rbase;
+ uint32_t symbolIndex = reloc->r_symbolnum();
+ const macho_nlist<P>* sym = &fSymbols[symbolIndex];
+ const char* symbolName = &fStrings[sym->n_strx()];
+ const char* weak_import = (sym->n_desc() & N_WEAK_REF) ? "weak" : "";
+ const char* fromDylib = classicOrdinalName(GET_LIBRARY_ORDINAL(sym->n_desc()));
+ uint8_t segIndex = segmentIndexForAddress(addr);
+ const char* typeName = relocTypeName(reloc->r_type());
+ const char* segName = segmentName(segIndex);
+ const char* sectName = sectionName(segIndex, addr);
+ const pint_t* addressMapped = mappedAddressForVMAddress(addr);
+ int64_t addend = P::getP(*addressMapped);
+ if ( fHeader->flags() & MH_PREBOUND ) {
+ // In prebound binaries the content is already pointing to the target.
+ // To get the addend requires subtracting out the base address it was prebound to.
+ addend -= sym->n_value();
+ }
+ printf("%-8s %-16s 0x%08llX %10s %4s %5lld %-16s %s\n", segName, sectName, (uint64_t)addr,
+ typeName, weak_import, addend, fromDylib, symbolName);
+ }
+ // look for non-lazy pointers
+ const uint32_t* indirectSymbolTable = (uint32_t*)(((uint8_t*)fHeader) + fDynamicSymbolTable->indirectsymoff());
+ for(typename std::vector<const macho_segment_command<P>*>::iterator segit=fSegments.begin(); segit != fSegments.end(); ++segit) {
+ const macho_segment_command<P>* segCmd = *segit;
+ macho_section<P>* const sectionsStart = (macho_section<P>*)((char*)segCmd + sizeof(macho_segment_command<P>));
+ macho_section<P>* const sectionsEnd = §ionsStart[segCmd->nsects()];
+ for(macho_section<P>* sect = sectionsStart; sect < sectionsEnd; ++sect) {
+ uint8_t type = sect->flags() & SECTION_TYPE;
+ if ( type == S_NON_LAZY_SYMBOL_POINTERS ) {
+ uint32_t indirectOffset = sect->reserved1();
+ uint32_t count = sect->size() / sizeof(pint_t);
+ for (uint32_t i=0; i < count; ++i) {
+ uint32_t symbolIndex = E::get32(indirectSymbolTable[indirectOffset+i]);
+ if ( symbolIndex != INDIRECT_SYMBOL_LOCAL ) {
+ const macho_nlist<P>* sym = &fSymbols[symbolIndex];
+ const char* symbolName = &fStrings[sym->n_strx()];
+ const char* weak_import = (sym->n_desc() & N_WEAK_REF) ? "weak" : "";
+ const char* fromDylib = classicOrdinalName(GET_LIBRARY_ORDINAL(sym->n_desc()));
+ pint_t addr = sect->addr() + i*sizeof(pint_t);
+ uint8_t segIndex = segmentIndexForAddress(addr);
+ const char* typeName = "pointer";
+ const char* segName = segmentName(segIndex);
+ const char* sectName = sectionName(segIndex, addr);
+ int64_t addend = 0;
+ printf("%-8s %-16s 0x%08llX %10s %4s %5lld %-16s %s\n", segName, sectName, (uint64_t)addr,
+ typeName, weak_import, addend, fromDylib, symbolName);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+template <typename A>
+void DyldInfoPrinter<A>::printClassicLazyBindingInfo()
+{
+ if ( fDynamicSymbolTable == NULL ) {
+ printf("no classic dynamic symbol table");
+ }
+ else {
+ printf("lazy binding information (from section records and indirect symbol table):\n");
+ printf("segment section address index dylib symbol\n");
+ const uint32_t* indirectSymbolTable = (uint32_t*)(((uint8_t*)fHeader) + fDynamicSymbolTable->indirectsymoff());
+ for(typename std::vector<const macho_segment_command<P>*>::iterator segit=fSegments.begin(); segit != fSegments.end(); ++segit) {
+ const macho_segment_command<P>* segCmd = *segit;
+ macho_section<P>* const sectionsStart = (macho_section<P>*)((char*)segCmd + sizeof(macho_segment_command<P>));
+ macho_section<P>* const sectionsEnd = §ionsStart[segCmd->nsects()];
+ for(macho_section<P>* sect = sectionsStart; sect < sectionsEnd; ++sect) {
+ uint8_t type = sect->flags() & SECTION_TYPE;
+ if ( type == S_LAZY_SYMBOL_POINTERS ) {
+ uint32_t indirectOffset = sect->reserved1();
+ uint32_t count = sect->size() / sizeof(pint_t);
+ for (uint32_t i=0; i < count; ++i) {
+ uint32_t symbolIndex = E::get32(indirectSymbolTable[indirectOffset+i]);
+ const macho_nlist<P>* sym = &fSymbols[symbolIndex];
+ const char* symbolName = &fStrings[sym->n_strx()];
+ const char* fromDylib = classicOrdinalName(GET_LIBRARY_ORDINAL(sym->n_desc()));
+ pint_t addr = sect->addr() + i*sizeof(pint_t);
+ uint8_t segIndex = segmentIndexForAddress(addr);
+ const char* segName = segmentName(segIndex);
+ const char* sectName = sectionName(segIndex, addr);
+ printf("%-7s %-16s 0x%08llX 0x%04X %-16s %s\n", segName, sectName, (uint64_t)addr, symbolIndex, fromDylib, symbolName);
+ }
+ }
+ else if ( (type == S_SYMBOL_STUBS) && (((sect->flags() & S_ATTR_SELF_MODIFYING_CODE) != 0)) && (sect->reserved2() == 5) ) {
+ // i386 self-modifying stubs
+ uint32_t indirectOffset = sect->reserved1();
+ uint32_t count = sect->size() / 5;
+ for (uint32_t i=0; i < count; ++i) {
+ uint32_t symbolIndex = E::get32(indirectSymbolTable[indirectOffset+i]);
+ if ( symbolIndex != INDIRECT_SYMBOL_ABS ) {
+ const macho_nlist<P>* sym = &fSymbols[symbolIndex];
+ const char* symbolName = &fStrings[sym->n_strx()];
+ const char* fromDylib = classicOrdinalName(GET_LIBRARY_ORDINAL(sym->n_desc()));
+ pint_t addr = sect->addr() + i*5;
+ uint8_t segIndex = segmentIndexForAddress(addr);
+ const char* segName = segmentName(segIndex);
+ const char* sectName = sectionName(segIndex, addr);
+ printf("%-7s %-16s 0x%08llX 0x%04X %-16s %s\n", segName, sectName, (uint64_t)addr, symbolIndex, fromDylib, symbolName);
+ }
+ }
+ }
+ }
+ }
+ }
+}
static void dump(const char* path)
{
size_t offset = OSSwapBigToHostInt32(archs[i].offset);
size_t size = OSSwapBigToHostInt32(archs[i].size);
cpu_type_t cputype = OSSwapBigToHostInt32(archs[i].cputype);
- if ( cputype == (uint32_t)sPreferredArch ) {
+ cpu_type_t cpusubtype = OSSwapBigToHostInt32(archs[i].cpusubtype);
+ if ( (cputype == sPreferredArch)
+ && ((sPreferredSubArch==0) || (sPreferredSubArch==cpusubtype)) ) {
switch(cputype) {
case CPU_TYPE_POWERPC:
if ( DyldInfoPrinter<ppc>::validFile(p + offset) )
sPreferredArch = CPU_TYPE_I386;
else if ( strcmp(arch, "x86_64") == 0 )
sPreferredArch = CPU_TYPE_X86_64;
+ else if ( strcmp(arch, "arm") == 0 )
+ sPreferredArch = CPU_TYPE_ARM;
+ else if ( strcmp(arch, "armv4t") == 0 ) {
+ sPreferredArch = CPU_TYPE_ARM;
+ sPreferredSubArch = CPU_SUBTYPE_ARM_V4T;
+ }
+ else if ( strcmp(arch, "armv5") == 0 ) {
+ sPreferredArch = CPU_TYPE_ARM;
+ sPreferredSubArch = CPU_SUBTYPE_ARM_V5TEJ;
+ }
+ else if ( strcmp(arch, "armv6") == 0 ) {
+ sPreferredArch = CPU_TYPE_ARM;
+ sPreferredSubArch = CPU_SUBTYPE_ARM_V6;
+ }
+ else if ( strcmp(arch, "armv7") == 0 ) {
+ sPreferredArch = CPU_TYPE_ARM;
+ sPreferredSubArch = CPU_SUBTYPE_ARM_V7;
+ }
else
throwf("unknown architecture %s", arch);
}
void getSymbolTableInfo();
const char* functionName(pint_t addr);
static const char* archName();
+ static void decode(uint32_t encoding, const uint8_t* funcStart, char* str);
const char* fPath;
const macho_header<P>* fHeader;
}
}
}
- return "??";
+ return "--anonymous function--";
}
return false;
}
+#define EXTRACT_BITS(value, mask) \
+ ( (value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask)))-1) )
+template <>
+void UnwindPrinter<x86_64>::decode(uint32_t encoding, const uint8_t* funcStart, char* str)
+{
+ *str = '\0';
+ switch ( encoding & UNWIND_X86_64_MODE_MASK ) {
+ case UNWIND_X86_64_MODE_RBP_FRAME:
+ {
+ uint32_t savedRegistersOffset = EXTRACT_BITS(encoding, UNWIND_X86_64_RBP_FRAME_OFFSET);
+ uint32_t savedRegistersLocations = EXTRACT_BITS(encoding, UNWIND_X86_64_RBP_FRAME_REGISTERS);
+ if ( savedRegistersLocations == 0 ) {
+ strcpy(str, "rbp frame, no saved registers");
+ }
+ else {
+ sprintf(str, "rbp frame, at -%d:", savedRegistersOffset*8);
+ bool needComma = false;
+ for (int i=0; i < 5; ++i) {
+ if ( needComma )
+ strcat(str, ",");
+ else
+ needComma = true;
+ switch (savedRegistersLocations & 0x7) {
+ case UNWIND_X86_64_REG_NONE:
+ strcat(str, "-");
+ break;
+ case UNWIND_X86_64_REG_RBX:
+ strcat(str, "rbx");
+ break;
+ case UNWIND_X86_64_REG_R12:
+ strcat(str, "r12");
+ break;
+ case UNWIND_X86_64_REG_R13:
+ strcat(str, "r13");
+ break;
+ case UNWIND_X86_64_REG_R14:
+ strcat(str, "r14");
+ break;
+ case UNWIND_X86_64_REG_R15:
+ strcat(str, "r15");
+ break;
+ default:
+ strcat(str, "r?");
+ }
+ savedRegistersLocations = (savedRegistersLocations >> 3);
+ if ( savedRegistersLocations == 0 )
+ break;
+ }
+ }
+ }
+ break;
+ case UNWIND_X86_64_MODE_STACK_IMMD:
+ case UNWIND_X86_64_MODE_STACK_IND:
+ {
+ uint32_t stackSize = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);
+ uint32_t stackAdjust = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST);
+ uint32_t regCount = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT);
+ uint32_t permutation = EXTRACT_BITS(encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION);
+ if ( (encoding & UNWIND_X86_64_MODE_MASK) == UNWIND_X86_64_MODE_STACK_IND ) {
+ // stack size is encoded in subl $xxx,%esp instruction
+ uint32_t subl = x86_64::P::E::get32(*((uint32_t*)(funcStart+stackSize)));
+ sprintf(str, "stack size=0x%08X, ", subl + 8*stackAdjust);
+ }
+ else {
+ sprintf(str, "stack size=%d, ", stackSize*8);
+ }
+ if ( regCount == 0 ) {
+ strcat(str, "no registers saved");
+ }
+ else {
+ int permunreg[6];
+ switch ( regCount ) {
+ case 6:
+ permunreg[0] = permutation/120;
+ permutation -= (permunreg[0]*120);
+ permunreg[1] = permutation/24;
+ permutation -= (permunreg[1]*24);
+ permunreg[2] = permutation/6;
+ permutation -= (permunreg[2]*6);
+ permunreg[3] = permutation/2;
+ permutation -= (permunreg[3]*2);
+ permunreg[4] = permutation;
+ permunreg[5] = 0;
+ break;
+ case 5:
+ permunreg[0] = permutation/120;
+ permutation -= (permunreg[0]*120);
+ permunreg[1] = permutation/24;
+ permutation -= (permunreg[1]*24);
+ permunreg[2] = permutation/6;
+ permutation -= (permunreg[2]*6);
+ permunreg[3] = permutation/2;
+ permutation -= (permunreg[3]*2);
+ permunreg[4] = permutation;
+ break;
+ case 4:
+ permunreg[0] = permutation/60;
+ permutation -= (permunreg[0]*60);
+ permunreg[1] = permutation/12;
+ permutation -= (permunreg[1]*12);
+ permunreg[2] = permutation/3;
+ permutation -= (permunreg[2]*3);
+ permunreg[3] = permutation;
+ break;
+ case 3:
+ permunreg[0] = permutation/20;
+ permutation -= (permunreg[0]*20);
+ permunreg[1] = permutation/4;
+ permutation -= (permunreg[1]*4);
+ permunreg[2] = permutation;
+ break;
+ case 2:
+ permunreg[0] = permutation/5;
+ permutation -= (permunreg[0]*5);
+ permunreg[1] = permutation;
+ break;
+ case 1:
+ permunreg[0] = permutation;
+ break;
+ }
+ // renumber registers back to standard numbers
+ int registers[6];
+ bool used[7] = { false, false, false, false, false, false, false };
+ for (int i=0; i < regCount; ++i) {
+ int renum = 0;
+ for (int u=1; u < 7; ++u) {
+ if ( !used[u] ) {
+ if ( renum == permunreg[i] ) {
+ registers[i] = u;
+ used[u] = true;
+ break;
+ }
+ ++renum;
+ }
+ }
+ }
+ bool needComma = false;
+ for (int i=0; i < regCount; ++i) {
+ if ( needComma )
+ strcat(str, ",");
+ else
+ needComma = true;
+ switch ( registers[i] ) {
+ case UNWIND_X86_64_REG_RBX:
+ strcat(str, "rbx");
+ break;
+ case UNWIND_X86_64_REG_R12:
+ strcat(str, "r12");
+ break;
+ case UNWIND_X86_64_REG_R13:
+ strcat(str, "r13");
+ break;
+ case UNWIND_X86_64_REG_R14:
+ strcat(str, "r14");
+ break;
+ case UNWIND_X86_64_REG_R15:
+ strcat(str, "r15");
+ break;
+ case UNWIND_X86_64_REG_RBP:
+ strcat(str, "rbp");
+ break;
+ default:
+ strcat(str, "r??");
+ }
+ }
+ }
+ }
+ break;
+ case UNWIND_X86_64_MODE_DWARF:
+ sprintf(str, "dwarf offset 0x%08X, ", encoding & UNWIND_X86_64_DWARF_SECTION_OFFSET);
+ break;
+ default:
+ if ( encoding == 0 )
+ strcat(str, "no unwind information");
+ else
+ strcat(str, "tbd ");
+ }
+ if ( encoding & UNWIND_HAS_LSDA ) {
+ strcat(str, " LSDA");
+ }
+
+}
+
+template <>
+void UnwindPrinter<x86>::decode(uint32_t encoding, const uint8_t* funcStart, char* str)
+{
+ *str = '\0';
+ switch ( encoding & UNWIND_X86_MODE_MASK ) {
+ case UNWIND_X86_MODE_EBP_FRAME:
+ {
+ uint32_t savedRegistersOffset = EXTRACT_BITS(encoding, UNWIND_X86_EBP_FRAME_OFFSET);
+ uint32_t savedRegistersLocations = EXTRACT_BITS(encoding, UNWIND_X86_EBP_FRAME_REGISTERS);
+ if ( savedRegistersLocations == 0 ) {
+ strcpy(str, "ebp frame, no saved registers");
+ }
+ else {
+ sprintf(str, "ebp frame, at -%d:", savedRegistersOffset*4);
+ bool needComma = false;
+ for (int i=0; i < 5; ++i) {
+ if ( needComma )
+ strcat(str, ",");
+ else
+ needComma = true;
+ switch (savedRegistersLocations & 0x7) {
+ case UNWIND_X86_REG_NONE:
+ strcat(str, "-");
+ break;
+ case UNWIND_X86_REG_EBX:
+ strcat(str, "ebx");
+ break;
+ case UNWIND_X86_REG_ECX:
+ strcat(str, "ecx");
+ break;
+ case UNWIND_X86_REG_EDX:
+ strcat(str, "edx");
+ break;
+ case UNWIND_X86_REG_EDI:
+ strcat(str, "edi");
+ break;
+ case UNWIND_X86_REG_ESI:
+ strcat(str, "esi");
+ break;
+ default:
+ strcat(str, "e??");
+ }
+ savedRegistersLocations = (savedRegistersLocations >> 3);
+ if ( savedRegistersLocations == 0 )
+ break;
+ }
+ }
+ }
+ break;
+ case UNWIND_X86_MODE_STACK_IMMD:
+ case UNWIND_X86_MODE_STACK_IND:
+ {
+ uint32_t stackSize = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);
+ uint32_t stackAdjust = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_ADJUST);
+ uint32_t regCount = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT);
+ uint32_t permutation = EXTRACT_BITS(encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION);
+ if ( (encoding & UNWIND_X86_MODE_MASK) == UNWIND_X86_MODE_STACK_IND ) {
+ // stack size is encoded in subl $xxx,%esp instruction
+ uint32_t subl = x86::P::E::get32(*((uint32_t*)(funcStart+stackSize)));
+ sprintf(str, "stack size=0x%08X, ", subl+4*stackAdjust);
+ }
+ else {
+ sprintf(str, "stack size=%d, ", stackSize*4);
+ }
+ if ( regCount == 0 ) {
+ strcat(str, "no saved regs");
+ }
+ else {
+ int permunreg[6];
+ switch ( regCount ) {
+ case 6:
+ permunreg[0] = permutation/120;
+ permutation -= (permunreg[0]*120);
+ permunreg[1] = permutation/24;
+ permutation -= (permunreg[1]*24);
+ permunreg[2] = permutation/6;
+ permutation -= (permunreg[2]*6);
+ permunreg[3] = permutation/2;
+ permutation -= (permunreg[3]*2);
+ permunreg[4] = permutation;
+ permunreg[5] = 0;
+ break;
+ case 5:
+ permunreg[0] = permutation/120;
+ permutation -= (permunreg[0]*120);
+ permunreg[1] = permutation/24;
+ permutation -= (permunreg[1]*24);
+ permunreg[2] = permutation/6;
+ permutation -= (permunreg[2]*6);
+ permunreg[3] = permutation/2;
+ permutation -= (permunreg[3]*2);
+ permunreg[4] = permutation;
+ break;
+ case 4:
+ permunreg[0] = permutation/60;
+ permutation -= (permunreg[0]*60);
+ permunreg[1] = permutation/12;
+ permutation -= (permunreg[1]*12);
+ permunreg[2] = permutation/3;
+ permutation -= (permunreg[2]*3);
+ permunreg[3] = permutation;
+ break;
+ case 3:
+ permunreg[0] = permutation/20;
+ permutation -= (permunreg[0]*20);
+ permunreg[1] = permutation/4;
+ permutation -= (permunreg[1]*4);
+ permunreg[2] = permutation;
+ break;
+ case 2:
+ permunreg[0] = permutation/5;
+ permutation -= (permunreg[0]*5);
+ permunreg[1] = permutation;
+ break;
+ case 1:
+ permunreg[0] = permutation;
+ break;
+ }
+ // renumber registers back to standard numbers
+ int registers[6];
+ bool used[7] = { false, false, false, false, false, false, false };
+ for (int i=0; i < regCount; ++i) {
+ int renum = 0;
+ for (int u=1; u < 7; ++u) {
+ if ( !used[u] ) {
+ if ( renum == permunreg[i] ) {
+ registers[i] = u;
+ used[u] = true;
+ break;
+ }
+ ++renum;
+ }
+ }
+ }
+ bool needComma = false;
+ for (int i=0; i < regCount; ++i) {
+ if ( needComma )
+ strcat(str, ",");
+ else
+ needComma = true;
+ switch ( registers[i] ) {
+ case UNWIND_X86_REG_EBX:
+ strcat(str, "ebx");
+ break;
+ case UNWIND_X86_REG_ECX:
+ strcat(str, "ecx");
+ break;
+ case UNWIND_X86_REG_EDX:
+ strcat(str, "edx");
+ break;
+ case UNWIND_X86_REG_EDI:
+ strcat(str, "edi");
+ break;
+ case UNWIND_X86_REG_ESI:
+ strcat(str, "esi");
+ break;
+ case UNWIND_X86_REG_EBP:
+ strcat(str, "ebp");
+ break;
+ default:
+ strcat(str, "e??");
+ }
+ }
+ }
+ }
+ break;
+ case UNWIND_X86_MODE_DWARF:
+ sprintf(str, "dwarf offset 0x%08X, ", encoding & UNWIND_X86_DWARF_SECTION_OFFSET);
+ break;
+ default:
+ if ( encoding == 0 )
+ strcat(str, "no unwind information");
+ else
+ strcat(str, "tbd ");
+ }
+ if ( encoding & UNWIND_HAS_LSDA ) {
+ strcat(str, " LSDA");
+ }
+
+}
+
+
+template <typename A>
+void UnwindPrinter<A>::decode(uint32_t encoding, const uint8_t* funcStart, char* str)
+{
+
+
+}
template <typename A>
void UnwindPrinter<A>::printUnwindSection()
printf("\tcommon encodings: (count=%u)\n", sectionHeader->commonEncodingsArrayCount());
const uint32_t* commonEncodings = (uint32_t*)§ionContent[sectionHeader->commonEncodingsArraySectionOffset()];
for (uint32_t i=0; i < sectionHeader->commonEncodingsArrayCount(); ++i) {
- printf("\t\tencoding[%2u]=0x%08X\n", i, A::P::E::get32(commonEncodings[i]));
+ printf("\t\tencoding[%3u]=0x%08X\n", i, A::P::E::get32(commonEncodings[i]));
}
printf("\tpersonalities: (count=%u)\n", sectionHeader->personalityArrayCount());
const uint32_t* personalityArray = (uint32_t*)§ionContent[sectionHeader->personalityArraySectionOffset()];
printf("\t\tentryCount=0x%08X\n", page->entryCount());
const macho_unwind_info_regular_second_level_entry<P>* entry = (macho_unwind_info_regular_second_level_entry<P>*)((char*)page+page->entryPageOffset());
for (uint32_t j=0; j < page->entryCount(); ++j) {
+ uint32_t funcOffset = entry[j].functionOffset();
if ( entry[j].encoding() & UNWIND_HAS_LSDA ) {
// verify there is a corresponding entry in lsda table
bool found = false;
- uint32_t funcOffset = entry[j].functionOffset();
for (uint32_t k=0; k < lsdaIndexArrayCount; ++k) {
if ( lindex[k].functionOffset() == funcOffset ) {
found = true;
fprintf(stderr, "MISSING LSDA entry for %s\n", functionName(funcOffset+fMachHeaderAddress));
}
}
- printf("\t\t\t[%3u] funcOffset=0x%08X, encoding=0x%08X %s\n",
- j, entry[j].functionOffset(), entry[j].encoding(), functionName(entry[j].functionOffset()+fMachHeaderAddress));
+ char encodingString[100];
+ decode(entry[j].encoding(), ((const uint8_t*)fHeader)+funcOffset, encodingString);
+ printf("\t\t\t[%3u] funcOffset=0x%08X, encoding=0x%08X (%-40s) %s\n",
+ j, funcOffset, entry[j].encoding(), encodingString, functionName(funcOffset+fMachHeaderAddress));
}
}
else if ( page->kind() == UNWIND_SECOND_LEVEL_COMPRESSED ) {
encoding = A::P::E::get32(commonEncodings[encodingIndex]);
else
encoding = A::P::E::get32(encodings[encodingIndex-sectionHeader->commonEncodingsArrayCount()]);
+ char encodingString[100];
uint32_t funcOff = UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entries[j])+baseFunctionOffset;
+ decode(encoding, ((const uint8_t*)fHeader)+funcOff, encodingString);
const char* name = functionName(funcOff+fMachHeaderAddress);
if ( encoding & UNWIND_HAS_LSDA ) {
// verify there is a corresponding entry in lsda table
fprintf(stderr, "MISSING LSDA entry for %s\n", name);
}
}
- printf("\t\t\t[%3u] funcOffset=0x%08X, encoding[%2u]=0x%08X %s\n",
- j, funcOff, encodingIndex, encoding, name);
+ printf("\t\t\t[%3u] funcOffset=0x%08X, encoding[%3u]=0x%08X (%-40s) %s\n",
+ j, funcOff, encodingIndex, encoding, encodingString, name);
}
}
else {
##
-# Copyright (c) 2008 Apple Inc. All rights reserved.
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
#
# @APPLE_LICENSE_HEADER_START@
#
TESTROOT = ../..
include ${TESTROOT}/include/common.makefile
-ifeq ($(ARCH),armv6)
- ARCH_FLAGS = -mlong-branch
-else
- ARCH_FLAGS =
-endif
-
-
#
# Simple test for branch islands
run: all
-
all:
${CC} ${CCFLAGS} hello.c space.s extra.c -o hello ${ARCH_FLAGS}
${PASS_IFF_GOOD_MACHO} hello
-#if __ppc__
+#if __ppc__
.text
#if __arm__
+ .text
+_prejunk:
+ mov r0, #1
+ nop
+
+#if __thumb2__
+ // thumb2 branches are +/- 16MB
+_space1:
+ .space 14*1024*1024
+_space2:
+ .space 14*1024*1024
+_space3:
+ .space 14*1024*1024
+
+#elif __thumb__
+ // thumb1 branches are +/- 4MB
_space1:
- .space 32*1024*1024 + 2
+ .space 3*1024*1024
+_space2:
+ .space 3*1024*1024
+_space3:
+ .space 3*1024*1024
+
+#else
+ // ARM branches are +/- 32MB
+_space1:
+ .space 14*1024*1024
+_space2:
+ .space 14*1024*1024
+_space3:
+ .space 14*1024*1024
#endif
+ .align 5
+_junk:
+ mov r0, #1
+ nop
+
+
+_space4:
+ .space 2*1024*1024
+#endif
.subsections_via_symbols
-
\ No newline at end of file
##
-# Copyright (c) 2008 Apple Inc. All rights reserved.
+# Copyright (c) 2008-2009 Apple Inc. All rights reserved.
#
# @APPLE_LICENSE_HEADER_START@
#
include ${TESTROOT}/include/common.makefile
#
-# Test that utf16 cfstring literals are not coalesced.
+# Test that utf16 cfstring literals are coalesced.
# There is 3 CFSTR in foo.m and 1 CFSTR in bar.m
-# After coalescing and dead stripping there should be only one CFSTR in the output
+# After coalescing and dead stripping there should be only two CFSTR in the output
#
ifeq (,${findstring 64,$(ARCH)})
- CFSTRING_SIZE = 48
+ CFSTRING_SIZE = 32
else
- CFSTRING_SIZE = 96
+ CFSTRING_SIZE = 64
endif
- USTRING_SIZE = 37
+ USTRING_SIZE = 27
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Test the if all symbols from a dylib are weak_import, that the whole dylib is weakly loaded
+#
+
+run: all-${ARCH}
+
+
+all-ppc:
+ ${PASS_IFF} true
+
+all-arm:
+ ${PASS_IFF} true
+
+all-i386: all-real
+
+all-x86_64: all-real
+
+
+all-real:
+ ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib
+ ${FAIL_IF_BAD_MACHO} libfoo.dylib
+
+ ${CC} ${CCFLAGS} main.c -o main libfoo.dylib
+ dyldinfo -bind main | grep wfoo | ${FAIL_IF_EMPTY}
+
+ ${PASS_IFF_GOOD_MACHO} main
+
+
+clean:
+ rm -rf libfoo.dylib main
--- /dev/null
+
+
+__attribute__((weak)) void wfoo() {}
+void foo() {}
--- /dev/null
+
+extern void foo();
+extern void wfoo();
+
+void* pfoo = &foo;
+void* pwfoo = &wfoo;
+
+int main (void)
+{
+ if (pfoo != &foo)
+ return 1;
+ if (pwfoo != &wfoo)
+ return 1;
+
+ return 0;
+}
+
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Check that __cstring sections in other segments are not coalesced
+#<rdar://problem/6535736> ld coalesces C strings in different segments
+#
+
+run: all
+
+all:
+ ${CC} ${CCFLAGS} main.c custom.s -o main
+ size -l main | grep __cstring | wc -l | grep 2 | ${FAIL_IF_EMPTY}
+ ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+ rm main
--- /dev/null
+
+
+
+ .section __MYSEG, __cstring, cstring_literals
+LC: .ascii "hello"
+
+
+
--- /dev/null
+#include <stdio.h>
+
+int main()
+{
+ printf("hello");
+ return 0;
+}
+void func() {}
+
const char kFoo[] = "foo";
const char* kFoo2 = "hello";
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Test that N_NO_DEAD_STRIP bit survives ld -r
+#
+
+run: all
+
+all:
+ ${CC} ${CCFLAGS} main.c -c -o main.o
+ nm -m main.o | grep _bar | grep "no dead strip" | ${FAIL_IF_EMPTY}
+ nm -m main.o | grep _foo | grep "no dead strip" | ${FAIL_IF_EMPTY}
+ ${LD} -r main.o -o main2.o
+ nm -m main2.o | grep _bar | grep "no dead strip" | ${FAIL_IF_EMPTY}
+ nm -m main2.o | grep _foo | grep "no dead strip" | ${FAIL_IF_EMPTY}
+ ${CC} main2.o -o main
+ nm -m main | grep _bar | grep "no dead strip" | ${PASS_IFF_EMPTY}
+
+clean:
+ rm -rf main.o main2.o main
--- /dev/null
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+__attribute__((used)) static void foo()
+{
+}
+
+
+__attribute__((used)) void bar()
+{
+}
+
+
+int main()
+{
+ foo();
+ bar();
+ return 0;
+}
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Check that symbols in no-dead-strip sections can be coalesced.
+# <rdar://problem/6578360> -dead_strip inhibits weak coalescing in no_dead_strip section
+#
+
+run: all
+
+all:
+ ${CC} ${CCFLAGS} baz.c -c -o baz.o
+ libtool -static baz.o -o libbaz.a
+ ${CC} ${CCFLAGS} main.c foo.c libbaz.a -dead_strip -o main
+ nm -j main | grep _hidden | wc -l | grep 1 | ${FAIL_IF_EMPTY}
+ ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+ rm -rf main baz.o libbaz.a
--- /dev/null
+void baz()
+{
+}
+
+
+#include "foo.c"
+
--- /dev/null
+
+// function can be coalesced and should not be dead stripped
+void __attribute__ ((weak, section ("__TEXT,__text_no_strip,regular,no_dead_strip"))) foo()
+{
+
+}
+
+
+// function should not be exported, can be coalesced, and should not be dead stripped
+void __attribute__ ((weak, visibility("hidden"), section ("__TEXT,__text_no_strip,regular,no_dead_strip"))) hidden()
+{
+
+}
+
+// bar should be dead stripped
+void __attribute__ ((weak, section ("__DATA,__text2"))) bar()
+{
+
+}
+
+__attribute__((constructor)) static void init()
+{
+ foo();
+ hidden();
+}
--- /dev/null
+
+// baz is in a lazily loaded archive
+extern void baz();
+
+int main()
+{
+ baz();
+ return 0;
+}
+
+
+#include "foo.c"
+
${LD} -r foo.no.o bar.no.o baz.no.o -o foobarbaz.no.o
${OBJECTDUMP} -no_content -no_sort foobarbaz.o > foobarbaz.dump
${OBJECTDUMP} -no_content -no_sort foobarbaz.no.o > foobarbaz.no.dump
- ${FAIL_IF_ERROR} dwarfdump --eh-frame --verify >/dev/null
+ ${FAIL_IF_ERROR} dwarfdump --eh-frame --verify foobarbaz.no.o >/dev/null
${PASS_IFF_SUCCESS} diff foobarbaz.dump foobarbaz.no.dump
run: all
all:
- ${CXX} ${CXXFLAGS} main.cxx foo.cxx bar.cxx -o main
- nm -s __TEXT __text -nj main | c++filt > actual-order.txt
+ ${CXX} ${CXXFLAGS} main.cxx foo.cxx bar.cxx -o main -dead_strip
+ nm -s __TEXT __text -nj main | grep -v dyld_stub_binding_helper | c++filt > actual-order.txt
${PASS_IFF} diff actual-order.txt expected-order.txt
__static_initialization_and_destruction_0(int, int)
global constructors keyed to b1
start
-dyld_stub_binding_helper
-__dyld_func_lookup
_main
M::~M()
Foo::~Foo()
nm -nm mykext | grep '(undefined) external _extern_global' | ${FAIL_IF_EMPTY}
nm -nm mykext | grep '(__DATA,__data) external _my_global' | ${FAIL_IF_EMPTY}
otool -rv mykext | grep '_extern_global' | ${FAIL_IF_EMPTY}
- otool -rv mykext | grep '_OSRuntimeFinalizeCPP' | ${FAIL_IF_EMPTY}
${PASS_IFF} true
clean:
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# <rdar://problem/6806033> Link Time Optimization error with 'dead code strip' + hidden symbol
+#
+
+LLVMGCC = /Developer/usr/bin/llvm-gcc-4.2 -arch ${ARCH}
+LLVMGXX = /Developer/usr/bin/llvm-g++-4.2 -arch ${ARCH}
+
+run: all
+
+all:
+ ${LLVMGCC} ${CCFLAGS} --emit-llvm bar.c -c -o bar.o -fvisibility=hidden
+ ${LLVMGCC} ${CCFLAGS} -dynamiclib bar.o -o libbar.dylib -dead_strip
+ ${PASS_IFF_GOOD_MACHO} libbar.dylib
+
+clean:
+ rm bar.o libbar.dylib
--- /dev/null
+
+
+void bar() {}
+
run: all
all:
- ${LLVMGCC} ${CCFLAGS} --emit-llvm main.c -c -o main.o
+ ${LLVMGCC} ${CCFLAGS} --emit-llvm main.c -c -o main.o -fvisibility=hidden
${LLVMGCC} ${CCFLAGS} main.o -o main
nm main | grep _foo | ${FAIL_IF_STDIN}
- ${LLVMGCC} ${CCFLAGS} main.o -o main2 -Wl,-mllvm -Wl,--disable-inlining
+ ${LLVMGCC} ${CCFLAGS} main.o -o main2 -fvisibility=hidden -Wl,-mllvm -Wl,--disable-inlining
nm main2 | grep _foo | ${FAIL_IF_EMPTY}
${PASS_IFF_GOOD_MACHO} main
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# <rdar://problem/6927148> link failure with -O4 on i386#
+# Check that LTO can bring in an ObjC class from an archive member
+#
+
+LLVMGCC = /Developer/usr/bin/llvm-gcc-4.2 -arch ${ARCH}
+LLVMGXX = /Developer/usr/bin/llvm-g++-4.2 -arch ${ARCH}
+
+run: all
+
+all:
+ ${CC} ${CCFLAGS} foo.m -c -o foo.o
+ ${CC} ${CCFLAGS} bar.m -c -o bar.o
+ ${CC} ${CCFLAGS} foo2.c -c -o foo2.o
+ ${CC} ${CCFLAGS} bar2.c -c -o bar2.o
+ libtool -static foo.o bar.o foo2.o bar2.o -o libfoobar.a
+ ${LLVMGCC} ${CCFLAGS} --emit-llvm main.m -c -o main.o
+ ${LLVMGCC} ${CCFLAGS} main.o -o main libfoobar.a -framework Foundation
+ ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+ rm -rf main foo.o bar.o foo2.o bar2.o libfoobar.a main.o
--- /dev/null
+#include <Foundation/Foundation.h>
+
+@interface Bar : NSObject
+@end
+
+extern void bar2();
--- /dev/null
+#include "bar.h"
+
+@implementation Bar
+- (void) test {
+ bar2();
+}
+@end
--- /dev/null
+
+void bar2() {}
--- /dev/null
+#include <Foundation/Foundation.h>
+
+@interface Foo : NSObject
+@end
+
+
+extern void foo2();
+
--- /dev/null
+
+#include "foo.h"
+
+@implementation Foo
+- (void) test {
+ foo2();
+}
+@end
--- /dev/null
+
+void foo2() {}
--- /dev/null
+
+#include <Foundation/Foundation.h>
+#include "foo.h"
+#include "bar.h"
+
+
+@interface FooSubClass : Foo
+@end
+
+
+@implementation FooSubClass
+@end
+
+
+int main()
+{
+ [Bar alloc];
+ return 0;
+}
+
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# <rdar://problem/6927148> link failure with -O4 on i386#
+# Check that LTO can bring in an ObjC class from an archive member
+#
+
+LLVMGCC = /Developer/usr/bin/llvm-gcc-4.2 -arch ${ARCH}
+LLVMGXX = /Developer/usr/bin/llvm-g++-4.2 -arch ${ARCH}
+
+run: all
+
+all:
+ ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib
+ ${LLVMGCC} ${CCFLAGS} --emit-llvm main.c -c -o main.o
+ ${LLVMGCC} ${CCFLAGS} main.o -o main libfoo.dylib
+ ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+ rm -rf main main.o libfoo.dylib
--- /dev/null
+
+
+void foo() {}
--- /dev/null
+
+#include <stdlib.h>
+
+extern void foo() __attribute__((weak_import));
+
+
+int main()
+{
+ if ( &foo != NULL )
+ foo();
+ return 0;
+}
+
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Check that a bundle built with no data links
+# <rdar://problem/6532377> gcc DejaGnu failure: building longcall/dylib library
+#
+
+run: all
+
+all:
+ ${CC} ${CCFLAGS} foo.c -bundle -o foo.bundle
+ ${PASS_IFF_GOOD_MACHO} foo.bundle
+
+clean:
+ rm foo.bundle
--- /dev/null
+#include <stdlib.h>
+
+void foo()
+{
+ rand();
+}
\ No newline at end of file
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+
+#
+# Verify an Objective-C object file when run through
+# ld -r -x
+# <rdar://problem/6605499> x86_64 obj-c runtime confused when static lib is stripped
+#
+#
+
+SELECTOR_REFS = "__OBJC,__message_refs"
+
+ifeq ($(ARCH),x86_64)
+ SELECTOR_REFS = "__DATA,__objc_selrefs"
+endif
+ifeq ($(ARCH),armv6)
+ SELECTOR_REFS = "__DATA,__objc_selrefs"
+endif
+
+
+
+run: all
+
+all:
+ ${CC} ${CCFLAGS} test.m -c -o test.o
+ ${OBJECTDUMP} -no_content test.o | grep -B3 -A6 ${SELECTOR_REFS} > test.dump
+
+ ${LD} -arch ${ARCH} -r test.o -x -o test-r.o
+ ${OBJECTDUMP} -no_content test-r.o | grep -B3 -A6 ${SELECTOR_REFS} > test-r.dump
+
+ diff test.dump test-r.dump | ${PASS_IFF_EMPTY}
+
+clean:
+ rm -rf test.o test.dump test-r.o test-r.dump
--- /dev/null
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+@interface Foo @end
+@implementation Foo
++(void)initialize { }
++(void)foo {
+ fprintf(stderr, "GOOD\n");
+ exit(0);
+}
++(void)bar {
+ fprintf(stderr, "BAD\n");
+ abort();
+}
+@end
+
+void PublicFunction(void)
+{
+ [Foo foo];
+ [Foo bar];
+}
##
-# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
#
# @APPLE_LICENSE_HEADER_START@
#
# verify if operator new is overridden that WEAK_DEFINES is set
${CXX} ${CXXFLAGS} -DOP_NEW -I${TESTROOT}/include -o main main.cxx
otool -hv main | grep WEAK_DEFINES | ${FAIL_IF_EMPTY}
+ # verify if operator new is overridden but not exported, WEAK_DEFINES is not set
+ ${CXX} ${CXXFLAGS} -DOP_NEW -I${TESTROOT}/include -o main main.cxx -Wl,-exported_symbol,_main
+ otool -hv main | grep WEAK_DEFINES | ${FAIL_IF_STDIN}
# verify if operator new is not overridden that WEAK_DEFINES is not set
${CXX} ${CXXFLAGS} -I${TESTROOT}/include -o main main.cxx
otool -hv main | grep WEAK_DEFINES | ${PASS_IFF_EMPTY}
#if OP_NEW
void* operator new(size_t s) throw (std::bad_alloc)
{
- return malloc(s);;
+ return malloc(s);
}
#endif
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Test that a public re-exported library is automatically added as a dependent
+# unless nothing is used from it.
+#
+
+
+run: all
+
+all:
+
+# -sub_library for 10.4
+ ${CC} ${CCFLAGS} -dynamiclib bar.c -o libbar.dylib -install_name /usr/lib/libbar.dylib -mmacosx-version-min=10.4
+ ${FAIL_IF_BAD_MACHO} libbar.dylib
+ ${CC} ${CCFLAGS} -dynamiclib middle.c -o libmiddle.dylib -lbar -L. -sub_library libbar -install_name /mid/libmiddle.dylib -mmacosx-version-min=10.4
+ ${FAIL_IF_BAD_MACHO} libmiddle.dylib
+ ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -lmiddle -L. -sub_library libmiddle -install_name /usr/lib/libfoo.dylib -mmacosx-version-min=10.4
+ ${FAIL_IF_BAD_MACHO} libfoo.dylib
+ ${CC} ${CCFLAGS} -dynamiclib other.c -o libother.dylib -lbar -L. -sub_library libbar -install_name /usr/lib/libother.dylib -mmacosx-version-min=10.4
+ ${FAIL_IF_BAD_MACHO} libother.dylib
+ ${CC} ${CCFLAGS} main.c -DCALL_BAR libfoo.dylib libother.dylib -o main -L. -mmacosx-version-min=10.4
+ nm -m main | grep _bar | grep libbar | ${FAIL_IF_EMPTY}
+ ${PASS_IFF_GOOD_MACHO} main
+
+# -sub_library for 10.5
+ ${CC} ${CCFLAGS} -dynamiclib bar.c -o libbar.dylib -install_name /usr/lib/libbar.dylib -mmacosx-version-min=10.5
+ ${FAIL_IF_BAD_MACHO} libbar.dylib
+ ${CC} ${CCFLAGS} -dynamiclib middle.c -o libmiddle.dylib -lbar -L. -sub_library libbar -install_name /mid/libmiddle.dylib -mmacosx-version-min=10.5
+ ${FAIL_IF_BAD_MACHO} libmiddle.dylib
+ ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -lmiddle -L. -sub_library libmiddle -install_name /usr/lib/libfoo.dylib -mmacosx-version-min=10.5
+ ${FAIL_IF_BAD_MACHO} libfoo.dylib
+ ${CC} ${CCFLAGS} -dynamiclib other.c -o libother.dylib -lbar -L. -sub_library libbar -install_name /usr/lib/libother.dylib -mmacosx-version-min=10.5
+ ${FAIL_IF_BAD_MACHO} libother.dylib
+ ${CC} ${CCFLAGS} main.c -DCALL_BAR libfoo.dylib libother.dylib -o main -L. -mmacosx-version-min=10.5
+ nm -m main | grep _bar | grep libbar | ${FAIL_IF_EMPTY}
+ ${PASS_IFF_GOOD_MACHO} main
+
+
+clean:
+ rm -rf libbar.dylib libfoo.dylib libmiddle.dylib libother.dylib main
--- /dev/null
+
+int bar (void)
+{
+ return 1;
+}
--- /dev/null
+int foo (void)
+{
+ return 1;
+}
--- /dev/null
+
+extern void bar();
+
+int main()
+{
+ bar();
+ return 0;
+}
--- /dev/null
+
+void middle() {}
+
--- /dev/null
+void other() {}
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# <rdar://problem/6583757> i386 relocation error with negative offsets from local labels
+#
+
+ifeq (${ARCH},i386)
+ TARGET = run-i386
+else
+ TARGET = run-other
+endif
+
+run: ${TARGET}
+
+run-other:
+ ${PASS_IFF} /usr/bin/true
+
+
+run-i386:
+ ${CC} ${ASMFLAGS} test.s -c -o test.o
+ ${OBJECTDUMP} test.o | grep "__data@0 plus 0xFFFFFFE2" | ${FAIL_IF_EMPTY}
+
+ ${LD} -arch ${ARCH} -r -keep_private_externs test.o -o test-r.o
+ ${OBJECTDUMP} test-r.o | grep "__data@0 plus 0xFFFFFFE2" | ${PASS_IFF_STDIN}
+
+
+clean:
+ rm -rf *.o
--- /dev/null
+/*
+ * Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+
+#if __i386__
+ .text
+ .align 2
+
+_negative_offset_from_local_label:
+ nop
+ .space 100
+ movl -80+L3(,%eax,4), %edx
+ ret
+
+ .data
+L2: .space 50
+L3: .space 50
+_d: .long 0
+
+#endif
+
+
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Validate long section names are preserved
+# <rdar://problem/6805002> corrupt metaclass entry in dynamic library
+#
+
+all:
+ ${CC} ${CCFLAGS} main.c a.s c.s b.s -o main
+ nm -m main | grep __aaaaaaaaaaaaaa | grep __TEXT | grep _at | ${FAIL_IF_EMPTY}
+ nm -m main | grep __bbbbbbbbbbbbbb | grep __TEXT | grep _bt | ${FAIL_IF_EMPTY}
+ nm -m main | grep __cccccccccccccc | grep __TEXT | grep _ct | ${FAIL_IF_EMPTY}
+ nm -m main | grep __aaaaaaaaaaaaaa | grep __DATA | grep _ad | ${FAIL_IF_EMPTY}
+ nm -m main | grep __bbbbbbbbbbbbbb | grep __DATA | grep _bd | ${FAIL_IF_EMPTY}
+ nm -m main | grep __cccccccccccccc | grep __DATA | grep _cd | ${FAIL_IF_EMPTY}
+ ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+ rm -rf main
--- /dev/null
+
+ .section __TEXT,__aaaaaaaaaaaaaa
+_at: .space 128
+
+ .section __DATA,__aaaaaaaaaaaaaa
+_ad: .space 128
+
+
+
--- /dev/null
+
+ .section __TEXT,__bbbbbbbbbbbbbb
+_bt: .space 128
+
+ .section __DATA,__bbbbbbbbbbbbbb
+_bd: .space 128
+
+
+
--- /dev/null
+
+ .section __TEXT,__cccccccccccccc
+_ct: .space 128
+
+
+ .section __DATA,__cccccccccccccc
+_cd: .space 128
+
+
+
+
--- /dev/null
+
+
+int main() { return 0; }
+
--- /dev/null
+##
+# Copyright (c) 2009 Apple Inc. All rights reserved.
+#
+# @APPLE_LICENSE_HEADER_START@
+#
+# This file contains Original Code and/or Modifications of Original Code
+# as defined in and that are subject to the Apple Public Source License
+# Version 2.0 (the 'License'). You may not use this file except in
+# compliance with the License. Please obtain a copy of the License at
+# http://www.opensource.apple.com/apsl/ and read it before using this
+# file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+# Please see the License for the specific language governing rights and
+# limitations under the License.
+#
+# @APPLE_LICENSE_HEADER_END@
+##
+TESTROOT = ../..
+include ${TESTROOT}/include/common.makefile
+
+#
+# Verify only dylibs with install paths in /System/Library or /usr/lib
+# get LC_SEGMENT_SPLIT_INFO
+#
+
+
+run: all
+
+all:
+ ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib -install_name /usr/lib/libfoo.dylib
+ otool -lv libfoo.dylib | grep LC_SEGMENT_SPLIT_INFO | ${FAIL_IF_EMPTY}
+ ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib -install_name /System/Library/Frameworks/Foo.framework/Foo
+ otool -lv libfoo.dylib | grep LC_SEGMENT_SPLIT_INFO | ${FAIL_IF_EMPTY}
+ ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib -install_name /usr/local/lib/libfoo.dylib
+ otool -lv libfoo.dylib | grep LC_SEGMENT_SPLIT_INFO | ${FAIL_IF_STDIN}
+ ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib
+ otool -lv libfoo.dylib | grep LC_SEGMENT_SPLIT_INFO | ${FAIL_IF_STDIN}
+ ${PASS_IFF_GOOD_MACHO} libfoo.dylib
+
+clean:
+ rm libfoo.dylib
--- /dev/null
+
+void foo() {}
+
##
-# Copyright (c) 2007 Apple Inc. All rights reserved.
+# Copyright (c) 2007-2009 Apple Inc. All rights reserved.
#
# @APPLE_LICENSE_HEADER_START@
#
TESTROOT = ../..
include ${TESTROOT}/include/common.makefile
-ifeq "${ARCH}" "i386"
- POINTER_SEGMENT = __IMPORT
- POINTER_SECTION = __pointers
-else
- POINTER_SEGMENT = __DATA
- POINTER_SECTION = __nl_symbol_ptr
-endif
+POINTER_SEGMENT = __DATA
+POINTER_SECTION = __nl_symbol_ptr
#
# Test that using strip -R to selectively strip symbol names
# of of a .o file still works with ld.
+# And for i386 that there are no __IMPORT/__pointers left <rdar://problem/6666004>
#
run: all
${CC} ${CCFLAGS} all.o -dynamiclib -o dylib2
otool -X -s ${POINTER_SEGMENT} ${POINTER_SECTION} dylib1 >dylib1.pointers
otool -X -s ${POINTER_SEGMENT} ${POINTER_SECTION} dylib2 >dylib2.pointers
+ size -l dylib1 | grep __IMPORT | ${FAIL_IF_STDIN}
+ size -l dylib2 | grep __IMPORT | ${FAIL_IF_STDIN}
${PASS_IFF} diff dylib1.pointers dylib2.pointers
clean:
${CC} ${CCFLAGS} -dynamiclib -single_module foo.c -o libfoo-${ARCH}.dylib
${FAIL_IF_BAD_MACHO} libfoo-${ARCH}.dylib
- ${CC} ${CCFLAGS} -mmacosx-version-min=10.4 main.c -o main-${ARCH} libfoo-${ARCH}.dylib
+ ${CC} ${CCFLAGS} main.c -o main-${ARCH} libfoo-${ARCH}.dylib
nm -m main-${ARCH} | grep _func1 | grep -v weak >/dev/null
nm -m main-${ARCH} | grep _func2 | grep weak >/dev/null
nm -m main-${ARCH} | grep _func3 | grep -v weak >/dev/null
nm -m main-${ARCH} | grep _data2 | grep weak >/dev/null
nm -m main-${ARCH} | grep _data3 | grep -v weak >/dev/null
nm -m main-${ARCH} | grep _data4 | grep weak >/dev/null
- otool -rv main-${ARCH} | grep _data6 > /dev/null
+ nm -m main-${ARCH} | grep _data5 | grep -v weak >/dev/null
+ nm -m main-${ARCH} | grep _data6 | grep weak >/dev/null
+ #otool -rv main-${ARCH} | grep _data6 > /dev/null
${FAIL_IF_BAD_MACHO} main-${ARCH}
- ${CC} ${CCFLAGS} -mmacosx-version-min=10.4 main.c -dynamiclib -o main-${ARCH}.dylib libfoo-${ARCH}.dylib
+ ${CC} ${CCFLAGS} main.c -dynamiclib -o main-${ARCH}.dylib libfoo-${ARCH}.dylib
nm -m main-${ARCH}.dylib | grep _func1 | grep -v weak >/dev/null
nm -m main-${ARCH}.dylib | grep _func2 | grep weak >/dev/null
nm -m main-${ARCH}.dylib | grep _func3 | grep -v weak >/dev/null
nm -m main-${ARCH}.dylib | grep _data2 | grep weak >/dev/null
nm -m main-${ARCH}.dylib | grep _data3 | grep -v weak >/dev/null
nm -m main-${ARCH}.dylib | grep _data4 | grep weak >/dev/null
- otool -rv main-${ARCH}.dylib | grep _data6 > /dev/null
+ #otool -rv main-${ARCH}.dylib | grep _data6 > /dev/null
${PASS_IFF_GOOD_MACHO} main-${ARCH}.dylib
clean: